[ooo-build-commit] .: scratch/mso-dumper

Kohei Yoshida kohei at kemper.freedesktop.org
Mon Mar 22 18:59:58 PDT 2010


 scratch/mso-dumper/src/globals.py   |    5 +
 scratch/mso-dumper/src/msodraw.py   |  117 ++++++++++++++++++++++++++++++------
 scratch/mso-dumper/src/xlsrecord.py |    5 +
 scratch/mso-dumper/src/xlsstream.py |    2 
 4 files changed, 110 insertions(+), 19 deletions(-)

New commits:
commit 34977150e72e84a65d07d28c1f2d3fa127b129da
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Mon Mar 22 21:58:44 2010 -0400

    [mso-dumper] Pick up Excel's MSODRAWINGGROUP record.
    
    * scratch/mso-dumper/src/globals.py:
    * scratch/mso-dumper/src/msodraw.py:
    * scratch/mso-dumper/src/xlsrecord.py:
    * scratch/mso-dumper/src/xlsstream.py:

diff --git a/scratch/mso-dumper/src/globals.py b/scratch/mso-dumper/src/globals.py
index a71867e..61631d8 100644
--- a/scratch/mso-dumper/src/globals.py
+++ b/scratch/mso-dumper/src/globals.py
@@ -29,6 +29,7 @@ import sys, struct, math, zipfile, xmlpp, StringIO
 
 class ByteConvertError(Exception): pass
 
+class ByteStreamError(Exception): pass
 
 class Params(object):
     """command-line parameters."""
@@ -64,6 +65,10 @@ class ByteStream(object):
         return self.size
 
     def readBytes (self, length):
+        if self.pos + length > self.size:
+            error("reading %d bytes from position %d would exceed the current size of %d\n"%
+                (length, self.pos, self.size))
+            raise ByteStreamError()
         r = self.bytes[self.pos:self.pos+length]
         self.pos += length
         return r
diff --git a/scratch/mso-dumper/src/msodraw.py b/scratch/mso-dumper/src/msodraw.py
index b650420..239d43f 100644
--- a/scratch/mso-dumper/src/msodraw.py
+++ b/scratch/mso-dumper/src/msodraw.py
@@ -36,26 +36,32 @@ def headerLine ():
 class RecordHeader:
 
     class Type:
-        dgContainer     = 0xF002
-        spgrContainer   = 0xF003
-        spContainer     = 0xF004
-        solverContainer = 0xF005
-        FDG             = 0xF008
-        FSPGR           = 0xF009
-        FSP             = 0xF00A
-        FOPT            = 0xF00B
-        FConnectorRule  = 0xF012
+        dggContainer            = 0xF000
+        dgContainer             = 0xF002
+        spgrContainer           = 0xF003
+        spContainer             = 0xF004
+        solverContainer         = 0xF005
+        FDGGBlock               = 0xF006
+        FDG                     = 0xF008
+        FSPGR                   = 0xF009
+        FSP                     = 0xF00A
+        FOPT                    = 0xF00B
+        FConnectorRule          = 0xF012
+        SplitMenuColorContainer = 0xF11E
 
     containerTypeNames = {
-        Type.dgContainer:      'OfficeArtDgContainer',
-        Type.spContainer:      'OfficeArtSpContainer',
-        Type.spgrContainer:    'OfficeArtSpgrContainer',
-        Type.solverContainer:  'OfficeArtSolverContainer',
-        Type.FDG:              'OfficeArtFDG',
-        Type.FOPT:             'OfficeArtFOPT',
-        Type.FSP:              'OfficeArtFSP',
-        Type.FSPGR:            'OfficeArtFSPGR',
-        Type.FConnectorRule:   'OfficeArtFConnectorRule'
+        Type.dggContainer:            'OfficeArtDggContainer',
+        Type.dgContainer:             'OfficeArtDgContainer',
+        Type.spContainer:             'OfficeArtSpContainer',
+        Type.spgrContainer:           'OfficeArtSpgrContainer',
+        Type.solverContainer:         'OfficeArtSolverContainer',
+        Type.FDG:                     'OfficeArtFDG',
+        Type.FDGGBlock:               'OfficeArtFDGGBlock',
+        Type.FOPT:                    'OfficeArtFOPT',
+        Type.FSP:                     'OfficeArtFSP',
+        Type.FSPGR:                   'OfficeArtFSPGR',
+        Type.FConnectorRule:          'OfficeArtFConnectorRule',
+        Type.SplitMenuColorContainer: 'OfficeArtSplitMenuColorContainer'
     }
 
     @staticmethod
@@ -136,6 +142,47 @@ class FDG:
         recHdl.appendLine("  last shape ID: %d"%self.lastShapeID)
 
 
