Changeset 725

Show
Ignore:
Timestamp:
01/30/06 09:50:23 (3 years ago)
Author:
mfenniak
Message:

New stream objects for easier working with streams.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • pypdf/trunk/pyPdf/generic.py

    r722 r725  
    3737import re 
    3838from utils import readNonWhitespace 
     39import filters 
    3940 
    4041def readObject(stream, pdf): 
     
    311312        stream.write("<<\n") 
    312313        for key, value in self.items(): 
    313             if key != "__streamdata__": 
    314                 key.writeToStream(stream) 
    315                 stream.write(" ") 
    316                 value.writeToStream(stream) 
    317                 stream.write("\n") 
     314            key.writeToStream(stream) 
     315            stream.write(" ") 
     316            value.writeToStream(stream) 
     317            stream.write("\n") 
    318318        stream.write(">>") 
    319         if self.has_key("__streamdata__"): 
    320             stream.write("\nstream\n") 
    321             stream.write(self["__streamdata__"]) 
    322             stream.write("\nendstream") 
    323319 
    324320    def readFromStream(stream, pdf): 
    325321        assert stream.read(2) == "<<" 
    326         retval = DictionaryObject() 
     322        data = {} 
    327323        while True: 
    328324            tok = readNonWhitespace(stream) 
     
    335331            stream.seek(-1, 1) 
    336332            value = readObject(stream, pdf) 
    337             if retval.has_key(key): 
    338                 # multiple definitions of key not handled yet 
     333            if data.has_key(key): 
     334                # multiple definitions of key not permitted 
    339335                assert False 
    340             retval[key] = value 
     336            data[key] = value 
    341337        pos = stream.tell() 
    342338        s = readNonWhitespace(stream) 
     
    348344                stream.read(1) 
    349345            # this is a stream object, not a dictionary 
    350             assert retval.has_key("/Length") 
    351             length = retval["/Length"] 
     346            assert data.has_key("/Length") 
     347            length = data["/Length"] 
    352348            if isinstance(length, IndirectObject): 
    353349                t = stream.tell() 
    354350                length = pdf.getObject(length) 
    355351                stream.seek(t, 0) 
    356             retval["__streamdata__"] = stream.read(length) 
    357             e = readNonWhitespace(stream) 
    358             ndstream = stream.read(8) 
    359             assert e == "e" and ndstream == "ndstream" 
     352            data["__streamdata__"] = stream.read(length) 
     353            # (sigh) - the odd PDF file has a length that is too long, so we'd 
     354            # need to read backwards to find the "endstream" ending.  Really, 
     355            # who cares - I am sure this code works properly given a correct 
     356            # PDF file, so I'm removing this assertion.  It's not necessary to 
     357            # read to the end of the object because streams are always in 
     358            # indirect objects - there's never an object after this one. 
     359            #e = readNonWhitespace(stream) 
     360            #ndstream = stream.read(8) 
     361            #assert e == "e" and ndstream == "ndstream" 
    360362        else: 
    361363            stream.seek(pos, 0) 
     364        if data.has_key("__streamdata__"): 
     365            return StreamObject.initializeFromDictionary(data) 
     366        else: 
     367            retval = DictionaryObject() 
     368            retval.update(data) 
     369            return retval 
     370    readFromStream = staticmethod(readFromStream) 
     371 
     372 
     373class StreamObject(DictionaryObject): 
     374    def __init__(self): 
     375        self._data = None 
     376        self.decodedSelf = None 
     377 
     378    def writeToStream(self, stream): 
     379        self[NameObject("/Length")] = NumberObject(len(self._data)) 
     380        DictionaryObject.writeToStream(self, stream) 
     381        del self["/Length"] 
     382        stream.write("\nstream\n") 
     383        stream.write(self._data) 
     384        stream.write("\nendstream") 
     385 
     386    def initializeFromDictionary(data): 
     387        if data.has_key("/Filter"): 
     388            retval = EncodedStreamObject() 
     389        else: 
     390            retval = DecodedStreamObject() 
     391        retval._data = data["__streamdata__"] 
     392        del data["__streamdata__"] 
     393        del data["/Length"] 
     394        retval.update(data) 
    362395        return retval 
    363     readFromStream = staticmethod(readFromStream) 
     396    initializeFromDictionary = staticmethod(initializeFromDictionary) 
     397 
     398 
     399class DecodedStreamObject(StreamObject): 
     400    def getData(self): 
     401        return self._data 
     402 
     403    def setData(self, data): 
     404        self._data = data 
     405 
     406 
     407class EncodedStreamObject(StreamObject): 
     408    def __init__(self): 
     409        self.decodedSelf = None 
     410 
     411    def getData(self): 
     412        if self.decodedSelf: 
     413            # cached version of decoded object 
     414            return self.decodedSelf.getData() 
     415        else: 
     416            # create decoded object 
     417            decoded = StreamObject() 
     418            decoded._data = filters.decodeStreamData(self) 
     419            for key, value in self.items(): 
     420                if not key in ("/Length", "/Filter", "/DecodeParms"): 
     421                    decoded[key] = value 
     422            self.decodedSelf = decoded 
     423            return decoded._data 
     424 
     425    def setData(self, data): 
     426        raise "Creating EncodedStreamObject is not currently supported" 
    364427 
    365428