ooo-build r14417 - in trunk: . scratch/sc-xlsutil scratch/sc-xlsutil/src



Author: kyoshida
Date: Tue Oct 28 15:48:04 2008
New Revision: 14417
URL: http://svn.gnome.org/viewvc/ooo-build?rev=14417&view=rev

Log:
2008-10-28  Kohei Yoshida  <kyoshida novell com>

	* scratch/sc-xlsutil/src/globals.py:
	* scratch/sc-xlsutil/src/record.py:
	* scratch/sc-xlsutil/src/stream.py:
	* scratch/sc-xlsutil/xls_dump.py: parse PivotTable Cache substreams
	and handle more PivotTable related records.


Modified:
   trunk/ChangeLog
   trunk/scratch/sc-xlsutil/src/globals.py
   trunk/scratch/sc-xlsutil/src/record.py
   trunk/scratch/sc-xlsutil/src/stream.py
   trunk/scratch/sc-xlsutil/xls_dump.py

Modified: trunk/scratch/sc-xlsutil/src/globals.py
==============================================================================
--- trunk/scratch/sc-xlsutil/src/globals.py	(original)
+++ trunk/scratch/sc-xlsutil/src/globals.py	Tue Oct 28 15:48:04 2008
@@ -5,11 +5,27 @@
 
 
 class Params(object):
+    """command-line parameters."""
     def __init__ (self):
         self.debug = False
         self.showSectorChain = False
 
 
+class StreamData(object):
+    """run-time stream data."""
+    def __init__ (self):
+        self.encrypted = False
+        self.pivotCacheIDs = {}
+
+    def appendPivotCacheId (self, newId):
+        # must be 4-digit with leading '0's.
+        strId = "%.4d"%newId
+        self.pivotCacheIDs[strId] = True
+
+    def isPivotCacheStream (self, name):
+        return self.pivotCacheIDs.has_key(name)
+
+
 def output (msg):
     sys.stdout.write(msg)
 

Modified: trunk/scratch/sc-xlsutil/src/record.py
==============================================================================
--- trunk/scratch/sc-xlsutil/src/record.py	(original)
+++ trunk/scratch/sc-xlsutil/src/record.py	Tue Oct 28 15:48:04 2008
@@ -7,13 +7,15 @@
 
 class BaseRecordHandler(object):
 
-    def __init__ (self, header, size, bytes):
+    def __init__ (self, header, size, bytes, strmData):
         self.header = header
         self.size = size
         self.bytes = bytes
         self.lines = []
         self.pos = 0       # current byte position
 
