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

Kohei Yoshida kohei at kemper.freedesktop.org
Tue Mar 23 20:51:10 PDT 2010


 scratch/mso-dumper/src/xlsmodel.py  |   94 ++++++++++++++++++++++++++++--
 scratch/mso-dumper/src/xlsrecord.py |  112 ++++++++++++++++++++++++++----------
 2 files changed, 170 insertions(+), 36 deletions(-)

New commits:
commit 29e055f40208c6aa438f2aa82834de7bf8f9885d
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Tue Mar 23 23:50:53 2010 -0400

    [mso-dumper] Display external ref sheet cache in cXML mode.
    
    * scratch/mso-dumper/src/xlsmodel.py:
    * scratch/mso-dumper/src/xlsrecord.py:

diff --git a/scratch/mso-dumper/src/xlsmodel.py b/scratch/mso-dumper/src/xlsmodel.py
index 3a1961e..9b1c507 100644
--- a/scratch/mso-dumper/src/xlsmodel.py
+++ b/scratch/mso-dumper/src/xlsmodel.py
@@ -73,7 +73,7 @@ class Workbook(ModelBase):
             return
 
         wbglobal = self.__sheets[0]
-#       nd.appendChild(wbglobal.createDOM(self))
+        nd.appendChild(wbglobal.createDOM(self))
         for i in xrange(1, n):
             sheet = self.__sheets[i]
             sheetNode = sheet.createDOM(self)
@@ -111,10 +111,7 @@ class Supbook(object):
         Unused   = 5
 
     def __init__ (self, sbType=None):
-        self.sbType = sbType
-
-    def getType (self):
-        return self.sbType
+        self.type = sbType
 
 
 class SupbookSelf(Supbook):
@@ -123,9 +120,86 @@ class SupbookSelf(Supbook):
         self.sheetCount = sheetCount
 
 
+class ExtSheetCache(object):
+    """External sheet cache
+
+To store external reference cache from XCT/CRN records."""
+
+    class CellType:
+        Empty   = 0x00
+        Number  = 0x01
+        String  = 0x02
+        Boolean = 0x04
+        Error   = 0x10
+
+    cellTypeNames = {
+        CellType.Empty:   'empty',
+        CellType.Number:  'number',
+        CellType.String:  'string',
+        CellType.Boolean: 'boolean',
+        CellType.Error:   'error'
+    }
+
+    def __init__ (self):
+        self.__rows = {}
+
+    def setValue (self, row, col, celltype, val):
+        if not self.__rows.has_key(row):
+            self.__rows[row] = {}
+        self.__rows[row][col] = (celltype, val)
+
+    def createDOM (self, wb):
+        nd = node.Element("sheet")
+        rows = self.__rows.keys()
+        rows.sort()
+        for row in rows:
+            rowElem = nd.appendElement("row")
+            rowElem.setAttr("id", row)
+            cols = self.__rows[row].keys()
+            cols.sort()
+            for col in cols:
+                cell = self.__rows[row][col]
+                celltype, val = cell[0], cell[1]
+                cellElem = rowElem.appendElement("cell")
+                cellElem.setAttr("col", col)
+                cellElem.setAttr("value", val)
+                cellElem.setAttr("type", globals.getValueOrUnknown(ExtSheetCache.cellTypeNames, celltype))
+
+        return nd
+
 class SupbookExternal(Supbook):
+
     def __init__ (self):
         Supbook.__init__(self, Supbook.Type.External)
