Skip to content

Instantly share code, notes, and snippets.

@fcicq
Last active October 4, 2015 07:37
Show Gist options
  • Save fcicq/2602230 to your computer and use it in GitHub Desktop.
Save fcicq/2602230 to your computer and use it in GitHub Desktop.
Range Limited File Class
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