+        self.strmData = strmData
+
     def parseBytes (self):
         """Parse the original bytes and generate human readable output.
 
@@ -37,6 +39,11 @@
         self.pos += length
         return r
 
+    def readRemainingBytes (self):
+        r = self.bytes[self.pos:]
+        self.pos = self.size
+        return r
+
     def getCurrentPos (self):
         return self.pos
 
@@ -49,6 +56,19 @@
         else:
             return 'no'
 
+    def readUnsignedInt (self, length):
+        bytes = self.readBytes(length)
+        return globals.getUnsignedInt(bytes)
+
+    def readSignedInt (self, length):
+        bytes = self.readBytes(length)
+        return globals.getSignedInt(bytes)
+
+    def readDouble (self):
+        # double is always 8 bytes.
+        bytes = self.readBytes(8)
+        return globals.getDouble(bytes)
+
 # --------------------------------------------------------------------
 
 class BOF(BaseRecordHandler):
@@ -593,6 +613,91 @@
         return verName
 
 
+class SXDb(BaseRecordHandler):
+
+    def parseBytes (self):
+        recCount = self.readUnsignedInt(4)
+        strmId   = self.readUnsignedInt(2)
+        flags    = self.readUnsignedInt(2)
+        self.appendLine("number of records: %d"%recCount)
+        self.appendLine("stream ID: 0x%4.4X"%strmId)
+        self.appendLine("flags: 0x%4.4X"%flags)
+
+        dbBlockRecs = self.readUnsignedInt(2)
+        baseFields = self.readUnsignedInt(2)
+        allFields = self.readUnsignedInt(2)
+        self.appendLine("DB block records: %d"%dbBlockRecs)
+        self.appendLine("base fields: %d"%baseFields)
+        self.appendLine("all fields: %d"%allFields)
+
+        dummy = self.readBytes(2)
+        type = self.readUnsignedInt(2)
+        self.appendLine("type: 0x%4.4X"%type)
+        textLen = self.readUnsignedInt(2)
+        changedBy, textLen = globals.getRichText(self.readRemainingBytes(), textLen)
+        self.appendLine("changed by: %s"%changedBy)
+
+
+class SXDbEx(BaseRecordHandler):
+
+    def parseBytes (self):
+        lastChanged = self.readDouble()
+        sxFmlaRecs = self.readUnsignedInt(4)
+        self.appendLine("last changed: %g"%lastChanged)
+        self.appendLine("SXFORMULA records: %d"%sxFmlaRecs)
+
+
+class SXField(BaseRecordHandler):
+
+    dataTypeNames = {
+        0x0000: 'spc',
+        0x0480: 'str',
+        0x0520: 'int[+dbl]',
+        0x0560: 'dbl',
+        0x05A0: 'str+int[+dbl]',
+        0x05E0: 'str+dbl',
+        0x0900: 'dat',
+        0x0D00: 'dat+int/dbl',
+        0x0D80: 'dat+str[+int/dbl]'
+    }
+
+    def parseBytes (self):
+        flags = self.readUnsignedInt(2)
+        origItems  = (flags & 0x0001)
+        postponed  = (flags & 0x0002)
+        calculated = (flags & 0x0004)
+        groupChild = (flags & 0x0008)
+        numGroup   = (flags & 0x0010)
+        longIndex  = (flags & 0x0200)
+        self.appendLine("original items: %s"%self.getYesNo(origItems))
+        self.appendLine("postponed: %s"%self.getYesNo(postponed))
+        self.appendLine("calculated: %s"%self.getYesNo(calculated))
+        self.appendLine("group child: %s"%self.getYesNo(groupChild))
+        self.appendLine("num group: %s"%self.getYesNo(numGroup))
+        self.appendLine("long index: %s"%self.getYesNo(longIndex))
+        dataType = (flags & 0x0DE0)
+        if SXField.dataTypeNames.has_key(dataType):
+            self.appendLine("data type: %s (0x%4.4X)"%(SXField.dataTypeNames[dataType], dataType))
+        else:
+            self.appendLine("data type: unknown (0x%4.4X)"%dataType)
+
+        grpSubField = self.readUnsignedInt(2)
+        grpBaseField = self.readUnsignedInt(2)
+        itemCount = self.readUnsignedInt(2)
+        grpItemCount = self.readUnsignedInt(2)
+        baseItemCount = self.readUnsignedInt(2)
+        srcItemCount = self.readUnsignedInt(2)
+        self.appendLine("group sub-field: %d"%grpSubField)
+        self.appendLine("group base-field: %d"%grpBaseField)
+        self.appendLine("item count: %d"%itemCount)
+        self.appendLine("group item count: %d"%grpItemCount)
+        self.appendLine("base item count: %d"%baseItemCount)
+        self.appendLine("source item count: %d"%srcItemCount)
+
+        # field name
+        textLen = self.readUnsignedInt(2)
+        name, textLen = globals.getRichText(self.readRemainingBytes(), textLen)
+        self.appendLine("field name: %s"%name)
 
 
 class SXStreamID(BaseRecordHandler):
@@ -602,6 +707,7 @@
             return
 
         strmId = globals.getSignedInt(self.bytes)
+        self.strmData.appendPivotCacheId(strmId)
         self.appendLine("pivot cache stream ID in SX DB storage: %d"%strmId)
 
 class SXViewSource(BaseRecordHandler):
@@ -745,6 +851,32 @@
         pass
 
 
+class SXDouble(BaseRecordHandler):
+    def parseBytes (self):
+        val = self.readDouble()
+        self.appendLine("value: %g"%val)
+
+
+class SXBoolean(BaseRecordHandler):
+    def parseBytes (self):
+        pass
+
+class SXError(BaseRecordHandler):
+    def parseBytes (self):
+        pass
+
+
+class SXInteger(BaseRecordHandler):
+    def parseBytes (self):
+        pass
+
+
+class SXString(BaseRecordHandler):
+    def parseBytes (self):
+        textLen = self.readUnsignedInt(2)
+        text, textLen = globals.getRichText(self.readRemainingBytes(), textLen)
+        self.appendLine("value: %s"%text)
+
 # -------------------------------------------------------------------
 # CT - Change Tracking
 

Modified: trunk/scratch/sc-xlsutil/src/stream.py
==============================================================================
--- trunk/scratch/sc-xlsutil/src/stream.py	(original)
+++ trunk/scratch/sc-xlsutil/src/stream.py	Tue Oct 28 15:48:04 2008
@@ -105,8 +105,16 @@
     0x00C2: ["ADDMENU", "Menu Addition"],
     0x00C3: ["DELMENU", "Menu Deletion"],
     0x00C5: ["SXDI", "Data Item"],
-    0x00C6: ["SXDB", "PivotTable Cache Data"],
-    0x00CD: ["SXSTRING", "String"],
+    0x00C6: ["SXDB", "PivotTable Cache Data", record.SXDb],
+    0x00C7: ["SXFIELD", "Pivot Field", record.SXField],
+    0x00C8: ["SXINDEXLIST", "Indices to Source Data"],       
+    0x00C9: ["SXDOUBLE", "Double Value", record.SXDouble],                    
+    0x00CA: ["SXBOOLEAN", "Boolean Value", record.SXBoolean],                  
+    0x00CB: ["SXERROR", "Error Code", record.SXError],                       
+    0x00CC: ["SXINTEGER", "Integer Value", record.SXInteger],                  
+    0x00CD: ["SXSTRING", "String", record.SXString],
+    0x00CE: ["SXDATETIME", "Date & Time Special Format"],    
+    0x00CF: ["SXEMPTY", "Empty Value"],                      
     0x00D0: ["SXTBL", "Multiple Consolidation Source Info"],
     0x00D1: ["SXTBRGIITM", "Page Item Name Count"],
     0x00D2: ["SXTBPG", "Page Item Indexes"],
@@ -142,7 +150,7 @@
     0x00FF: ["EXTSST", "Extended Shared String Table"],
     0x0100: ["SXVDEX", "Extended PivotTable View Fields"],
     0x0103: ["SXFORMULA", "PivotTable Formula Record"],
-    0x0122: ["SXDBEX", "PivotTable Cache Data"],
+    0x0122: ["SXDBEX", "PivotTable Cache Data", record.SXDbEx],
     0x013D: ["TABID", "Sheet Tab Index Array"],
     0x0160: ["USESELFS", "Natural Language Formulas Flag"],
     0x0161: ["DSF", "Double Stream File"],
@@ -261,7 +269,7 @@
 
 class XLStream(object):
 
-    def __init__ (self, chars, params):
+    def __init__ (self, chars, params, strmData):
         self.chars = chars
         self.size = len(self.chars)
         self.pos = 0
@@ -272,6 +280,7 @@
         self.SAT = None
 
         self.params = params
+        self.strmData = strmData
 
     def __printSep (self, c='-', w=68, prefix=''):
         print(prefix + c*w)
@@ -329,22 +338,24 @@
         bytes = []
         if obj != None:
             bytes = obj.getRawStreamByName(name)
-        strm = XLDirStream(bytes, self.params)
+        strm = XLDirStream(bytes, self.params, self.strmData)
         return strm
 
 class DirType:
     Workbook = 0
     RevisionLog = 1
+    PivotTableCache = 2
 
 class XLDirStream(object):
 
-    def __init__ (self, bytes, params):
+    def __init__ (self, bytes, params, strmData):
         self.bytes = bytes
         self.size = len(self.bytes)
         self.pos = 0
         self.type = DirType.Workbook
 
         self.params = params
+        self.strmData = strmData
 
 
     def readRaw (self, size=1):
@@ -393,12 +404,12 @@
             print("%4.4Xh: %s - %s (%4.4Xh)"%
                   (header, recData[header][0], recData[header][1], header))
             if len(recData[header]) >= 3:
-                handler = recData[header][2](header, size, bytes)
+                handler = recData[header][2](header, size, bytes, self.strmData)
         elif self.type == DirType.RevisionLog and recDataRev.has_key(header):
             print("%4.4Xh: %s - %s (%4.4Xh)"%
                   (header, recDataRev[header][0], recDataRev[header][1], header))
             if len(recDataRev[header]) >= 3:
-                handler = recDataRev[header][2](header, size, bytes)
+                handler = recDataRev[header][2](header, size, bytes, self.strmData)
         else:
             print("%4.4Xh: [unknown record name] (%4.4Xh)"%(header, header))
         print("%4.4Xh:   size = %d; pos = %d"%(header, size, pos))

Modified: trunk/scratch/sc-xlsutil/xls_dump.py
==============================================================================
--- trunk/scratch/sc-xlsutil/xls_dump.py	(original)
+++ trunk/scratch/sc-xlsutil/xls_dump.py	Tue Oct 28 15:48:04 2008
@@ -31,7 +31,8 @@
 
     def dump (self):
         file = open(self.filepath, 'rb')
-        strm = stream.XLStream(file.read(), self.params)
+        strmData = globals.StreamData()
+        strm = stream.XLStream(file.read(), self.params, strmData)
         file.close()
         strm.printStreamInfo()
         strm.printHeader()
@@ -59,6 +60,22 @@
                         header = dirstrm.readRecord()
                 except stream.EndOfStream:
                     continue
+            elif dirname == '_SX_DB_CUR':
+                dirstrm.type = stream.DirType.PivotTableCache
+                try:
+                    header = 0x0000
+                    while header != 0x000A:
+                        header = dirstrm.readRecord()
+                except stream.EndOfStream:
+                    continue
+            elif strmData.isPivotCacheStream(dirname):
+                dirstrm.type = stream.DirType.PivotTableCache
+                try:
+                    header = 0x0000
+                    while header != 0x000A:
+                        header = dirstrm.readRecord()
+                except stream.EndOfStream:
+                    continue
             else:
                 globals.dumpBytes(dirstrm.bytes, 512)
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]