~ubuntu-branches/ubuntu/saucy/python-imaging/saucy-proposed

« back to all changes in this revision

Viewing changes to PIL/OleFileIO.py

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-01-31 20:49:20 UTC
  • mfrom: (27.1.1 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20130131204920-b5zshy6vgfvdionl
Tags: 1.1.7+1.7.8-1ubuntu1
Rewrite build dependencies to allow cross builds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
# See the README file for information on usage and redistribution.
37
37
#
38
38
 
39
 
import string, StringIO
40
 
 
41
 
 
42
 
def i16(c, o = 0):
43
 
    return ord(c[o])+(ord(c[o+1])<<8)
44
 
 
45
 
def i32(c, o = 0):
46
 
    return ord(c[o])+(ord(c[o+1])<<8)+(ord(c[o+2])<<16)+(ord(c[o+3])<<24)
47
 
 
48
 
 
49
 
MAGIC = '\320\317\021\340\241\261\032\341'
 
39
from __future__ import print_function
 
40
 
 
41
import io
 
42
import sys
 
43
from . import _binary
 
44
 
 
45
if str is not bytes:
 
46
    long = int
 
47
 
 
48
i8 = _binary.i8
 
49
i16 = _binary.i16le
 
50
i32 = _binary.i32le
 
51
 
 
52
 
 
53
MAGIC = b'\320\317\021\340\241\261\032\341'
50
54
 
51
55
#
52
56
# --------------------------------------------------------------------
65
69
# map property id to name (for debugging purposes)
66
70
 
67
71
VT = {}
68
 
for k, v in vars().items():
 
72
for k, v in list(vars().items()):
69
73
    if k[:3] == "VT_":
70
74
        VT[v] = k
71
75
 
79
83
#
80
84
# --------------------------------------------------------------------
81
85
 
82
 
class _OleStream(StringIO.StringIO):
 
86
class _OleStream(io.BytesIO):
83
87
 
84
88
    """OLE2 Stream
85
89
 
105
109
            data.append(fp.read(sectorsize))
106
110
            sect = fat[sect]
107
111
 
108
 
        data = string.join(data, "")
 
112
        data = b"".join(data)
109
113
 
110
114
        # print len(data), size
111
115
 
112
 
        StringIO.StringIO.__init__(self, data[:size])
 
116
        io.BytesIO.__init__(self, data[:size])
113
117
 
114
118
#
115
119
# --------------------------------------------------------------------
173
177
                if right != -1: # 0xFFFFFFFFL:
174
178
                    # and then back to the left
175
179
                    sid = right
176
 
                    while 1:
 
180
                    while True:
177
181
                        left, right, child = sidlist[sid][4]
178
182
                        if left == -1: # 0xFFFFFFFFL:
179
183
                            break
181
185
                        sid = left
182
186
                else:
183
187
                    # couldn't move right; move up instead
184
 
                    while 1:
 
188
                    while True:
185
189
                        ptr = stack[-1]
186
190
                        del stack[-1]
187
191
                        left, right, child = sidlist[ptr][4]
208
212
        TYPES = ["(invalid)", "(storage)", "(stream)", "(lockbytes)",
209
213
                 "(property)", "(root)"]
210
214
 
211
 
        print " "*tab + repr(self.name), TYPES[self.type],
 
215
        print(" "*tab + repr(self.name), TYPES[self.type], end=' ')
212
216
        if self.type in (2, 5):
213
 
            print self.size, "bytes",
214
 
        print
 
217
            print(self.size, "bytes", end=' ')
 
218
        print()
215
219
        if self.type in (1, 5) and self.clsid:
216
 
            print " "*tab + "{%s}" % self.clsid
 
220
            print(" "*tab + "{%s}" % self.clsid)
217
221
 
218
222
        for kid in self.kids:
219
223
            kid.dump(tab + 2)
265
269
    def open(self, filename):
266
270
        """Open an OLE2 file"""
267
271
 
268
 
        if type(filename) == type(""):
 
272
        if isinstance(filename, str):
269
273
            self.fp = open(filename, "rb")
270
274
        else:
271
275
            self.fp = filename
273
277
        header = self.fp.read(512)
274
278
 
275
279
        if len(header) != 512 or header[:8] != MAGIC:
276
 
            raise IOError, "not an OLE2 structured storage file"
 
280
            raise IOError("not an OLE2 structured storage file")
277
281
 
278
282
        # file clsid (probably never used, so we don't store it)
279
283
        clsid = self._clsid(header[8:24])
307
311
            if ix == -2 or ix == -1: # ix == 0xFFFFFFFEL or ix == 0xFFFFFFFFL:
308
312
                break
309
313
            s = self.getsect(ix)
310
 
            fat = fat + map(lambda i, s=s: i32(s, i), range(0, len(s), 4))
 
314
            fat = fat + [i32(s, i) for i in range(0, len(s), 4)]
311
315
        self.fat = fat
312
316
 
313
317
    def loadminifat(self):
316
320
 
317
321
        s = self._open(self.minifatsect).read()
318
322
 
319
 
        self.minifat = map(lambda i, s=s: i32(s, i), range(0, len(s), 4))
 
323
        self.minifat = [i32(s, i) for i in range(0, len(s), 4)]
320
324
 
321
325
    def getsect(self, sect):
322
326
        # Read given sector
327
331
    def _unicode(self, s):
328
332
        # Map unicode string to Latin 1
329
333
 
330
 
        # FIXME: some day, Python will provide an official way to handle
331
 
        # Unicode strings, but until then, this will have to do...
332
 
        return filter(ord, s)
 
334
        if bytes is str:
 
335
            # Old version tried to produce a Latin-1 str
 
336
            return s.decode('utf-16').encode('latin-1', 'replace')
 
337
        else:
 
338
            # Provide actual Unicode string
 
339
            return s.decode('utf-16')
333
340
 
334
341
    def loaddirectory(self, sect):
335
342
        # Load the directory.  The directory is stored in a standard
340
347
 
341
348
        # create list of sid entries
342
349
        self.sidlist = []
343
 
        while 1:
 
350
        while True:
344
351
            entry = fp.read(128)
345
352
            if not entry:
346
353
                break
347
 
            type = ord(entry[66])
 
354
            type = i8(entry[66])
348
355
            name = self._unicode(entry[0:0+i16(entry, 64)])
349
356
            ptrs = i32(entry, 68), i32(entry, 72), i32(entry, 76)
350
357
            sect, size = i32(entry, 116), i32(entry, 120)
364
371
            return ""
365
372
        return (("%08X-%04X-%04X-%02X%02X-" + "%02X" * 6) %
366
373
                ((i32(clsid, 0), i16(clsid, 4), i16(clsid, 6)) +
367
 
                tuple(map(ord, clsid[8:16]))))
 
374
                tuple(map(i8, clsid[8:16]))))
368
375
 
369
376
    def _list(self, files, prefix, node):
370
377
        # listdir helper
385
392
                if kid.name == name:
386
393
                    break
387
394
            else:
388
 
                raise IOError, "file not found"
 
395
                raise IOError("file not found")
389
396
            node = kid
390
397
        return node.sid
391
398
 
423
430
        slot = self._find(filename)
424
431
        name, type, sect, size, sids, clsid = self.sidlist[slot]
425
432
        if type != 2:
426
 
            raise IOError, "this file is not a stream"
 
433
            raise IOError("this file is not a stream")
427
434
        return self._open(sect, size)
428
435
 
429
436
    ##
480
487
                value = long(i32(s, offset+4)) + (long(i32(s, offset+8))<<32)
481
488
                # FIXME: this is a 64-bit int: "number of 100ns periods
482
489
                # since Jan 1,1601".  Should map this to Python time
483
 
                value = value / 10000000L # seconds
 
490
                value = value // 10000000 # seconds
484
491
            elif type == VT_UI1:
485
 
                value = ord(s[offset+4])
 
492
                value = i8(s[offset+4])
486
493
            elif type == VT_CLSID:
487
494
                value = self._clsid(s[offset+4:offset+20])
488
495
            elif type == VT_CF:
512
519
    for file in sys.argv[1:]:
513
520
        try:
514
521
            ole = OleFileIO(file)
515
 
            print "-" * 68
516
 
            print file
517
 
            print "-" * 68
 
522
            print("-" * 68)
 
523
            print(file)
 
524
            print("-" * 68)
518
525
            ole.dumpdirectory()
519
526
            for file in ole.listdir():
520
527
                if file[-1][0] == "\005":
521
 
                    print file
 
528
                    print(file)
522
529
                    props = ole.getproperties(file)
523
 
                    props = props.items()
524
 
                    props.sort()
 
530
                    props = sorted(props.items())
525
531
                    for k, v in props:
526
 
                        print "   ", k, v
527
 
        except IOError, v:
528
 
            print "***", "cannot read", file, "-", v
 
532
                        print("   ", k, v)
 
533
        except IOError as v:
 
534
            print("***", "cannot read", file, "-", v)