+class IDCL:
+    def __init__ (self, strm):
+        self.dgid = strm.readUnsignedInt(4)
+        self.cspidCur = strm.readUnsignedInt(4)
+
+    def appendLines (self, recHdl, rh):
+        recHdl.appendLine("IDCL content:")
+        recHdl.appendLine("  drawing ID: %d"%self.dgid)
+        recHdl.appendLine("  cspidCur: 0x%8.8X"%self.cspidCur)
+
+class FDGG:
+    def __init__ (self, strm):
+        self.spidMax  = strm.readUnsignedInt(4) # current max shape ID
+        self.cidcl    = strm.readUnsignedInt(4) # number of OfficeArtIDCL's.
+        self.cspSaved = strm.readUnsignedInt(4) # total number of shapes in all drawings
+        self.cdgSaved = strm.readUnsignedInt(4) # total number of drawings saved in the file
+
+    def appendLines (self, recHdl, rh):
+        recHdl.appendLine("FDGG content:")
+        recHdl.appendLine("  current max shape ID: %d"%self.spidMax)
+        recHdl.appendLine("  number of OfficeArtIDCL's: %d"%self.cidcl)
+        recHdl.appendLine("  total number of shapes in all drawings: %d"%self.cspSaved)
+        recHdl.appendLine("  total number of drawings in the file: %d"%self.cdgSaved)
+
+class FDGGBlock:
+    def __init__ (self, strm):
+        self.head = FDGG(strm)
+        self.idcls = []
+        # NOTE: The spec says head.cidcl stores the number of IDCL's, but each
+        # FDGGBlock only contains bytes enough to store (head.cidcl - 1) of 
+        # IDCL's.
+        for i in xrange(0, self.head.cidcl-1):
+            idcl = IDCL(strm)
+            self.idcls.append(idcl)
+
+    def appendLines (self, recHdl, rh):
+        self.head.appendLines(recHdl, rh)
+        for idcl in self.idcls:
+            idcl.appendLines(recHdl, rh)
+
+
 class FOPT:
     """property table for a shape instance"""
 
@@ -388,6 +435,34 @@ class FConnectorRule:
         recHdl.appendLine("  ID of the connection site in the begin shape: %d"%self.conSiteIDA)
         recHdl.appendLine("  ID of the connection site in the end shape: %d"%self.conSiteIDB)
 
+
+class MSOCR:
+    def __init__ (self, strm):
+        self.red = strm.readUnsignedInt(1)
+        self.green = strm.readUnsignedInt(1)
+        self.blue = strm.readUnsignedInt(1)
+        flag = strm.readUnsignedInt(1)
+        self.isSchemeIndex = (flag & 0x08) != 0
+
+    def appendLines (self, recHdl, rh):
+        recHdl.appendLine("MSOCR content (color index)")
+        if self.isSchemeIndex:
+            recHdl.appendLine("  scheme index: %d"%self.red)
+        else:
+            recHdl.appendLine("  RGB color: (red=%d, green=%d, blue=%d)"%(self.red, self.green, self.blue))
+
+class SplitMenuColorContainer:
+    def __init__ (self, strm):
+        self.smca = []
+        # this container contains 4 MSOCR records.
+        for i in xrange(0, 4):
+            msocr = MSOCR(strm)
+            self.smca.append(msocr)
+
+    def appendLines (self, recHdl, rh):
+        for msocr in self.smca:
+            msocr.appendLines(recHdl, rh)
+
 # ----------------------------------------------------------------------------
 
 class MSODrawHandler(globals.ByteStream):
@@ -428,6 +503,9 @@ class MSODrawHandler(globals.ByteStream):
             if rh.recType == RecordHeader.Type.FDG:
                 fdg = FDG(self)
                 fdg.appendLines(self.parent, rh)
+            elif rh.recType == RecordHeader.Type.FDGGBlock:
+                fdgg = FDGGBlock(self)
+                fdgg.appendLines(self.parent, rh)
             elif rh.recType == RecordHeader.Type.FOPT:
                 fopt = self.readFOPT(rh)
                 fopt.appendLines(self.parent, rh)
@@ -440,6 +518,9 @@ class MSODrawHandler(globals.ByteStream):
             elif rh.recType == RecordHeader.Type.FConnectorRule:
                 fcon = FConnectorRule(self)
                 fcon.appendLines(self.parent, rh)
+            elif rh.recType == RecordHeader.Type.SplitMenuColorContainer:
+                smcc = SplitMenuColorContainer(self)
+                smcc.appendLines(self.parent, rh)
             else:
                 # unknown object
                 bytes = self.readBytes(rh.recLen)
diff --git a/scratch/mso-dumper/src/xlsrecord.py b/scratch/mso-dumper/src/xlsrecord.py
index 9948b8c..80be3d1 100644
--- a/scratch/mso-dumper/src/xlsrecord.py
+++ b/scratch/mso-dumper/src/xlsrecord.py
@@ -2755,3 +2755,8 @@ together.
         msodHdl.parseBytes()
 
 
+class MSODrawingGroup(BaseRecordHandler):
+
+    def parseBytes (self):
+        msoHdl = msodraw.MSODrawHandler(self.bytes, self)
+        msoHdl.parseBytes()
diff --git a/scratch/mso-dumper/src/xlsstream.py b/scratch/mso-dumper/src/xlsstream.py
index bf0605f..9e099f6 100644
--- a/scratch/mso-dumper/src/xlsstream.py
+++ b/scratch/mso-dumper/src/xlsstream.py
@@ -160,7 +160,7 @@ recData = {
     0x00E2: ["INTERFACEEND", "End of User Interface Records"],
     0x00E3: ["SXVS", "View Source", xlsrecord.SXViewSource],
     0x00EA: ["TABIDCONF", "Sheet Tab ID of Conflict History"],
-    0x00EB: ["MSODRAWINGGROUP", "Microsoft Office Drawing Group"],
+    0x00EB: ["MSODRAWINGGROUP", "Microsoft Office Drawing Group", xlsrecord.MSODrawingGroup],
     0x00EC: ["MSODRAWING", "Microsoft Office Drawing", xlsrecord.MSODrawing],
     0x00ED: ["MSODRAWINGSELECTION", "Microsoft Office Drawing Selection"],
     0x00EF: ["PHONETIC", "Asian Phonetic Settings", xlsrecord.PhoneticInfo],


More information about the ooo-build-commit mailing list