+        self.docURL = None
+        self.__sheets = []
+        self.__curSheet = 0
+
+    def appendSheetName (self, name):
+        # the 2nd item is the sheet cache.
+        self.__sheets.append([name, None])
+
+    def setCurrentSheet (self, sheetID):
+        self.__curSheet = sheetID
+
+    def getCurrentSheetCache (self):
+        sheetItem = self.__sheets[self.__curSheet]
+        if sheetItem[1] == None:
+            sheetItem[1] = ExtSheetCache()
+        return sheetItem[1]
+
+    def createDOM (self, wb):
+        nd = node.Element("external-sheet-cache")
+        # 1st char is always 0x1.
+        nd.setAttr("url", globals.encodeName(self.docURL[1:]))
+        for sheet in self.__sheets:
+            if sheet[1] == None:
+                continue
+            elem = sheet[1].createDOM(wb)
+            elem.setAttr("name", sheet[0])
+            nd.appendChild(elem)
+
+        return nd
 
 
 class WorkbookGlobal(SheetBase):
@@ -142,9 +216,15 @@ class WorkbookGlobal(SheetBase):
         self.__supbooks = []
         self.__externSheets = []  # tuple (book ID, sheet begin ID, sheet end ID)
         self.__dbRanges = {}      # key: sheet ID (0-based), value: range tokens
+        self.__lastSupbook = None
 
     def createDOM (self, wb):
         nd = node.Element('workbook-global')
+        for sb in self.__supbooks:
+            if sb.type != Supbook.Type.External:
+                continue
+            nd.appendChild(sb.createDOM(wb))
+
         return nd
 
     def appendSheetData (self, data):
@@ -163,12 +243,16 @@ class WorkbookGlobal(SheetBase):
 
     def appendSupbook (self, sb):
         self.__supbooks.append(sb)
+        self.__lastSupbook = sb
 
     def getSupbook (self, sbID):
         if len(self.__supbooks) <= sbID:
             return None
         return self.__supbooks[sbID]
 
+    def getLastSupbook (self):
+        return self.__lastSupbook
+
     def appendExternSheet (self, bookID, sheetBeginID, sheetEndID):
         self.__externSheets.append((bookID, sheetBeginID, sheetEndID))
 
diff --git a/scratch/mso-dumper/src/xlsrecord.py b/scratch/mso-dumper/src/xlsrecord.py
index aec7944..806b1f4 100644
--- a/scratch/mso-dumper/src/xlsrecord.py
+++ b/scratch/mso-dumper/src/xlsrecord.py
@@ -1234,10 +1234,16 @@ class SupBook(BaseRecordHandler):
         if self.sbType == SupBook.Type.Self:
             sb = xlsmodel.SupbookSelf(self.ctab)
             wbg.appendSupbook(sb)
-        else:
+        elif self.sbType == SupBook.Type.AddIn:
             # generic supbook instance just to keep the indices in sync.
             wbg.appendSupbook(xlsmodel.Supbook())
-
+        else:
+            # external document supbook
+            sb = xlsmodel.SupbookExternal()
+            sb.docURL = self.names[0]
+            for name in self.names[1:]:
+                sb.appendSheetName(name)
+            wbg.appendSupbook(sb)
 
 
 class ExternSheet(BaseRecordHandler):
@@ -1311,57 +1317,101 @@ class ExternName(BaseRecordHandler):
 
 class Xct(BaseRecordHandler):
 
+    def __parseBytes (self):
+        self.crnCount = self.readSignedInt(2)
+        self.sheetIndex = self.readUnsignedInt(2)
+
     def parseBytes (self):
-        crnCount = globals.getSignedInt(self.bytes[0:2])
-        sheetIndex = globals.getSignedInt(self.bytes[2:4])
-        self.appendLine("CRN count: %d"%crnCount)
-        self.appendLine("index of referenced sheet in the SUPBOOK record: %d"%sheetIndex)
+        self.__parseBytes()
+        self.appendLine("CRN count: %d"%self.crnCount)
+        self.appendLine("index of referenced sheet in the SUPBOOK record: %d"%self.sheetIndex)
+
+    def fillModel (self, model):
+        self.__parseBytes()
+        sb = model.getWorkbookGlobal().getLastSupbook()
+        # this must be an external document supbook.
+        if sb.type != xlsmodel.Supbook.Type.External:
+            return
+        sb.setCurrentSheet(self.sheetIndex)
 
 
 class Crn(BaseRecordHandler):
 
