def __init__(self, drop): self._drop = drop self._io = IOForURL(drop.dataURL)
class DROPFile(object): """ A file-like object (currently only supporting the read() operation, more to be added in the future) that wraps the DROP given at construction time. Depending on the underlying storage of the data the file-like object returned by this method will directly access the data pointed by the DROP if possible, or will access it through the DROP methods instead. Objects of this class will automatically close themselves when no referenced anymore (i.e., when __del__ is called), but users should still try to invoke `close()` eagerly to free underlying resources. Objects of this class can also be used in a `with` context. """ def __init__(self, drop): self._drop = drop self._io = IOForURL(drop.dataURL) def open(self): if self._io: self._io.open(OpenMode.OPEN_READ) # TODO: This is still very insufficient, since when we `open` a DROP # for reading we don't only increment its reference count, # but also check that it's in a proper state, and we also # fire an 'open' event. We then should have two explicitly # different mechanisms to open a DROP, one actually opening the # underlying storage and the other not doing it (because we # do it here). # The same concerns are valid for the close() operation self._drop.incrRefCount() else: self._fd = self._drop.open() self._isClosed = False @property def closed(self): return self._isClosed def close(self): if self._isClosed: return if self._io: self._io.close() # See the comment above regarding the call to drop.incrRefCount() self._drop.decrRefCount() else: self._drop.close(self._fd) self._isClosed = True def read(self, size=4096): if self._io: return self._io.read(size) return self._drop.read(self._fd, size) # Support for the `with` keyword def __enter__(self): self.open() return self def __exit__(self, typ, value, traceback): self.close() def __del__(self): if not self._isClosed: self.close()