# -*- coding: utf-8 -*- # Copyright 2013 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """FilePart implementation for representing part of a file.""" from __future__ import absolute_import import os class FilePart(file): """Subclass of the file API for representing part of a file. This class behaves as a contiguous subset of a given file (e.g., this object will behave as though the desired part of the file was written to another file, and the second file was opened). """ # pylint: disable=super-init-not-called def __init__(self, filename, offset, length): """Initializes the FilePart. Args: filename: The name of the existing file, of which this object represents a part. offset: The position (in bytes) in the original file that corresponds to the first byte of the FilePart. length: The total number of bytes in the FilePart. """ self._fp = open(filename, 'rb') self.length = length self._start = offset self._end = self._start + self.length self._fp.seek(self._start) def __enter__(self): pass # pylint: disable=redefined-builtin def __exit__(self, type, value, traceback): self.close() def tell(self): return self._fp.tell() - self._start def read(self, size=-1): if size < 0: size = self.length size = min(size, self._end - self._fp.tell()) # Only read to our EOF return self._fp.read(max(0, size)) def seek(self, offset, whence=os.SEEK_SET): if whence == os.SEEK_END: return self._fp.seek(offset + self._end) elif whence == os.SEEK_CUR: return self._fp.seek(offset, whence) else: return self._fp.seek(self._start + offset) def close(self): self._fp.close() def flush(self, size=None): raise NotImplementedError('flush is not implemented in FilePart.') def fileno(self, size=None): raise NotImplementedError('fileno is not implemented in FilePart.') def isatty(self, size=None): raise NotImplementedError('isatty is not implemented in FilePart.') def next(self, size=None): raise NotImplementedError('next is not implemented in FilePart.') def readline(self, size=None): raise NotImplementedError('readline is not implemented in FilePart.') def readlines(self, size=None): raise NotImplementedError('readlines is not implemented in FilePart.') def xreadlines(self, size=None): raise NotImplementedError('xreadlines is not implemented in FilePart.') def truncate(self, size=None): raise NotImplementedError('truncate is not implemented in FilePart.') def write(self, size=None): raise NotImplementedError('write is not implemented in FilePart.') def writelines(self, size=None): raise NotImplementedError('writelines is not implemented in FilePart.')