+    def __parseBytes (self):
+        self.lastCol = self.readUnsignedInt(1)
+        self.firstCol = self.readUnsignedInt(1)
+        self.rowIndex = self.readUnsignedInt(2)
+        self.cells = []
+        for i in xrange(0, self.lastCol-self.firstCol+1):
+            typeId = self.readUnsignedInt(1)
+            if typeId == 0x00:
+                # empty value
+                self.readBytes(8)
+                self.cells.append((typeId, None))
+            elif typeId == 0x01:
+                # number
+                val = self.readDouble()
+                self.cells.append((typeId, val))
+            elif typeId == 0x02:
+                # string
+                pos = self.getCurrentPos()
+                ret, length = globals.getUnicodeRichExtText(self.bytes[pos:])
+                text = ret.baseText
+                text = globals.encodeName(text)
+                self.moveForward(length)
+                self.cells.append((typeId, text))
+            elif typeId == 0x04:
+                # boolean
+                val = self.readUnsignedInt(1)
+                self.readBytes(7) # next 7 bytes not used
+                self.cells.append((typeId, val))
+            elif typeId == 0x10:
+                # error value
+                val = self.readUnsignedInt(1)
+                self.readBytes(7) # next 7 bytes not used
+                self.cells.append((typeId, val))
+            else:
+                globals.error("error parsing CRN record\n")
+                sys.exit(1)
+
     def parseBytes (self):
-        lastCol = globals.getSignedInt(self.bytes[0:1])
-        firstCol = globals.getSignedInt(self.bytes[1:2])
-        rowIndex = globals.getSignedInt(self.bytes[2:4])
-        self.appendLine("first column: %d"%firstCol)
-        self.appendLine("last column:  %d"%lastCol)
-        self.appendLine("row index: %d"%rowIndex)
+        self.__parseBytes()
+        self.appendLine("first column: %d"%self.firstCol)
+        self.appendLine("last column:  %d"%self.lastCol)
+        self.appendLine("row index: %d"%self.rowIndex)
 
-        i = 4
-        n = len(self.bytes)
-        while i < n:
-            typeId = self.bytes[i]
-            i += 1
+        for cell in self.cells:
+            typeId, val = cell[0], cell[1]
             if typeId == 0x00:
                 # empty value
-                i += 8
                 self.appendLine("* empty value")
             elif typeId == 0x01:
                 # number
-                val = globals.getDouble(self.bytes[i:i+8])
-                i += 8
                 self.appendLine("* numeric value (%g)"%val)
-            elif typeId == 0x2:
+            elif typeId == 0x02:
                 # string
-                ret, length = globals.getUnicodeRichExtText(self.bytes[i:])
-                text = ret.baseText
-                i += length
-                text = globals.encodeName(text)
-                self.appendLine("* string value (%s)"%text)
+                self.appendLine("* string value (%s)"%val)
             elif typeId == 0x04:
                 # boolean
-                val = self.bytes[i]
-                i += 7 # next 7 bytes not used
                 self.appendLine("* boolean value (%d)"%val)
             elif typeId == 0x10:
                 # error value
-                val = self.bytes[i]
-                i += 7 # not used
                 self.appendLine("* error value (%d)"%val)
             else:
-                sys.stderr.write("error parsing CRN record")
+                error("error parsing CRN record\n")
                 sys.exit(1)
+
+    def fillModel (self, model):
+        self.__parseBytes()
+        sb = model.getWorkbookGlobal().getLastSupbook()
+        # this must be an external document supbook.
+        if sb.type != xlsmodel.Supbook.Type.External:
+            return
+        cache = sb.getCurrentSheetCache()
+        for col in xrange(self.firstCol, self.lastCol+1):
+            cell = self.cells[col-self.firstCol]
+            typeId, val = cell[0], cell[1]
+            cache.setValue(self.rowIndex, col, typeId, val)
             
 
 class RefreshAll(BaseRecordHandler):


More information about the ooo-build-commit mailing list