Last active
October 4, 2015 07:37
-
-
Save fcicq/2602230 to your computer and use it in GitHub Desktop.
Range Limited File Class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import sys | |
try: | |
file | |
except NameError: | |
import io | |
file = io.FileIO | |
class RangeFile(file): | |
_limitstart = None | |
_limitend = None | |
def __init__(self, *args, **kwargs): | |
file.__init__(self, *args, **kwargs) | |
if sys.platform == 'win32' and self.mode.find('b') == -1: | |
raise Exception('RangeFile requires binary mode(mode=rb) for win32') | |
def fileno(self): # trick the os.fstat? | |
return -1 | |
def limitrange(self, startpos, endpos): | |
if not (isinstance(startpos, int) and isinstance(endpos, int)): | |
raise ValueError('Wrong Pos') | |
if startpos > endpos: | |
raise ValueError('Wrong Range') | |
if startpos < 0: | |
raise ValueError('Wrong Start Range') | |
file.seek(self, 0, os.SEEK_END) | |
filelen = file.tell(self) | |
if endpos >= filelen: | |
raise Exception('Wrong End Range') | |
self._limitstart = startpos | |
self._limitend = endpos | |
file.seek(self, startpos) | |
return self # make RangeFile('file').limitrange(0,100).read() possible :) | |
def tell(self): | |
if self._limitstart is None: | |
return file.tell(self) | |
return file.tell(self) - self._limitstart | |
def read(self, size=-1): | |
if self._limitstart is None: | |
return file.read(self, size) | |
currpos = file.tell(self) | |
if size < 0: | |
size = self._limitend - currpos + 1 | |
else: | |
size = min(self._limitend - currpos + 1, size) | |
return file.read(self, size) | |
def seek(self, offset, whence=0): | |
if self._limitstart is None: | |
return file.seek(self, offset, whence) | |
if whence == 0: # absolute, from beginning | |
if offset < 0: raise ValueError('no negative allowed') | |
if self._limitstart + offset <= self._limitend: | |
return file.seek(self, self._limitstart + offset) | |
else: | |
raise Exception('Range Exceeded') | |
if whence == 2: # relative to the end | |
if offset > 0: raise ValueError('no positive allowed') | |
if self._limitend + offset >= self._limitstart: | |
return file.seek(self, self._limitend + offset) | |
else: | |
raise Exception('Range Exceeded') | |
if whence != 1: raise Exception('relative to current expected') | |
pos = file.tell(self) | |
r = file.seek(self, offset, whence) | |
currpos = file.tell(self) | |
if currpos >= self._limitstart and currpos <= self._limitend: | |
return r | |
else: | |
file.seek(self, pos) | |
raise Exception('Range Exceeded') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment