summaryrefslogtreecommitdiffstats
path: root/oox/source/dump
diff options
context:
space:
mode:
Diffstat (limited to 'oox/source/dump')
-rw-r--r--oox/source/dump/biffdumper.ini2397
-rw-r--r--oox/source/dump/dffdumper.cxx227
-rw-r--r--oox/source/dump/dffdumper.ini676
-rw-r--r--oox/source/dump/dumperbase.cxx2580
-rw-r--r--oox/source/dump/dumperbase.ini412
-rw-r--r--oox/source/dump/oledumper.cxx2085
-rw-r--r--oox/source/dump/oledumper.ini904
-rw-r--r--oox/source/dump/pptxdumper.cxx131
-rw-r--r--oox/source/dump/pptxdumper.ini35
-rw-r--r--oox/source/dump/xlsbdumper.ini1204
10 files changed, 10651 insertions, 0 deletions
diff --git a/oox/source/dump/biffdumper.ini b/oox/source/dump/biffdumper.ini
new file mode 100644
index 000000000..a5ae4c12a
--- /dev/null
+++ b/oox/source/dump/biffdumper.ini
@@ -0,0 +1,2397 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# dumper settings ============================================================
+
+# Path to additional configuration data, relative to this file.
+include-config-file=dumperbase.ini
+include-config-file=dffdumper.ini
+include-config-file=oledumper.ini
+
+# Enable entire dumper. This option does not affect the option 'enable-import'.
+# 0=off, 1=on, missing = use setting from dumperbase.ini
+# enable-dumper=1
+
+# Enable import after dumping. Disabling this option allows to dump a file
+# without loading it. This option is independent from the 'enable-dumper'
+# option.
+# 0=off, 1=on, missing = use setting from dumperbase.ini
+# enable-import=1
+
+# BIFF record settings -------------------------------------------------------
+
+# Merge CONTINUE records with leading record (default=on).
+# 0=off - show CONTINUE records separately (hex dump)
+# 1=on - show contents of leading record together with following CONTINUE
+merge-continue-record=1
+
+# name lists =================================================================
+
+# common ---------------------------------------------------------------------
+
+unitconverter=CONV-PERCENT-NEG,-1,%
+unitconverter=CONV-COLWIDTH,/256,chars
+unitconverter=CONV-TINT,/327.67,%
+
+shortlist=BIFF,0,biff2,biff3,biff4,biff5,biff8
+
+constlist=ERRORCODES
+ 0x00=#NULL!
+ 0x07=#DIV/0!
+ 0x0F=#VALUE!
+ 0x17=#REF!
+ 0x1D=#NAME?
+ 0x24=#NUM!
+ 0x2A=#N/A
+end
+
+shortlist=WINDOWS-PALETTE-0,0,black,white,red,green,blue,yellow,magenta,cyan
+shortlist=WINDOWS-PALETTE-8,8,black,white,red,green,blue,yellow,magenta,cyan
+shortlist=WINDOWS-PALETTE-16,16,dark-red,dark-green,dark-blue,dark-yellow,dark-magenta,dark-cyan,light-grey,dark-grey
+
+multilist=WINDOWS-SYSCOLORS-BIFF2
+ 24=sys-window-text,sys-window-bg
+ 0x7FFF=sys-window-text
+end
+
+multilist=WINDOWS-SYSCOLORS-BIFF5
+ 64=sys-window-text,sys-window-bg,,sys-button-face
+ 77=sys-window-text-chart,sys-window-bg-chart,auto-border-chart,sys-tooltip-bg,sys-tooltip-text
+ 0x7FFF=sys-window-text
+end
+
+constlist=COLORS-BIFF2
+ include=WINDOWS-PALETTE-0
+ include=WINDOWS-SYSCOLORS-BIFF2
+end
+
+constlist=COLORS-BIFF3
+ include=WINDOWS-PALETTE-0
+ include=WINDOWS-PALETTE-8
+ include=WINDOWS-PALETTE-16
+ include=WINDOWS-SYSCOLORS-BIFF2
+end
+
+multilist=COLORS-BIFF5
+ include=WINDOWS-PALETTE-0
+ include=WINDOWS-PALETTE-8
+ include=WINDOWS-PALETTE-16
+ 24=0x8080FF,0x802060,0xFFFFC0,0xA0E0E0,0x600080,0xFF8080,0x0080C0,0xC0C0FF
+ 32=0x000080,0xFF00FF,0xFFFF00,0x00FFFF,0x800080,0x800000,0x008080,0x0000FF
+ 40=0x00CFFF,0x69FFFF,0xE0FFE0,0xFFFF80,0xA6CAF0,0xDD9CB3,0xB38FEE,0xE3E3E3
+ 48=0x2A6FF9,0x3FB8CD,0x488436,0x958C41,0x8E5E42,0xA0627A,0x624FAC,0x969696
+ 56=0x1D2FBE,0x286676,0x004500,0x453E01,0x6A2813,0x85396A,0x4A3285,0x424242
+ include=WINDOWS-SYSCOLORS-BIFF5
+end
+
+multilist=COLORS-BIFF8
+ include=WINDOWS-PALETTE-0
+ include=WINDOWS-PALETTE-8
+ include=WINDOWS-PALETTE-16
+ 24=0x9999FF,0x993366,0xFFFFCC,0xCCFFFF,0x660066,0xFF8080,0x0066CC,0xCCCCFF
+ 32=0x000080,0xFF00FF,0xFFFF00,0x00FFFF,0x800080,0x800000,0x008080,0x0000FF
+ 40=0x00CCFF,0xCCFFFF,0xCCFFCC,0xFFFF99,0x99CCFF,0xFF99CC,0xCC99FF,0xFFCC99
+ 48=0x3366FF,0x33CCCC,0x99CC00,0xFFCC00,0xFF9900,0xFF6600,0x666699,0x969696
+ 56=0x003366,0x339966,0x003300,0x333300,0x993300,0x993366,0x333399,0x333333
+ include=WINDOWS-SYSCOLORS-BIFF5
+end
+
+shortlist=BORDERSTYLES-BIFF3,0,none,thin,medium,dash,dot,thick,double,hair
+
+multilist=BORDERSTYLES-BIFF8
+ include=BORDERSTYLES-BIFF3
+ 8=medium-dash,thin-dash-dot,medium-dash-dot,thin-dash-dot-dot,medium-dash-dot-dot,slant-dash-dot
+end
+
+multilist=FILLPATTERNS-BIFF3
+ 0=no-fill,solid-fill,50%-grey,75%-grey,25%-grey
+ 5=hor-stripe,ver-stripe,rev-diag-stripe,diag-stripe,diag-crosshatch
+ 10=thick-diag-crosshatch,thin-hor-stripe,thin-ver-stripe,thin-rev-diag-stripe,thin-diag-stripe
+ 15=thin-hor-crosshatch,thin-diag-crosshatch,12.5%-grey,6.25%-grey
+end
+
+shortlist=TEXTORIENTATION,0,horizontal,stacked,90°-ccw,90°-cw
+
+constlist=TEXTROTATION-BIFF8
+ default=
+ 255=stacked
+end
+
+multilist=BUILTIN-FORMATS
+ quote-names=1
+ 0=General,0,0.00,'#,##0','#,##0.00'
+ 5='"$"#,##0_);\("$"#,##0\)','"$"#,##0_);[Red]\("$"#,##0\)','"$"#,##0.00_);\("$"#,##0.00\)','"$"#,##0.00_);[Red]\("$"#,##0.00\)',0%
+ 10=0.00%,0.00E+00,# ?/?,# ??/??,M/D/YYYY
+ 15=D-MMM-YY,D-MMM,MMM-YY,h:mm AM/PM,h:mm:ss AM/PM
+ 20=h:mm,h:mm:ss,M/D/YYYY h:mm,General,General
+ 25=General,General,M/D/YYYY,M/D/YYYY,M/D/YYYY
+ 30=M/D/YYYY,M/D/YYYY,h:mm:ss,h:mm:ss,h:mm:ss
+ 35=h:mm:ss,M/D/YYYY,'#,##0_);(#,##0)','#,##0_);[Red](#,##0)','#,##0.00_);(#,##0.00)'
+ 40='#,##0.00_);[Red](#,##0.00)'
+ 41='_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)'
+ 42='_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_)'
+ 43='_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)'
+ 44='_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)'
+ 45=mm:ss,[h]:mm:ss,mm:ss.0,##0.0E+0,@
+ 50=M/D/YYYY,M/D/YYYY,M/D/YYYY,M/D/YYYY,M/D/YYYY
+ 55=M/D/YYYY,M/D/YYYY,M/D/YYYY,M/D/YYYY,0
+ 60=0.00,'#,##0','#,##0.00','$#,##0_);($#,##0)','$#,##0_);[Red]($#,##0)'
+ 65='$#,##0.00_);($#,##0.00)','$#,##0.00_);[Red]($#,##0.00)',0%,0.00%,# ?/?
+ 70=# ??/??,M/D/YYYY,M/D/YYYY,D-MMM-YY,D-MMM
+ 75=MMM-YY,h:mm,h:mm:ss,M/D/YYYY h:mm,mm:ss
+ 80=[h]:mm:ss,mm:ss.0
+end
+
+constlist=CONSTVALUE-TYPE
+ 0=empty
+ 1=number
+ 2=string
+ 4=boolean
+ 16=error
+end
+
+constlist=PIVOT-NAMELEN
+ default=
+ 0xFFFF=name-in-cache
+end
+
+flagslist=FR-FLAGS
+ 0x0001=has-ref
+ 0x0002=alert-unsupported
+end
+
+shortlist=EXTCOLOR-TYPE,0,auto,indexed,rgb,theme,n/a
+
+combilist=EXTCOLOR-FLAGS
+ 0x01=rgb-valid
+ 0xFE=uint8,dec,type,EXTCOLOR-TYPE
+end
+
+shortlist=EXTGRADIENT-TYPE,0,linear,path
+
+shortlist=EXTFONT-SCHEME,-1,n/a,none,major,minor
+
+# DFF ------------------------------------------------------------------------
+
+flagslist=DFF-CLIENTANCHOR-FLAGS
+ 0x0001=pos-locked
+ 0x0002=size-locked
+end
+
+# formulas -------------------------------------------------------------------
+
+multilist=BASETOKENS-BIFF2
+ 0x00=,tExp,tTbl,tAdd,tSub,tMul,tDiv,tPower
+ 0x08=tConcat,tLT,tLE,tEQ,tGE,tGT,tNE,tIsect
+ 0x10=tList,tRange,tUplus,tUminus,tPercent,tParen,tMissArg,tStr
+ 0x18=,tAttr,tSheet,tEndSheet,tErr,tBool,tInt,tNum
+end
+
+constlist=BASETOKENS-BIFF5
+ include=BASETOKENS-BIFF2
+ exclude=0x1A,0x1B
+end
+
+constlist=BASETOKENS-BIFF8
+ include=BASETOKENS-BIFF5
+ 0x18=tNlr
+end
+
+constlist=TOKENCLASSES
+ 0x20=R
+ 0x40=V
+ 0x60=A
+end
+
+multilist=CLASSTOKENS-BIFF2
+ 0x00=tArray,tFunc,tFuncVar,tName,tRef,tArea,tMemArea,tMemErr
+ 0x08=tMemNoMem,tMemFunc,tRefErr,tAreaErr,tRefN,tAreaN,tMemAreaN,tMemNoMemN
+ 0x18=tFuncCE
+end
+
+constlist=CLASSTOKENS-BIFF4
+ include=CLASSTOKENS-BIFF2
+ exclude=0x18
+end
+
+multilist=CLASSTOKENS-BIFF5
+ include=CLASSTOKENS-BIFF4
+ 0x19=tNameX,tRef3d,tArea3d,tRefErr3d,tAreaErr3d
+end
+
+combilist=FUNCID
+ 0x7FFF=uint16,dec,func-id
+ 0x8000=command
+end
+
+combilist=PARAMCOUNT-CMD
+ 0x7F=uint8,dec,count
+ 0x80=prompt
+end
+
+combilist=REFRELFLAGS
+ 0x3FFF=uint16,dec,value
+ 0x4000=col-rel
+ 0x8000=row-rel
+end
+
+multilist=NLRTYPES
+ 0x00=,tNlrErr,tNlrRowR,tNlrColR,,,tNlrRowV,tNlrColV
+ 0x08=,,tNlrRange,tNlrSRange,tNlrSRowR,tNlrSColR,tNlrSRowV,tNlrSColV
+ 0x10=tNlrRangeErr,,,,,,,
+ 0x18=,,,,,tNlrSxName,,
+end
+
+combilist=NLRADDFLAGS
+ 0x3FFFFFFF=uint32,dec,count
+ 0x80000000=rel
+end
+
+flagslist=ATTRTYPES
+ 0x00=skip
+ 0x01=volatile
+ 0x02=if
+ 0x04=choose
+ 0x08=skip
+ 0x10=sum
+ 0x20=assign
+ 0x40=space
+end
+
+shortlist=ATTRSPACETYPES,0,space-before-token,cr-before-token,space-before-open,cr-before-open,space-before-close,cr-before-close,leading-space
+
+# record names ---------------------------------------------------------------
+
+multilist=RECORD-NAMES-BIFF2
+ # worksheet records
+ 0x0000=DIMENSION,BLANK,INTEGER,NUMBER,LABEL,BOOLERR,FORMULA,STRING
+ 0x0008=ROW,BOF,EOF,INDEX,CALCCOUNT,CALCMODE,PRECISION,REFMODE
+ 0x0010=DELTA,ITERATION,PROTECT,PASSWORD,HEADER,FOOTER,EXTERNCOUNT,EXTERNSHEET
+ 0x0018=DEFINEDNAME,WINDOWPROTECT,VERTICALPAGEBREAKS,HORIZONTALPAGEBREAKS,NOTE,SELECTION,FORMAT,BUILTINFMTCOUNT
+ 0x0020=COLUMNDEFAULT,ARRAY,DATEMODE,EXTERNALNAME,COLWIDTH,DEFAULTROWHEIGHT,LEFTMARGIN,RIGHTMARGIN
+ 0x0028=TOPMARGIN,BOTTOMMARGIN,PRINTHEADERS,PRINTGRIDLINES,,,,FILEPASS
+ 0x0030=,FONT,FONT2,PRINTSIZE,,INFOOPTS,DATATABLE,DATATABLE2
+ 0x0038=WNDESK,,BEGINPREF,ENDPREF,CONTINUE,WINDOW1,WINDOW2,
+ 0x0040=BACKUP,PANE,CODEPAGE,XF,IXFE,EFONT,SHOWSCROLL,SHOWFORMULA
+ 0x0048=STATUSBAR,SHORTMENUS,DDEENABLED,AUTODEC,MENUKEY,PLS|ZOOM,MENUUND,MOVESEL
+ 0x0050=DCON,DCONREF,DCONNAME,,,DEFCOLWIDTH,,
+ # worksheet records new in BIFF3, but supported in BIFF2 streams
+ 0x0200=DIMENSION,BLANK,,NUMBER,LABEL,BOOLERR,,
+ 0x0208=,,,INDEX,,,,
+ 0x027E=RK
+ # BIFF5 style BOF
+ 0x0809=BOF
+ # chart records
+ 0x1000=,CHUNITS,CHCHART,CHSERIES,CHSOURCELINK,,CHDATAFORMAT,CHLINEFORMAT
+ 0x1008=,CHMARKERFORMAT,CHAREAFORMAT,CHPIEFORMAT,CHATTACHEDLABEL,CHSTRING,,
+ 0x1010=,,,,CHTYPEGROUP,CHLEGEND,CHSERIESLIST,CHBAR
+ 0x1018=CHLINE,CHPIE,CHAREA,CHSCATTER,CHCHARTLINE,CHAXIS,CHTICK,CHVALUERANGE
+ 0x1020=CHLABELRANGE,CHAXISLINE,CHFORMATLINK,,CHDEFAULTTEXT,CHTEXT,CHFONT,CHOBJECTLINK
+ 0x1028=,,,,,CHARROW,,CHARROWHEAD
+ 0x1030=,,CHFRAME,CHBEGIN,CHEND,CHPLOTFRAME,CHCHARTSIZE,CHRELPOSITION
+ 0x1038=CHARROWRELPOS,,CHCHART3D,,,,,
+end
+
+multilist=RECORD-NAMES-BIFF3
+ include=RECORD-NAMES-BIFF2
+ # worksheet records
+ exclude=0x0006,0x0008,0x0009,0x000B,0x0018,0x0020,0x0023,0x0024,0x0025,0x0031,0x0036,0x0037,0x003E,0x0043,0x0044,0x0045
+ 0x0050=,,,,,,BUILTINFMTCOUNT,
+ 0x0058=TOOLBAR,XCT,CRN,FILESHARING,WRITEACCESS,OBJ,UNCALCED,SAFERECALC
+ 0x0060=TEMPLATE,INTL,,OBJECTPROTECT,,,,
+ 0x0068=,,,,,,,
+ 0x0070=,,,,,,,
+ 0x0078=,,,,,COLINFO,,IMGDATA
+ 0x0080=GUTS,SHEETPR,GRIDSET,HCENTER,VCENTER,,WRITEPROT,ADDIN
+ 0x0088=EDG,PUB,NOTEOFF,LH,COUNTRY,HIDEOBJ,,
+ 0x0090=SORT,SUB,PALETTE,,LHRECORD,LHNGRAPH,,
+ 0x0200=,,,,,,FORMULA,STRING
+ 0x0208=ROW,BOF,,,,,,
+ 0x0218=DEFINEDNAME
+ 0x0221=ARRAY
+ 0x0223=EXTERNALNAME
+ 0x0225=DEFAULTROWHEIGHT
+ 0x0231=FONT
+ 0x0236=DATATABLE
+ 0x023E=WINDOW2
+ 0x0243=XF
+ 0x0293=STYLE
+ # chart records
+ 0x103C=CHPICFORMAT
+end
+
+multilist=RECORD-NAMES-BIFF4
+ include=RECORD-NAMES-BIFF3
+ # worksheet/workbook records
+ exclude=0x0206,0x0209,0x001E,0x0243
+ 0x0085=SHEET
+ 0x0088=,,,,,,SHEETSOFFSET,SHEETHEADER
+ 0x0090=,,,,,,NOTESOUND,SYNC
+ 0x0098=LPR,STANDARDWIDTH,FNGROUPNAME,,FNGROUPCOUNT,,,
+ 0x00A0=SCL,PAGESETUP,FNPROTO,PROJEXTSHEET,,,,
+ 0x00A8=DRAGDROP,COORDLIST,,GCW,,,,
+ 0x0406=FORMULA
+ 0x0409=BOF
+ 0x041E=FORMAT
+ 0x0443=XF
+ # chart records
+ 0x1038=,,,CHMULTILINK,,CHDROPBAR,CHRADARLINE,CHSURFACE
+end
+
+multilist=RECORD-NAMES-BIFF5
+ include=RECORD-NAMES-BIFF4
+ # worksheet/workbook records
+ exclude=0x0409,0x0218,0x0223,0x0231,0x0443
+ 0x0006=FORMULA
+ 0x0018=DEFINEDNAME
+ 0x0023=EXTERNALNAME
+ 0x0031=FONT
+ 0x0098=,,,FILTERMODE,,AUTOFILTER,FILTERCOLUMN,
+ 0x00A8=,,,,,,SCENARIOS,SCENARIO
+ 0x00B0=PTDEFINITION,PTFIELD,PTFITEM,,PTROWCOLFIELDS,PTROWCOLITEMS,PTPAGEFIELDS,
+ 0x00B8=DOCROUTE,RECIPNAME,,,,MULTRK,MULTBLANK,TOOLBARHDR
+ 0x00C0=TOOLBAREND,MMS,ADDMENU,DELMENU,,PTDATAFIELD,PCDEFINITION,PCDFIELD
+ 0x00C8=PCITEM_INDEXLIST,PCITEM_DOUBLE,PCITEM_BOOL,PCITEM_ERROR,PCITEM_INTEGER,PCITEM_STRING,PCITEM_DATE,PCITEM_MISSING
+ 0x00D0=SXTBL,SXTBRGITEM,SXTBPG,VBAPROJECT,,PIVOTCACHE,RSTRING,DBCELL
+ 0x00D8=PCDFRANGEPR,PCDFDISCRETEPR,BOOKBOOL,REVERT,DBORPARAMQUERY,SCENPROTECT,OLESIZE,UDDESC
+ 0x00E0=XF,INTERFACEHDR,INTERFACEEND,PCDSOURCE,,,,
+ 0x0206=FORMULA
+ 0x04BC=SHAREDFMLA
+ # chart records
+ exclude=0x1004,0x102D,0x102F,0x1036,0x1037,0x1038,0x103B
+ 0x1040=CHRADARAREA,CHAXESSET,,CHLEGENDENTRY,CHPROPERTIES,CHSERGROUP,CHUSEDAXESSETS,
+ 0x1048=CHPIVOTRANGE,,CHSERPARENT,CHSERTRENDLINE,,,CHFORMAT,CHFRAMEPOS
+ 0x1050=CHFORMATRUNS,CHSOURCELINK,,,,,,
+ 0x1058=,,,CHSERERRORBAR,,CHSERIESFORMAT,,
+end
+
+multilist=RECORD-NAMES-BIFF8
+ include=RECORD-NAMES-BIFF5
+ # worksheet/workbook records
+ 0x00E0=,,,,,CELLMERGING,,
+ 0x00E8=,IMGDATA,,MSODRAWINGGROUP,MSODRAWING,MSODRAWINGSELECTION,,PHONETICPR
+ 0x00F0=,PTDEFINITION2,,,,,,
+ 0x00F8=,PCDFORMULAFIELD,,,SST,LABELSST,,EXTSST
+ 0x0100=PTFIELD2,,,PCDFIELDINDEX,,,,
+ 0x0120=,,PCDEFINITION2,,,,,
+ 0x0130=,,,,,,,CHTRINSERT
+ 0x0138=CHTRINFO,,,CHTRCELLCONTENT,,TABID,,
+ 0x0140=CHTRMOVERANGE,,,,,,,
+ 0x0148=,,,,,CHTRINSERTTAB,,
+ 0x0158=,,,,,,,LABELRANGES
+ 0x0160=USESELFS,DSF,XL5MODIFY,,,,,
+ 0x0190=,,,,,,CHTRHEADER,
+ 0x01A8=,USERBVIEW,USERSVIEWBEGIN,USERSVIEWEND,,QUERYTABLE,EXTERNALBOOK,PROT4REV
+ 0x01B0=CFHEADER,CFRULE,DATAVALIDATIONS,,,DCONBINAME,TXO,REFRESHALL
+ 0x01B8=HYPERLINK,NLRDELNAME,CODENAME,PCDFSQLTYPE,PROT4REVPASS,VBAPROJECTEMPTY,DATAVALIDATION,
+ 0x01C0=XL9FILE,RECALCID,INTCACHEDDATA,,,,,
+ # future records
+ 0x0800=SCREENTIP,,QUERYTABLEREFRESH,QUERYTABLESETTINGS,QUERYTABLESTRING,,,
+ 0x0850=CHFRINFO,CHFRWRAPPER,CHFRBLOCKBEGIN,CHFRBLOCKEND,,,CHFRCATEGORYPROPS,CHFRUNITPROPS
+ 0x0858=CHPIVOTREF,CHPIVOTFLAGS,,,,,,
+ 0x0860=,,SHEETEXT,BOOKEXT,,,,SHAREDFEATHEAD
+ 0x0868=,,,CHFRLABELPROPS,,,,
+ 0x0870=,,,,,,CONNECTION,
+ 0x0878=,,CFRULE12,CFRULEEXT,XFCRC,XFEXT,FILTERCOLUMN12,CONTINUE12
+ 0x0888=,,,PAGELAYOUTVIEW,CHECKCOMPAT,DXF,TABLESTYLES,
+ 0x0890=,,STYLEEXT,,,,THEME,
+ 0x0898=,,MTHREADSETTINGS,COMPRESSPICS,HEADERFOOTER,CHFRLAYOUT,CHFREXTPROPS,CHFREXTPROPSCONT
+ 0x08A0=,,,FORCEFULLCALC,CHFRSHAPEPROPS,CHFRTEXTPROPS,,CHFRPLOTAREALAYOUT
+ # chart records
+ 0x1058=,,,,,,,CH3DDATAFORMAT
+ 0x1060=CHFONTBASE,CHPIEEXT,CHDATERANGE,CHDATATABLE,CHPLOTGROWTH,CHSERINDEX,CHESCHERFORMAT,CHPIEEXTSETT
+end
+
+# simple records -------------------------------------------------------------
+
+constlist=SIMPLE-RECORDS-BIFF2
+ 0x000C=uint16,dec,max-iterations
+ 0x000D=int16,dec,calc-mode,CALCMODE
+ 0x000E=uint16,bool,calc-precise
+ 0x000F=uint16,dec,ref-mode,REFMODE
+ 0x0010=double,dec,epsilon
+ 0x0011=uint16,bool,iterate-recursive
+ 0x0012=uint16,bool,contents-protected
+ 0x0013=uint16,hex,password-hash
+ 0x0016=uint16,dec,externsheets
+ 0x0019=uint16,bool,window-protected
+ 0x001F=uint16,dec,builtin-fmt-count
+ 0x0022=uint16,dec,null-date,DATEMODE
+ 0x0025=uint16,hex,rowheight-flags,DEFROWHEIGHT-FLAGS
+ 0x0026=double,dec,left-margin,CONV-INCH-TO-CM
+ 0x0027=double,dec,right-margin,CONV-INCH-TO-CM
+ 0x0028=double,dec,top-margin,CONV-INCH-TO-CM
+ 0x0029=double,dec,bottom-margin,CONV-INCH-TO-CM
+ 0x002A=uint16,bool,print-sheet-headers
+ 0x002B=uint16,bool,print-gridlines
+ 0x0040=uint16,bool,backup-on-save
+ 0x0044=uint16,dec,xf-idx
+ 0x0045=uint16,dec,font-color-idx,COLORS
+ 0x0055=uint16,dec,base-col-width
+ 0x100B=uint16,dec,extrusion,CONV-PERCENT
+ 0x100C=uint16,hex,flags,CHATTACHEDLABEL-FLAGS
+ 0x1018=uint16,hex,flags,CHLINE-FLAGS
+ 0x101A=uint16,hex,flags,CHAREA-FLAGS
+ 0x101C=uint16,dec,line-type,CHCHARTLINE-TYPE
+ 0x1021=uint16,dec,axisline-id,CHAXISLINE-ID
+ 0x1024=uint16,dec,text-idx
+ 0x1026=uint16,dec,font-idx,FONTNAMES
+ 0x1045=uint16,dec,group-idx
+ 0x1046=uint16,dec,used-axessets
+ 0x104A=uint16,dec,series-idx
+ 0x104E=uint16,dec,fmt-idx,FORMATS
+end
+
+constlist=SIMPLE-RECORDS-BIFF3
+ include=SIMPLE-RECORDS-BIFF2
+ 0x0056=uint16,dec,builtin-fmt-count
+ 0x005E=uint16,unused
+ 0x005F=uint16,bool,recalc-on-save
+ 0x0063=uint16,bool,objects-protected
+ 0x0081=uint16,hex,flags,SHEETPR-FLAGS
+ 0x0082=uint16,bool,print-gridlines-changed
+ 0x0083=uint16,bool,horizontal-centered
+ 0x0084=uint16,bool,vertical-centered
+ 0x008D=uint16,dec,object-mode,HIDEOBJ
+end
+
+constlist=SIMPLE-RECORDS-BIFF4
+ include=SIMPLE-RECORDS-BIFF3
+ 0x008E=uint32,hex,stream-pos,CONV-DEC
+ 0x0099=uint16,dec,default-col-width,CONV-COLWIDTH
+ 0x009C=uint16,dec,func-group-count
+ 0x103D=uint16,dec,bar-dist
+ 0x103E=uint16,hex,flags,CHRADAR-FLAGS
+ 0x103F=uint16,hex,flags,CHSURFACE-FLAGS
+end
+
+constlist=SIMPLE-RECORDS-BIFF5
+ include=SIMPLE-RECORDS-BIFF4
+ 0x009D=uint16,dec,column-count
+ 0x00C9=double,dec,value
+ 0x00CA=uint16,bool,value
+ 0x00CB=uint16,hex,error-code,ERRORCODES
+ 0x00CC=int16,dec,value
+ 0x00D5=uint16,hex,cache-id
+ 0x00D8=uint16,hex,flags,PCDFRANGEPR-FLAGS
+ 0x00DA=uint16,bool,strip-cached-values
+ 0x00DD=uint16,bool,scenarios-protected
+ 0x00E3=uint16,dec,source-type,PCDSOURCE-TYPE
+ 0x1040=uint16,hex,flags,CHRADAR-FLAGS
+ 0x105D=uint16,hex,flags,CHSERIESFORMAT-FLAGS
+end
+
+constlist=SIMPLE-RECORDS-BIFF8
+ include=SIMPLE-RECORDS-BIFF5
+ 0x00E1=uint16,dec,codepage,CODEPAGES
+ 0x0160=uint16,bool,use-nat-lang-refs
+ 0x0161=uint16,bool,double-stream
+ 0x01AF=uint16,bool,revlog-protected
+ 0x01B7=uint16,bool,refresh-all
+ 0x01BB=uint16,dec,sql-data-type,PCDFSQLTYPE-DATATYPE
+ 0x01BC=uint16,hex,password-hash
+ 0x1065=uint16,dec,series-idx
+end
+
+# ARRAY ----------------------------------------------------------------------
+
+flagslist=ARRAY-FLAGS-BIFF2
+ 0x0001=recalc-always
+end
+
+flagslist=ARRAY-FLAGS-BIFF3
+ include=ARRAY-FLAGS-BIFF2
+ 0x0002=recalc-onload
+end
+
+# BOF ------------------------------------------------------------------------
+
+constlist=BOF-BIFFTYPE
+ 0x0000=from-id
+ 0x0007=biff2
+ 0x0200=biff2
+ 0x0300=biff3
+ 0x0400=biff4
+ 0x0500=biff5
+ 0x0600=biff8
+end
+
+constlist=BOF-SHEETTYPE
+ 0x0005=globals
+ 0x0006=vb-module
+ 0x0010=sheet
+ 0x0020=chart
+ 0x0040=macro
+ 0x0100=workspace
+end
+
+shortlist=BOF-EXCELVERSION,0,excel-97,excel-2000,excel-2002,excel-2003,excel-2007,,excel-2010
+shortlist=BOF-LOWESTVERSION-BIFF,6,biff8
+
+combilist=BOF-HISTORY-FLAGS
+ ignore=0x000000C0
+ 0x00000001=windows
+ 0x00000002=risc
+ 0x00000004=beta
+ 0x00000008=win-any
+ 0x00000010=mac-any
+ 0x00000020=beta-any
+ 0x00000100=risc-any
+ 0x00000200=out-of-mem
+ 0x00000400=out-of-mem-renderer
+ 0x00002000=font-limit-255
+ 0x0003C000=uint8,dec,max-version-saved,BOF-EXCELVERSION
+end
+
+combilist=BOF-LOWESTVERSION-FLAGS
+ 0x000000FF=uint8,dec,biff-version,BOF-LOWESTVERSION-BIFF
+ 0x00000F00=uint8,dec,version-saved,BOF-EXCELVERSION
+end
+
+# BOOKEXT --------------------------------------------------------------------
+
+combilist=BOOKEXT-FLAGS1
+ 0x00000001=no-auto-recover
+ 0x00000002=hide-pivot-list
+ 0x00000004=filter-privacy
+ 0x00000008=embed-smarttags
+ 0x00000030=uint8,dec,display-smarttags,BOOKEXT-DISPLAY-SMARTTAGS
+ 0x00000040=saved-on-recovery
+ 0x00000080=minimal-save
+ 0x00000100=opened-on-recovery
+ 0x00000200=opened-in-save-mode
+end
+
+shortlist=BOOKEXT-DISPLAY-SMARTTAGS,0,button-and-indicator,button,nothing
+
+flagslist=BOOKEXT-FLAGS2
+ 0x01=warn-smart-doc-manifest
+ 0x02=show-inc-annotations
+end
+
+flagslist=BOOKEXT-FLAGS3
+ 0x02=!all-published!selected-items-published
+ 0x04=show-pivot-chart-filter
+end
+
+# CALCMODE -------------------------------------------------------------------
+
+shortlist=CALCMODE,-1,automatic-no-table,manual,automatic
+
+# CFHEADER -------------------------------------------------------------------
+
+combilist=CFHEADER-FLAGS
+ 0x0001=complex
+ 0xFFFE=uint16,dec,id
+end
+
+# CFRULE ---------------------------------------------------------------------
+
+shortlist=CFRULE-TYPE,1,value,formula
+shortlist=CFRULE-OPERATOR,0,none,between,not-between,equal,not-equal,greater-than,less-than,greater-equal,less-equal
+
+flagslist=CFRULE-FLAGS1
+ ignore=0x00200000
+ 0x00000001=!hor-align-used
+ 0x00000002=!vert-align-used
+ 0x00000004=!text-wrap-used
+ 0x00000008=!rotation-used
+ 0x00000010=!justify-lastline-used
+ 0x00000020=!indent-used
+ 0x00000040=!shrinktofit-used
+ 0x00000080=!cell-merged-used
+ 0x00000100=!cell-locked-used
+ 0x00000200=!cell-hidden-used
+ 0x00000400=!left-border-used
+ 0x00000800=!right-border-used
+ 0x00001000=!top-border-used
+ 0x00002000=!bottom-border-used
+ 0x00004000=!tl-to-br-used
+ 0x00008000=!bl-to-tr-used
+ 0x00010000=!fill-pattern-used
+ 0x00020000=!fg-color-idx-used
+ 0x00040000=!bg-color-idx-used
+ 0x00080000=!fmt-idx-used
+ 0x00100000=!def-font-used
+ 0x02000000=numfmt-block
+ 0x04000000=font-block
+ 0x08000000=alignment-block
+ 0x10000000=border-block
+ 0x20000000=pattern-block
+ 0x40000000=protection-block
+ 0x80000000=!text-dir-used
+end
+
+flagslist=CFRULE-FLAGS2
+ ignore=0x0002
+ 0x0001=!numfmt-id!numfmt-string
+ 0x0004=outline-border
+ 0x8000=use-text-dir
+end
+
+combilist=CFRULE-ALIGNMENT
+ 0x07=uint8,dec,hor-align,XF-HORALIGN
+ 0x08=text-wrap
+ 0x70=uint8,dec,ver-align,XF-VERALIGN
+ 0x80=justify-lastline
+end
+
+combilist=CFRULE-INDENT
+ 0x000F=uint8,dec,indent
+ 0x0010=shrink-to-fit
+ 0x0020=cell-merged
+ 0x00C0=uint8,dec,text-dir,XF-TEXTDIRECTION
+end
+
+flagslist=CFRULE-FONTFLAGS
+ 0x00000002=italic
+ 0x00000008=outline
+ 0x00000010=shadow
+ 0x00000020=condense
+ 0x00000040=extend
+ 0x00000080=strikeout
+end
+
+constlist=CFRULE-FONTWEIGHT
+ include=FONT-WEIGHT
+ -1=unused
+end
+
+constlist=CFRULE-FONTESCAPEMENT
+ include=FONT-ESCAPEMENT
+ -1=unused
+end
+
+constlist=CFRULE-FONTUNDERLINE
+ include=FONT-UNDERLINE
+ -1=unused
+end
+
+constlist=CFRULE-FONTCOLOR
+ include=COLORS-BIFF8
+ -1=unused
+end
+
+flagslist=CFRULE-FONTUSEDFLAGS
+ ignore=0xFFFFFF00
+ 0x00000002=!italic-used
+ 0x00000008=!outline-used
+ 0x00000010=!shadow-used
+ 0x00000020=!condense-used
+ 0x00000040=!extend-used
+ 0x00000080=!strikeout-used
+end
+
+constlist=CFRULE-FONTUSED
+ 0=used
+ 1=not-used
+end
+
+combilist=CFRULE-BORDERCOLOR2
+ 0x0000007F=uint8,dec,top-color,COLORS
+ 0x00003F80=uint8,dec,bottom-color,COLORS
+ 0x001FC000=uint8,dec,diag-color,COLORS
+ 0x01E00000=uint8,dec,diag-style,BORDERSTYLES
+end
+
+combilist=CFRULE-FILLBLOCK
+ 0x0000FC00=uint8,dec,fill-pattern,FILLPATTERNS
+ 0x007F0000=uint8,dec,fg-color-idx,COLORS
+ 0x3F800000=uint8,dec,bg-color-idx,COLORS
+end
+
+flagslist=CFRULE-PROTECTION-FLAGS
+ 0x0001=locked
+ 0x0002=formula-hidden
+end
+
+# CFRULE12 -------------------------------------------------------------------
+
+shortlist=CFRULE12-TYPE,1,cell-is,expression,color-scale,data-bar,top-ten,icon-set
+
+flagslist=CFRULE12-FLAGS
+ 0x0002=stop-if-true
+end
+
+multilist=CFRULE12-SUBTYPE
+ 0=cell-is,expression,color-scale,data-bar,icon-set,top-ten,,unique-values,contains-text,contains-blanks
+ 10=not-contains-blanks,contains-errors,not-contains-errors,,,today,tomorrow,yesterday,last-7-days,last-month
+ 20=next-month,this-week,next-week,last-week,this-month,above-average,below-average,duplicate-values,,equal-above-average
+ 30=equal-below-average
+end
+
+flagslist=CFRULE12-TOP10-FLAGS
+ 0x01=!bottom!top
+ 0x02=percent
+end
+
+shortlist=CFRULE12-TEXT-OPERATOR,0,contains,not-contains,begins-with,ends-with
+shortlist=CFRULE12-DATE-OPERATOR,0,today,yesterday,last-7-days,this-week,last-week,last-month,tomorrow,next-week,next-month,this-month
+
+# CFRULEEXT ------------------------------------------------------------------
+
+flagslist=CFRULEEXT-FLAGS
+ 0x0001=active
+ 0x0002=stop-if-true
+end
+
+# CH3DDATAFORMAT -------------------------------------------------------------
+
+shortlist=CH3DDATAFORMAT-BASE,0,rectangular,circular
+shortlist=CH3DDATAFORMAT-TOP,0,straight,sharp,trunc
+
+# CHAREA ---------------------------------------------------------------------
+
+flagslist=CHAREA-FLAGS
+ 0x0001=stacked
+ 0x0002=percent
+ 0x0004=shadow
+end
+
+# CHAREAFORMAT ---------------------------------------------------------------
+
+flagslist=CHAREAFORMAT-FLAGS
+ 0x0001=auto
+ 0x0002=swap-negative
+end
+
+# CHATTACHEDLABEL ------------------------------------------------------------
+
+flagslist=CHATTACHEDLABEL-FLAGS
+ 0x0001=show-value
+ 0x0002=show-percent
+ 0x0004=show-categ-percent
+ 0x0008=smoothed
+ 0x0010=show-categ
+ 0x0020=show-bubble
+end
+
+# CHAXESSET ------------------------------------------------------------------
+
+shortlist=CHAXESSET-ID,0,primary,secondary
+
+# CHAXIS ---------------------------------------------------------------------
+
+shortlist=CHAXIS-TYPE,0,x-axis,y-axis,z-axis
+
+# CHAXISLINE -----------------------------------------------------------------
+
+shortlist=CHAXISLINE-ID,0,axisline,major-grid,minor-grid,wall
+
+# CHBAR ----------------------------------------------------------------------
+
+flagslist=CHBAR-FLAGS
+ 0x0001=horizontal
+ 0x0002=stacked
+ 0x0004=percent
+ 0x0008=shadow
+end
+
+# CHCHART3D ------------------------------------------------------------------
+
+flagslist=CHCHART3D-FLAGS
+ ignore=0x0010
+ 0x0001=real3d
+ 0x0002=clustered
+ 0x0004=auto-height
+ 0x0020=2d-plotarea
+end
+
+# CHTYPEGROUP ----------------------------------------------------------------
+
+flagslist=CHTYPEGROUP-FLAGS
+ 0x0001=varied-colors
+end
+
+# CHCHARTLINE ----------------------------------------------------------------
+
+shortlist=CHCHARTLINE-TYPE,0,drop-line,hi-lo-line,series-connector
+
+# CHDATAFORMAT ---------------------------------------------------------------
+
+constlist=CHDATAFORMAT-POINTIDX
+ default=
+ -1=all-points
+end
+
+constlist=CHDATAFORMAT-FORMATIDX
+ default=
+ -3=axesset-global
+end
+
+flagslist=CHDATAFORMAT-FLAGS
+ 0x0001=excel4-colors
+end
+
+# CHDATERANGE ----------------------------------------------------------------
+
+shortlist=CHDATERANGE-UNIT,0,days,months,years
+
+flagslist=CHDATERANGE-FLAGS
+ 0x0001=auto-minimum
+ 0x0002=auto-maximum
+ 0x0004=auto-major
+ 0x0008=auto-minor
+ 0x0010=date-axis
+ 0x0020=auto-base
+ 0x0040=auto-axis-cross
+ 0x0080=auto-date
+end
+
+# CHFRAME --------------------------------------------------------------------
+
+shortlist=CHFRAME-FORMAT,0,standard,,,,shadow
+
+flagslist=CHFRAME-FLAGS
+ 0x0001=auto-size
+ 0x0002=auto-pos
+end
+
+# CHFRAMEPOS -----------------------------------------------------------------
+
+shortlist=CHFRAMEPOS-POSMODE,0,rel-points,abssize-points,parent-dependent,offset-plotarea-size,,chartsize
+
+# CHFRBLOCKBEGIN, CHFRBLOCKEND -----------------------------------------------
+
+shortlist=CHFRBLOCK-TYPE,0,axes-set,,text,,axis,type-group,data-table,frame,,legend,legend-exception,,series,chart,data-format,drop-bar
+
+# CHFRCATEGORYPROPS ----------------------------------------------------------
+
+shortlist=CHFRCATEGORYPROPS-ALIGN,1,top-left,center,bottom-right
+
+flagslist=CHFRCATEGORYPROPS-FLAGS
+ ignore=0xFFFE
+ 0x0001=auto-label-frequency
+end
+
+# CHFREXTPROPS ---------------------------------------------------------------
+
+constlist=CHFREXTPROPS-PARENT
+ 0x0001=log-scaling
+ 0x0002=style
+ 0x0004=category-scaling
+ 0x0005=chart-props
+ 0x000F=legend
+ 0x0013=marker
+ 0x0016=plot-area
+ 0x0019=chart-title
+ 0x0037=3d-props
+end
+
+constlist=CHFREXTPROPS-TYPE
+ 0=start
+ 1=end
+ 2=bool
+ 3=double
+ 4=int32
+ 5=string
+ 6=uint16
+ 7=blob
+end
+
+constlist=CHFREXTPROPS-TAG
+ 0x0000=log-base
+ 0x0003=style
+ 0x001E=chart-formatting
+ 0x0020=text-formatting
+ 0x0022=symbol-type
+ 0x002E=no-multi-level
+ 0x002F=overlay
+ 0x0033=theme-override
+ 0x0034=color-mapping-override
+ 0x0035=backwall-thickness
+ 0x0036=floor-thickness
+ 0x004D=perspective
+ 0x004E=rotation-x
+ 0x004F=rotation-y
+ 0x0050=right-angled-axes-off
+ 0x0052=tick-mark-skip
+ 0x0051=tick-label-skip
+ 0x0053=major-unit
+ 0x0054=minor-unit
+ 0x0055=max
+ 0x0056=min
+ 0x0059=side-wall
+ 0x005B=show-data-labels-over-max
+ 0x005C=tick-label-pos
+ 0x005E=pie-combination
+ 0x005F=basetime-unit
+ 0x0064=format-code
+ 0x0065=height-percent
+ 0x0066=display-blanks-as
+ 0x006A=major-unit-type
+ 0x006B=minor-unit-type
+ 0x0076=edit-language
+end
+
+constlist=CHFREXTPROPS-TAG-NAMELIST
+ default=
+ 0x0022=CHFREXTPROPS-SYMBOLTYPE
+ 0x0035=CONV-PERCENT
+ 0x0036=CONV-PERCENT
+ 0x004E=CONV-DEG
+ 0x004F=CONV-DEG
+ 0x005C=CHFREXTPROPS-TICKLABELPOS
+ 0x005F=CHFREXTPROPS-TIMEUNIT
+ 0x0065=CONV-PERCENT
+ 0x0066=CHFREXTPROPS-DISPBLANKSAS
+ 0x006A=CHFREXTPROPS-TIMEUNIT
+ 0x006B=CHFREXTPROPS-TIMEUNIT
+end
+
+shortlist=CHFREXTPROPS-DISPBLANKSAS,0x0067,gap,,spanned
+shortlist=CHFREXTPROPS-SYMBOLTYPE,0x0023,none,diamond,square,triangle,x,star,dot,dash,circle,plus
+shortlist=CHFREXTPROPS-TICKLABELPOS,0x005D,center
+shortlist=CHFREXTPROPS-TIMEUNIT,0x0060,days,months,years
+
+# CHFRINFO -------------------------------------------------------------------
+
+shortlist=CHFRINFO-APPVERSION,9,excel-2000,excel-xp-2003,,excel-2007
+
+# CHFRLABELPROPS -------------------------------------------------------------
+
+flagslist=CHFRLABELPROPS-FLAGS
+ 0x0001=show-series
+ 0x0002=show-categ
+ 0x0004=show-value
+ 0x0008=show-percent
+ 0x0010=show-bubble
+end
+
+# CHFRLAYOUT -----------------------------------------------------------------
+
+combilist=CHFRLAYOUT-FLAGS
+ 0x001E=uint8,dec,legend-pos,CHFRLAYOUT-LEGENDPOS
+end
+
+shortlist=CHFRLAYOUT-LEGENDPOS,0,bottom,top-right,top,right,left
+
+shortlist=CHFRLAYOUT-MODE,0,auto,factor,edge
+
+# CHFRPLOTAREALAYOUT ---------------------------------------------------------
+
+flagslist=CHFRPLOTAREALAYOUT-FLAGS
+ 0x0001=!outer!inner
+end
+
+shortlist=CHFRLAYOUT-LEGENDPOS,0,bottom,top-right,top,right,left
+
+shortlist=CHFRLAYOUT-MODE,0,auto,factor,edge
+
+# CHFRUNITPROPS --------------------------------------------------------------
+
+shortlist=CHFRUNITPROPS-PRESET,-1,manual,none,hundred,thousand,10000,100000,million,10-million,100-million,billion,trillion
+
+flagslist=CHFRUNITPROPS-FLAGS
+ 0x0002=show-unit
+end
+
+# CHLABELRANGE ---------------------------------------------------------------
+
+flagslist=CHLABELRANGE-FLAGS
+ 0x0001=cross-between-categ
+ 0x0002=maximum-axis-cross
+ 0x0004=reverse-order
+end
+
+# CHLEGEND -------------------------------------------------------------------
+
+shortlist=CHLEGEND-DOCKPOS,0,bottom,top-right,top,right,left,,,manual
+shortlist=CHLEGEND-SPACING,0,close,medium,open
+
+flagslist=CHLEGEND-FLAGS
+ 0x0001=docked
+ 0x0002=auto-series
+ 0x0004=auto-pos-x
+ 0x0008=auto-pos-y
+ 0x0010=stacked
+ 0x0020=data-table
+end
+
+# CHLINE ---------------------------------------------------------------------
+
+flagslist=CHLINE-FLAGS
+ 0x0001=stacked
+ 0x0002=percent
+ 0x0004=shadow
+end
+
+# CHLINEFORMAT ---------------------------------------------------------------
+
+shortlist=CHLINEFORMAT-LINETYPE,0,solid,dash,dot,dash-dot,dash-dot-dot,none,25%-pattern,50%-pattern,75%-pattern
+shortlist=CHLINEFORMAT-LINEWEIGHT,-1,hair,thin,medium,thick
+
+flagslist=CHLINEFORMAT-FLAGS
+ 0x0001=auto
+ 0x0004=axis-enabled
+ 0x0008=system-color
+end
+
+# CHMARKERFORMAT -------------------------------------------------------------
+
+shortlist=CHMARKERFORMAT-TYPE,0,none,square,diamond,triangle,cross,star,dow-jones,std-dev,circle,plus
+
+flagslist=CHMARKERFORMAT-FLAGS
+ 0x0001=auto
+ 0x0010=no-fill
+ 0x0020=no-border
+end
+
+# CHOBJECTLINK ---------------------------------------------------------------
+
+shortlist=CHOBJECTLINK-TARGET,0,none,title,y-axis,x-axis,datapoint,legend,none,z-axis,,,,,axis-unit
+
+constlist=CHOBJECTLINK-POINT
+ default=
+ -2=unknown
+ -1=all-points
+end
+
+# CHPICFORMAT ----------------------------------------------------------------
+
+shortlist=CHPICFORMAT-BITMAP-MODE,1,stretched,stacked,stacked-scaled
+
+combilist=CHPICFORMAT-FLAGS
+ 0x0200=top-bottom
+ 0x0400=front-back
+ 0x0800=left-right
+end
+
+# CHPIE ----------------------------------------------------------------------
+
+flagslist=CHPIE-FLAGS
+ 0x0001=shadow
+ 0x0002=connectors
+end
+
+# CHPIVOTFLAGS ---------------------------------------------------------------
+
+flagslist=CHPIVOTFLAGS-FLAGS
+ 0x0001=hide-field-captions
+end
+
+# CHRADAR, CHRADARAREA -------------------------------------------------------
+
+flagslist=CHRADAR-FLAGS
+ 0x0001=axis-labels
+ 0x0002=shadow
+end
+
+# CHPROPERTIES ---------------------------------------------------------------
+
+shortlist=CHPROPERTIES-EMPTYCELLS,0,do-not-plot,as-zero,interpolated
+
+flagslist=CHPROPERTIES-FLAGS
+ 0x0001=manual-series
+ 0x0002=plot-visible-only
+ 0x0004=fixed-size
+ 0x0008=manual-plotarea
+ 0x0010=apply-plotarea-pos
+end
+
+# CHSCATTER ------------------------------------------------------------------
+
+shortlist=CHSCATTER-SIZETYPE,0,none,area,width
+
+flagslist=CHSCATTER-FLAGS
+ 0x0001=bubbles
+ 0x0002=show-negative
+ 0x0004=shadow
+end
+
+# CHSERERRORBAR --------------------------------------------------------------
+
+shortlist=CHSERERRORBAR-TYPE,1,x-plus,x-minus,y-plus,y-minus
+shortlist=CHSERERRORBAR-SOURCE,1,percent,fixed,std-deviation,custom,std-error
+
+# CHSERIES -------------------------------------------------------------------
+
+shortlist=CHSERIES-TYPE,0,date,numeric,sequence,text
+
+# CHSERIESFORMAT -------------------------------------------------------------
+
+flagslist=CHSERIESFORMAT-FLAGS
+ 0x0001=spline
+ 0x0002=bubbles-3d
+ 0x0004=shadow
+end
+
+# CHSERTRENDLINE -------------------------------------------------------------
+
+shortlist=CHSERTRENDLINE-TYPE,0,polynomial,exponential,logarithmic,power,moving-average
+
+# CHSOURCELINK ---------------------------------------------------------------
+
+shortlist=CHSOURCELINK-TARGET,0,title,values,category,bubbles
+shortlist=CHSOURCELINK-TYPE,0,default,constant,sheet-link
+
+flagslist=CHSOURCELINK-FLAGS
+ 0x0001=custom-numfmt
+end
+
+# CHSTRING -------------------------------------------------------------------
+
+shortlist=CHSTRING-TYPE,0,text,category-default,value-default,x-prefix,x-postfix,y-prefix,y-postfix,comment
+
+# CHSURFACE ------------------------------------------------------------------
+
+flagslist=CHSURFACE-FLAGS
+ 0x0001=filled
+ 0x0002=shadow
+end
+
+# CHTEXT ---------------------------------------------------------------------
+
+shortlist=CHTEXT-HORALIGN,1,left,center,right,block,distribute
+shortlist=CHTEXT-VERALIGN,1,top,center,bottom,block,distribute
+shortlist=CHTEXT-FILLMODE,1,transparent,opaque
+
+flagslist=CHTEXT-FLAGS1-BIFF2
+ 0x0001=auto-color
+ 0x0002=show-symbol
+ 0x0004=show-value
+ 0x0008=vertical
+ 0x0010=auto-text
+ 0x0020=default-format
+ 0x0040=deleted
+ 0x0080=auto-fill
+end
+
+combilist=CHTEXT-FLAGS1-BIFF3
+ include=CHTEXT-FLAGS1-BIFF2
+ 0x0700=uint8,dec,orientation,TEXTORIENTATION
+end
+
+combilist=CHTEXT-FLAGS1-BIFF5
+ include=CHTEXT-FLAGS1-BIFF3
+ 0x0800=show-categ-percent
+ 0x1000=show-percent
+end
+
+combilist=CHTEXT-FLAGS1-BIFF8
+ include=CHTEXT-FLAGS1-BIFF5
+ 0x2000=show-bubble-size
+ 0x4000=show-categ
+end
+
+combilist=CHTEXT-FLAGS2
+ ignore=0x3FF0
+ 0x000F=uint8,dec,placement,CHTEXT-PLACEMENT
+ 0xC000=uint8,dec,text-dir,XF-TEXTDIRECTION
+end
+
+shortlist=CHTEXT-PLACEMENT,0,context,outside,inside,center,axis,above,below,left,right,auto,manual
+
+# CHTICK ---------------------------------------------------------------------
+
+shortlist=CHTICK-TYPE,0,none,inside,outside,both
+# TODO: really different label positions in BIFF2-BIFF4?
+shortlist=CHTICK-LABELPOS-BIFF2,0,none,near,below,above
+shortlist=CHTICK-LABELPOS-BIFF5,0,none,below,above,near
+
+flagslist=CHTICK-FLAGS-BIFF2
+ 0x0001=auto-color
+ 0x0002=auto-fill
+end
+
+combilist=CHTICK-FLAGS-BIFF3
+ include=CHTICK-FLAGS-BIFF2
+ 0x001C=uint8,dec,orientation,TEXTORIENTATION
+ 0x0020=auto-rotation
+end
+
+# CHVALUERANGE ---------------------------------------------------------------
+
+flagslist=CHVALUERANGE-FLAGS
+ ignore=0x0100
+ 0x0001=auto-minimum
+ 0x0002=auto-maximum
+ 0x0004=auto-major
+ 0x0008=auto-minor
+ 0x0010=auto-axis-cross
+ 0x0020=logarithmic
+ 0x0040=reverse-order
+ 0x0080=maximum-axis-cross
+end
+
+# COLINFO --------------------------------------------------------------------
+
+combilist=COLINFO-FLAGS
+ 0x0001=hidden
+ 0x0002=custom-width
+ 0x0004=best-fit
+ 0x0008=show-phonetic
+ 0x0700=uint8,dec,outline-level
+ 0x1000=outline-collapsed
+end
+
+# CONNECTION -----------------------------------------------------------------
+
+shortlist=CONNECTION-SOURCETYPE,1,odbc,dao,file,html,ole-db,text,ado,dsp
+
+flagslist=CONNECTION-FLAGS
+ 0x0001=save-password
+ 0x0002=html-tables
+ 0x0004=table-names
+ 0x0008=deleted
+ 0x0010=stand-alone
+ 0x0020=only-use-conn-file
+ 0x0040=background
+ 0x0080=refresh-on-load
+ 0x0100=save-data
+end
+
+shortlist=CONNECTION-RECONNECTTYPE,0,as-required,always,never
+shortlist=CONNECTION-CREDENTIALS,0,integrated,none,stored-sso,prompt
+shortlist=CONNECTION-LINKEDOBJECTTYPE,0,none,query-table,pivot-cache
+
+# DATATABLE ------------------------------------------------------------------
+
+flagslist=DATATABLE-FLAGS-BIFF3
+ 0x0001=recalc-always
+ 0x0002=recalc-on-load
+ 0x0004=row-table
+ 0x0008=table-2d
+end
+
+flagslist=DATATABLE-FLAGS-BIFF8
+ include=DATATABLE-FLAGS-BIFF3
+ 0x0010=ref1-deleted
+ 0x0020=ref2-deleted
+end
+
+# DATAVALIDATION -------------------------------------------------------------
+
+combilist=DATAVALIDATION-FLAGS
+ 0x0000000F=uint8,dec,type,DATAVALIDATION-TYPE
+ 0x00000070=uint8,dec,error-style,DATAVALIDATION-ERRORSTYLE
+ 0x00000080=string-list
+ 0x00000100=ignore-empty
+ 0x00000200=no-dropdown
+ 0x00040000=show-input-box
+ 0x00080000=show-error-box
+ 0x00F00000=uint8,dec,operator,DATAVALIDATION-OPERATOR
+end
+
+shortlist=DATAVALIDATION-TYPE,0,any,whole,decimal,list,date,time,text-length,custom
+shortlist=DATAVALIDATION-OPERATOR,0,between,not-between,equal,not-equal,greater-than,less-than,greater-equal,less-equal
+shortlist=DATAVALIDATION-ERRORSTYLE,0,error,warning,info
+
+# DATAVALIDATIONS ------------------------------------------------------------
+
+flagslist=DATAVALIDATIONS-FLAGS
+ 0x0001=input-box-visible
+ 0x0002=input-box-at-cell
+ 0x0004=cached
+end
+
+# DATEMODE -------------------------------------------------------------------
+
+shortlist=DATEMODE,0,1899-12-31,1904-01-01
+
+# DBQUERY --------------------------------------------------------------------
+
+combilist=DBQUERY-FLAGS
+ 0x0007=uint8,dec,source-type,CONNECTION-SOURCETYPE
+ 0x0008=odbc-connection
+ 0x0010=sql-query
+ 0x0020=server-sql
+ 0x0040=html-query
+ 0x0080=save-password
+ 0x0100=html-tables
+end
+
+# DEFINEDNAME ----------------------------------------------------------------
+
+flagslist=DEFINEDNAME-FLAGS-BIFF2
+ 0x02=macro
+ 0x04=complex
+end
+
+shortlist=DEFINEDNAME-MACROTYPE-BIFF2,0,none,function,procedure
+
+flagslist=DEFINEDNAME-FLAGS-BIFF3
+ 0x0001=hidden
+ 0x0002=function
+ 0x0004=command
+ 0x0008=macro
+ 0x0010=complex
+ 0x0020=builtin
+end
+
+shortlist=DEFINEDNAME-BUILTINID,0,consolidate-area,auto-open,auto-close,extract,database,criteria,print-area,print-titles,recorder,data-form,auto-activate,auto-deactivate,sheet-title,filterdatabase
+
+combilist=DEFINEDNAME-FLAGS-BIFF4
+ include=DEFINEDNAME-FLAGS-BIFF3
+ 0x0FC0=uint16,dec,func-group,DEFINEDNAME-FUNCGROUP
+end
+
+combilist=DEFINEDNAME-FLAGS-BIFF5
+ include=DEFINEDNAME-FLAGS-BIFF4
+ 0x0004=vba
+ 0x1000=binary
+end
+
+shortlist=DEFINEDNAME-FUNCGROUP,0,none,financial,date-time,math-trig,statistical,lookup-ref,database,text,logical,information,commands,customizing,macro-control,dde-external,user-definded
+
+constlist=DEFINEDNAME-SHEETIDX
+ default=
+ 0=global
+end
+
+# DEFROWHEIGHT ---------------------------------------------------------------
+
+combilist=DEFROWHEIGHT-FLAGS-BIFF2
+ 0x7FFF=uint16,dec,row-height,CONV-TWIP-TO-PT
+ 0x8000=unchanged
+end
+
+flagslist=DEFROWHEIGHT-FLAGS-BIFF3
+ 0x0001=custom-height
+ 0x0002=hidden
+ 0x0004=thick-top
+ 0x0008=thick-bottom
+end
+
+# DXF ------------------------------------------------------------------------
+
+flagslist=DXF-FLAGS
+ 0x0001=!swap-fg-bg-color
+ 0x0002=use-internal-borders
+end
+
+multilist=DXF-SUBREC
+ 0=FILL-PATTERN,FILL-FGCOLOR,FILL-BGCOLOR,FILL-GRADIENT,FILL-STOP
+ 5=FONT-COLOR,BORDER-TOP,BORDER-BOTTOM,BORDER-LEFT,BORDER-RIGHT
+ 10=BORDER-DIAGONAL,BORDER-VERTICAL,BORDER-HORIZONTAL,BORDER-DIAGUP,BORDER-DIAGDOWN
+ 15=ALIGN-HORIZONTAL,ALIGN-VERTICAL,ALIGN-ROTATION,ALIGN-INDENT,ALIGN-READINGORDER
+ 20=ALIGN-WRAPTEXT,ALIGN-JUSTLASTLINE,ALIGN-SHRINKTOFIT,ALIGN-MERGED,FONT-NAME
+ 25=FONT-WEIGHT,FONT-UNDERLINE,FONT-ESCAPEMENT,FONT-ITALIC,FONT-STRIKE
+ 30=FONT-OUTLINE,FONT-SHADOW,FONT-CONDENSE,FONT-EXTEND,FONT-CHARSET
+ 35=FONT-PITCHFAMILY,FONT-HEIGHT,FONT-SCHEME,NUMFMT-CODE,
+ 40=,NUMFMT-ID,ALIGN-RELINDENT,PROT-LOCKED,PROT-HIDDEN
+end
+
+# EXTERNALBOOK ---------------------------------------------------------------
+
+constlist=EXTERNALBOOK-KEY
+ 0x0401=self-reference
+ 0x3A01=analysis-addin
+end
+
+# EXTERNALNAME ---------------------------------------------------------------
+
+flagslist=EXTERNALNAME-FLAGS-BIFF3
+ 0x0001=builtin
+ 0x0002=automatic
+ 0x0004=pic-link
+ 0x0008=dde-stddocumentname
+end
+
+combilist=EXTERNALNAME-FLAGS-BIFF5
+ include=EXTERNALNAME-FLAGS-BIFF3
+ 0x0010=ole-link
+ 0x7FE0=uint16,dec,clipboard-format
+ 0x8000=iconified
+end
+
+# EXTERNSHEET ----------------------------------------------------------------
+
+constlist=EXTERNSHEET-IDX-BIFF8
+ default=
+ -1=deleted
+ -2=special
+end
+
+# FILEPASS -------------------------------------------------------------------
+
+shortlist=FILEPASS-TYPE,0,xor,rc4
+shortlist=FILEPASS-MAJOR,1,rc4,crypto-api-2003,crypto-api-2007
+
+# FILTERCOLUMN ---------------------------------------------------------------
+
+combilist=FILTERCOLUMN-FLAGS
+ 0x0001=!and!or
+ 0x0004=op-1-simple
+ 0x0008=op-2-simple
+ 0x0010=top-10
+ 0x0020=!bottom!top
+ 0x0040=percent
+ 0xFF80=uint16,dec,top-10-count
+end
+
+constlist=FILTERCOLUMN-DATATYPE
+ 0=none
+ 2=rk
+ 4=double
+ 6=string
+ 8=boolean
+ 12=blank
+ 14=not-blank
+end
+
+shortlist=FILTERCOLUMN-OPERATOR,0,none,less,equal,less-equal,greater,not-equal,greater-equal
+
+# FONT -----------------------------------------------------------------------
+
+flagslist=FONT-FLAGS
+ 0x0001=bold
+ 0x0002=italic
+ 0x0004=underline
+ 0x0008=strikeout
+ 0x0010=outline
+ 0x0020=shadow
+ 0x0040=condense
+ 0x0080=extend
+end
+
+multilist=FONT-UNDERLINE
+ 0x00=none,single,double
+ 0x21=single-acc,double-acc
+end
+
+shortlist=FONT-ESCAPEMENT,0,none,superscript,subscript
+
+# FORMULA --------------------------------------------------------------------
+
+flagslist=FORMULA-FLAGS-BIFF2
+ 0x0001=recalc-always
+end
+
+flagslist=FORMULA-FLAGS-BIFF3
+ include=FORMULA-FLAGS-BIFF2
+ 0x0002=recalc-onload
+end
+
+flagslist=FORMULA-FLAGS-BIFF5
+ include=FORMULA-FLAGS-BIFF3
+ 0x0008=shared-fmla
+end
+
+shortlist=FORMULA-RESULTTYPE,0,string,boolean,error,empty
+
+# GUTS -----------------------------------------------------------------------
+
+shortlist=GUTS-LEVELS,0,none,,1-level,2-levels,3-levels,4-levels,5-levels,6-levels,7-levels
+
+# HEADERFOOTER ---------------------------------------------------------------
+
+flagslist=HEADERFOOTER-FLAGS
+ ignore=0xFFF0
+ 0x0001=has-even-hf
+ 0x0002=has-first-hf
+ 0x0004=scale-with-sheet
+ 0x0008=align-with-margins
+end
+
+# HIDEOBJ --------------------------------------------------------------------
+
+shortlist=HIDEOBJ,0,show,placeholder,hide
+
+# IMGDATA --------------------------------------------------------------------
+
+constlist=IMGDATA-FORMAT
+ -1=none
+ 2=wmf-pict
+ 9=dib
+ 14=native
+end
+
+shortlist=IMGDATA-ENV,1,windows,apple
+
+# NOTE -----------------------------------------------------------------------
+
+flagslist=NOTE-FLAGS-BIFF8
+ 0x0002=visible
+ 0x0080=row-hidden
+ 0x0100=col-hidden
+end
+
+# NOTESOUND ------------------------------------------------------------------
+
+constlist=NOTESOUND-FORMAT
+ 1=pcm
+ 3=ieee-float
+ 6=a-law
+ 7=mu-law
+ 0xFFFE=extensible
+end
+
+# OBJ ------------------------------------------------------------------------
+
+# object types ---
+
+multilist=OBJ-TYPE-BIFF3
+ 0=group,line,rectangle,oval,arc,chart,textbox,button,picture
+end
+
+multilist=OBJ-TYPE-BIFF4
+ include=OBJ-TYPE-BIFF3
+ 9=polygon
+end
+
+multilist=OBJ-TYPE-BIFF5
+ include=OBJ-TYPE-BIFF4
+ 10=,checkbox,optionbutton,edit,label,dialog,spin,scrollbar,listbox,groupbox
+ 20=dropdown
+end
+
+multilist=OBJ-TYPE-BIFF8
+ include=OBJ-TYPE-BIFF5
+ 25=note
+ 30=drawing
+end
+
+# flags and constants ---
+
+flagslist=OBJ-FLAGS-BIFF3
+ 0x0001=selected
+ 0x0002=auto-size
+ 0x0004=auto-move
+ 0x0010=protected
+ 0x0080=grouped
+ 0x0100=hidden
+ 0x0200=visible
+end
+
+flagslist=OBJ-FLAGS-BIFF4
+ include=OBJ-FLAGS-BIFF3
+ 0x0400=printable
+end
+
+flagslist=OBJ-AUTO-FLAGS
+ 0x01=auto
+end
+
+multilist=OBJ-LINETYPE
+ 0=solid,dash,dot,dash-dot,dash-dot-dot,25%-pattern,50%-pattern,75%-pattern
+ 255=none
+end
+
+shortlist=OBJ-LINEWEIGHT,0,hair,thin,medium,thick
+
+shortlist=OBJ-ARROWHEAD-TYPE,0,none,open,filled,double-end-open,double-end-filled
+shortlist=OBJ-ARROWHEAD-WIDTH,0,narrow,medium,wide
+shortlist=OBJ-ARROWHEAD-LENGTH,0,short,medium,long
+
+combilist=OBJ-LINEENDS
+ 0x000F=uint8,dec,arrowhead-type,OBJ-ARROWHEAD-TYPE
+ 0x00F0=uint8,dec,arrowhead-width,OBJ-ARROWHEAD-WIDTH
+ 0x0F00=uint8,dec,arrowhead-length,OBJ-ARROWHEAD-LENGTH
+end
+
+shortlist=OBJ-LINEDIR,0,topleft-to-bottomright,topright-to-bottomleft,bottomright-to-topleft,bottomleft-to-topright
+
+shortlist=OBJ-ARC-QUADRANT,0,upper-right,upper-left,lower-left,lower-right
+
+combilist=OBJ-FRAMESTYLE-FLAGS
+ 0x0001=rounded
+ 0x0002=shadow
+ 0x03FC=uint16,dec,rounded-diameter
+end
+
+shortlist=OBJ-HORALIGN,0,none,left,center,right,justify
+shortlist=OBJ-VERALIGN,0,none,top,center,bottom,justify
+
+combilist=OBJ-TEXT-FLAGS
+ 0x000E=uint16,dec,hor-align,OBJ-HORALIGN
+ 0x0070=uint16,dec,ver-align,OBJ-VERALIGN
+ 0x0080=auto-size
+ 0x0200=text-locked
+ 0x0400=selected
+end
+
+flagslist=OBJ-PICTURE-FLAGS
+ 0x0001=auto-size
+ 0x0002=linked
+ 0x0008=symbol
+end
+
+flagslist=OBJ-POLYGON-FLAGS
+ 0x0100=closed
+end
+
+flagslist=OBJ-CHART-FLAGS-BIFF5
+ 0x0001=linked-to-sheet
+end
+
+flagslist=OBJ-BUTTON-FLAGS-BIFF5
+ 0x0001=default-btn
+ 0x0002=help-btn
+ 0x0004=cancel-btn
+ 0x0008=close-btn
+end
+
+shortlist=OBJ-CHECKBOX-STATE-BIFF5,0,unchecked,checked,tristate
+
+flagslist=OBJ-CHECKBOX-FLAGS-BIFF5
+ 0x0001=flat
+ 0x0002=box-only
+end
+
+shortlist=OBJ-EDIT-TYPE-BIFF5,0,text,integer,double,reference,formula
+
+flagslist=OBJ-SCROLLBAR-FLAGS-BIFF5
+ 0x0001=visible
+ 0x0002=slider-only
+ 0x0004=tracking
+ 0x0008=flat
+end
+
+combilist=OBJ-LISTBOX-FLAGS-BIFF5
+ 0x0004=linked-edit
+ 0x0008=flat
+ 0x0030=uint8,dec,selection-type,OBJ-LISTBOX-SELTYPE-BIFF5
+end
+
+shortlist=OBJ-LISTBOX-SELTYPE-BIFF5,0,single,multi,range
+
+flagslist=OBJ-GROUPBOX-FLAGS-BIFF5
+ 0x0001=flat
+end
+
+combilist=OBJ-DROPDOWN-FLAGS-BIFF5
+ 0x0003=uint8,dec,type,OBJ-DROPDOWN-TYPE-BIFF5
+ 0x0008=filtered
+end
+
+shortlist=OBJ-DROPDOWN-TYPE-BIFF5,0,listbox,combobox,simple,max
+
+multilist=OBJ-RECNAMES-BIFF8
+ 0x0000=OBJEND,,,,OBJMACRO,,OBJGMO,OBJCF
+ 0x0008=OBJFLAGS,OBJPICTFMLA,OBJCBLS,OBJRBO,OBJSBS,OBJNTS,OBJSBSFMLA,OBJGBODATA
+ 0x0010=OBJEDODATA,OBJRBODATA,OBJCBLSDATA,OBJLBSDATA,OBJCBLSFMLA,OBJCMO,,
+end
+
+flagslist=OBJFLAGS-FLAGS
+ 0x0001=manual-size
+ 0x0002=linked
+ 0x0004=update-on-print
+ 0x0008=symbol
+ 0x0010=control
+ 0x0020=ctls-stream
+ 0x0080=camera-pic
+ 0x0100=default-size
+ 0x0200=auto-load
+end
+
+flagslist=OBJCMO-FLAGS
+ 0x0001=locked
+ 0x0004=default-size
+ 0x0008=published
+ 0x0010=printable
+ 0x0080=disabled
+ 0x0100=auxiliary
+ 0x0200=recalc-on-load
+ 0x1000=recalc-always
+ 0x2000=auto-line
+ 0x4000=auto-area
+end
+
+# PAGELAYOUTVIEW -------------------------------------------------------------
+
+flagslist=PAGELAYOUTVIEW-FLAGS
+ ignore=0xFFF8
+ 0x0001=page-layout-view
+ 0x0002=show-ruler
+ 0x0004=hide-margins
+end
+
+# PAGESETUP ------------------------------------------------------------------
+
+multilist=PAGESETUP-PAPERSIZE
+ 0=undefined,letter,letter-small,tabloid,ledger,legal,statement,executive,a3,a4
+ 10=a4-small,a5,b4,b5,folio,quarto,10x14,11x17,note,envelope-9
+ 20=envelope-10,envelope-11,envelope-12,envelope-14,c,d,e,envelope-dl,envelope-c5,envelope-c3
+ 30=envelope-c4,envelope-c6,envelope-c65,envelope-b4,envelope-b5,envelope-b6,envelope-italy,envelope-monarch,envelope-6-3/4,us-standard-fanfold
+ 40=german-standard-fanfold,german-legal-fanfold,b4,japanese-dbl-postcaed,9x11,10x11,15x11,,
+ 50=envelope-invite,letter-extra,legal-extra,tabloid-extra,a4-extra,letter-transverse,a4-transverse,letter-extra-transverse,super-a-a4,super-b-a3,letter-plus
+ 60=a4-plus,a5-transverse,jis-b5-transverse,a3-extra,a5-extra,b5-extra,a2,a3-transverse,a3-extra-transverse
+end
+
+constlist=PAGESETUP-SCALETOPAGES
+ default=
+ 0=automatic
+end
+
+flagslist=PAGESETUP-FLAGS-BIFF4
+ 0x0001=print-in-rows
+ 0x0002=portrait
+ 0x0004=uninitialized
+ 0x0008=black-and-white
+end
+
+flagslist=PAGESETUP-FLAGS-BIFF5
+ include=PAGESETUP-FLAGS-BIFF4
+ 0x0010=draft-quality
+ 0x0020=print-notes
+ 0x0040=default-orientation
+ 0x0080=use-first-page
+end
+
+combilist=PAGESETUP-FLAGS-BIFF8
+ include=PAGESETUP-FLAGS-BIFF5
+ 0x0200=print-notes-at-end
+ 0x0C00=uint8,dec,print-errors,PAGESETUP-PRINTERRORS
+end
+
+shortlist=PAGESETUP-PRINTERRORS,0,displayed,none,as-dashes,as-na
+
+unitconverter=PAGESETUP-DPI,1,dpi
+
+# PANE -----------------------------------------------------------------------
+
+shortlist=PANE-ID,0,bottom-right,top-right,bottom-left,top-left
+
+# PCDEFINITION ---------------------------------------------------------------
+
+flagslist=PCDEFINITION-FLAGS
+ 0x0001=save-data
+ 0x0002=invalid
+ 0x0004=refresh-on-load
+ 0x0008=optimize-memory
+ 0x0010=background-query
+ 0x0020=enable-refresh
+end
+
+# PCDFIELD -------------------------------------------------------------------
+
+flagslist=PCDFIELD-FLAGS
+ 0x0001=has-items
+ 0x0002=has-unshared-items
+ 0x0004=calculated
+ 0x0008=has-parent
+ 0x0010=range-group
+ 0x0020=is-numeric
+ 0x0040=is-integer
+ 0x0080=has-semi-mixed-types
+ 0x0100=has-min-max
+ 0x0200=16bit-indexes
+ 0x0400=has-non-date
+ 0x0800=has-date
+end
+
+# PCDFRANGEPR ----------------------------------------------------------------
+
+combilist=PCDFRANGEPR-FLAGS
+ ignore=0xFFE0
+ 0x0001=auto-start
+ 0x0002=auto-end
+ 0x001C=uint8,dec,group-by,PCDFRANGEPR-GROUPBY
+end
+
+shortlist=PCDFRANGEPR-GROUPBY,0,numeric,seconds,minutes,hours,days,months,quarters,years
+
+# PCDFSQLTYPE ----------------------------------------------------------------
+
+shortlist=PCDFSQLTYPE-DATATYPE,0,unknown,char,numeric,decimal,int32,int16,float,real,double,,,datetime,var-char
+
+# PCDSOURCE ------------------------------------------------------------------
+
+flagslist=PCDSOURCE-TYPE
+ 0x0001=spreadsheet
+ 0x0002=extern
+ 0x0004=consolidation-area
+ 0x0010=scenario
+end
+
+# PHONETICPR -----------------------------------------------------------------
+
+shortlist=PHONETICPR-TYPE,0,halfwidth-katakana,fullwidth-katakana,hiragana,no-conversion
+shortlist=PHONETICPR-ALIGNMENT,0,no-control,left,center,distributed
+
+combilist=PHONETICPR-FLAGS
+ ignore=0xFFF0
+ 0x0003=uint8,dec,type,PHONETICPR-TYPE
+ 0x000C=uint8,dec,alignment,PHONETICPR-ALIGNMENT
+end
+
+# PROJEXTSHEET ---------------------------------------------------------------
+
+shortlist=PROJEXTSHEET-TYPE,0,sheet,macro,chart
+
+# PTDATAFIELD ----------------------------------------------------------------
+
+shortlist=PTDATAFIELD-SUBTOTAL,0,sum,count-all,average,max,min,product,count-num,std-dev,std-dev-p,variance,variance-p
+shortlist=PTDATAFIELD-SHOWDATAAS,0,normal,diff-from,percent-of,percent-diff-from,running-total-in,percent-of-row,percent-of-column,percent-of-total,index
+
+multilist=PTDATAFIELD-BASEITEM
+ default=
+ 0x7FFB=previous-item,next-item
+end
+
+# PTDEFINITION ---------------------------------------------------------------
+
+flagslist=PTDEFINITION-FLAGS
+ 0x0001=row-grandtotals
+ 0x0002=column-grandtotals
+ 0x0008=auto-format
+ 0x0010=size-auto-format
+ 0x0020=font-auto-format
+ 0x0040=align-auto-format
+ 0x0080=border-auto-format
+ 0x0100=pattern-auto-format
+ 0x0200=number-auto-format
+end
+
+constlist=PTDEFINITION-DATAFIELD-POS
+ default=
+ -1=append
+end
+
+# PTDEFINITION2 --------------------------------------------------------------
+
+combilist=PTDEFINITION2-FLAGS
+ 0x00000001=page-over-then-down
+ 0x000001FE=dec,uint8,page-wrap
+ 0x00010000=enable-wizard
+ 0x00020000=enable-drill
+ 0x00040000=enable-field-props
+ 0x00080000=preserve-formatting
+ 0x00100000=merge-labels
+ 0x00200000=show-error
+ 0x00400000=show-missing
+ 0x00800000=multiple-page-items
+end
+
+# PTFIELD --------------------------------------------------------------------
+
+flagslist=PTFIELD-AXISTYPE
+ 0x0001=row
+ 0x0002=column
+ 0x0004=page
+ 0x0008=data
+end
+
+flagslist=PTFIELD-SUBTOTALS
+ 0x0001=default
+ 0x0002=sum
+ 0x0004=count-all
+ 0x0008=average
+ 0x0010=max
+ 0x0020=min
+ 0x0040=product
+ 0x0080=count-num
+ 0x0100=std-dev
+ 0x0200=std-dev-p
+ 0x0400=variance
+ 0x0800=variance-p
+end
+
+# PTFIELD2 -------------------------------------------------------------------
+
+combilist=PTFIELD2-FLAGS
+ 0x00000001=show-all-items
+ 0x00000002=drag-to-row
+ 0x00000004=drag-to-column
+ 0x00000008=drag-to-page
+ 0x00000010=drag-to-hide
+ 0x00000080=server-based
+ 0x00000200=autosort
+ 0x00000400=ascend-sort
+ 0x00000800=autoshow
+ 0x00001000=autoshow-top
+ 0x00002000=calculated
+ 0x00200000=outline
+ 0x00400000=insert-blank-row
+ 0x00800000=subtotal-top
+ 0xFF000000=uint8,dec,autoshow-item-count
+end
+
+# PTFITEM --------------------------------------------------------------------
+
+multilist=PTFITEM-ITEMTYPE
+ 0=data,default,sum,count-all,average,max,min,product,count-num,std-dev,std-dev-p,variance,variance-p,grandtotal
+ 254=page,none
+end
+
+flagslist=PTFITEM-FLAGS
+ 0x0001=hidden
+ 0x0002=hide-detail
+ 0x0008=calculated
+ 0x0010=missing
+end
+
+constlist=PTFITEM-CACHEIDX
+ default=
+ -1=no-cache-item
+end
+
+# PTPAGEFIELDS ---------------------------------------------------------------
+
+constlist=PTPAGEFIELDS-ITEM
+ default=
+ 0x7FFD=all
+end
+
+# PTROWCOLITEMS --------------------------------------------------------------
+
+shortlist=PTROWCOLITEMS-ITEMTYPE,0,data,default,sum,count-all,average,max,min,product,count-num,std-dev,std-dev-p,variance,variance-p,grandtotal,blank-line
+
+combilist=PTROWCOLITEMS-FLAGS
+ ignore=0xC000
+ 0x0001=field-name
+ 0x01FE=uint16,dec,data-field-idx
+ 0x0200=subtotal
+ 0x0400=blocktotal
+ 0x0800=grandtotal
+ 0x1000=multi-data
+end
+
+# QUERYTABLE -----------------------------------------------------------------
+
+combilist=QUERYTABLE-FLAGS
+ 0x0001=headers
+ 0x0002=row-numbers
+ 0x0004=disable-refresh
+ 0x0008=background
+ 0x0010=first-background
+ 0x0020=refresh-on-load
+ 0x0040=delete-unused
+ 0x0080=fill-formulas
+ 0x0100=adjust-column-width
+ 0x0200=save-data
+ 0x0400=disable-edit
+ 0x2000=overwrite-existing
+end
+
+combilist=QUERYTABLE-AUTOFORMAT-FLAGS
+ 0x0001=apply-num-fmt
+ 0x0002=apply-font
+ 0x0004=apply-alignment
+ 0x0008=apply-border
+ 0x0010=apply-fill
+ 0x0020=apply-protection
+end
+
+# QUERYTABLEREFRESH ----------------------------------------------------------
+
+flagslist=QUERYTABLEREFRESH-FLAGS
+ 0x0001=enable-refresh
+ 0x0002=pivot-cache-invalid
+ 0x0004=olap-pivot-table
+end
+
+flagslist=QUERYTABLEREFRESH-PTFLAGS
+ 0x00000001=disable-draw-drop
+ 0x00000002=hide-totals-annotation
+ 0x00000008=include-empty-rows
+ 0x00000010=include-empty-columns
+end
+
+flagslist=QUERYTABLEREFRESH-QTFLAGS
+ 0x00000001=preserve-formatting
+ 0x00000002=adjust-column-width
+ 0x00000010=ext-data-list
+ 0x00000040=create-table-list
+ 0x00000080=create-dummy-list
+end
+
+# QUERYTABLESETTINGS ---------------------------------------------------------
+
+flagslist=QUERYTABLESETTINGS-FLAGS
+ 0x0001=keep-alive
+ 0x0002=new
+ 0x0004=source-data
+ 0x0008=web-based-prov
+ 0x0010=reinit-list
+ 0x0080=xml
+end
+
+flagslist=QUERYTABLESETTINGS-HTML-FLAGS
+ 0x0001=parse-pre
+ 0x0002=consecutive-delimiters
+ 0x0004=first-row
+ 0x0008=xl97-created
+ 0x0010=text-dates
+ 0x0020=xl2000-refreshed
+end
+
+combilist=QUERYTABLESETTINGS-OLEDB-FLAGS
+ 0x0007=uint8,dec,command-type,QUERYTABLESETTINGS-OLEDB-COMMANDTYPE
+ 0x0008=alt-connection-string
+ 0x0010=no-refresh-cube
+ 0x0020=olap-has-locale
+ 0x0040=server-num-fmt
+ 0x0080=server-fill-color
+ 0x0100=server-font-color
+ 0x0200=server-font-format
+ 0x0400=olap-member-l10n
+end
+
+shortlist=QUERYTABLESETTINGS-OLEDB-COMMANDTYPE,0,none,cube,sql,table,default,list
+
+flagslist=QUERYTABLESETTINGS-ADO-FLAGS
+ 0x0100=ado-refreshable
+end
+
+flagslist=QUERYTABLESETTINGS-EXT-FLAGS
+ 0x0001=text-query
+ 0x0002=table-names
+end
+
+unitconverter=QUERYTABLESETTINGS-INTERVAL,60,sec
+shortlist=QUERYTABLESETTINGS-HTMLFORMAT,1,none,rtf,all
+
+# REFMODE --------------------------------------------------------------------
+
+shortlist=REFMODE,0,R1C1,A1
+
+# ROW ------------------------------------------------------------------------
+
+combilist=ROW-HEIGHT
+ 0x7FFF=uint16,dec,height,CONV-TWIP-TO-PT
+ 0x8000=default-height
+end
+
+combilist=ROW-FLAGS
+ ignore=0x00000100
+ 0x00000007=uint8,dec,outline-level
+ 0x00000010=outline-collapsed
+ 0x00000020=hidden
+ 0x00000040=custom-height
+ 0x00000080=custom-format
+ 0x0FFF0000=uint16,dec,custom-xf-idx
+ 0x10000000=thick-top
+ 0x20000000=thick-bottom
+ 0x40000000=show-phonetic
+end
+
+# SHAREDFEATHEAD -------------------------------------------------------------
+
+shortlist=SHAREDFEATHEAD-TYPE,2,protection,ignored-formula-errors,smarttag,table
+
+flagslist=SHAREDFEATHEAD-PROT-FLAGS
+ 0x00000001=edit-object
+ 0x00000002=edit-scenario
+ 0x00000004=format-cell
+ 0x00000008=format-column
+ 0x00000010=format-row
+ 0x00000020=insert-column
+ 0x00000040=insert-row
+ 0x00000080=insert-hyperlink
+ 0x00000100=delete-column
+ 0x00000200=delete-row
+ 0x00000400=select-locked
+ 0x00000800=sort
+ 0x00001000=use-autofilter
+ 0x00002000=pivottable-report
+ 0x00004000=select-unlocked
+end
+
+# SHEET ----------------------------------------------------------------------
+
+shortlist=SHEET-STATE,0,visible,hidden,very-hidden
+shortlist=SHEET-TYPE,0,worksheet,macrosheet,chartsheet,,,,vb-module
+
+# SHEETEXT -------------------------------------------------------------------
+
+combilist=SHEETEXT-FLAGS1
+ 0x0000007F=uint8,dec,color-idx,SHEETEXT-COLOR
+end
+
+constlist=SHEETEXT-COLOR
+ include=COLORS
+ 0x7F=undefined
+end
+
+combilist=SHEETEXT-FLAGS2
+ include=SHEETEXT-FLAGS1
+ 0x00000080=eval-cond-formats
+ 0x00000100=!published!unpublished
+end
+
+# SHEETPR --------------------------------------------------------------------
+
+shortlist=SHEETPR-WINDOWPOS,0,tiled,horizontal,vertical,cascaded
+
+flagslist=SHEETPR-FLAGS-BIFF3
+ 0x0001=show-autopagebreaks
+ 0x0020=outline-auto-style
+ 0x0040=outline-symbols-below
+ 0x0080=outline-symbols-right
+ 0x0100=fit-to-pages
+ 0x0200=skip-linked-values
+ 0x0400=show-row-outline
+ 0x0800=show-column-outline
+end
+
+flagslist=SHEETPR-FLAGS-BIFF4
+ include=SHEETPR-FLAGS-BIFF3
+ 0x3000=uint8,dec,window-pos,SHEETPR-WINDOWPOS
+ 0x4000=lotus-expr-eval
+ 0x8000=lotus-formula-edit
+end
+
+flagslist=SHEETPR-FLAGS-BIFF5
+ include=SHEETPR-FLAGS-BIFF4
+ exclude=0x0200,0x3000
+ 0x0010=dialog-sheet
+end
+
+# STYLE ----------------------------------------------------------------------
+
+combilist=STYLE-FLAGS
+ 0x0FFF=uint16,dec,xf-idx
+ 0x8000=builtin
+end
+
+shortlist=STYLE-BUILTIN,-1,user-defined,normal,rowlevel,collevel,comma,currency,percent,comma-0,currency-0,hyperlink,followed-hyperlink
+
+# STYLEEXT -------------------------------------------------------------------
+
+flagslist=STYLEEXT-FLAGS
+ 0x01=builtin
+ 0x02=hidden
+ 0x04=custom
+end
+
+shortlist=STYLEEXT-CATEGORY,0,custom,good-bad-neutral,data-model,title-heading,themed,number-format
+
+multilist=STYLEEXT-BUILTIN
+ include=STYLE-BUILTIN
+ 10=note,warning-text,,,,title,heading-1,heading-2,heading-3,heading-4
+ 20=input,output,calculation,check-cell,linked-cell,total,good,bad,neutral,accent1
+ 30=20%-accent1,40%-accent1,60%-accent1,accent2,20%-accent2,40%-accent2,60%-accent2,accent3,20%-accent3,40%-accent3
+ 40=60%-accent3,accent4,20%-accent4,40%-accent4,60%-accent4,accent5,20%-accent5,40%-accent5,60%-accent5,accent6
+ 50=20%-accent6,40%-accent6,60%-accent6,explanatory-text
+end
+
+# THEME ----------------------------------------------------------------------
+
+constlist=THEME-VERSION
+ 0=custom
+ 123820=default
+ 124226=default
+end
+
+# TXO ------------------------------------------------------------------------
+
+combilist=TXO-FLAGS
+ 0x000E=uint16,dec,hor-align,OBJ-HORALIGN
+ 0x0070=uint16,dec,ver-align,OBJ-VERALIGN
+ 0x0200=text-locked
+end
+
+# WINDOW1 --------------------------------------------------------------------
+
+flagslist=WINDOW1-FLAGS
+ 0x0001=hidden
+ 0x0002=minimized
+ 0x0008=show-horizontal-scroll
+ 0x0010=show-vertical-scroll
+ 0x0020=show-tabbar
+end
+
+unitconverter=WINDOW1-TABBARRATIO,/10,%
+
+# WINDOW2 --------------------------------------------------------------------
+
+flagslist=WINDOW2-FLAGS-BIFF3
+ 0x0001=show-formulas
+ 0x0002=show-gridlines
+ 0x0004=show-headings
+ 0x0008=frozen-panes
+ 0x0010=show-zeros
+ 0x0020=default-gridcolor
+ 0x0040=right-to-left
+ 0x0080=show-outline-symbols
+ 0x0100=remove-split-with-freeze
+end
+
+flagslist=WINDOW2-FLAGS-BIFF5
+ include=WINDOW2-FLAGS-BIFF3
+ 0x0200=sheet-selected
+ 0x0400=sheet-active
+end
+
+flagslist=WINDOW2-FLAGS-BIFF8
+ include=WINDOW2-FLAGS-BIFF5
+ 0x0800=pagebreak-mode
+end
+
+# XF -------------------------------------------------------------------------
+
+shortlist=XF-HORALIGN,0,general,left,center,right,fill,block,center-across-sel,distribute
+shortlist=XF-VERALIGN,0,top,center,bottom,justify,distribute
+shortlist=XF-TEXTDIRECTION,0,context,left-to-right,right-to-left
+
+flagslist=XF-PROTECTION-FLAGS
+ 0x01=locked
+ 0x02=formula-hidden
+ 0x04=style-xf
+ 0x08=apostroph-quote
+end
+
+flagslist=XF-USEDATTRIBS-FLAGS
+ 0x04=format
+ 0x08=font
+ 0x10=alignment
+ 0x20=border
+ 0x40=area
+ 0x80=protection
+end
+
+combilist=XF-STYLEFLAGS-BIFF2
+ 0x07=uint8,dec,hor-align,XF-HORALIGN
+ 0x08=left-border
+ 0x10=right-border
+ 0x20=top-border
+ 0x40=bottom-border
+ 0x80=fill
+end
+
+combilist=XF-TYPEFLAGS-BIFF2
+ 0x3F=uint8,dec,fmt-idx,FORMATS
+ 0x40=locked
+ 0x80=formula-hidden
+end
+
+flagslist=XF-TYPEFLAGS-BIFF3
+ include=XF-PROTECTION-FLAGS
+end
+
+combilist=XF-TYPEFLAGS-BIFF4
+ include=XF-TYPEFLAGS-BIFF3
+ 0xFFF0=uint16,dec,parent-xf-idx
+end
+
+combilist=XF-ALIGNMENT-BIFF3
+ 0x0007=uint8,dec,hor-align,XF-HORALIGN
+ 0x0008=text-wrap
+ 0xFFF0=uint16,dec,parent-xf-idx
+end
+
+combilist=XF-ALIGNMENT-BIFF4
+ 0x07=uint8,dec,hor-align,XF-HORALIGN
+ 0x08=text-wrap
+ 0x30=uint8,dec,ver-align,XF-VERALIGN
+ 0xC0=uint8,dec,orientation,TEXTORIENTATION
+end
+
+combilist=XF-ALIGNMENT-BIFF5
+ 0x07=uint8,dec,hor-align,XF-HORALIGN
+ 0x08=text-wrap
+ 0x70=uint8,dec,ver-align,XF-VERALIGN
+ 0x80=justify-lastline
+end
+
+combilist=XF-ORIENTATTRIBS-BIFF5
+ include=XF-USEDATTRIBS-FLAGS
+ 0x03=uint8,dec,orientation,TEXTORIENTATION
+end
+
+combilist=XF-TEXTFLAGS-BIFF8
+ 0x0F=uint8,dec,indent
+ 0x10=shrink-to-fit
+ 0xC0=uint8,dec,text-dir,XF-TEXTDIRECTION
+end
+
+combilist=XF-FILL-BIFF3
+ 0x003F=uint8,dec,fill-pattern,FILLPATTERNS
+ 0x07C0=uint8,dec,fg-color-idx,COLORS
+ 0xF800=uint8,dec,bg-color-idx,COLORS
+end
+
+combilist=XF-BORDER-BIFF3
+ 0x00000007=uint8,dec,top-style,BORDERSTYLES
+ 0x000000F8=uint8,dec,top-color,COLORS
+ 0x00000700=uint8,dec,left-style,BORDERSTYLES
+ 0x0000F800=uint8,dec,left-color,COLORS
+ 0x00070000=uint8,dec,bottom-style,BORDERSTYLES
+ 0x00F80000=uint8,dec,bottom-color,COLORS
+ 0x07000000=uint8,dec,right-style,BORDERSTYLES
+ 0xF8000000=uint8,dec,right-color,COLORS
+end
+
+combilist=XF-FILL-BIFF5
+ 0x0000007F=uint8,dec,fg-color-idx,COLORS
+ 0x00003F80=uint8,dec,bg-color-idx,COLORS
+ 0x003F0000=uint8,dec,fill-pattern,FILLPATTERNS
+ 0x01C00000=uint8,dec,bottom-style,BORDERSTYLES
+ 0xFE000000=uint8,dec,bottom-color,COLORS
+end
+
+combilist=XF-BORDER-BIFF5
+ 0x00000007=uint8,dec,top-style,BORDERSTYLES
+ 0x00000038=uint8,dec,left-style,BORDERSTYLES
+ 0x000001C0=uint8,dec,right-style,BORDERSTYLES
+ 0x0000FE00=uint8,dec,top-color,COLORS
+ 0x007F0000=uint8,dec,left-color,COLORS
+ 0x3F800000=uint8,dec,right-color,COLORS
+end
+
+combilist=XF-BORDERSTYLE-BIFF8
+ 0x000F=uint8,dec,left-style,BORDERSTYLES
+ 0x00F0=uint8,dec,right-style,BORDERSTYLES
+ 0x0F00=uint8,dec,top-style,BORDERSTYLES
+ 0xF000=uint8,dec,bottom-style,BORDERSTYLES
+end
+
+combilist=XF-BORDERCOLOR1-BIFF8
+ 0x007F=uint8,dec,left-color,COLORS
+ 0x3F80=uint8,dec,right-color,COLORS
+ 0x4000=diag-tl-to-br
+ 0x8000=diag-bl-to-tr
+end
+
+combilist=XF-BORDERCOLOR2-BIFF8
+ 0x0000007F=uint8,dec,top-color,COLORS
+ 0x00003F80=uint8,dec,bottom-color,COLORS
+ 0x001FC000=uint8,dec,diag-color,COLORS
+ 0x01E00000=uint8,dec,diag-style,BORDERSTYLES
+ 0xFC000000=uint8,dec,fill-pattern,FILLPATTERNS
+end
+
+combilist=XF-FILLCOLOR-BIFF8
+ 0x007F=uint8,dec,fg-color-idx,COLORS
+ 0x3F80=uint8,dec,bg-color-idx,COLORS
+end
+
+# BIFF2 cell records ----------------------------------------------------------
+
+constlist=XFINDEX-BIFF2
+ default=
+ 63=from-ixfe
+end
+
+combilist=CELL-XFINDEX-BIFF2
+ 0x3F=uint8,dec,xf-idx,XFINDEX-BIFF2
+ 0x40=locked
+ 0x80=formula-hidden
+end
+
+combilist=CELL-XFFORMAT-BIFF2
+ 0x3F=uint8,dec,fmt-idx,FORMATS
+ 0xC0=uint8,dec,font-idx,FONTNAMES
+end
+
+combilist=CELL-XFSTYLE-BIFF2
+ include=XF-STYLEFLAGS-BIFF2
+end
+
+# XFEXT ----------------------------------------------------------------------
+
+multilist=XFEXT-SUBREC
+ 0=,,,,FILL-FGCOLOR
+ 5=FILL-BGCOLOR,FILL-GRADIENT,BORDER-TOP-COLOR,BORDER-BOTTOM-COLOR,BORDER-LEFT-COLOR
+ 10=BORDER-RIGHT-COLOR,BORDER-DIAG-COLOR,,TEXT-COLOR,FONT-SCHEME
+ 15=INDENT
+end
+
+# ============================================================================
diff --git a/oox/source/dump/dffdumper.cxx b/oox/source/dump/dffdumper.cxx
new file mode 100644
index 000000000..9c8acd828
--- /dev/null
+++ b/oox/source/dump/dffdumper.cxx
@@ -0,0 +1,227 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <oox/dump/dffdumper.hxx>
+
+#ifdef DBG_UTIL
+
+namespace oox::dump {
+
+namespace {
+
+const sal_uInt16 DFF_ID_BSE = 0xF007; /// BLIP store entry.
+const sal_uInt16 DFF_ID_BSTORECONTAINER = 0xF001; /// BLIP store container.
+const sal_uInt16 DFF_ID_CHILDANCHOR = 0xF00F; /// Child anchor (in groups).
+const sal_uInt16 DFF_ID_CLIENTANCHOR = 0xF010; /// Client anchor.
+const sal_uInt16 DFF_ID_DG = 0xF008; /// Drawing.
+const sal_uInt16 DFF_ID_DGG = 0xF006; /// Drawing group.
+const sal_uInt16 DFF_ID_OPT = 0xF00B; /// Property set.
+const sal_uInt16 DFF_ID_OPT2 = 0xF121; /// Secondary property set.
+const sal_uInt16 DFF_ID_OPT3 = 0xF122; /// Ternary property set.
+const sal_uInt16 DFF_ID_SP = 0xF00A; /// Shape.
+const sal_uInt16 DFF_ID_SPGR = 0xF009; /// Shape group.
+const sal_uInt16 DFF_ID_SPLITMENUCOLORS = 0xF11E; /// Current toolbar colors.
+
+const sal_uInt16 DFF_OPT_IDMASK = 0x3FFF;
+const sal_uInt16 DFF_OPT_COMPLEX = 0x8000;
+
+} // namespace
+
+bool DffStreamObject::implReadRecordHeader( BinaryInputStream& rBaseStrm, sal_Int64& ornRecId, sal_Int64& ornRecSize )
+{
+ mnInstVer = rBaseStrm.readuInt16();
+ ornRecId = rBaseStrm.readuInt16();
+ mnRealSize = rBaseStrm.readInt32();
+ ornRecSize = isContainer() ? 0 : mnRealSize;
+ return !rBaseStrm.isEof();
+}
+
+void DffStreamObject::implWriteExtHeader()
+{
+ const char* pcListName = "DFF-RECORD-INST";
+ switch( getRecId() )
+ {
+ case DFF_ID_BSE: pcListName = "DFFBSE-RECORD-INST"; break; // BLIP type
+ case DFF_ID_BSTORECONTAINER: pcListName = "DFFBSTORECONT-RECORD-INST"; break; // BLIP count
+ case DFF_ID_DG: pcListName = "DFFDG-RECORD-INST"; break; // drawing ID
+ case DFF_ID_OPT: pcListName = "DFFOPT-RECORD-INST"; break; // property count
+ case DFF_ID_SP: pcListName = "DFFSP-RECORD-INST"; break; // shape type
+ case DFF_ID_SPLITMENUCOLORS: pcListName = "DFFSPLITMENUC-RECORD-INST"; break; // number of colors
+ }
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeHexItem( "instance", mnInstVer, pcListName );
+ if( isContainer() ) writeDecItem( "container-size", mnRealSize );
+}
+
+void DffStreamObject::implDumpRecordBody()
+{
+ switch( getRecId() )
+ {
+ case DFF_ID_BSE:
+ dumpDec< sal_uInt8 >( "win-type", "DFFBSE-TYPE" );
+ dumpDec< sal_uInt8 >( "mac-type", "DFFBSE-TYPE" );
+ dumpGuid( "guid" );
+ dumpDec< sal_uInt16 >( "tag" );
+ dumpDec< sal_uInt32 >( "blip-size" );
+ dumpDec< sal_uInt32 >( "blip-refcount" );
+ dumpDec< sal_uInt32 >( "blip-streampos" );
+ dumpDec< sal_uInt8 >( "blip-usage", "DFFBSE-USAGE" );
+ dumpDec< sal_uInt8 >( "blip-name-len" );
+ dumpUnused( 2 );
+ break;
+
+ case DFF_ID_CHILDANCHOR:
+ dumpDec< sal_uInt32 >( "left" );
+ dumpDec< sal_uInt32 >( "top" );
+ dumpDec< sal_uInt32 >( "right" );
+ dumpDec< sal_uInt32 >( "bottom" );
+ break;
+
+ case DFF_ID_CLIENTANCHOR:
+ break;
+
+ case DFF_ID_DG:
+ dumpDec< sal_uInt32 >( "shape-count" );
+ dumpHex< sal_uInt32 >( "max-shape-id", "CONV-DEC" );
+ break;
+
+ case DFF_ID_DGG:
+ {
+ dumpHex< sal_uInt32 >( "max-shape-id", "CONV-DEC" );
+ sal_uInt32 nClusters = dumpDec< sal_uInt32 >( "id-cluster-count" );
+ dumpDec< sal_uInt32 >( "shape-count" );
+ dumpDec< sal_uInt32 >( "drawing-count" );
+ mxOut->resetItemIndex( 1 );
+ TableGuard aTabGuard( mxOut, 15, 16 );
+ for( sal_uInt32 nCluster = 1; !mxStrm->isEof() && (nCluster < nClusters); ++nCluster )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( "#cluster" );
+ dumpDec< sal_uInt32 >( "drawing-id" );
+ dumpHex< sal_uInt32 >( "next-free-id", "CONV-DEC" );
+ }
+ }
+ break;
+
+ case DFF_ID_OPT:
+ case DFF_ID_OPT2:
+ case DFF_ID_OPT3:
+ dumpDffOpt();
+ break;
+
+ case DFF_ID_SP:
+ dumpHex< sal_uInt32 >( "shape-id", "CONV-DEC" );
+ dumpHex< sal_uInt32 >( "shape-flags", "DFFSP-FLAGS" );
+ break;
+
+ case DFF_ID_SPGR:
+ dumpDec< sal_uInt32 >( "left" );
+ dumpDec< sal_uInt32 >( "top" );
+ dumpDec< sal_uInt32 >( "right" );
+ dumpDec< sal_uInt32 >( "bottom" );
+ break;
+
+ case DFF_ID_SPLITMENUCOLORS:
+ dumpDffSimpleColor( "fill-color" );
+ dumpDffSimpleColor( "line-color" );
+ dumpDffSimpleColor( "shadow-color" );
+ dumpDffSimpleColor( "3d-color" );
+ break;
+ }
+}
+
+sal_uInt32 DffStreamObject::dumpDffSimpleColor( const String& rName )
+{
+ return dumpHex< sal_uInt32 >( rName, "DFF-SIMPLE-COLOR" );
+}
+
+namespace {
+
+enum class PropType { Binary };
+
+struct PropInfo
+{
+ OUString maName;
+ PropType meType;
+ sal_uInt16 mnId;
+ sal_uInt32 mnSize;
+ explicit PropInfo( const OUString& rName, PropType eType, sal_uInt16 nId, sal_uInt32 nSize ) :
+ maName( rName ), meType( eType ), mnId( nId ), mnSize( nSize ) {}
+};
+
+typedef ::std::vector< PropInfo > PropInfoVector;
+
+} // namespace
+
+void DffStreamObject::dumpDffOpt()
+{
+ sal_uInt16 nPropCount = getInst();
+ PropInfoVector aPropInfos;
+ mxOut->resetItemIndex();
+ for( sal_uInt16 nPropIdx = 0; !mxStrm->isEof() && (nPropIdx < nPropCount); ++nPropIdx )
+ {
+ sal_uInt16 nPropId = dumpDffOptPropHeader();
+ sal_uInt16 nBaseId = nPropId & DFF_OPT_IDMASK;
+ sal_uInt32 nValue = mxStrm->readuInt32();
+
+ IndentGuard aIndent( mxOut );
+ if( getFlag( nPropId, DFF_OPT_COMPLEX ) )
+ {
+ writeHexItem( "complex-size", nValue, "CONV-DEC" );
+ aPropInfos.emplace_back( String( "property-data" ), PropType::Binary, nBaseId, nValue );
+ }
+ else
+ {
+ writeHexItem( "value", nValue );
+ }
+ }
+
+ mxOut->resetItemIndex();
+ for (auto const& propInfo : aPropInfos)
+ {
+ if (mxStrm->isEof())
+ break;
+ mxOut->startMultiItems();
+ writeEmptyItem( "#complex-data" );
+ writeHexItem( "id", propInfo.mnId, "DFFOPT-PROPERTY-NAMES" );
+ mxOut->endMultiItems();
+ IndentGuard aIndent( mxOut );
+ switch(propInfo.meType)
+ {
+ case PropType::Binary:
+ dumpBinary( propInfo.maName, propInfo.mnSize );
+ break;
+ default: assert(false && "missing implementation?");
+ }
+ }
+}
+
+sal_uInt16 DffStreamObject::dumpDffOptPropHeader()
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ TableGuard aTabGuard( mxOut, 11 );
+ writeEmptyItem( "#prop" );
+ return dumpHex< sal_uInt16 >( "id", "DFFOPT-PROPERTY-ID" );
+}
+
+} // namespace oox::dump
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/dump/dffdumper.ini b/oox/source/dump/dffdumper.ini
new file mode 100644
index 000000000..45b5aecc7
--- /dev/null
+++ b/oox/source/dump/dffdumper.ini
@@ -0,0 +1,676 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# dumper settings ============================================================
+
+# Path to additional configuration data, relative to this file.
+include-config-file=dumperbase.ini
+
+# name lists =================================================================
+
+multilist=DFF-RECORD-NAMES
+ 0xF000=DFFDGGCONTAINER,DFFBSTORECONTAINER,DFFDGCONTAINER,DFFSPGRCONTAINER,DFFSPCONTAINER,DFFSOLVERCONTAINER,DFFDGG,DFFBSE
+ 0xF008=DFFDG,DFFSPGR,DFFSP,DFFOPT,DFFTEXTBOX,DFFCLIENTTEXTBOX,DFFANCHOR,DFFCHILDANCHOR
+ 0xF010=DFFCLIENTANCHOR,DFFCLIENTDATA,DFFCONNECTORRULE,DFFALIGNRULE,DFFARCRULE,DFFCLIENTRULE,DFFCLASSID,DFFCALLOUTRULE
+ # 0xF018-0xF117 reserved for pictures
+ 0xF118=DFFREGROUPITEM,DFFSELECTION,DFFCOLORMRU,,,DFFDELETEDPSPL,DFFSPLITMENUCOLORS,DFFOLEOBJECT
+ 0xF120=DFFCOLORSCHEME,DFFOPT2,DFFOPT3
+end
+
+combilist=DFF-RECORD-INST
+ 0x000F=uint8,hex,version,DFF-RECORD-VERSION
+ 0xFFF0=uint16,dec,instance
+end
+
+constlist=DFF-RECORD-VERSION
+ default=
+ 15=container
+end
+
+combilist=DFF-SIMPLE-COLOR
+ 0x000000FF=uint8,dec,red,,filter=0x10000000~0x00000000
+ 0x0000FF00=uint8,dec,green,,filter=0x10000000~0x00000000
+ 0x00FF0000=uint8,dec,blue,,filter=0x10000000~0x00000000
+ 0x000000FF=uint8,dec,scheme-idx,,filter=0x10000000~0x10000000
+ 0x10000000=!rgb!scheme
+ ignore=0x08000000
+end
+
+combilist=DFF-COLOR
+ 0x0000FFFF=uint16,dec,palette-idx,,filter=0xFF000000~0x01000000
+ 0x000000FF=uint8,dec,red,,filter=0xF9000000~0x00000000
+ 0x0000FF00=uint8,dec,green,,filter=0xF9000000~0x00000000
+ 0x00FF0000=uint8,dec,blue,,filter=0xF9000000~0x00000000
+ 0x000000FF=uint8,dec,scheme-idx,,filter=0xFF000000~0x08000000
+ 0x0000FFFF=uint16,dec,system-idx,DFF-SYSTEMCOLOR,filter=0xFF000000~0x10000000
+ 0x00FF0000=uint16,dec,mod-by,,filter=0xFF000000~0x10000000
+ 0x01000000=palette-idx
+ 0x02000000=palette-rgb
+ 0x04000000=system-rgb
+ 0x08000000=scheme-idx
+ 0x10000000=system-idx
+end
+
+combilist=DFF-SYSTEMCOLOR
+ 0x00FF=uint8,dec,color-id,DFF-SYSTEMCOLOR-ID
+ 0x0F00=uint8,dec,mod,DFF-SYSTEMCOLOR-MOD
+ 0x2000=invert-after
+ 0x4000=half-invert-after
+ 0x8000=grey-before
+end
+
+constlist=DFF-SYSTEMCOLOR-ID
+ include=SYSTEMCOLOR
+ 0xF0=shape-fill
+ 0xF1=shape-line-or-fill
+ 0xF2=shape-line
+ 0xF3=shape-shadow
+ 0xF4=current-or-last-used
+ 0xF5=shape-fill-back
+ 0xF6=shape-line-back
+ 0xF7=shape-fill-or-line
+end
+
+shortlist=DFF-SYSTEMCOLOR-MOD,0,none,darken-by,lighten-by,add-grey-by,sub-grey-by,reverse-sub-grey-by,monochrome-by
+
+combilist=DFF-COLORMOD
+ 0x00000300=uint8,dec,type,DFF-COLORMOD-TYPE
+ 0x00FF0000=uint8,dec,level
+ ignore=0x200000FF
+end
+
+shortlist=DFF-COLORMOD-TYPE,0,none,shade,tint
+
+unitconverter=DFF-OPACITY,/655.36,%
+unitconverter=DFF-DEGREES,/65536,°
+
+# DFFBSE ---------------------------------------------------------------------
+
+combilist=DFFBSE-RECORD-INST
+ include=DFF-RECORD-INST
+ 0xFFF0=uint16,dec,blip-type,DFFBSE-TYPE
+end
+
+multilist=DFFBSE-TYPE
+ 0=error,unknown,emf,wmf,pict,jpeg,png,dib
+ 17=tiff,cmyk-jpeg
+end
+
+shortlist=DFFBSE-USAGE,0,default,texture
+
+# DFFBSTORECONTAINER ---------------------------------------------------------
+
+combilist=DFFBSTORECONT-RECORD-INST
+ include=DFF-RECORD-INST
+ 0xFFF0=uint16,dec,blip-count
+end
+
+# DFFDG ----------------------------------------------------------------------
+
+combilist=DFFDG-RECORD-INST
+ include=DFF-RECORD-INST
+ 0xFFF0=uint16,dec,drawing-id
+end
+
+# DFFOPT ---------------------------------------------------------------------
+
+combilist=DFFOPT-RECORD-INST
+ include=DFF-RECORD-INST
+ 0xFFF0=uint16,dec,property-count
+end
+
+combilist=DFFOPT-PROPERTY-ID
+ 0x3FFF=uint16,dec,id,DFFOPT-PROPERTY-NAMES
+ 0x4000=picture
+ 0x8000=complex
+end
+
+multilist=DFFOPT-PROPERTY-NAMES
+ # 0x0000-0x003F: transformation
+ 0x0000=transf-left,transf-top,transf-right,transf-bottom,transf-rotation,transf-page
+ 0x003F=transf-flags
+ # 0x0040-0x007F: protection
+ 0x007F=prot-flags
+ # 0x0080-0x00BF: text
+ 0x0080=text-id,text-left,text-top,text-right,text-bottom,text-wrap-mode,text-scale,text-anchor-mode
+ 0x0088=text-flow,text-font-orient,text-next-shape,text-bidi
+ 0x00BF=text-flags
+ # 0x00C0-0x00FF: text geometry
+ 0x00C0=textgeo-unicode-string,textgeo-rtf-string,textgeo-curve-align,textgeo-def-size,textgeo-spacing,textgeo-font,textgeo-css-font
+ 0x00FF=textgeo-flags
+ # 0x0100-0x013F: picture (BLIP)
+ 0x0100=blip-crop-top,blip-crop-bottom,blip-crop-left,blip-crop-right,blip-id,blip-name,blip-opt,blip-transparency-color
+ 0x0108=blip-contrast,blip-brightness,blip-gamma,blip-ole-id,blip-double-cr-mod,blip-fill-cr-mod,blip-line-cr-mod,blip-print-id
+ 0x0110=blip-print-name,blip-print-opt,blip-movie,,,blip-transparency-color-ext,reserved,blip-transparency-color-ext-mod
+ 0x0118=reserved,reserved,blip-recolor,blip-recolor-ext,reserved,blip-recolor-ext-mod,reserved,reserved
+ 0x013F=blip-flags
+ # 0x0140-0x017F: shape geometry
+ 0x0140=geo-left,geo-top,geo-right,geo-bottom,geo-shape-path,geo-vertices,geo-segment-info,geo-adjust-1
+ 0x0148=geo-adjust-2,geo-adjust-3,geo-adjust-4,geo-adjust-5,geo-adjust-6,geo-adjust-7,geo-adjust-8,
+ 0x0150=,geo-connect-sites,geo-connect-sites-dir,geo-stretch-x,geo-stretch-y,geo-handles,geo-guides,geo-inscribe
+ 0x0158=geo-connect-points
+ 0x017F=geo-flags
+ # 0x0180-0x01BF: fill style
+ 0x0180=fill-type,fill-color,fill-opacity,fill-back-color,fill-back-opacity,fill-cr-mod,fill-blip,fill-blip-name
+ 0x0188=fill-blip-opt,fill-width,fill-height,fill-angle,fill-focus,fill-to-left,fill-to-top,fill-to-right
+ 0x0190=fill-to-bottom,fill-rect-left,fill-rect-top,fill-rect-right,fill-rect-bottom,fill-dz-type,fill-shade-preset,fill-shade-colors
+ 0x0198=fill-origin-x,fill-origin-y,fill-shape-origin-x,fill-shape-origin-y,fill-shade-type,,fill-color-ext,reserved
+ 0x01A0=fill-color-ext-mod,reserved,fill-back-color-ext,reserved,fill-back-color-ext-mod,reserved,reserved,reserved
+ 0x01BF=fill-flags
+ # 0x01C0-0x01FF: line style
+ 0x01C0=line-color,line-opacity,line-back-color,line-cr-mod,line-type,line-fill-blip,line-fill-blip-name,line-fill-blip-opt
+ 0x01C8=line-fill-width,line-fill-height,line-fill-dz-type,line-width,line-miter-limit,line-style,line-dash,line-dash-style
+ 0x01D0=line-start-arrow-head,line-end-arrow-head,line-start-arrow-width,line-start-arrow-length,line-end-arrow-width,line-end-arrow-length,line-join-style,line-end-cap-style
+ 0x01D8=,line-color-ext,reserved,line-color-ext-mod,reserved,line-back-color-ext,reserved,line-back-color-ext-mod
+ 0x01E0=reserved,reserved,reserved
+ 0x01FF=line-flags
+ # 0x0200-0x023F: shadow style
+ 0x0200=shadow-type,shadow-color,shadow-highlight,shadow-cr-mod,shadow-opacity,shadow-offset-x,shadow-offset-y,shadow-2nd-offset-x
+ 0x0208=shadow-2nd-offset-y,,,,,,,
+ 0x0210=shadow-origin-x,shadow-origin-y,shadow-color-ext,reserved,shadow-color-ext-mod,reserved,shadow-highlight-ext,reserved
+ 0x0218=shadow-highlight-ext-mod,reserved,reserved,reserved
+ 0x023F=shadow-flags
+ # 0x0240-0x027F: perspective
+ 0x0240=persp-type,persp-offset-x,persp-offsety,persp-scale-x-to-x,persp-scale-y-to-x,persp-scale-x-to-y,persp-scale-y-to-y,persp-persp-x
+ 0x0248=persp-persp-y,persp-weight,persp-origin-x,persp-origin-y
+ 0x027F=persp-flags
+ # 0x0280-0x02BF: 3d object
+ 0x0280=3dobj-specular-amt,3dobj-diffuse-amt,3dobj-shininess,3dobj-edge-thickness,3dobj-extrude-forward,3dobj-extrude-backward,3dobj-extrude-plane,3dobj-extrusion-color
+ 0x0288=3dobj-cr-mod,3dobj-extrusion-color-ext,reserved,3dobj-extrusion-color-ext-mod,reserved,reserved
+ 0x02BF=3dobj-flags
+ # 0x02C0-0x02FF: 3d style
+ 0x02C0=3dstyle-y-rotation,3dstyle-x-rotation,3dstyle-rotation-axis-x,3dstyle-rotation-axis-y,3dstyle-rotation-axis-z,3dstyle-rotation,3dstyle-rotation-center-x,3dstyle-rotation-center-y
+ 0x02C8=3dstyle-rotation-center-z,3dstyle-render-mode,3dstyle-tolerance,3dstyle-view-point-x,3dstyle-view-point-y,3dstyle-view-point-z,3dstyle-origin-x,3dstyle-origin-y
+ 0x02D0=3dstyle-skew-angle,3dstyle-skew-amount,3dstyle-ambient-intensity,3dstyle-key-light-x,3dstyle-key-light-y,3dstyle-key-light-z,3dstyle-key-light-intensity,3dstyle-fill-light-x
+ 0x02D8=3dstyle-fill-light-y,3dstyle-fill-light-z,3dstyle-fill-light-intensity
+ 0x02FF=3dstyle-flags
+ # 0x0300-0x033F: shape
+ 0x0300=,shape-master,,shape-connect-style,shape-bw-mod,shape-bw-mode-pure-bw,shape-bw-mode-bw,shape-discuss-anchor-id
+ 0x0308=,shape-dia-layout,shape-dia-node-kind,shape-dia-layout-mru,shape-equation-xml
+ 0x033F=shape-flags
+ # 0x0340-0x037F: callout
+ 0x0340=callout-type,callout-box-distance,callout-angle,callout-drop-type,callout-drop-pos,callout-length
+ 0x037F=callout-flags
+ # 0x0380-0x03BF: group or shape
+ 0x0380=group-name,group-description,group-hyperlink,group-wrap-polygon-vertices,group-wrap-left,group-wrap-top,group-wrap-right,group-wrap-bottom
+ 0x0388=group-regroup-id,,,,,group-tooltip,group-script,group-pos-h
+ 0x0390=group-pos-rel-h,group-pos-v,group-pos-rel-v,group-rel-width-hr,group-align-hr,group-height-hr,group-width-hr,group-script-ext-attr
+ 0x0398=group-script-lang,,group-script-lang-attr,group-border-top-color,group-border-left-color,group-border-bottom-color,group-border-right-color,group-table-props
+ 0x03A0=group-table-row-props,,,,,group-web-bot,,
+ 0x03A8=,group-metro-blob,group-rel-z-order,
+ 0x03BF=group-flags
+ # 0x03C0-0x03FF: relative transformation
+ 0x03C0=reltransf-left,reltransf-top,reltransf-right,reltransf-bottom,reltransf-rotation,reltransf-page
+ 0x03FF=reltransf-flags
+ # 0x0400-0x043F: unknown HTML
+ 0x0400=,,uhtml-line-id,uhtml-fill-id,uhtml-pic-id,uhtml-path-id,uhtml-shadow-id,uhtml-persp-id
+ 0x0408=uhtml-text-path-id,uhtml-formulae-id,uhtml-handles-id,uhtml-callout-id,uhtml-lock-id,uhtml-text-id,uhtml-3d-id
+ 0x043F=uhtml-flags
+ # 0x0500-0x053F: diagram
+ 0x0500=dia-type,dia-style,,,dia-rel-table,dia-scale-x,dia-scale-y,dia-def-fontsize
+ 0x0508=dia-constrain-bounds,dia-base-text-scale
+ 0x053F=dia-flags
+ # 0x0540-0x057F: left line style
+ 0x0540=lline-color,lline-opacity,lline-back-color,lline-cr-mod,lline-type,lline-fill-blip,lline-fill-blip-name,lline-fill-blip-opt
+ 0x0548=lline-fill-width,lline-fill-height,lline-fill-dz-type,lline-width,lline-miter-limit,lline-style,lline-dash,lline-dash-style
+ 0x0550=lline-start-arrow-head,lline-end-arrow-head,lline-start-arrow-width,lline-start-arrow-length,lline-end-arrow-width,lline-end-arrow-length,lline-join-style,lline-end-cap-style
+ 0x0558=,lline-color-ext,reserved,lline-color-ext-mod,reserved,lline-back-color-ext,reserved,lline-back-color-ext-mod
+ 0x0560=reserved,reserved,reserved
+ 0x057F=lline-flags
+ # 0x0580-0x05BF: top line style
+ 0x0580=tline-color,tline-opacity,tline-back-color,tline-cr-mod,tline-type,tline-fill-blip,tline-fill-blip-name,tline-fill-blip-opt
+ 0x0588=tline-fill-width,tline-fill-height,tline-fill-dz-type,tline-width,tline-miter-limit,tline-style,tline-dash,tline-dash-style
+ 0x0590=tline-start-arrow-head,tline-end-arrow-head,tline-start-arrow-width,tline-start-arrow-length,tline-end-arrow-width,tline-end-arrow-length,tline-join-style,tline-end-cap-style
+ 0x0598=,tline-color-ext,reserved,tline-color-ext-mod,reserved,tline-back-color-ext,reserved,tline-back-color-ext-mod
+ 0x05A0=reserved,reserved,reserved
+ 0x05BF=tline-flags
+ # 0x05C0-0x05FF: right line style
+ 0x05C0=rline-color,rline-opacity,rline-back-color,rline-cr-mod,rline-type,rline-fill-blip,rline-fill-blip-name,rline-fill-blip-opt
+ 0x05C8=rline-fill-width,rline-fill-height,rline-fill-dz-type,rline-width,rline-miter-limit,rline-style,rline-dash,rline-dash-style
+ 0x05D0=rline-start-arrow-head,rline-end-arrow-head,rline-start-arrow-width,rline-start-arrow-length,rline-end-arrow-width,rline-end-arrow-length,rline-join-style,rline-end-cap-style
+ 0x05D8=,rline-color-ext,reserved,rline-color-ext-mod,reserved,rline-back-color-ext,reserved,rline-back-color-ext-mod
+ 0x05E0=reserved,reserved,reserved
+ 0x05FF=rline-flags
+ # 0x0600-0x063F: bottom line style
+ 0x0600=bline-color,bline-opacity,bline-back-color,bline-cr-mod,bline-type,bline-fill-blip,bline-fill-blip-name,bline-fill-blip-opt
+ 0x0608=bline-fill-width,bline-fill-height,bline-fill-dz-type,bline-width,bline-miter-limit,bline-style,bline-dash,bline-dash-style
+ 0x0610=bline-start-arrow-head,bline-end-arrow-head,bline-start-arrow-width,bline-start-arrow-length,bline-end-arrow-width,bline-end-arrow-length,bline-join-style,bline-end-cap-style
+ 0x0618=,bline-color-ext,reserved,bline-color-ext-mod,reserved,bline-back-color-ext,reserved,bline-back-color-ext-mod
+ 0x0620=reserved,reserved,reserved
+ 0x063F=bline-flags
+ # 0x0680-0x06BF: web component
+ 0x0680=webcomp-html,webcomp-name,webcomp-url
+ 0x06BF=webcomp-flags
+ # 0x0700-0x073F: ink data
+ 0x0700=ink-data
+ 0x073F=ink-flags
+ # 0x0780-0x07BF: signature line
+ 0x0780=,sigline-guid,sigline-provider-guid,sigline-suggested-signer,sigline-suggested-signer-info,sigline-suggested-signer-email,sigline-sign-instruction,sigline-add-xml
+ 0x0788=sigline-provider-url
+ 0x07BF=sigline-flags
+ # 0x07C0-0x07FF: group or shape #2
+ 0x07C0=group2-rel-width,group2-rel-height,group2-rel-pos-x,group2-rel-pos-y,group2-size-rel-h,group2-size-rel-v
+end
+
+constlist=DFFOPT-SIMPLE-PROPERTIES
+ # transformation
+ 0x003F=uint32,hex,flags,DFFOPT-TRANSFORM-FLAGS
+ # protection
+ 0x007F=uint32,hex,flags,DFFOPT-PROTECTION-FLAGS
+ # text
+ 0x00BF=uint32,hex,flags,DFFOPT-TEXT-FLAGS
+ # text geometry
+ 0x00FF=uint32,hex,flags,DFFOPT-TEXTGEO-FLAGS
+ # picture (BLIP)
+ 0x013F=uint32,hex,flags,DFFOPT-BLIP-FLAGS
+ # shape geometry
+ 0x017F=uint32,hex,flags,DFFOPT-GEO-FLAGS
+ # fill style
+ 0x0180=uint32,dec,type,DFFOPT-FILL-TYPE
+ 0x0181=uint32,hex,color,DFF-COLOR
+ 0x0182=int32,fix,opacity,DFF-OPACITY
+ 0x0183=uint32,hex,color,DFF-COLOR
+ 0x0184=int32,fix,opacity,DFF-OPACITY
+ 0x0185=uint32,hex,color,DFF-COLOR
+ 0x0186=uint32,dec,blip-id
+ 0x0188=uint32,dec,blip-opt,DFFOPT-BLIPOPT
+ 0x0189=int32,dec,width
+ 0x018A=int32,dec,height
+ 0x018B=int32,fix,angle,DFF-DEGREES
+ 0x018C=int32,dec,focus,CONV-PERCENT
+ 0x018D=int32,fix,size,DFF-OPACITY
+ 0x018E=int32,fix,size,DFF-OPACITY
+ 0x018F=int32,fix,size,DFF-OPACITY
+ 0x0190=int32,fix,size,DFF-OPACITY
+ 0x0191=int32,fix,size,CONV-EMU-TO-CM
+ 0x0192=int32,fix,size,CONV-EMU-TO-CM
+ 0x0193=int32,fix,size,CONV-EMU-TO-CM
+ 0x0194=int32,fix,size,CONV-EMU-TO-CM
+ 0x0195=uint32,dec,type,DFFOPT-FILL-DZTYPE
+ 0x0196=int32,dec,preset
+ 0x0198=int32,fix,pos,DFF-OPACITY
+ 0x0199=int32,fix,pos,DFF-OPACITY
+ 0x019A=int32,fix,pos,DFF-OPACITY
+ 0x019B=int32,fix,pos,DFF-OPACITY
+ 0x019C=uint32,hex,type,DFFOPT-FILL-SHADETYPE
+ 0x019E=uint32,hex,color,DFF-COLOR
+ 0x01A0=uint32,hex,color-mod,DFF-COLORMOD
+ 0x01A2=uint32,hex,color,DFF-COLOR
+ 0x01A4=uint32,hex,color-mod,DFF-COLORMOD
+ 0x01BF=uint32,hex,flags,DFFOPT-FILL-FLAGS
+ # line style
+ 0x01C0=uint32,hex,color,DFF-COLOR
+ 0x01C2=uint32,hex,color,DFF-COLOR
+ 0x01FF=uint32,hex,flags,DFFOPT-LINE-FLAGS
+ # shadow style
+ 0x0201=uint32,hex,color,DFF-COLOR
+ 0x023F=uint32,hex,flags,DFFOPT-SHADOW-FLAGS
+ # perspective
+ 0x027F=uint32,hex,flags,DFFOPT-PERSP-FLAGS
+ # 3d object
+ 0x02BF=uint32,hex,flags,DFFOPT-3DOBJ-FLAGS
+ # 3d style
+ 0x02FF=uint32,hex,flags,DFFOPT-3DSTYLE-FLAGS
+ # shape
+ 0x033F=uint32,hex,flags,DFFOPT-SHAPE-FLAGS
+ # callout
+ 0x037F=uint32,hex,flags,DFFOPT-CALLOUT-FLAGS
+ # group or shape
+ 0x03BF=uint32,hex,flags,DFFOPT-GROUP-FLAGS
+ # relative transformation
+ 0x03FF=uint32,hex,flags,DFFOPT-TRANSFORM-FLAGS
+ # unknown HTML
+ 0x043F=uint32,hex,flags,DFFOPT-UHTML-FLAGS
+ # diagram
+ 0x053F=uint32,hex,flags,DFFOPT-DIAGRAM-FLAGS
+ # left line style
+ 0x0540=uint32,hex,color,DFF-COLOR
+ 0x0542=uint32,hex,color,DFF-COLOR
+ 0x057F=uint32,hex,flags,DFFOPT-LINE-FLAGS
+ # top line style
+ 0x0580=uint32,hex,color,DFF-COLOR
+ 0x0582=uint32,hex,color,DFF-COLOR
+ 0x05BF=uint32,hex,flags,DFFOPT-LINE-FLAGS
+ # right line style
+ 0x05C0=uint32,hex,color,DFF-COLOR
+ 0x05C2=uint32,hex,color,DFF-COLOR
+ 0x05FF=uint32,hex,flags,DFFOPT-LINE-FLAGS
+ # bottom line style
+ 0x0600=uint32,hex,color,DFF-COLOR
+ 0x0602=uint32,hex,color,DFF-COLOR
+ 0x063F=uint32,hex,flags,DFFOPT-LINE-FLAGS
+ # web component
+ 0x06BF=uint32,hex,flags,DFFOPT-WEBCOMP-FLAGS
+ # ink data
+ 0x073F=uint32,hex,flags,DFFOPT-INK-FLAGS
+ # signature line
+ 0x07BF=uint32,hex,flags,DFFOPT-SIGLINE-FLAGS
+ # group or shape #2
+end
+
+constlist=DFFOPT-COMPLEX-PROPERTIES
+ 0x0186=uint32,hex,blip,blip
+ 0x0187=uint32,hex,blip-name,string
+ 0x0197=uint32,hex,shade-colors,colorarray
+ 0x0380=uint32,hex,shape-name,string
+end
+
+# common
+
+combilist=DFFOPT-BLIPOPT
+ 0x00000003=uint8,dec,type,DFFOPT-BLIPOPT-TYPE
+ 0x00000004=do-not-save
+ 0x00000008=linked
+end
+
+shortlist=DFFOPT-BLIPOPT-TYPE,0,comment,file,url
+
+# transformation
+
+flagslist=DFFOPT-TRANSFORM-FLAGS
+ 0x0001=:flip-h
+ 0x0002=:flip-v
+end
+
+# protection
+
+flagslist=DFFOPT-PROTECTION-FLAGS
+ 0x0001=:lock-against-grouping
+ 0x0002=:lock-adjust-handles
+ 0x0004=:lock-text
+ 0x0008=:lock-vertices
+ 0x0010=:lock-cropping
+ 0x0020=:lock-against-select
+ 0x0040=:lock-position
+ 0x0080=:lock-aspect-ratio
+ 0x0100=:lock-rotation
+ 0x0200=:lock-against-ungrouping
+end
+
+# text
+
+flagslist=DFFOPT-TEXT-FLAGS
+ 0x0002=:fit-shape-to-text
+ 0x0008=:auto-text-margin
+ 0x0010=:select-text
+ ignore=0x0005
+end
+
+# text geometry
+
+flagslist=DFFOPT-TEXTGEO-FLAGS
+ 0x0001=:strike-through
+ 0x0002=:small-caps
+ 0x0004=:shadow
+ 0x0008=:underline
+ 0x0010=:italic
+ 0x0020=:bold
+ 0x0040=:no-measure-along-path
+ 0x0080=:normalize
+ 0x0100=:best-fit
+ 0x0200=:shrink-to-fit
+ 0x0400=:stretch-to-fit
+ 0x0800=:tightening
+ 0x1000=:kerning
+ 0x2000=:vertical
+ 0x4000=:has-effect
+ 0x8000=:reverse-rows
+end
+
+# picture (BLIP)
+
+flagslist=DFFOPT-BLIP-FLAGS
+ 0x0001=:ole-alive
+ 0x0002=:bi-level-display
+ 0x0004=:grayscale
+ 0x0008=:no-hit-test
+ 0x0010=:loop-anim
+ 0x0020=:rewind-anim
+ 0x0040=:preserve-gray
+end
+
+# shape geometry
+
+flagslist=DFFOPT-GEO-FLAGS
+ 0x0001=:fill-support
+ 0x0002=:fill-shade-shape-support
+ 0x0004=:fontwork-support
+ 0x0008=:line-support
+ 0x0010=:3d-support
+ 0x0020=:shadow-support
+end
+
+# fill style
+
+shortlist=DFFOPT-FILL-TYPE,0,solid,pattern,texture,picture,edge-shade,linear-shade,shape-shade,point-shade,title-shade,background
+
+combilist=DFFOPT-FILL-DZTYPE
+ 0x00000003=uint8,dec,unit,DFFOPT-FILL-DZTYPE-UNIT
+ 0x0000000C=uint8,dec,aspect,DFFOPT-FILL-DZTYPE-ASPECT
+end
+
+shortlist=DFFOPT-FILL-DZTYPE-UNIT,0,unused,emu,pixel,shape-size-rel
+shortlist=DFFOPT-FILL-DZTYPE-ASPECT,0,none,fixed,prefer-largest
+
+flagslist=DFFOPT-FILL-SHADETYPE
+ ignore=0x40000000
+ 0x00000001=none
+ 0x00000002=gamma
+ 0x00000004=sigma-transfer
+ 0x00000008=flat-band
+ 0x00000010=one-color
+end
+
+flagslist=DFFOPT-FILL-FLAGS
+ 0x0001=:no-fill-hit-test
+ 0x0002=:fill-to-rect
+ 0x0004=:fill-rel-to-shape
+ 0x0008=:hit-test-fill
+ 0x0010=:has-fill
+ 0x0020=:shape-anchor
+ 0x0040=:recolor-as-pic
+end
+
+# line style
+
+flagslist=DFFOPT-LINE-FLAGS
+ 0x0001=:draw-dash-for-invisible
+ 0x0002=:fill-rel-to-shape
+ 0x0004=:hit-test-line
+ 0x0008=:has-line
+ 0x0010=:arrowhead-support
+ 0x0020=:inset-pen-support
+ 0x0040=:inset-pen
+ 0x0200=:opaque-back-line
+end
+
+# shadow style
+
+flagslist=DFFOPT-SHADOW-FLAGS
+ 0x0001=:obscured-shadow
+ 0x0002=:has-shadow
+end
+
+# perspective
+
+flagslist=DFFOPT-PERSP-FLAGS
+ 0x0001=:has-perspective
+end
+
+# 3d object
+
+flagslist=DFFOPT-3DOBJ-FLAGS
+ 0x0001=:light-face
+ 0x0002=:extrusion-color
+ 0x0004=:metallic
+ 0x0008=:has-3d
+end
+
+# 3d style
+
+flagslist=DFFOPT-3DSTYLE-FLAGS
+ 0x0001=:fill-color-harsh
+ 0x0002=:key-color-harsh
+ 0x0004=:parallel
+ 0x0008=:rotation-center-auto
+ 0x0010=:constrain-rotation
+end
+
+# shape
+
+flagslist=DFFOPT-SHAPE-FLAGS
+ 0x0001=:background
+ 0x0004=:initiator
+ 0x0008=:lock-shape-type
+ 0x0010=:prefer-rel-resize
+ 0x0020=:ole-iconified
+ 0x0040=:flip-v-override
+ 0x0080=:flip-h-override
+ 0x0100=:policy-barcode
+ 0x0200=:policy-label
+end
+
+# callout
+
+flagslist=DFFOPT-CALLOUT-FLAGS
+ 0x0001=:length-specified
+ 0x0002=:drop-auto
+ 0x0004=:minus-y
+ 0x0008=:minus-x
+ 0x0010=:has-text-border
+ 0x0020=:has-accent-bar
+ 0x0040=:is-callout
+end
+
+# group or shape
+
+flagslist=DFFOPT-GROUP-FLAGS
+ 0x0001=:print
+ 0x0002=:hidden
+ 0x0004=:1d-adjustment
+ 0x0008=:is-button
+ 0x0010=:notify-double-click
+ 0x0020=:behind-doc
+ 0x0040=:wrap-edited
+ 0x0080=:script-anchor
+ 0x0100=:really-hidden
+ 0x0200=:allow-overlap
+ 0x0400=:user-drawn
+ 0x0800=:is-hr
+ 0x1000=:no-shade-hr
+ 0x2000=:standard-hr
+ 0x4000=:is-bullet
+ 0x8000=:layout-in-cell
+end
+
+# unknown HTML
+
+flagslist=DFFOPT-UHTML-FLAGS
+ 0x0002=:fake-master
+ 0x0004=:ole-from-html
+end
+
+# diagram
+
+flagslist=DFFOPT-DIAGRAM-FLAGS
+ 0x0001=:pseudo-inline
+ 0x0002=:do-layout
+ 0x0004=:reverse
+ 0x0008=:do-format
+end
+
+# web component
+
+flagslist=DFFOPT-WEBCOMP-FLAGS
+ 0x0001=:is-web-component
+end
+
+# ink data
+
+flagslist=DFFOPT-INK-FLAGS
+ 0x0001=:render-ink
+ 0x0002=:render-shape
+ 0x0004=:hit-test-ink
+ 0x0008=:ink-annotation
+end
+
+# signature line
+
+flagslist=DFFOPT-SIGLINE-FLAGS
+ 0x0001=:is-signature-line
+ 0x0002=:show-sign-instruction
+ 0x0004=:show-sign-comment
+ 0x0008=:show-sign-date
+end
+
+# group or shape #2
+
+# DFFSP ----------------------------------------------------------------------
+
+combilist=DFFSP-RECORD-INST
+ include=DFF-RECORD-INST
+ 0xFFF0=uint16,dec,shape-type,DFFSP-TYPE
+end
+
+multilist=DFFSP-TYPE
+ 0=not-primitive,rectangle,round-rectangle,ellipse,diamond,isoceles-triangle,right-triangle,parallelogram,trapezoid,hexagon
+ 10=octagon,plus,star,arrow,thick-arrow,home-plate,cube,balloon,seal,arc
+ 20=line,plaque,can,donut,text-simple,text-octagon,text-hexagon,text-curve,text-wave,text-ring
+ 30=text-on-curve,text-on-ring,straight-connector-1,bent-connector-2,bent-connector-3,bent-connector-4,bent-connector-5,curved-connector-2,curved-connector-3,curved-connector-4
+ 40=curved-connector-5,callout-1,callout-2,callout-3,accent-callout-1,accent-callout-2,accent-callout-3,border-callout-1,border-callout-2,border-callout-3
+ 50=accent-border-callout-1,accent-border-callout-2,accent-border-callout-3,ribbon,ribbon-2,chevron,pentagon,no-smoking,seal-8,seal-16
+ 60=seal-32,wedge-rect-callout,wedge-rrect-callout,wedge-ellipse-callout,wave,folded-corner,left-arrow,down-arrow,up-arrow,left-right-arrow
+ 70=up-down-arrow,irregular-seal-1,irregular-seal-2,lightning-bolt,heart,picture-frame,quad-arrow,left-arrow-callout,right-arrow-callout,up-arrow-callout
+ 80=down-arrow-callout,left-right-arrow-callout,up-down-arrow-callout,quad-arrow-callout,bevel,left-bracket,right-bracket,left-brace,right-brace,left-up-arrow
+ 90=bent-up-arrow,bent-arrow,seal-24,striped-right-arrow,notched-right-arrow,block-arc,smiley-face,vertical-scroll,horizontal-scroll,circular-arrow
+ 100=notched-circular-arrow,uturn-arrow,curved-right-arrow,curved-left-arrow,curved-up-arrow,curved-down-arrow,cloud-callout,ellipse-ribbon,ellipse-ribbon-2,flow-chart-process
+ 110=flow-chart-decision,flow-chart-input-output,flow-chart-predefined-process,flow-chart-internal-storage,flow-chart-document,flow-chart-multidocument,flow-chart-terminator,flow-chart-preparation,flow-chart-manual-input,flow-chart-manual-operation
+ 120=flow-chart-connector,flow-chart-punched-card,flow-chart-punched-tape,flow-chart-summing-junction,flow-chart-or,flow-chart-collate,flow-chart-sort,flow-chart-extract,flow-chart-merge,flow-chart-offline-storage
+ 130=flow-chart-online-storage,flow-chart-magnetic-tape,flow-chart-magnetic-disk,flow-chart-magnetic-drum,flow-chart-display,flow-chart-delay,text-plain-text,text-stop,text-triangle,text-triangle-inverted
+ 140=text-chevron,text-chevron-inverted,text-ring-inside,text-ring-outside,text-arch-up-curve,text-arch-down-curve,text-circle-curve,text-button-curve,text-arch-up-pour,text-arch-down-pour
+ 150=text-circle-pour,text-button-pour,text-curve-up,text-curve-down,text-cascade-up,text-cascade-down,text-wave-1,text-wave-2,text-wave-3,text-wave-4
+ 160=text-inflate,text-deflate,text-inflate-bottom,text-deflate-bottom,text-inflate-top,text-deflate-top,text-deflate-inflate,text-deflate-inflate-deflate,text-fade-right,text-fade-left
+ 170=text-fade-up,text-fade-down,text-slant-up,text-slant-down,text-can-up,text-can-down,flow-chart-alternate-process,flow-chart-offpage-connector,callout-90,accent-callout-90
+ 180=border-callout-90,accent-border-callout-90,left-right-up-arrow,sun,moon,bracket-pair,brace-pair,seal-4,double-wave,action-button-blank
+ 190=action-button-home,action-button-help,action-button-information,action-button-forward-next,action-button-back-previous,action-button-end,action-button-beginning,action-button-return,action-button-document,action-button-sound
+ 200=action-button-movie,host-control,text-box
+end
+
+flagslist=DFFSP-FLAGS
+ 0x00000001=group
+ 0x00000002=child
+ 0x00000004=patriarch
+ 0x00000008=deleted
+ 0x00000010=ole
+ 0x00000020=has-master
+ 0x00000040=flip-horizontal
+ 0x00000080=flip-vertical
+ 0x00000100=connector
+ 0x00000200=has-anchor
+ 0x00000400=background
+ 0x00000800=has-shape-type
+end
+
+# DFFSPLITMENUCOLORS ---------------------------------------------------------
+
+combilist=DFFSPLITMENUC-RECORD-INST
+ include=DFF-RECORD-INST
+ 0xFFF0=uint16,dec,color-count
+end
+
+# ============================================================================
diff --git a/oox/source/dump/dumperbase.cxx b/oox/source/dump/dumperbase.cxx
new file mode 100644
index 000000000..61d603228
--- /dev/null
+++ b/oox/source/dump/dumperbase.cxx
@@ -0,0 +1,2580 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <oox/dump/dumperbase.hxx>
+
+#include <algorithm>
+#include <string_view>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/io/TextOutputStream.hpp>
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
+#include <osl/file.hxx>
+#include <rtl/math.hxx>
+#include <rtl/tencinfo.h>
+#include <oox/core/filterbase.hxx>
+#include <oox/helper/binaryoutputstream.hxx>
+#include <oox/helper/textinputstream.hxx>
+#include <tools/time.hxx>
+#include <o3tl/string_view.hxx>
+
+#ifdef DBG_UTIL
+
+namespace oox::dump {
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+
+using ::oox::core::FilterBase;
+
+namespace {
+
+const sal_Unicode OOX_DUMP_BOM = 0xFEFF;
+const sal_Int32 OOX_DUMP_MAXSTRLEN = 80;
+const sal_Int32 OOX_DUMP_INDENT = 2;
+const sal_Unicode OOX_DUMP_BINDOT = '.';
+const sal_Unicode OOX_DUMP_CFG_LISTSEP = ',';
+const sal_Unicode OOX_DUMP_CFG_QUOTE = '\'';
+const sal_Unicode OOX_DUMP_LF = '\n';
+const sal_Unicode OOX_DUMP_ITEMSEP = '=';
+const sal_Int32 OOX_DUMP_BYTESPERLINE = 16;
+const sal_Int64 OOX_DUMP_MAXARRAY = 16;
+
+} // namespace
+
+// file names -----------------------------------------------------------------
+
+OUString InputOutputHelper::convertFileNameToUrl( const OUString& rFileName )
+{
+ OUString aFileUrl;
+ if( ::osl::FileBase::getFileURLFromSystemPath( rFileName, aFileUrl ) == ::osl::FileBase::E_None )
+ return aFileUrl;
+ return OUString();
+}
+
+sal_Int32 InputOutputHelper::getFileNamePos( std::u16string_view rFileUrl )
+{
+ size_t nSepPos = rFileUrl.find( '/' );
+ return (nSepPos == std::u16string_view::npos) ? 0 : (nSepPos + 1);
+}
+
+std::u16string_view InputOutputHelper::getFileNameExtension( std::u16string_view rFileUrl )
+{
+ sal_Int32 nNamePos = getFileNamePos( rFileUrl );
+ size_t nExtPos = rFileUrl.rfind( '.' );
+ if( nExtPos != std::u16string_view::npos && static_cast<sal_Int32>(nExtPos) >= nNamePos )
+ return rFileUrl.substr( nExtPos + 1 );
+ return std::u16string_view();
+}
+
+// input streams --------------------------------------------------------------
+
+Reference< XInputStream > InputOutputHelper::openInputStream(
+ const Reference< XComponentContext >& rxContext, const OUString& rFileName )
+{
+ Reference< XInputStream > xInStrm;
+ if( rxContext.is() ) try
+ {
+ Reference<XSimpleFileAccess3> xFileAccess(SimpleFileAccess::create(rxContext));
+ xInStrm = xFileAccess->openFileRead( rFileName );
+ }
+ catch( Exception& )
+ {
+ }
+ return xInStrm;
+}
+
+// output streams -------------------------------------------------------------
+
+Reference< XOutputStream > InputOutputHelper::openOutputStream(
+ const Reference< XComponentContext >& rxContext, const OUString& rFileName )
+{
+ Reference< XOutputStream > xOutStrm;
+ if( rxContext.is() ) try
+ {
+ Reference<XSimpleFileAccess3> xFileAccess(SimpleFileAccess::create(rxContext));
+ xOutStrm = xFileAccess->openFileWrite( rFileName );
+ }
+ catch( Exception& )
+ {
+ }
+ return xOutStrm;
+}
+
+Reference< XTextOutputStream2 > InputOutputHelper::openTextOutputStream(
+ const Reference< XComponentContext >& rxContext, const Reference< XOutputStream >& rxOutStrm, rtl_TextEncoding eTextEnc )
+{
+ Reference< XTextOutputStream2 > xTextOutStrm;
+ const char* pcCharset = rtl_getMimeCharsetFromTextEncoding( eTextEnc );
+ if( rxContext.is() && rxOutStrm.is() && pcCharset ) try
+ {
+ xTextOutStrm = TextOutputStream::create(rxContext);
+ xTextOutStrm->setOutputStream( rxOutStrm );
+ xTextOutStrm->setEncoding( OUString::createFromAscii( pcCharset ) );
+ }
+ catch( Exception& )
+ {
+ }
+ return xTextOutStrm;
+}
+
+Reference< XTextOutputStream2 > InputOutputHelper::openTextOutputStream(
+ const Reference< XComponentContext >& rxContext, const OUString& rFileName, rtl_TextEncoding eTextEnc )
+{
+ return openTextOutputStream( rxContext, openOutputStream( rxContext, rFileName ), eTextEnc );
+}
+
+ItemFormat::ItemFormat() :
+ meDataType( DATATYPE_VOID ),
+ meFmtType( FORMATTYPE_NONE )
+{
+}
+
+void ItemFormat::set( DataType eDataType, FormatType eFmtType, const OUString& rItemName )
+{
+ meDataType = eDataType;
+ meFmtType = eFmtType;
+ maItemName = rItemName;
+ maListName.clear();
+}
+
+OUStringVector::const_iterator ItemFormat::parse( const OUStringVector& rFormatVec )
+{
+ set( DATATYPE_VOID, FORMATTYPE_NONE, OUString() );
+
+ OUStringVector::const_iterator aIt = rFormatVec.begin(), aEnd = rFormatVec.end();
+ OUString aDataType, aFmtType;
+ if( aIt != aEnd ) aDataType = *aIt++;
+ if( aIt != aEnd ) aFmtType = *aIt++;
+ if( aIt != aEnd ) maItemName = *aIt++;
+ if( aIt != aEnd ) maListName = *aIt++;
+
+ meDataType = StringHelper::convertToDataType( aDataType );
+ meFmtType = StringHelper::convertToFormatType( aFmtType );
+
+ if( meFmtType == FORMATTYPE_NONE )
+ {
+ if ( aFmtType == "unused" )
+ set( meDataType, FORMATTYPE_HEX, OOX_DUMP_UNUSED );
+ else if ( aFmtType == "unknown" )
+ set( meDataType, FORMATTYPE_HEX, OOX_DUMP_UNKNOWN );
+ }
+
+ return aIt;
+}
+
+OUStringVector ItemFormat::parse( const OUString& rFormatStr )
+{
+ OUStringVector aFormatVec;
+ StringHelper::convertStringToStringList( aFormatVec, rFormatStr, false );
+ OUStringVector::const_iterator aIt = parse( aFormatVec );
+ return OUStringVector( aIt, const_cast< const OUStringVector& >( aFormatVec ).end() );
+}
+
+// append string to string ----------------------------------------------------
+
+void StringHelper::appendChar( OUStringBuffer& rStr, sal_Unicode cChar, sal_Int32 nCount )
+{
+ for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
+ rStr.append( cChar );
+}
+
+void StringHelper::appendString( OUStringBuffer& rStr, const OUString& rData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendChar( rStr, cFill, nWidth - rData.getLength() );
+ rStr.append( rData );
+}
+
+// append decimal -------------------------------------------------------------
+
+void StringHelper::appendDec( OUStringBuffer& rStr, sal_uInt8 nData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendString( rStr, OUString::number( nData ), nWidth, cFill );
+}
+
+void StringHelper::appendDec( OUStringBuffer& rStr, sal_Int8 nData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendString( rStr, OUString::number( nData ), nWidth, cFill );
+}
+
+void StringHelper::appendDec( OUStringBuffer& rStr, sal_uInt16 nData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendString( rStr, OUString::number( nData ), nWidth, cFill );
+}
+
+void StringHelper::appendDec( OUStringBuffer& rStr, sal_Int16 nData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendString( rStr, OUString::number( nData ), nWidth, cFill );
+}
+
+void StringHelper::appendDec( OUStringBuffer& rStr, sal_uInt32 nData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendString( rStr, OUString::number( nData ), nWidth, cFill );
+}
+
+void StringHelper::appendDec( OUStringBuffer& rStr, sal_Int32 nData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendString( rStr, OUString::number( nData ), nWidth, cFill );
+}
+
+void StringHelper::appendDec( OUStringBuffer& rStr, sal_uInt64 nData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ /* Values greater than biggest signed 64bit integer will change to
+ negative when converting to sal_Int64. Therefore, the trailing digit
+ will be written separately. */
+ OUStringBuffer aBuffer;
+ if( nData > 9 )
+ aBuffer.append( static_cast<sal_Int64>(nData / 10 ) );
+ aBuffer.append( static_cast< sal_Unicode >( '0' + (nData % 10) ) );
+ appendString( rStr, aBuffer.makeStringAndClear(), nWidth, cFill );
+}
+
+void StringHelper::appendDec( OUStringBuffer& rStr, sal_Int64 nData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendString( rStr, OUString::number( nData ), nWidth, cFill );
+}
+
+void StringHelper::appendDec( OUStringBuffer& rStr, double fData, sal_Int32 nWidth, sal_Unicode cFill )
+{
+ appendString( rStr, ::rtl::math::doubleToUString( fData, rtl_math_StringFormat_G, 15, '.', true ), nWidth, cFill );
+}
+
+// append hexadecimal ---------------------------------------------------------
+
+void StringHelper::appendHex( OUStringBuffer& rStr, sal_uInt8 nData, bool bPrefix )
+{
+ static const sal_Unicode spcHexDigits[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
+ if( bPrefix )
+ rStr.append( "0x" );
+ rStr.append( spcHexDigits[ (nData >> 4) & 0x0F ] ).append( spcHexDigits[ nData & 0x0F ] );
+}
+
+void StringHelper::appendHex( OUStringBuffer& rStr, sal_Int8 nData, bool bPrefix )
+{
+ appendHex( rStr, static_cast< sal_uInt8 >( nData ), bPrefix );
+}
+
+void StringHelper::appendHex( OUStringBuffer& rStr, sal_uInt16 nData, bool bPrefix )
+{
+ appendHex( rStr, static_cast< sal_uInt8 >( nData >> 8 ), bPrefix );
+ appendHex( rStr, static_cast< sal_uInt8 >( nData ), false );
+}
+
+void StringHelper::appendHex( OUStringBuffer& rStr, sal_Int16 nData, bool bPrefix )
+{
+ appendHex( rStr, static_cast< sal_uInt16 >( nData ), bPrefix );
+}
+
+void StringHelper::appendHex( OUStringBuffer& rStr, sal_uInt32 nData, bool bPrefix )
+{
+ appendHex( rStr, static_cast< sal_uInt16 >( nData >> 16 ), bPrefix );
+ appendHex( rStr, static_cast< sal_uInt16 >( nData ), false );
+}
+
+void StringHelper::appendHex( OUStringBuffer& rStr, sal_Int32 nData, bool bPrefix )
+{
+ appendHex( rStr, static_cast< sal_uInt32 >( nData ), bPrefix );
+}
+
+void StringHelper::appendHex( OUStringBuffer& rStr, sal_uInt64 nData, bool bPrefix )
+{
+ appendHex( rStr, static_cast< sal_uInt32 >( nData >> 32 ), bPrefix );
+ appendHex( rStr, static_cast< sal_uInt32 >( nData ), false );
+}
+
+void StringHelper::appendHex( OUStringBuffer& rStr, sal_Int64 nData, bool bPrefix )
+{
+ appendHex( rStr, static_cast< sal_uInt64 >( nData ), bPrefix );
+}
+
+static sal_uInt64
+lcl_ConvertDouble(double const f)
+{
+ sal_uInt64 i = sal_uInt64();
+ for (size_t j = 0; j < sizeof(double); ++j)
+ { // hopefully both endian independent and strict aliasing safe
+ reinterpret_cast<char *>(&i)[j] = reinterpret_cast<char const *>(&f)[j];
+ }
+ return i;
+}
+
+void StringHelper::appendHex( OUStringBuffer& rStr, double fData, bool bPrefix )
+{
+ appendHex( rStr, lcl_ConvertDouble(fData), bPrefix );
+}
+
+// append shortened hexadecimal -----------------------------------------------
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt8 nData, bool bPrefix )
+{
+ appendHex( rStr, nData, bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int8 nData, bool bPrefix )
+{
+ appendHex( rStr, nData, bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt16 nData, bool bPrefix )
+{
+ if( nData > SAL_MAX_UINT8 )
+ appendHex( rStr, nData, bPrefix );
+ else
+ appendHex( rStr, static_cast< sal_uInt8 >( nData ), bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int16 nData, bool bPrefix )
+{
+ appendShortHex( rStr, static_cast< sal_uInt16 >( nData ), bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt32 nData, bool bPrefix )
+{
+ if( nData > SAL_MAX_UINT16 )
+ appendHex( rStr, nData, bPrefix );
+ else
+ appendShortHex( rStr, static_cast< sal_uInt16 >( nData ), bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int32 nData, bool bPrefix )
+{
+ appendShortHex( rStr, static_cast< sal_uInt32 >( nData ), bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_uInt64 nData, bool bPrefix )
+{
+ if( nData > SAL_MAX_UINT32 )
+ appendHex( rStr, nData, bPrefix );
+ else
+ appendShortHex( rStr, static_cast< sal_uInt32 >( nData ), bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, sal_Int64 nData, bool bPrefix )
+{
+ appendShortHex( rStr, static_cast< sal_uInt64 >( nData ), bPrefix );
+}
+
+void StringHelper::appendShortHex( OUStringBuffer& rStr, double fData, bool bPrefix )
+{
+ appendHex( rStr, fData, bPrefix );
+}
+
+// append binary --------------------------------------------------------------
+
+void StringHelper::appendBin( OUStringBuffer& rStr, sal_uInt8 nData, bool bDots )
+{
+ for( sal_uInt8 nMask = 0x80; nMask != 0; (nMask >>= 1) &= 0x7F )
+ {
+ rStr.append( static_cast< sal_Unicode >( (nData & nMask) ? '1' : '0' ) );
+ if( bDots && (nMask == 0x10) )
+ rStr.append( OOX_DUMP_BINDOT );
+ }
+}
+
+void StringHelper::appendBin( OUStringBuffer& rStr, sal_Int8 nData, bool bDots )
+{
+ appendBin( rStr, static_cast< sal_uInt8 >( nData ), bDots );
+}
+
+void StringHelper::appendBin( OUStringBuffer& rStr, sal_uInt16 nData, bool bDots )
+{
+ appendBin( rStr, static_cast< sal_uInt8 >( nData >> 8 ), bDots );
+ if( bDots )
+ rStr.append( OOX_DUMP_BINDOT );
+ appendBin( rStr, static_cast< sal_uInt8 >( nData ), bDots );
+}
+
+void StringHelper::appendBin( OUStringBuffer& rStr, sal_Int16 nData, bool bDots )
+{
+ appendBin( rStr, static_cast< sal_uInt16 >( nData ), bDots );
+}
+
+void StringHelper::appendBin( OUStringBuffer& rStr, sal_uInt32 nData, bool bDots )
+{
+ appendBin( rStr, static_cast< sal_uInt16 >( nData >> 16 ), bDots );
+ if( bDots )
+ rStr.append( OOX_DUMP_BINDOT );
+ appendBin( rStr, static_cast< sal_uInt16 >( nData ), bDots );
+}
+
+void StringHelper::appendBin( OUStringBuffer& rStr, sal_Int32 nData, bool bDots )
+{
+ appendBin( rStr, static_cast< sal_uInt32 >( nData ), bDots );
+}
+
+void StringHelper::appendBin( OUStringBuffer& rStr, sal_uInt64 nData, bool bDots )
+{
+ appendBin( rStr, static_cast< sal_uInt32 >( nData >> 32 ), bDots );
+ if( bDots )
+ rStr.append( OOX_DUMP_BINDOT );
+ appendBin( rStr, static_cast< sal_uInt32 >( nData ), bDots );
+}
+
+void StringHelper::appendBin( OUStringBuffer& rStr, sal_Int64 nData, bool bDots )
+{
+ appendBin( rStr, static_cast< sal_uInt64 >( nData ), bDots );
+}
+
+void StringHelper::appendBin( OUStringBuffer& rStr, double fData, bool bDots )
+{
+ appendBin( rStr, lcl_ConvertDouble(fData), bDots );
+}
+
+// append formatted value -----------------------------------------------------
+
+void StringHelper::appendBool( OUStringBuffer& rStr, bool bData )
+{
+ rStr.appendAscii( bData ? "true" : "false" );
+}
+
+// encoded text output --------------------------------------------------------
+
+void StringHelper::appendCChar( OUStringBuffer& rStr, sal_Unicode cChar, bool bPrefix )
+{
+ if( cChar > 0x00FF )
+ {
+ if( bPrefix )
+ rStr.append( "\\u" );
+ appendHex( rStr, static_cast< sal_uInt16 >( cChar ), false );
+ }
+ else
+ {
+ if( bPrefix )
+ rStr.append( "\\x" );
+ appendHex( rStr, static_cast< sal_uInt8 >( cChar ), false );
+ }
+}
+
+void StringHelper::appendEncChar( OUStringBuffer& rStr, sal_Unicode cChar, sal_Int32 nCount, bool bPrefix )
+{
+ if( cChar < 0x0020 )
+ {
+ // C-style hex code
+ OUStringBuffer aCode;
+ appendCChar( aCode, cChar, bPrefix );
+ OUString aCodeStr = aCode.makeStringAndClear();
+ for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
+ rStr.append( aCodeStr );
+ }
+ else
+ {
+ appendChar( rStr, cChar, nCount );
+ }
+}
+
+void StringHelper::appendEncString( OUStringBuffer& rStr, const OUString& rData, bool bPrefix )
+{
+ sal_Int32 nBeg = 0;
+ sal_Int32 nIdx = 0;
+ sal_Int32 nEnd = rData.getLength();
+ while( nIdx < nEnd )
+ {
+ // find next character that needs encoding
+ while( (nIdx < nEnd) && (rData[ nIdx ] >= 0x20) ) ++nIdx;
+ // append portion
+ if( nBeg < nIdx )
+ {
+ if( (nBeg == 0) && (nIdx == nEnd) )
+ rStr.append( rData );
+ else
+ rStr.append( rData.subView(nBeg, nIdx - nBeg) );
+ }
+ // append characters to be encoded
+ while( (nIdx < nEnd) && (rData[ nIdx ] < 0x20) )
+ {
+ appendCChar( rStr, rData[ nIdx ], bPrefix );
+ ++nIdx;
+ }
+ // adjust limits
+ nBeg = nIdx;
+ }
+}
+
+// token list -----------------------------------------------------------------
+
+void StringHelper::appendToken( OUStringBuffer& rStr, std::u16string_view rToken, sal_Unicode cSep )
+{
+ if( (rStr.getLength() > 0) && (!rToken.empty()) )
+ rStr.append( cSep );
+ rStr.append( rToken );
+}
+
+void StringHelper::appendIndex( OUStringBuffer& rStr, sal_Int64 nIdx )
+{
+ OUStringBuffer aToken;
+ appendDec( aToken, nIdx );
+ rStr.append( '[' ).append( aToken.makeStringAndClear() ).append( ']' );
+}
+
+std::u16string_view StringHelper::getToken( std::u16string_view rData, sal_Int32& rnPos, sal_Unicode cSep )
+{
+ return trimSpaces( o3tl::getToken(rData, 0, cSep, rnPos ) );
+}
+
+void StringHelper::enclose( OUStringBuffer& rStr, sal_Unicode cOpen, sal_Unicode cClose )
+{
+ rStr.insert( 0, cOpen ).append( cClose ? cClose : cOpen );
+}
+
+// string conversion ----------------------------------------------------------
+
+namespace {
+
+sal_Int32 lclIndexOf( const OUString& rStr, sal_Unicode cChar, sal_Int32 nStartPos )
+{
+ sal_Int32 nIndex = rStr.indexOf( cChar, nStartPos );
+ return (nIndex < 0) ? rStr.getLength() : nIndex;
+}
+
+OUString lclTrimQuotedStringList( const OUString& rStr )
+{
+ OUStringBuffer aBuffer;
+ sal_Int32 nPos = 0;
+ sal_Int32 nLen = rStr.getLength();
+ while( nPos < nLen )
+ {
+ if( rStr[ nPos ] == OOX_DUMP_CFG_QUOTE )
+ {
+ // quoted string, skip leading quote character
+ ++nPos;
+ // process quoted text and embedded literal quote characters
+ OUStringBuffer aToken;
+ do
+ {
+ // seek to next quote character and add text portion to token buffer
+ sal_Int32 nEnd = lclIndexOf( rStr, OOX_DUMP_CFG_QUOTE, nPos );
+ aToken.append( rStr.subView(nPos, nEnd - nPos) );
+ // process literal quotes
+ while( (nEnd + 1 < nLen) && (rStr[ nEnd ] == OOX_DUMP_CFG_QUOTE) && (rStr[ nEnd + 1 ] == OOX_DUMP_CFG_QUOTE) )
+ {
+ aToken.append( OOX_DUMP_CFG_QUOTE );
+ nEnd += 2;
+ }
+ // nEnd is start of possible next text portion
+ nPos = nEnd;
+ }
+ while( (nPos < nLen) && (rStr[ nPos ] != OOX_DUMP_CFG_QUOTE) );
+ // add token, seek to list separator, ignore text following closing quote
+ aBuffer.append( aToken.makeStringAndClear() );
+ nPos = lclIndexOf( rStr, OOX_DUMP_CFG_LISTSEP, nPos );
+ if( nPos < nLen )
+ aBuffer.append( OOX_DUMP_LF );
+ // set current position behind list separator
+ ++nPos;
+ }
+ else
+ {
+ // find list separator, add token text to buffer
+ sal_Int32 nEnd = lclIndexOf( rStr, OOX_DUMP_CFG_LISTSEP, nPos );
+ aBuffer.append( rStr.subView(nPos, nEnd - nPos) );
+ if( nEnd < nLen )
+ aBuffer.append( OOX_DUMP_LF );
+ // set current position behind list separator
+ nPos = nEnd + 1;
+ }
+ }
+
+ return aBuffer.makeStringAndClear();
+}
+
+} // namespace
+
+std::u16string_view StringHelper::trimSpaces( std::u16string_view rStr )
+{
+ size_t nBeg = 0;
+ while( (nBeg < rStr.size()) && ((rStr[ nBeg ] == ' ') || (rStr[ nBeg ] == '\t')) )
+ ++nBeg;
+ size_t nEnd = rStr.size();
+ while( (nEnd > nBeg) && ((rStr[ nEnd - 1 ] == ' ') || (rStr[ nEnd - 1 ] == '\t')) )
+ --nEnd;
+ return rStr.substr( nBeg, nEnd - nBeg );
+}
+
+OUString StringHelper::trimTrailingNul( const OUString& rStr )
+{
+ sal_Int32 nLastPos = rStr.getLength() - 1;
+ if( (nLastPos >= 0) && (rStr[ nLastPos ] == 0) )
+ return rStr.copy( 0, nLastPos );
+ return rStr;
+}
+
+OString StringHelper::convertToUtf8( std::u16string_view rStr )
+{
+ return OUStringToOString( rStr, RTL_TEXTENCODING_UTF8 );
+}
+
+DataType StringHelper::convertToDataType( std::u16string_view rStr )
+{
+ DataType eType = DATATYPE_VOID;
+ if ( rStr == u"int8" )
+ eType = DATATYPE_INT8;
+ else if ( rStr == u"uint8" )
+ eType = DATATYPE_UINT8;
+ else if ( rStr == u"int16" )
+ eType = DATATYPE_INT16;
+ else if ( rStr == u"uint16" )
+ eType = DATATYPE_UINT16;
+ else if ( rStr == u"int32" )
+ eType = DATATYPE_INT32;
+ else if ( rStr == u"uint32" )
+ eType = DATATYPE_UINT32;
+ else if ( rStr == u"int64" )
+ eType = DATATYPE_INT64;
+ else if ( rStr == u"uint64" )
+ eType = DATATYPE_UINT64;
+ else if ( rStr == u"float" )
+ eType = DATATYPE_FLOAT;
+ else if ( rStr == u"double" )
+ eType = DATATYPE_DOUBLE;
+ return eType;
+}
+
+FormatType StringHelper::convertToFormatType( std::u16string_view rStr )
+{
+ FormatType eType = FORMATTYPE_NONE;
+ if ( rStr == u"dec" )
+ eType = FORMATTYPE_DEC;
+ else if ( rStr == u"hex" )
+ eType = FORMATTYPE_HEX;
+ else if ( rStr == u"shorthex" )
+ eType = FORMATTYPE_SHORTHEX;
+ else if ( rStr == u"bin" )
+ eType = FORMATTYPE_BIN;
+ else if ( rStr == u"fix" )
+ eType = FORMATTYPE_FIX;
+ else if ( rStr == u"bool" )
+ eType = FORMATTYPE_BOOL;
+ return eType;
+}
+
+bool StringHelper::convertFromDec( sal_Int64& ornData, std::u16string_view rData )
+{
+ size_t nPos = 0;
+ size_t nLen = rData.size();
+ bool bNeg = false;
+ if( (nLen > 0) && (rData[ 0 ] == '-') )
+ {
+ bNeg = true;
+ ++nPos;
+ }
+ ornData = 0;
+ for( ; nPos < nLen; ++nPos )
+ {
+ sal_Unicode cChar = rData[ nPos ];
+ if( (cChar < '0') || (cChar > '9') )
+ return false;
+ ornData = (ornData * 10) + (cChar - '0');
+ }
+ if( bNeg )
+ ornData *= -1;
+ return true;
+}
+
+bool StringHelper::convertFromHex( sal_Int64& ornData, std::u16string_view rData )
+{
+ ornData = 0;
+ for( size_t nPos = 0, nLen = rData.size(); nPos < nLen; ++nPos )
+ {
+ sal_Unicode cChar = rData[ nPos ];
+ if( ('0' <= cChar) && (cChar <= '9') )
+ cChar -= '0';
+ else if( ('A' <= cChar) && (cChar <= 'F') )
+ cChar -= ('A' - 10);
+ else if( ('a' <= cChar) && (cChar <= 'f') )
+ cChar -= ('a' - 10);
+ else
+ return false;
+ ornData = (ornData << 4) + cChar;
+ }
+ return true;
+}
+
+bool StringHelper::convertStringToInt( sal_Int64& ornData, std::u16string_view rData )
+{
+ if( (rData.size() > 2) && (rData[ 0 ] == '0') && ((rData[ 1 ] == 'X') || (rData[ 1 ] == 'x')) )
+ return convertFromHex( ornData, rData.substr( 2 ) );
+ return convertFromDec( ornData, rData );
+}
+
+bool StringHelper::convertStringToDouble( double& orfData, std::u16string_view rData )
+{
+ rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
+ sal_Int32 nSize = 0;
+ sal_Unicode const * pBegin = rData.data();
+ sal_Unicode const * pEnd;
+ orfData = rtl_math_uStringToDouble(pBegin,
+ pBegin + rData.size(),
+ '.', '\0',
+ &eStatus, &pEnd);
+ nSize = static_cast<sal_Int32>(pEnd - pBegin);
+ return (eStatus == rtl_math_ConversionStatus_Ok) && (nSize == static_cast<sal_Int32>(rData.size()));
+}
+
+bool StringHelper::convertStringToBool( std::u16string_view rData )
+{
+ if ( rData == u"true" )
+ return true;
+ if ( rData == u"false" )
+ return false;
+ sal_Int64 nData;
+ return convertStringToInt( nData, rData ) && (nData != 0);
+}
+
+OUStringPair StringHelper::convertStringToPair( const OUString& rString, sal_Unicode cSep )
+{
+ OUStringPair aPair;
+ if( !rString.isEmpty() )
+ {
+ sal_Int32 nEqPos = rString.indexOf( cSep );
+ if( nEqPos < 0 )
+ {
+ aPair.first = rString;
+ }
+ else
+ {
+ aPair.first = StringHelper::trimSpaces( rString.subView( 0, nEqPos ) );
+ aPair.second = StringHelper::trimSpaces( rString.subView( nEqPos + 1 ) );
+ }
+ }
+ return aPair;
+}
+
+void StringHelper::convertStringToStringList( OUStringVector& orVec, const OUString& rData, bool bIgnoreEmpty )
+{
+ orVec.clear();
+ OUString aUnquotedData = lclTrimQuotedStringList( rData );
+ sal_Int32 nPos = 0;
+ sal_Int32 nLen = aUnquotedData.getLength();
+ while( (0 <= nPos) && (nPos < nLen) )
+ {
+ std::u16string_view aToken = getToken( aUnquotedData, nPos, OOX_DUMP_LF );
+ if( !bIgnoreEmpty || !aToken.empty() )
+ orVec.push_back( OUString(aToken) );
+ }
+}
+
+void StringHelper::convertStringToIntList( Int64Vector& orVec, const OUString& rData, bool bIgnoreEmpty )
+{
+ orVec.clear();
+ OUString aUnquotedData = lclTrimQuotedStringList( rData );
+ sal_Int32 nPos = 0;
+ sal_Int32 nLen = aUnquotedData.getLength();
+ sal_Int64 nData;
+ while( (0 <= nPos) && (nPos < nLen) )
+ {
+ bool bOk = convertStringToInt( nData, getToken( aUnquotedData, nPos, OOX_DUMP_LF ) );
+ if( !bIgnoreEmpty || bOk )
+ orVec.push_back( bOk ? nData : 0 );
+ }
+}
+
+Base::~Base()
+{
+}
+
+ConfigItemBase::~ConfigItemBase()
+{
+}
+
+void ConfigItemBase::readConfigBlock( TextInputStream& rStrm )
+{
+ readConfigBlockContents( rStrm );
+}
+
+void ConfigItemBase::implProcessConfigItemStr(
+ TextInputStream& /*rStrm*/, const OUString& /*rKey*/, const OUString& /*rData*/ )
+{
+}
+
+void ConfigItemBase::implProcessConfigItemInt(
+ TextInputStream& /*rStrm*/, sal_Int64 /*nKey*/, const OUString& /*rData*/ )
+{
+}
+
+void ConfigItemBase::readConfigBlockContents( TextInputStream& rStrm )
+{
+ bool bLoop = true;
+ while( bLoop && !rStrm.isEof() )
+ {
+ OUString aKey, aData;
+ switch( readConfigLine( rStrm, aKey, aData ) )
+ {
+ case LINETYPE_DATA:
+ processConfigItem( rStrm, aKey, aData );
+ break;
+ case LINETYPE_END:
+ bLoop = false;
+ break;
+ }
+ }
+}
+
+ConfigItemBase::LineType ConfigItemBase::readConfigLine(
+ TextInputStream& rStrm, OUString& orKey, OUString& orData )
+{
+ OUString aLine;
+ while( !rStrm.isEof() && aLine.isEmpty() )
+ {
+ aLine = rStrm.readLine();
+ if( !aLine.isEmpty() && (aLine[ 0 ] == OOX_DUMP_BOM) )
+ aLine = aLine.copy( 1 );
+ aLine = StringHelper::trimSpaces( aLine );
+ if( !aLine.isEmpty() )
+ {
+ // ignore comments (starting with hash or semicolon)
+ sal_Unicode cChar = aLine[ 0 ];
+ if( (cChar == '#') || (cChar == ';') )
+ aLine.clear();
+ }
+ }
+
+ OUStringPair aPair = StringHelper::convertStringToPair( aLine );
+ orKey = aPair.first;
+ orData = aPair.second;
+ return ( !orKey.isEmpty() && (!orData.isEmpty() || orKey != "end" )) ?
+ LINETYPE_DATA : LINETYPE_END;
+}
+
+void ConfigItemBase::processConfigItem(
+ TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
+{
+ sal_Int64 nKey;
+ if( StringHelper::convertStringToInt( nKey, rKey ) )
+ implProcessConfigItemInt( rStrm, nKey, rData );
+ else
+ implProcessConfigItemStr( rStrm, rKey, rData );
+}
+
+NameListBase::~NameListBase()
+{
+}
+
+void NameListBase::setName( sal_Int64 nKey, const String& rName )
+{
+ implSetName( nKey, rName );
+}
+
+void NameListBase::includeList( const NameListRef& rxList )
+{
+ if( rxList )
+ {
+ for (auto const& elem : *rxList)
+ maMap[ elem.first ] = elem.second;
+ implIncludeList( *rxList );
+ }
+}
+
+bool NameListBase::implIsValid() const
+{
+ return true;
+}
+
+void NameListBase::implProcessConfigItemStr(
+ TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
+{
+ if ( rKey == "include" )
+ include( rData );
+ else if ( rKey == "exclude" )
+ exclude( rData );
+ else
+ ConfigItemBase::implProcessConfigItemStr( rStrm, rKey, rData );
+}
+
+void NameListBase::implProcessConfigItemInt(
+ TextInputStream& /*rStrm*/, sal_Int64 nKey, const OUString& rData )
+{
+ implSetName( nKey, rData );
+}
+
+void NameListBase::insertRawName( sal_Int64 nKey, const OUString& rName )
+{
+ maMap[ nKey ] = rName;
+}
+
+const OUString* NameListBase::findRawName( sal_Int64 nKey ) const
+{
+ const_iterator aIt = maMap.find( nKey );
+ return (aIt == end()) ? nullptr : &aIt->second;
+}
+
+void NameListBase::include( const OUString& rListKeys )
+{
+ OUStringVector aVec;
+ StringHelper::convertStringToStringList( aVec, rListKeys, true );
+ for (auto const& elem : aVec)
+ includeList( mrCfgData.getNameList(elem) );
+}
+
+void NameListBase::exclude( const OUString& rKeys )
+{
+ Int64Vector aVec;
+ StringHelper::convertStringToIntList( aVec, rKeys, true );
+ for (auto const& elem : aVec)
+ maMap.erase(elem);
+}
+
+void ItemFormatMap::insertFormats( const NameListRef& rxNameList )
+{
+ if( Base::isValid( rxNameList ) )
+ {
+ for (auto const& elemName : *rxNameList)
+ maMap[ elemName.first ].parse( elemName.second );
+ }
+}
+
+ConstList::ConstList( const SharedConfigData& rCfgData ) :
+ NameListBase( rCfgData ),
+ maDefName( OOX_DUMP_ERR_NONAME ),
+ mbQuoteNames( false )
+{
+}
+
+void ConstList::implProcessConfigItemStr(
+ TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
+{
+ if ( rKey == "default" )
+ maDefName = rData; // Sets a default name for unknown keys.
+ else if ( rKey == "quote-names" )
+ setQuoteNames( StringHelper::convertStringToBool( rData ) );
+ else
+ NameListBase::implProcessConfigItemStr( rStrm, rKey, rData );
+}
+
+void ConstList::implSetName( sal_Int64 nKey, const OUString& rName )
+{
+ insertRawName( nKey, rName );
+}
+
+OUString ConstList::implGetName( const Config& /*rCfg*/, sal_Int64 nKey ) const
+{
+ const OUString* pName = findRawName( nKey );
+ OUString aName = pName ? *pName : maDefName;
+ if( mbQuoteNames )
+ {
+ OUStringBuffer aBuffer( aName );
+ StringHelper::enclose( aBuffer, OOX_DUMP_STRQUOTE );
+ aName = aBuffer.makeStringAndClear();
+ }
+ return aName;
+}
+
+OUString ConstList::implGetNameDbl( const Config& /*rCfg*/, double /*fValue*/ ) const
+{
+ return OUString();
+}
+
+void ConstList::implIncludeList( const NameListBase& rList )
+{
+ if( const ConstList* pConstList = dynamic_cast< const ConstList* >( &rList ) )
+ {
+ maDefName = pConstList->maDefName;
+ mbQuoteNames = pConstList->mbQuoteNames;
+ }
+}
+
+MultiList::MultiList( const SharedConfigData& rCfgData ) :
+ ConstList( rCfgData ),
+ mbIgnoreEmpty( true )
+{
+}
+
+void MultiList::setNamesFromVec( sal_Int64 nStartKey, const OUStringVector& rNames )
+{
+ sal_Int64 nKey = nStartKey;
+ for (auto const& name : rNames)
+ {
+ if( !mbIgnoreEmpty || !name.isEmpty() )
+ insertRawName( nKey, name);
+ ++nKey;
+ }
+}
+
+void MultiList::implProcessConfigItemStr(
+ TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
+{
+ if ( rKey == "ignore-empty" )
+ mbIgnoreEmpty = StringHelper::convertStringToBool( rData );
+ else
+ ConstList::implProcessConfigItemStr( rStrm, rKey, rData );
+}
+
+void MultiList::implSetName( sal_Int64 nKey, const OUString& rName )
+{
+ OUStringVector aNames;
+ StringHelper::convertStringToStringList( aNames, rName, false );
+ setNamesFromVec( nKey, aNames );
+}
+
+FlagsList::FlagsList( const SharedConfigData& rCfgData ) :
+ NameListBase( rCfgData ),
+ mnIgnore( 0 )
+{
+}
+
+void FlagsList::implProcessConfigItemStr(
+ TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
+{
+ if ( rKey == "ignore" )
+ {
+ sal_Int64 nIgnore;
+ if( StringHelper::convertStringToInt( nIgnore, rData ) )
+ setIgnoreFlags( nIgnore );
+ }
+ else
+ {
+ NameListBase::implProcessConfigItemStr( rStrm, rKey, rData );
+ }
+}
+
+void FlagsList::implSetName( sal_Int64 nKey, const OUString& rName )
+{
+ if( (nKey != 0) && ((nKey & (nKey - 1)) == 0) ) // only a single bit set?
+ insertRawName( nKey, rName );
+}
+
+OUString FlagsList::implGetName( const Config& /*rCfg*/, sal_Int64 nKey ) const
+{
+ sal_Int64 nFound = mnIgnore;
+ OUStringBuffer aName;
+ // add known flags
+ for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
+ {
+ sal_Int64 nMask = aIt->first;
+ setFlag( nFound, nMask );
+ if( !getFlag( mnIgnore, nMask ) )
+ {
+ const OUString& rFlagName = aIt->second;
+ bool bOnOff = rFlagName.startsWith(":");
+ bool bFlag = getFlag( nKey, nMask );
+ if( bOnOff )
+ {
+ StringHelper::appendToken( aName, rFlagName.subView( 1 ) );
+ aName.appendAscii( bFlag ? ":on" : ":off" );
+ }
+ else
+ {
+ bool bNegated = rFlagName.startsWith("!");
+ sal_Int32 nBothSep = bNegated ? rFlagName.indexOf( '!', 1 ) : -1;
+ if( bFlag )
+ {
+ if( !bNegated )
+ StringHelper::appendToken( aName, rFlagName );
+ else if( nBothSep > 0 )
+ StringHelper::appendToken( aName, rFlagName.subView( nBothSep + 1 ) );
+ }
+ else if( bNegated )
+ {
+ if( nBothSep > 0 )
+ StringHelper::appendToken( aName, rFlagName.subView( 1, nBothSep - 1 ) );
+ else
+ StringHelper::appendToken( aName, rFlagName.subView( 1 ) );
+ }
+ }
+ }
+ }
+ // add unknown flags
+ setFlag( nKey, nFound, false );
+ if( nKey != 0 )
+ {
+ OUStringBuffer aUnknown( OOX_DUMP_UNKNOWN );
+ aUnknown.append( OOX_DUMP_ITEMSEP );
+ StringHelper::appendShortHex( aUnknown, nKey );
+ StringHelper::enclose( aUnknown, '(', ')' );
+ StringHelper::appendToken( aName, aUnknown.makeStringAndClear() );
+ }
+ return aName.makeStringAndClear();
+}
+
+OUString FlagsList::implGetNameDbl( const Config& /*rCfg*/, double /*fValue*/ ) const
+{
+ return OUString();
+}
+
+void FlagsList::implIncludeList( const NameListBase& rList )
+{
+ if( const FlagsList* pFlagsList = dynamic_cast< const FlagsList* >( &rList ) )
+ mnIgnore = pFlagsList->mnIgnore;
+}
+
+bool CombiList::ExtItemFormatKey::operator<( const ExtItemFormatKey& rRight ) const
+{
+ return (mnKey < rRight.mnKey) || ((mnKey == rRight.mnKey) && (maFilter < rRight.maFilter));
+}
+
+CombiList::CombiList( const SharedConfigData& rCfgData ) :
+ FlagsList( rCfgData )
+{
+}
+
+void CombiList::implSetName( sal_Int64 nKey, const OUString& rName )
+{
+ if( (nKey & (nKey - 1)) != 0 ) // more than a single bit set?
+ {
+ ::std::set< ExtItemFormatKey > aItemKeys;
+ ExtItemFormat aItemFmt;
+ OUStringVector aRemain = aItemFmt.parse( rName );
+ for (auto const& elemRemain : aRemain)
+ {
+ OUStringPair aPair = StringHelper::convertStringToPair(elemRemain);
+ if ( aPair.first == "noshift" )
+ {
+ aItemFmt.mbShiftValue = StringHelper::convertStringToBool( aPair.second );
+ }
+ else if ( aPair.first == "filter" )
+ {
+ OUStringPair aFilter = StringHelper::convertStringToPair( aPair.second, '~' );
+ ExtItemFormatKey aKey( nKey );
+ if( !aFilter.first.isEmpty() && StringHelper::convertStringToInt( aKey.maFilter.first, aFilter.first ) &&
+ !aFilter.second.isEmpty() && StringHelper::convertStringToInt( aKey.maFilter.second, aFilter.second ) )
+ {
+ if( aKey.maFilter.first == 0 )
+ aKey.maFilter.second = 0;
+ aItemKeys.insert( aKey );
+ }
+ }
+ }
+ if( aItemKeys.empty() )
+ aItemKeys.insert( ExtItemFormatKey( nKey ) );
+ for (auto const& itemKey : aItemKeys)
+ maFmtMap[itemKey] = aItemFmt;
+ }
+ else
+ {
+ FlagsList::implSetName( nKey, rName );
+ }
+}
+
+OUString CombiList::implGetName( const Config& rCfg, sal_Int64 nKey ) const
+{
+ sal_Int64 nFound = 0;
+ OUStringBuffer aName;
+ // add known flag fields
+ for (auto const& fmt : maFmtMap)
+ {
+ const ExtItemFormatKey& rMapKey = fmt.first;
+ sal_Int64 nMask = rMapKey.mnKey;
+ if( (nMask != 0) && ((nKey & rMapKey.maFilter.first) == rMapKey.maFilter.second) )
+ {
+ const ExtItemFormat& rItemFmt = fmt.second;
+
+ sal_uInt64 nUFlags = static_cast< sal_uInt64 >( nKey );
+ sal_uInt64 nUMask = static_cast< sal_uInt64 >( nMask );
+ if( rItemFmt.mbShiftValue )
+ while( (nUMask & 1) == 0 ) { nUFlags >>= 1; nUMask >>= 1; }
+
+ sal_uInt64 nUValue = nUFlags & nUMask;
+ sal_Int64 nSValue = static_cast< sal_Int64 >( nUValue );
+ if( getFlag< sal_uInt64 >( nUValue, (nUMask + 1) >> 1 ) )
+ setFlag( nSValue, static_cast< sal_Int64 >( ~nUMask ) );
+
+ OUStringBuffer aItem( rItemFmt.maItemName );
+ OUStringBuffer aValue;
+ switch( rItemFmt.meDataType )
+ {
+ case DATATYPE_INT8: StringHelper::appendValue( aValue, static_cast< sal_Int8 >( nSValue ), rItemFmt.meFmtType ); break;
+ case DATATYPE_UINT8: StringHelper::appendValue( aValue, static_cast< sal_uInt8 >( nUValue ), rItemFmt.meFmtType ); break;
+ case DATATYPE_INT16: StringHelper::appendValue( aValue, static_cast< sal_Int16 >( nSValue ), rItemFmt.meFmtType ); break;
+ case DATATYPE_UINT16: StringHelper::appendValue( aValue, static_cast< sal_uInt16 >( nUValue ), rItemFmt.meFmtType ); break;
+ case DATATYPE_INT32: StringHelper::appendValue( aValue, static_cast< sal_Int32 >( nSValue ), rItemFmt.meFmtType ); break;
+ case DATATYPE_UINT32: StringHelper::appendValue( aValue, static_cast< sal_uInt32 >( nUValue ), rItemFmt.meFmtType ); break;
+ case DATATYPE_INT64: StringHelper::appendValue( aValue, nSValue, rItemFmt.meFmtType ); break;
+ case DATATYPE_UINT64: StringHelper::appendValue( aValue, nUValue, rItemFmt.meFmtType ); break;
+ case DATATYPE_FLOAT: StringHelper::appendValue( aValue, static_cast< float >( nSValue ), rItemFmt.meFmtType ); break;
+ case DATATYPE_DOUBLE: StringHelper::appendValue( aValue, static_cast< double >( nSValue ), rItemFmt.meFmtType ); break;
+ default:;
+ }
+ StringHelper::appendToken( aItem, aValue.makeStringAndClear(), OOX_DUMP_ITEMSEP );
+ if( !rItemFmt.maListName.isEmpty() )
+ {
+ OUString aValueName = rCfg.getName( rItemFmt.maListName, static_cast< sal_Int64 >( nUValue ) );
+ StringHelper::appendToken( aItem, aValueName, OOX_DUMP_ITEMSEP );
+ }
+ StringHelper::enclose( aItem, '(', ')' );
+ StringHelper::appendToken( aName, aItem.makeStringAndClear() );
+ setFlag( nFound, nMask );
+ }
+ }
+ setFlag( nKey, nFound, false );
+ StringHelper::appendToken( aName, FlagsList::implGetName( rCfg, nKey ) );
+ return aName.makeStringAndClear();
+}
+
+void CombiList::implIncludeList( const NameListBase& rList )
+{
+ if( const CombiList* pCombiList = dynamic_cast< const CombiList* >( &rList ) )
+ maFmtMap = pCombiList->maFmtMap;
+ FlagsList::implIncludeList( rList );
+}
+
+UnitConverter::UnitConverter( const SharedConfigData& rCfgData ) :
+ NameListBase( rCfgData ),
+ mfFactor( 1.0 )
+{
+}
+
+void UnitConverter::implSetName( sal_Int64 /*nKey*/, const OUString& /*rName*/ )
+{
+ // nothing to do
+}
+
+OUString UnitConverter::implGetName( const Config& rCfg, sal_Int64 nKey ) const
+{
+ return implGetNameDbl( rCfg, static_cast< double >( nKey ) );
+}
+
+OUString UnitConverter::implGetNameDbl( const Config& /*rCfg*/, double fValue ) const
+{
+ OUStringBuffer aValue;
+ StringHelper::appendDec( aValue, mfFactor * fValue );
+ aValue.append( maUnitName );
+ return aValue.makeStringAndClear();
+}
+
+void UnitConverter::implIncludeList( const NameListBase& /*rList*/ )
+{
+}
+
+const NameListRef & NameListWrapper::getNameList( const Config& rCfg ) const
+{
+ if (!mxList)
+ mxList = rCfg.getNameList( maName );
+ return mxList;
+}
+
+SharedConfigData::SharedConfigData( const OUString& rFileName,
+ const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg,
+ const OUString& rSysFileName ) :
+ mxContext( rxContext ),
+ mxRootStrg( rxRootStrg ),
+ maSysFileName( rSysFileName ),
+ mbLoaded( false )
+{
+ OUString aFileUrl = InputOutputHelper::convertFileNameToUrl( rFileName );
+ if( !aFileUrl.isEmpty() )
+ {
+ sal_Int32 nNamePos = InputOutputHelper::getFileNamePos( aFileUrl );
+ maConfigPath = aFileUrl.copy( 0, nNamePos );
+ mbLoaded = readConfigFile( aFileUrl );
+ }
+}
+
+SharedConfigData::~SharedConfigData()
+{
+}
+
+const OUString* SharedConfigData::getOption( const OUString& rKey ) const
+{
+ ConfigDataMap::const_iterator aIt = maConfigData.find( rKey );
+ return (aIt == maConfigData.end()) ? nullptr : &aIt->second;
+}
+
+void SharedConfigData::setNameList( const OUString& rListName, const NameListRef& rxList )
+{
+ if( !rListName.isEmpty() )
+ maNameLists[ rListName ] = rxList;
+}
+
+void SharedConfigData::eraseNameList( const OUString& rListName )
+{
+ maNameLists.erase( rListName );
+}
+
+NameListRef SharedConfigData::getNameList( const OUString& rListName ) const
+{
+ NameListRef xList;
+ NameListMap::const_iterator aIt = maNameLists.find( rListName );
+ if( aIt != maNameLists.end() )
+ xList = aIt->second;
+ return xList;
+}
+
+bool SharedConfigData::implIsValid() const
+{
+ return mbLoaded && mxContext.is() && mxRootStrg && !maSysFileName.isEmpty();
+}
+
+void SharedConfigData::implProcessConfigItemStr(
+ TextInputStream& rStrm, const OUString& rKey, const OUString& rData )
+{
+ if ( rKey == "include-config-file" )
+ readConfigFile( maConfigPath + rData );
+ else if ( rKey == "constlist" )
+ readNameList< ConstList >( rStrm, rData );
+ else if ( rKey == "multilist" )
+ readNameList< MultiList >( rStrm, rData );
+ else if ( rKey == "flagslist" )
+ readNameList< FlagsList >( rStrm, rData );
+ else if ( rKey == "combilist" )
+ readNameList< CombiList >( rStrm, rData );
+ else if ( rKey == "shortlist" )
+ createShortList( rData );
+ else if ( rKey == "unitconverter" )
+ createUnitConverter( rData );
+ else
+ maConfigData[ rKey ] = rData;
+}
+
+bool SharedConfigData::readConfigFile( const OUString& rFileUrl )
+{
+ bool bLoaded = maConfigFiles.count( rFileUrl ) > 0;
+ if( !bLoaded )
+ {
+ Reference< XInputStream > xInStrm = InputOutputHelper::openInputStream( mxContext, rFileUrl );
+ TextInputStream aTxtStrm( mxContext, xInStrm, RTL_TEXTENCODING_UTF8 );
+ if( !aTxtStrm.isEof() )
+ {
+ maConfigFiles.insert( rFileUrl );
+ readConfigBlockContents( aTxtStrm );
+ bLoaded = true;
+ }
+ }
+ return bLoaded;
+}
+
+void SharedConfigData::createShortList( const OUString& rData )
+{
+ OUStringVector aDataVec;
+ StringHelper::convertStringToStringList( aDataVec, rData, false );
+ if( aDataVec.size() < 3 )
+ return;
+
+ sal_Int64 nStartKey;
+ if( StringHelper::convertStringToInt( nStartKey, aDataVec[ 1 ] ) )
+ {
+ std::shared_ptr< MultiList > xList = createNameList< MultiList >( aDataVec[ 0 ] );
+ if( xList )
+ {
+ aDataVec.erase( aDataVec.begin(), aDataVec.begin() + 2 );
+ xList->setNamesFromVec( nStartKey, aDataVec );
+ }
+ }
+}
+
+void SharedConfigData::createUnitConverter( const OUString& rData )
+{
+ OUStringVector aDataVec;
+ StringHelper::convertStringToStringList( aDataVec, rData, false );
+ if( aDataVec.size() < 2 )
+ return;
+
+ OUString aFactor = aDataVec[ 1 ];
+ bool bRecip = aFactor.startsWith("/");
+ if( bRecip )
+ aFactor = aFactor.copy( 1 );
+ double fFactor;
+ if( StringHelper::convertStringToDouble( fFactor, aFactor ) && (fFactor != 0.0) )
+ {
+ std::shared_ptr< UnitConverter > xList = createNameList< UnitConverter >( aDataVec[ 0 ] );
+ if( xList )
+ {
+ xList->setFactor( bRecip ? (1.0 / fFactor) : fFactor );
+ if( aDataVec.size() >= 3 )
+ xList->setUnitName( aDataVec[ 2 ] );
+ }
+ }
+}
+
+Config::Config( const char* pcEnvVar, const FilterBase& rFilter )
+{
+ construct( pcEnvVar, rFilter );
+}
+
+Config::Config( const char* pcEnvVar, const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg, const OUString& rSysFileName )
+{
+ construct( pcEnvVar, rxContext, rxRootStrg, rSysFileName );
+}
+
+Config::~Config()
+{
+}
+
+void Config::construct( const char* pcEnvVar, const FilterBase& rFilter )
+{
+ if( !rFilter.getFileUrl().isEmpty() )
+ construct( pcEnvVar, rFilter.getComponentContext(), rFilter.getStorage(), rFilter.getFileUrl() );
+}
+
+void Config::construct( const char* pcEnvVar, const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg, const OUString& rSysFileName )
+{
+ if( pcEnvVar && rxRootStrg && !rSysFileName.isEmpty() )
+ if( const char* pcFileName = ::getenv( pcEnvVar ) )
+ mxCfgData = std::make_shared<SharedConfigData>( OUString::createFromAscii( pcFileName ), rxContext, rxRootStrg, rSysFileName );
+}
+
+const OUString& Config::getStringOption( const String& rKey, const OUString& rDefault ) const
+{
+ const OUString* pData = implGetOption( rKey );
+ return pData ? *pData : rDefault;
+}
+
+bool Config::getBoolOption( const String& rKey, bool bDefault ) const
+{
+ const OUString* pData = implGetOption( rKey );
+ return pData ? StringHelper::convertStringToBool( *pData ) : bDefault;
+}
+
+bool Config::isDumperEnabled() const
+{
+ return getBoolOption( "enable-dumper", false );
+}
+
+bool Config::isImportEnabled() const
+{
+ return getBoolOption( "enable-import", true );
+}
+
+void Config::eraseNameList( const String& rListName )
+{
+ mxCfgData->eraseNameList( rListName );
+}
+
+NameListRef Config::getNameList( const String& rListName ) const
+{
+ return mxCfgData->getNameList( rListName );
+}
+
+bool Config::implIsValid() const
+{
+ return isValid( mxCfgData );
+}
+
+const OUString* Config::implGetOption( const OUString& rKey ) const
+{
+ return mxCfgData->getOption( rKey );
+}
+
+Output::Output( const Reference< XComponentContext >& rxContext, const OUString& rFileName ) :
+ mxStrm( InputOutputHelper::openTextOutputStream( rxContext, rFileName, RTL_TEXTENCODING_UTF8 ) ),
+ mnCol( 0 ),
+ mnItemLevel( 0 ),
+ mnMultiLevel( 0 ),
+ mnItemIdx( 0 ),
+ mnLastItem( 0 )
+{
+ if( mxStrm.is() )
+ mxStrm->writeString( OUString( OOX_DUMP_BOM ) );
+}
+
+void Output::newLine()
+{
+ if( maLine.getLength() > 0 )
+ {
+ mxStrm->writeString( maIndent );
+ maLine.append( '\n' );
+ mxStrm->writeString( maLine.makeStringAndClear() );
+ mnCol = 0;
+ mnLastItem = 0;
+ }
+}
+
+void Output::emptyLine( size_t nCount )
+{
+ for( size_t nIdx = 0; nIdx < nCount; ++nIdx )
+ mxStrm->writeString( OUString('\n') );
+}
+
+void Output::incIndent()
+{
+ OUStringBuffer aBuffer( maIndent );
+ StringHelper::appendChar( aBuffer, ' ', OOX_DUMP_INDENT );
+ maIndent = aBuffer.makeStringAndClear();
+}
+
+void Output::decIndent()
+{
+ if( maIndent.getLength() >= OOX_DUMP_INDENT )
+ maIndent = maIndent.copy( OOX_DUMP_INDENT );
+}
+
+void Output::startTable( sal_Int32 nW1 )
+{
+ startTable( 1, &nW1 );
+}
+
+void Output::startTable( sal_Int32 nW1, sal_Int32 nW2 )
+{
+ sal_Int32 pnColWidths[ 2 ];
+ pnColWidths[ 0 ] = nW1;
+ pnColWidths[ 1 ] = nW2;
+ startTable( 2, pnColWidths );
+}
+
+void Output::startTable( sal_Int32 nW1, sal_Int32 nW2, sal_Int32 nW3, sal_Int32 nW4 )
+{
+ sal_Int32 pnColWidths[ 4 ];
+ pnColWidths[ 0 ] = nW1;
+ pnColWidths[ 1 ] = nW2;
+ pnColWidths[ 2 ] = nW3;
+ pnColWidths[ 3 ] = nW4;
+ startTable( 4, pnColWidths );
+}
+
+void Output::startTable( size_t nColCount, const sal_Int32* pnColWidths )
+{
+ maColPos.clear();
+ maColPos.push_back( 0 );
+ sal_Int32 nColPos = 0;
+ for( size_t nCol = 0; nCol < nColCount; ++nCol )
+ {
+ nColPos = nColPos + pnColWidths[ nCol ];
+ maColPos.push_back( nColPos );
+ }
+}
+
+void Output::tab()
+{
+ tab( mnCol + 1 );
+}
+
+void Output::tab( size_t nCol )
+{
+ mnCol = nCol;
+ if( mnCol < maColPos.size() )
+ {
+ sal_Int32 nColPos = maColPos[ mnCol ];
+ if( maLine.getLength() >= nColPos )
+ maLine.setLength( ::std::max< sal_Int32 >( nColPos - 1, 0 ) );
+ StringHelper::appendChar( maLine, ' ', nColPos - maLine.getLength() );
+ }
+ else
+ {
+ StringHelper::appendChar( maLine, ' ', 2 );
+ }
+}
+
+void Output::endTable()
+{
+ maColPos.clear();
+}
+
+void Output::resetItemIndex( sal_Int64 nIdx )
+{
+ mnItemIdx = nIdx;
+}
+
+void Output::startItem( const String& rItemName )
+{
+ if( mnItemLevel == 0 )
+ {
+ if( (mnMultiLevel > 0) && (maLine.getLength() > 0) )
+ tab();
+ if( rItemName.has() )
+ {
+ writeItemName( rItemName );
+ writeChar( OOX_DUMP_ITEMSEP );
+ }
+ }
+ ++mnItemLevel;
+ mnLastItem = maLine.getLength();
+}
+
+void Output::contItem()
+{
+ if( mnItemLevel > 0 )
+ {
+ if( (maLine.getLength() == 0) || (maLine[ maLine.getLength() - 1 ] != OOX_DUMP_ITEMSEP) )
+ writeChar( OOX_DUMP_ITEMSEP );
+ mnLastItem = maLine.getLength();
+ }
+}
+
+void Output::endItem()
+{
+ if( mnItemLevel > 0 )
+ {
+ maLastItem = maLine.copy( mnLastItem ).makeStringAndClear();
+ if( maLastItem.isEmpty() && mnLastItem > 0 && maLine[ mnLastItem - 1 ] == OOX_DUMP_ITEMSEP )
+ maLine.setLength( mnLastItem - 1 );
+ --mnItemLevel;
+ }
+ if( mnItemLevel == 0 )
+ {
+ if( mnMultiLevel == 0 )
+ newLine();
+ }
+ else
+ contItem();
+}
+
+void Output::startMultiItems()
+{
+ ++mnMultiLevel;
+}
+
+void Output::endMultiItems()
+{
+ if( mnMultiLevel > 0 )
+ --mnMultiLevel;
+ if( mnMultiLevel == 0 )
+ newLine();
+}
+
+void Output::writeChar( sal_Unicode cChar, sal_Int32 nCount )
+{
+ StringHelper::appendEncChar( maLine, cChar, nCount );
+}
+
+void Output::writeAscii( const char* pcStr )
+{
+ if( pcStr )
+ maLine.appendAscii( pcStr );
+}
+
+void Output::writeString( const OUString& rStr )
+{
+ StringHelper::appendEncString( maLine, rStr );
+}
+
+void Output::writeArray( const sal_uInt8* pnData, std::size_t nSize, sal_Unicode cSep )
+{
+ const sal_uInt8* pnEnd = pnData ? (pnData + nSize) : nullptr;
+ for( const sal_uInt8* pnByte = pnData; pnByte < pnEnd; ++pnByte )
+ {
+ if( pnByte > pnData )
+ writeChar( cSep );
+ writeHex( *pnByte, false );
+ }
+}
+
+void Output::writeBool( bool bData )
+{
+ StringHelper::appendBool( maLine, bData );
+}
+
+void Output::writeDateTime( const util::DateTime& rDateTime )
+{
+ writeDec( rDateTime.Year, 4, '0' );
+ writeChar( '-' );
+ writeDec( rDateTime.Month, 2, '0' );
+ writeChar( '-' );
+ writeDec( rDateTime.Day, 2, '0' );
+ writeChar( 'T' );
+ writeDec( rDateTime.Hours, 2, '0' );
+ writeChar( ':' );
+ writeDec( rDateTime.Minutes, 2, '0' );
+ writeChar( ':' );
+ writeDec( rDateTime.Seconds, 2, '0' );
+}
+
+bool Output::implIsValid() const
+{
+ return mxStrm.is();
+}
+
+void Output::writeItemName( const String& rItemName )
+{
+ if( rItemName.has() && (rItemName[ 0 ] == '#') )
+ {
+ writeString( rItemName.copy( 1 ) );
+ StringHelper::appendIndex( maLine, mnItemIdx++ );
+ }
+ else
+ writeString( rItemName );
+}
+
+StorageIterator::StorageIterator( const StorageRef& rxStrg ) :
+ mxStrg( rxStrg )
+{
+ if( mxStrg )
+ mxStrg->getElementNames( maNames );
+ maIt = maNames.begin();
+}
+
+StorageIterator::~StorageIterator()
+{
+}
+
+StorageIterator& StorageIterator::operator++()
+{
+ if( maIt != maNames.end() )
+ ++maIt;
+ return *this;
+}
+
+OUString StorageIterator::getName() const
+{
+ OUString aName;
+ if( maIt != maNames.end() )
+ aName = *maIt;
+ return aName;
+}
+
+bool StorageIterator::isStream() const
+{
+ return isValid() && mxStrg->openInputStream( *maIt ).is();
+}
+
+bool StorageIterator::isStorage() const
+{
+ if( !isValid() )
+ return false;
+ StorageRef xStrg = mxStrg->openSubStorage( *maIt, false );
+ return xStrg && xStrg->isStorage();
+}
+
+bool StorageIterator::implIsValid() const
+{
+ return mxStrg && mxStrg->isStorage() && (maIt != maNames.end());
+}
+
+ObjectBase::~ObjectBase()
+{
+}
+
+void ObjectBase::construct( const ConfigRef& rxConfig )
+{
+ mxConfig = rxConfig;
+}
+
+void ObjectBase::construct( const ObjectBase& rParent )
+{
+ *this = rParent;
+}
+
+void ObjectBase::dump()
+{
+ if( isValid() )
+ implDump();
+}
+
+bool ObjectBase::implIsValid() const
+{
+ return isValid( mxConfig );
+}
+
+void ObjectBase::implDump()
+{
+}
+
+void StorageObjectBase::construct( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath )
+{
+ ObjectBase::construct( rParent );
+ mxStrg = rxStrg;
+ maSysPath = rSysPath;
+}
+
+void StorageObjectBase::construct( const ObjectBase& rParent )
+{
+ ObjectBase::construct( rParent );
+ if( ObjectBase::implIsValid() )
+ {
+ mxStrg = cfg().getRootStorage();
+ maSysPath = cfg().getSysFileName();
+ }
+}
+
+bool StorageObjectBase::implIsValid() const
+{
+ return mxStrg && !maSysPath.isEmpty() && ObjectBase::implIsValid();
+}
+
+void StorageObjectBase::implDump()
+{
+ bool bIsStrg = mxStrg->isStorage();
+ bool bIsRoot = mxStrg->isRootStorage();
+ Reference< XInputStream > xBaseStrm;
+ if( !bIsStrg )
+ xBaseStrm = mxStrg->openInputStream( OUString() );
+
+ OUString aSysOutPath = maSysPath;
+ if( bIsRoot ) try
+ {
+ aSysOutPath += OOX_DUMP_DUMPEXT;
+ Reference<XSimpleFileAccess3> xFileAccess(SimpleFileAccess::create(getContext()));
+ xFileAccess->kill( aSysOutPath );
+ }
+ catch( Exception& )
+ {
+ }
+
+ if( bIsStrg )
+ {
+ extractStorage( mxStrg, OUString(), aSysOutPath );
+ }
+ else if( xBaseStrm.is() )
+ {
+ BinaryInputStreamRef xInStrm( std::make_shared<BinaryXInputStream>( xBaseStrm, false ) );
+ xInStrm->seekToStart();
+ implDumpBaseStream( xInStrm, aSysOutPath );
+ }
+}
+
+void StorageObjectBase::implDumpStream( const Reference< XInputStream >&, const OUString&, const OUString&, const OUString& )
+{
+}
+
+void StorageObjectBase::implDumpStorage( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rSysPath )
+{
+ extractStorage( rxStrg, rStrgPath, rSysPath );
+}
+
+void StorageObjectBase::implDumpBaseStream( const BinaryInputStreamRef&, const OUString& )
+{
+}
+
+void StorageObjectBase::addPreferredStream( const String& rStrmName )
+{
+ if( rStrmName.has() )
+ maPreferred.emplace_back( rStrmName, false );
+}
+
+void StorageObjectBase::addPreferredStorage( const String& rStrgPath )
+{
+ if( rStrgPath.has() )
+ maPreferred.emplace_back( rStrgPath, true );
+}
+
+OUString StorageObjectBase::getSysFileName(
+ const OUString& rStrmName, std::u16string_view rSysOutPath )
+{
+ // encode all characters < 0x20
+ OUStringBuffer aBuffer;
+ StringHelper::appendEncString( aBuffer, rStrmName, false );
+
+ // replace all characters reserved in file system
+ OUString aFileName = aBuffer.makeStringAndClear();
+ static const sal_Unicode spcReserved[] = { '/', '\\', ':', '*', '?', '<', '>', '|' };
+ for(const sal_Unicode cChar : spcReserved)
+ aFileName = aFileName.replace(cChar, '_');
+
+ // build full path
+ return OUString::Concat(rSysOutPath) + "/" + aFileName;
+}
+
+void StorageObjectBase::extractStream( StorageBase& rStrg, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
+{
+ BinaryXInputStream aInStrm( rStrg.openInputStream( rStrmName ), true );
+ if( !aInStrm.isEof() )
+ {
+ BinaryXOutputStream aOutStrm( InputOutputHelper::openOutputStream( getContext(), rSysFileName ), true );
+ if( !aOutStrm.isEof() )
+ aInStrm.copyToStream( aOutStrm );
+ }
+ Reference< XInputStream > xDumpStrm = InputOutputHelper::openInputStream( getContext(), rSysFileName );
+ if( xDumpStrm.is() )
+ implDumpStream( xDumpStrm, rStrgPath, rStrmName, rSysFileName );
+}
+
+void StorageObjectBase::extractStorage( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rSysPath )
+{
+ // create directory in file system
+ ::osl::FileBase::RC eRes = ::osl::Directory::create( rSysPath );
+ if( (eRes != ::osl::FileBase::E_None) && (eRes != ::osl::FileBase::E_EXIST) )
+ return;
+
+ // process preferred storages and streams in root storage first
+ if( rStrgPath.isEmpty() )
+ {
+ for (auto const& elemPreferred : maPreferred)
+ extractItem( rxStrg, rStrgPath, elemPreferred.maName, rSysPath, elemPreferred.mbStorage, !elemPreferred.mbStorage );
+ }
+
+ // process children of the storage
+ for( StorageIterator aIt( rxStrg ); aIt.isValid(); ++aIt )
+ {
+ // skip processed preferred items
+ OUString aItemName = aIt.getName();
+ bool bFound = false;
+ if( rStrgPath.isEmpty() )
+ {
+ for (auto const& elemPreferred : maPreferred)
+ {
+ bFound = elemPreferred.maName == aItemName;
+ if (bFound)
+ break;
+ }
+ }
+ if( !bFound )
+ extractItem( rxStrg, rStrgPath, aItemName, rSysPath, aIt.isStorage(), aIt.isStream() );
+ }
+}
+
+void StorageObjectBase::extractItem( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rItemName, std::u16string_view rSysPath, bool bIsStrg, bool bIsStrm )
+{
+ OUString aSysFileName = getSysFileName( rItemName, rSysPath );
+ if( bIsStrg )
+ {
+ OUStringBuffer aStrgPath( rStrgPath );
+ StringHelper::appendToken( aStrgPath, rItemName, '/' );
+ implDumpStorage( rxStrg->openSubStorage( rItemName, false ), aStrgPath.makeStringAndClear(), aSysFileName );
+ }
+ else if( bIsStrm )
+ {
+ extractStream( *rxStrg, rStrgPath, rItemName, aSysFileName );
+ }
+}
+
+OutputObjectBase::~OutputObjectBase()
+{
+}
+
+void OutputObjectBase::construct( const ObjectBase& rParent, const OUString& rSysFileName )
+{
+ ObjectBase::construct( rParent );
+ if( ObjectBase::implIsValid() )
+ {
+ maSysFileName = rSysFileName;
+ mxOut = std::make_shared<Output>( getContext(), rSysFileName + OOX_DUMP_DUMPEXT );
+ }
+}
+
+void OutputObjectBase::construct( const OutputObjectBase& rParent )
+{
+ *this = rParent;
+}
+
+bool OutputObjectBase::implIsValid() const
+{
+ return isValid( mxOut ) && ObjectBase::implIsValid();
+}
+
+void OutputObjectBase::writeEmptyItem( const String& rName )
+{
+ ItemGuard aItem( mxOut, rName );
+}
+
+void OutputObjectBase::writeInfoItem( const String& rName, const String& rData )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeString( rData );
+}
+
+void OutputObjectBase::writeCharItem( const String& rName, sal_Unicode cData )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeChar( OOX_DUMP_STRQUOTE );
+ mxOut->writeChar( cData );
+ mxOut->writeChar( OOX_DUMP_STRQUOTE );
+}
+
+void OutputObjectBase::writeStringItem( const String& rName, const OUString& rData )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeAscii( "(len=" );
+ mxOut->writeDec( rData.getLength() );
+ mxOut->writeAscii( ")," );
+ OUStringBuffer aValue( rData.subView( 0, ::std::min( rData.getLength(), OOX_DUMP_MAXSTRLEN ) ) );
+ StringHelper::enclose( aValue, OOX_DUMP_STRQUOTE );
+ mxOut->writeString( aValue.makeStringAndClear() );
+ if( rData.getLength() > OOX_DUMP_MAXSTRLEN )
+ mxOut->writeAscii( ",cut" );
+}
+
+void OutputObjectBase::writeArrayItem( const String& rName, const sal_uInt8* pnData, std::size_t nSize, sal_Unicode cSep )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeArray( pnData, nSize, cSep );
+}
+
+void OutputObjectBase::writeDateTimeItem( const String& rName, const util::DateTime& rDateTime )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeDateTime( rDateTime );
+}
+
+void OutputObjectBase::writeGuidItem( const String& rName, const OUString& rGuid )
+{
+ ItemGuard aItem( mxOut, rName );
+ mxOut->writeString( rGuid );
+ aItem.cont();
+ mxOut->writeString( cfg().getStringOption( rGuid, OUString() ) );
+}
+
+InputObjectBase::~InputObjectBase()
+{
+}
+
+void InputObjectBase::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
+{
+ OutputObjectBase::construct( rParent, rSysFileName );
+ mxStrm = rxStrm;
+}
+
+void InputObjectBase::construct( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm )
+{
+ OutputObjectBase::construct( rParent );
+ mxStrm = rxStrm;
+}
+
+void InputObjectBase::construct( const InputObjectBase& rParent )
+{
+ *this = rParent;
+}
+
+bool InputObjectBase::implIsValid() const
+{
+ return mxStrm && OutputObjectBase::implIsValid();
+}
+
+void InputObjectBase::skipBlock( sal_Int64 nBytes, bool bShowSize )
+{
+ sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->size() );
+ if( mxStrm->tell() < nEndPos )
+ {
+ if( bShowSize )
+ writeDecItem( "skipped-data-size", static_cast< sal_uInt64 >( nEndPos - mxStrm->tell() ) );
+ mxStrm->seek( nEndPos );
+ }
+}
+
+void InputObjectBase::dumpRawBinary( sal_Int64 nBytes, bool bShowOffset, bool bStream )
+{
+ TableGuard aTabGuard( mxOut,
+ bShowOffset ? 12 : 0,
+ 3 * OOX_DUMP_BYTESPERLINE / 2 + 1,
+ 3 * OOX_DUMP_BYTESPERLINE / 2 + 1,
+ OOX_DUMP_BYTESPERLINE / 2 + 1 );
+
+ sal_Int64 nMaxShowSize = cfg().getIntOption< sal_Int64 >(
+ bStream ? "max-binary-stream-size" : "max-binary-data-size", SAL_MAX_INT64 );
+
+ bool bSeekable = mxStrm->size() >= 0;
+ sal_Int64 nEndPos = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->size() ) : 0;
+ sal_Int64 nDumpEnd = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nMaxShowSize, nEndPos ) : nMaxShowSize;
+ sal_Int64 nPos = bSeekable ? mxStrm->tell() : 0;
+ bool bLoop = true;
+
+ while( bLoop && (nPos < nDumpEnd) )
+ {
+ mxOut->writeHex( static_cast< sal_uInt32 >( nPos ) );
+ mxOut->tab();
+
+ sal_uInt8 pnLineData[ OOX_DUMP_BYTESPERLINE ];
+ sal_Int32 nLineSize = bSeekable ? ::std::min( static_cast< sal_Int32 >( nDumpEnd - mxStrm->tell() ), OOX_DUMP_BYTESPERLINE ) : OOX_DUMP_BYTESPERLINE;
+ sal_Int32 nReadSize = mxStrm->readMemory( pnLineData, nLineSize );
+ bLoop = nReadSize == nLineSize;
+ nPos += nReadSize;
+
+ if( nReadSize > 0 )
+ {
+ const sal_uInt8* pnByte = nullptr;
+ const sal_uInt8* pnEnd = nullptr;
+ for( pnByte = pnLineData, pnEnd = pnLineData + nReadSize; pnByte != pnEnd; ++pnByte )
+ {
+ if( (pnByte - pnLineData) == (OOX_DUMP_BYTESPERLINE / 2) ) mxOut->tab();
+ mxOut->writeHex( *pnByte, false );
+ mxOut->writeChar( ' ' );
+ }
+
+ aTabGuard.tab( 3 );
+ for( pnByte = pnLineData, pnEnd = pnLineData + nReadSize; pnByte != pnEnd; ++pnByte )
+ {
+ if( (pnByte - pnLineData) == (OOX_DUMP_BYTESPERLINE / 2) ) mxOut->tab();
+ mxOut->writeChar( static_cast< sal_Unicode >( (*pnByte < 0x20) ? '.' : *pnByte ) );
+ }
+ mxOut->newLine();
+ }
+ }
+
+ // skip undumped data
+ if( bSeekable )
+ skipBlock( nEndPos - mxStrm->tell() );
+}
+
+void InputObjectBase::dumpBinary( const String& rName, sal_Int64 nBytes, bool bShowOffset )
+{
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( rName );
+ writeDecItem( "size", nBytes );
+ }
+ IndentGuard aIndGuard( mxOut );
+ dumpRawBinary( nBytes, bShowOffset );
+}
+
+void InputObjectBase::dumpRemaining( sal_Int64 nBytes )
+{
+ if( nBytes > 0 )
+ {
+ if( cfg().getBoolOption( "show-trailing-unknown", true ) )
+ dumpBinary( "remaining-data", nBytes, false );
+ else
+ skipBlock( nBytes );
+ }
+}
+
+void InputObjectBase::dumpRemainingTo( sal_Int64 nPos )
+{
+ if( mxStrm->isEof() || (mxStrm->tell() > nPos) )
+ writeInfoItem( "stream-state", OOX_DUMP_ERR_STREAM );
+ else
+ dumpRemaining( nPos - mxStrm->tell() );
+ mxStrm->seek( nPos );
+}
+
+void InputObjectBase::dumpRemainingStream()
+{
+ dumpRemainingTo( mxStrm->size() );
+}
+
+void InputObjectBase::dumpArray( const String& rName, sal_Int32 nBytes, sal_Unicode cSep )
+{
+ sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->size() - mxStrm->tell(), 0, nBytes );
+ if( nDumpSize > OOX_DUMP_MAXARRAY )
+ {
+ dumpBinary( rName, nBytes, false );
+ }
+ else if( nDumpSize > 1 )
+ {
+ sal_uInt8 pnData[ OOX_DUMP_MAXARRAY ];
+ mxStrm->readMemory( pnData, nDumpSize );
+ writeArrayItem( rName, pnData, nDumpSize, cSep );
+ }
+ else if( nDumpSize == 1 )
+ dumpHex< sal_uInt8 >( rName );
+}
+
+sal_Unicode InputObjectBase::dumpUnicode( const String& rName )
+{
+ sal_uInt16 nChar = mxStrm->readuInt16();
+ sal_Unicode cChar = static_cast< sal_Unicode >( nChar );
+ writeCharItem( rName( "char" ), cChar );
+ return cChar;
+}
+
+OUString InputObjectBase::dumpCharArray( const String& rName, sal_Int32 nLen, rtl_TextEncoding eTextEnc, bool bHideTrailingNul )
+{
+ sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->size() - mxStrm->tell(), 0, nLen );
+ OUString aString;
+ if( nDumpSize > 0 )
+ {
+ ::std::vector< char > aBuffer( static_cast< std::size_t >( nLen ) + 1 );
+ sal_Int32 nCharsRead = mxStrm->readMemory(aBuffer.data(), nLen);
+ aBuffer[ nCharsRead ] = 0;
+ aString = OStringToOUString(std::string_view(aBuffer.data()), eTextEnc);
+ }
+ if( bHideTrailingNul )
+ aString = StringHelper::trimTrailingNul( aString );
+ writeStringItem( rName( "text" ), aString );
+ return aString;
+}
+
+OUString InputObjectBase::dumpUnicodeArray( const String& rName, sal_Int32 nLen, bool bHideTrailingNul )
+{
+ OUStringBuffer aBuffer;
+ for( sal_Int32 nIndex = 0; !mxStrm->isEof() && (nIndex < nLen); ++nIndex )
+ {
+ aBuffer.append( static_cast< sal_Unicode >( mxStrm->readuInt16() ) );
+ }
+ OUString aString = aBuffer.makeStringAndClear();
+ if( bHideTrailingNul )
+ aString = StringHelper::trimTrailingNul( aString );
+ writeStringItem( rName( "text" ), aString );
+ return aString;
+}
+
+util::DateTime InputObjectBase::dumpFileTime( const String& rName )
+{
+ util::DateTime aDateTime;
+
+ ItemGuard aItem( mxOut, rName( "file-time" ) );
+ sal_Int64 nFileTime = dumpDec< sal_Int64 >( EMPTY_STRING );
+ // file time is in 10^-7 seconds (100 nanoseconds), convert to nanoseconds
+ nFileTime *= 100;
+ // entire days
+ sal_Int64 nDays = nFileTime / sal_Int64( ::tools::Time::nanoSecPerDay );
+ // number of entire years
+ sal_Int64 nYears = (nDays - (nDays / (4 * 365)) + (nDays / (100 * 365)) - (nDays / (400 * 365))) / 365;
+ // remaining days in the year
+ sal_Int64 nDaysInYear = nDays - (nYears * 365 + nYears / 4 - nYears / 100 + nYears / 400);
+ // the year (file dates start from 1601-01-01)
+ aDateTime.Year = static_cast< sal_uInt16 >( 1601 + nYears );
+ // leap year?
+ bool bLeap = ((aDateTime.Year % 4 == 0) && (aDateTime.Year % 100 != 0)) || (aDateTime.Year % 400 == 0);
+ // static arrays with number of days in month
+ static const sal_Int64 spnDaysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ static const sal_Int64 spnDaysInMonthL[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ const sal_Int64* pnDaysInMonth = bLeap ? spnDaysInMonthL : spnDaysInMonth;
+ // the month
+ aDateTime.Month = 1;
+ while( nDaysInYear >= *pnDaysInMonth )
+ {
+ nDaysInYear -= *pnDaysInMonth++;
+ ++aDateTime.Month;
+ }
+ // the day
+ aDateTime.Day = static_cast< sal_uInt16 >( nDaysInYear + 1 );
+ // number of nanoseconds in the day
+ sal_Int64 nTimeInDay = nFileTime % sal_Int64( ::tools::Time::nanoSecPerDay );
+ // nanoseconds
+ aDateTime.NanoSeconds = static_cast< sal_uInt32 >( nTimeInDay % ::tools::Time::nanoSecPerSec );
+ nTimeInDay /= ::tools::Time::nanoSecPerSec;
+ // seconds
+ aDateTime.Seconds = static_cast< sal_uInt16 >( nTimeInDay % ::tools::Time::secondPerMinute );
+ nTimeInDay /= ::tools::Time::secondPerMinute;
+ // minutes
+ aDateTime.Minutes = static_cast< sal_uInt16 >( nTimeInDay % ::tools::Time::minutePerHour );
+ nTimeInDay /= ::tools::Time::minutePerHour;
+ // hours
+ aDateTime.Hours = static_cast< sal_uInt16 >( nTimeInDay );
+
+ writeDateTimeItem( EMPTY_STRING, aDateTime );
+ return aDateTime;
+}
+
+OUString InputObjectBase::dumpGuid( const String& rName )
+{
+ OUStringBuffer aBuffer;
+ sal_uInt32 nData32;
+ sal_uInt16 nData16;
+ sal_uInt8 nData8;
+
+ nData32 = mxStrm->readuInt32();
+ StringHelper::appendHex( aBuffer, nData32, false );
+ aBuffer.append( '-' );
+ nData16 = mxStrm->readuInt16();
+ StringHelper::appendHex( aBuffer, nData16, false );
+ aBuffer.append( '-' );
+ nData16 = mxStrm->readuInt16();
+ StringHelper::appendHex( aBuffer, nData16, false );
+ aBuffer.append( '-' );
+ nData8 = mxStrm->readuChar();
+ StringHelper::appendHex( aBuffer, nData8, false );
+ nData8 = mxStrm->readuChar( );
+ StringHelper::appendHex( aBuffer, nData8, false );
+ aBuffer.append( '-' );
+ for( int nIndex = 0; nIndex < 6; ++nIndex )
+ {
+ nData8 = mxStrm->readuChar( );
+ StringHelper::appendHex( aBuffer, nData8, false );
+ }
+ StringHelper::enclose( aBuffer, '{', '}' );
+ OUString aGuid = aBuffer.makeStringAndClear();
+ writeGuidItem( rName( "guid" ), aGuid );
+ return aGuid;
+}
+
+void InputObjectBase::dumpItem( const ItemFormat& rItemFmt )
+{
+ switch( rItemFmt.meDataType )
+ {
+ case DATATYPE_VOID: break;
+ case DATATYPE_INT8: dumpValue< sal_Int8 >( rItemFmt ); break;
+ case DATATYPE_UINT8: dumpValue< sal_uInt8 >( rItemFmt ); break;
+ case DATATYPE_INT16: dumpValue< sal_Int16 >( rItemFmt ); break;
+ case DATATYPE_UINT16: dumpValue< sal_uInt16 >( rItemFmt ); break;
+ case DATATYPE_INT32: dumpValue< sal_Int32 >( rItemFmt ); break;
+ case DATATYPE_UINT32: dumpValue< sal_uInt32 >( rItemFmt ); break;
+ case DATATYPE_INT64: dumpValue< sal_Int64 >( rItemFmt ); break;
+ case DATATYPE_UINT64: dumpValue< sal_uInt64 >( rItemFmt ); break;
+ case DATATYPE_FLOAT: dumpValue< float >( rItemFmt ); break;
+ case DATATYPE_DOUBLE: dumpValue< double >( rItemFmt ); break;
+ default:;
+ }
+}
+
+BinaryStreamObject::BinaryStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
+{
+ InputObjectBase::construct( rParent, rxStrm, rSysFileName );
+}
+
+void BinaryStreamObject::dumpBinaryStream( bool bShowOffset )
+{
+ mxStrm->seekToStart();
+ dumpRawBinary( mxStrm->size(), bShowOffset, true );
+ mxOut->emptyLine();
+}
+
+void BinaryStreamObject::implDump()
+{
+ dumpBinaryStream();
+}
+
+void TextStreamObjectBase::construct( const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc, const OUString& rSysFileName )
+{
+ InputObjectBase::construct( rParent, rxStrm, rSysFileName );
+ constructTextStrmObj( eTextEnc );
+}
+
+void TextStreamObjectBase::construct( const OutputObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc )
+{
+ InputObjectBase::construct( rParent, rxStrm );
+ constructTextStrmObj( eTextEnc );
+}
+
+bool TextStreamObjectBase::implIsValid() const
+{
+ return InputObjectBase::implIsValid() && mxTextStrm;
+}
+
+void TextStreamObjectBase::implDump()
+{
+ implDumpText( *mxTextStrm );
+}
+
+void TextStreamObjectBase::constructTextStrmObj( rtl_TextEncoding eTextEnc )
+{
+ if( mxStrm )
+ mxTextStrm = std::make_shared<TextInputStream>( getContext(), *mxStrm, eTextEnc );
+}
+
+TextLineStreamObject::TextLineStreamObject( const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc, const OUString& rSysFileName )
+{
+ TextStreamObjectBase::construct( rParent, rxStrm, eTextEnc, rSysFileName );
+}
+
+TextLineStreamObject::TextLineStreamObject( const OutputObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc )
+{
+ TextStreamObjectBase::construct( rParent, rxStrm, eTextEnc );
+}
+
+void TextLineStreamObject::implDumpText( TextInputStream& rTextStrm )
+{
+ sal_uInt32 nLine = 0;
+ while( !rTextStrm.isEof() )
+ {
+ OUString aLine = rTextStrm.readLine();
+ if( !rTextStrm.isEof() || !aLine.isEmpty() )
+ implDumpLine( aLine, ++nLine );
+ }
+}
+
+void TextLineStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 nLine )
+{
+ TableGuard aTabGuard( mxOut, 8 );
+ mxOut->writeDec( nLine, 6 );
+ mxOut->tab();
+ mxOut->writeString( rLine );
+ mxOut->newLine();
+}
+
+XmlStreamObject::XmlStreamObject( const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
+{
+ TextStreamObjectBase::construct( rParent, rxStrm, RTL_TEXTENCODING_UTF8, rSysFileName );
+}
+
+void XmlStreamObject::implDumpText( TextInputStream& rTextStrm )
+{
+ /* Buffers a start element and the following element text. Needed to dump
+ matching start/end elements and the element text on the same line. */
+ OUStringBuffer aOldStartElem;
+ // special handling for VML
+ bool bIsVml = o3tl::equalsIgnoreAsciiCase(InputOutputHelper::getFileNameExtension( maSysFileName ), u"vml");
+
+ while( !rTextStrm.isEof() )
+ {
+ // get the next element and the following element text from text stream
+ OUString aElem = rTextStrm.readToChar( '>', true ).trim();
+ OUString aText = rTextStrm.readToChar( '<', false );
+
+ // remove multiple whitespace from element
+ sal_Int32 nPos = 0;
+ while( nPos < aElem.getLength() )
+ {
+ while( (nPos < aElem.getLength()) && (aElem[ nPos ] >= 32) ) ++nPos;
+ if( nPos < aElem.getLength() )
+ aElem = aElem.subView( 0, nPos ) + OUStringChar(' ') + o3tl::trim(aElem.subView( nPos ));
+ ++nPos;
+ }
+
+ sal_Int32 nElemLen = aElem.getLength();
+ if( (nElemLen >= 2) && (aElem[ 0 ] == '<') && (aElem[ nElemLen - 1 ] == '>') )
+ {
+ // determine type of the element
+ bool bSimpleElem = (aElem[ 1 ] == '!') || (aElem[ 1 ] == '?') || (aElem[ nElemLen - 2 ] == '/') ||
+ (bIsVml && (nElemLen == 4) && (aElem[ 1 ] == 'b') && (aElem[ 2 ] == 'r'));
+ bool bStartElem = !bSimpleElem && (aElem[ 1 ] != '/');
+ bool bEndElem = !bSimpleElem && !bStartElem;
+
+ /* Start element or simple element: flush old start element and
+ its text from previous iteration, and start a new indentation
+ level for the new element. Trim whitespace and line breaks from
+ the text of the old start element. */
+ if( (bSimpleElem || bStartElem) && (aOldStartElem.getLength() > 0) )
+ {
+ mxOut->writeString( aOldStartElem.makeStringAndClear().trim() );
+ mxOut->newLine();
+ mxOut->incIndent();
+ }
+
+ /* Start element: remember it and its text, to be able to print the
+ matching end element on the same line in the next iteration. */
+ if( bStartElem )
+ {
+ aOldStartElem.append( aElem + aText );
+ }
+ else
+ {
+ /* End element: if a start element has been remembered in the
+ previous iteration, write it out here untrimmed, to show
+ all whitespace in the element text, and without trailing
+ line break. Code below will add the end element right after
+ it. Otherwise, return to previous indentation level. */
+ if( bEndElem )
+ {
+ if( aOldStartElem.getLength() == 0 )
+ mxOut->decIndent();
+ else
+ mxOut->writeString( aOldStartElem.makeStringAndClear() );
+ }
+
+ /* Write the element. Write following element text in a new
+ line, but only, if it does not contain of white space
+ entirely. */
+ mxOut->writeString( aElem );
+ mxOut->newLine();
+ if( !aText.trim().isEmpty() )
+ {
+ mxOut->writeString( aText );
+ mxOut->newLine();
+ }
+ }
+ }
+ }
+}
+
+void RecordObjectBase::construct( const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxBaseStrm, const OUString& rSysFileName,
+ const BinaryInputStreamRef& rxRecStrm, const String& rRecNames, const String& rSimpleRecs )
+{
+ InputObjectBase::construct( rParent, rxRecStrm, rSysFileName );
+ constructRecObjBase( rxBaseStrm, rRecNames, rSimpleRecs );
+}
+
+bool RecordObjectBase::implIsValid() const
+{
+ return mxBaseStrm && InputObjectBase::implIsValid();
+}
+
+void RecordObjectBase::implDump()
+{
+ NameListRef xRecNames = maRecNames.getNameList( cfg() );
+ ItemFormatMap aSimpleRecs( maSimpleRecs.getNameList( cfg() ) );
+
+ while( implStartRecord( *mxBaseStrm, mnRecPos, mnRecId, mnRecSize ) )
+ {
+ // record header
+ mxOut->emptyLine();
+ writeHeader();
+ implWriteExtHeader();
+ IndentGuard aIndGuard( mxOut );
+ sal_Int64 nRecPos = mxStrm->tell();
+
+ // record body
+ if( !mbBinaryOnly && cfg().hasName( xRecNames, mnRecId ) )
+ {
+ ::std::map< sal_Int64, ItemFormat >::const_iterator aIt = aSimpleRecs.find( mnRecId );
+ if( aIt != aSimpleRecs.end() )
+ dumpItem( aIt->second );
+ else
+ implDumpRecordBody();
+ }
+
+ // remaining undumped data
+ if( !mxStrm->isEof() && (mxStrm->tell() == nRecPos) )
+ dumpRawBinary( mnRecSize, false );
+ else
+ dumpRemainingTo( nRecPos + mnRecSize );
+ }
+}
+
+void RecordObjectBase::implWriteExtHeader()
+{
+}
+
+void RecordObjectBase::implDumpRecordBody()
+{
+}
+
+void RecordObjectBase::constructRecObjBase( const BinaryInputStreamRef& rxBaseStrm, const String& rRecNames, const String& rSimpleRecs )
+{
+ mxBaseStrm = rxBaseStrm;
+ maRecNames = rRecNames;
+ maSimpleRecs = rSimpleRecs;
+ mnRecPos = mnRecId = mnRecSize = 0;
+ mbBinaryOnly = false;
+ if( InputObjectBase::implIsValid() )
+ mbShowRecPos = cfg().getBoolOption( "show-record-position", true );
+}
+
+void RecordObjectBase::writeHeader()
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( "REC" );
+ if( mbShowRecPos && mxBaseStrm->isSeekable() )
+ writeShortHexItem( "pos", mnRecPos, "CONV-DEC" );
+ writeShortHexItem( "size", mnRecSize, "CONV-DEC" );
+ ItemGuard aItem( mxOut, "id" );
+ mxOut->writeShortHex( mnRecId );
+ addNameToItem( mnRecId, "CONV-DEC" );
+ addNameToItem( mnRecId, maRecNames );
+}
+
+void SequenceRecordObjectBase::construct( const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxBaseStrm, const OUString& rSysFileName,
+ const String& rRecNames, const String& rSimpleRecs )
+{
+ BinaryInputStreamRef xRecStrm( std::make_shared<SequenceInputStream>( *mxRecData ) );
+ RecordObjectBase::construct( rParent, rxBaseStrm, rSysFileName, xRecStrm, rRecNames, rSimpleRecs );
+}
+
+bool SequenceRecordObjectBase::implStartRecord( BinaryInputStream& rBaseStrm, sal_Int64& ornRecPos, sal_Int64& ornRecId, sal_Int64& ornRecSize )
+{
+ bool bValid = true;
+ if( rBaseStrm.isSeekable() )
+ {
+ ornRecPos = rBaseStrm.tell();
+ // do not try to overread seekable streams, may cause assertions
+ bValid = ornRecPos < rBaseStrm.size();
+ }
+
+ // read the record header
+ if( bValid )
+ bValid = implReadRecordHeader( rBaseStrm, ornRecId, ornRecSize ) && !rBaseStrm.isEof() && (0 <= ornRecSize) && (ornRecSize <= 0x00100000);
+
+ // read record contents into data sequence
+ if( bValid )
+ {
+ sal_Int32 nRecSize = static_cast< sal_Int32 >( ornRecSize );
+ mxRecData->realloc( nRecSize );
+ bValid = (nRecSize == 0) || (rBaseStrm.readData( *mxRecData, nRecSize ) == nRecSize);
+ mxStrm->seekToStart();
+ }
+ return bValid;
+}
+
+DumperBase::~DumperBase()
+{
+}
+
+bool DumperBase::isImportEnabled() const
+{
+ return !isValid() || cfg().isImportEnabled();
+}
+
+void DumperBase::construct( const ConfigRef& rxConfig )
+{
+ if( isValid( rxConfig ) && rxConfig->isDumperEnabled() )
+ ObjectBase::construct( rxConfig );
+}
+
+} // namespace oox
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/dump/dumperbase.ini b/oox/source/dump/dumperbase.ini
new file mode 100644
index 000000000..efb42651f
--- /dev/null
+++ b/oox/source/dump/dumperbase.ini
@@ -0,0 +1,412 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# dumper settings ============================================================
+#
+# Basic concepts
+#
+# - Character encoding of dumper ini files is UTF-8.
+# - Whitespace characters are generally stripped, e.g. at start and end of
+# lines, before/after equal signs, commas, etc.
+# - Comments start with the hash (#) or semicolon (;) character. Leading
+# whitespace characters are ignored.
+#
+# ----------------------------------------------------------------------------
+
+# Enable entire dumper (default=off). This option does not affect the option
+# 'enable-import'.
+# 0=off, 1=on
+enable-dumper=1
+
+# Enable import after dumping (default=on). Disabling this option allows
+# to dump a file without loading it. This option is independent from the
+# 'enable-dumper' option.
+# 0=off, 1=on
+enable-import=1
+
+# Maximum size of binary stream dumps (default=infinite).
+max-binary-stream-size=65536
+
+# Maximum size of binary data blocks in content dumps (default=infinite).
+max-binary-data-size=128
+
+# Shows unknown trailing data as binary dump (default=on).
+# 0=off, 1=on
+show-trailing-unknown=1
+
+# Shows the absolute stream position of records in the record header field
+# (default=on).
+# 0=off, 1=on
+show-record-position=0
+
+# name lists =================================================================
+#
+# Syntax descriptions
+#
+# - Optional items are enclosed in brackets [].
+# - Optional items that may be repeated are marked with an ellipsis (...).
+# - Items in a set to choose from are separated by vertical lines (|).
+# - <LISTNAME> denotes the name of a list. List names may consist of any non-
+# whitespace characters.
+# - <value>, <firstvalue>, <bitfield>, <bitmask> etc. denote integer values.
+# Decimal and hexadecimal notation is supported, using C/C++ notation.
+# - <bool> denotes a boolean value. Possible values are 0|1|false|true.
+# - <constname> denotes a literal name for a constant or bit.
+#
+# ----------------------------------------------------------------------------
+#
+# constlist
+#
+# Defines names for a list of specific values.
+#
+# Syntax:
+#
+# constlist = <LISTNAME>
+# default = <constname>
+# include = <LISTNAME>[,<LISTNAME>...]
+# exclude = <value>[,<value>...]
+# quote-names = <bool>
+# <value> = <constname>
+# end
+#
+# - default (optional): Declares <constname> as a default name for values not
+# specified in the name list. <constname> may be the empty string. If not
+# set, the literal string '?err:no-name' (unquoted) is the default name.
+# - include (optional): Includes the specified name list(s) into the own list.
+# - exclude (optional): Removes values from the name lists, useful e.g. after
+# a name list has been included.
+# - quote-names (optional): Specifies whether to return the contained names
+# enclosed in single quote (') characters. Default is false.
+#
+# The order of the declarations is important, later declarations may overwrite
+# names generated from earlier declarations.
+#
+# Example:
+#
+# constlist = EXAMPLE-CONSTLIST
+# 1 = my-value
+# include = OTHER-LIST
+# exclude = 2,3
+# 0x0004 = other-value
+# end
+#
+# - Defines the name 'my-value' for the constant 1.
+# - Includes 'OTHER-LIST' which may overwrite the name of the constant 1.
+# - Excludes the names of constants 2 and 3, which may have been included from
+# the name list 'OTHER-LIST'.
+# - Defines the name 'other-value' for the constant 4, which may overwrite the
+# name of this constant included from the name list 'OTHER-LIST'.
+#
+# ----------------------------------------------------------------------------
+#
+# multilist
+#
+# Defines names for contiguous ranges of values.
+#
+# Syntax:
+#
+# multilist = <LISTNAME>
+# default = <constname>
+# include = <LISTNAME>[,<LISTNAME>...]
+# exclude = <value>[,<value>...]
+# ignore-empty = <bool>
+# <firstvalue> = <constname>[,<constname>...]
+# end
+#
+# - default (optional): See constlist above.
+# - include (optional): See constlist above.
+# - exclude (optional): See constlist above.
+# - ignore-empty (optional): Specifies whether to skip empty names in a list.
+# - True = skips an empty entry, the default name will be generated.
+# - False = creates an empty string for the entry.
+# Default is true (skip empty entries).
+#
+# Examples:
+#
+# multilist = EXAMPLE-MULTILIST
+# 0 = value0,value1,,value3
+# 8 = value8
+# end
+#
+# - Defines the names 'value0' for the constant 0, 'value1' for the constant
+# 1, 'value3' for the constant 3, and 'value8' for the constant 8.
+#
+# multilist = EXAMPLE-MULTILIST-2
+# include = EXAMPLE-MULTILIST
+# ignore-empty = false
+# default = other
+# end
+#
+# - Same as example above (includes EXAMPLE-MULTILIST), but defines the empty
+# string for the constant 2. Other constants (less than 0 or greater than 3
+# and not equal to 8) get the default name 'other'.
+#
+# ----------------------------------------------------------------------------
+#
+# shortlist
+#
+# Defines names for a contiguous range of values. The entire list definition
+# is given in a single text line.
+#
+# Syntax:
+#
+# shortlist = <LISTNAME>,<firstvalue>,<constname>[,<constname>...]
+#
+# Uses default settings of the multi-list (i.e. skips empty entries).
+#
+# ----------------------------------------------------------------------------
+#
+# flagslist
+#
+# Defines names for single bits in a bit field.
+#
+# Syntax:
+#
+# flagslist = <LISTNAME>
+# include = <LISTNAME>[,<LISTNAME>...]
+# exclude = <bitfield>[,<bitfield>...]
+# ignore = <bitfield>
+# <bitmask> = <cname> | !<cname> | :<cname> | !<cname0>!<cname1>
+# end
+#
+# - include (optional): See constlist above.
+# - exclude (optional): See constlist above.
+# - ignore (optional): Specifies bits to be ignored. Bits without an explicit
+# name and not set in this declaration will be shown as unknown. Default is
+# to not ignore a bit.
+# - <bitmask>: The bit to be named. Must be a value with a single bit set.
+# - <cname> - Sets a name for the bit that will be shown if the bit is set.
+# Does not show anything if the bit is cleared.
+# - !<cname> - Sets a name for the bit that will be shown if the bit is
+# cleared. Does not show anything if the bit is set.
+# - :<cname> - Sets a name for the bit that will always be shown together
+# with the actual state of the bit, appended as ':on' or ':off'.
+# - !<cname0>!<cname1> - Sets a name for both the cleared bit (cname0), and
+# for the set bit (cname1).
+#
+# ----------------------------------------------------------------------------
+#
+# combilist
+#
+# Defines names for single bits and for embedded values in a bit field. This
+# is an extension of the flagslist described above.
+#
+# Syntax:
+#
+# combilist = <LISTNAME>
+# include = <LISTNAME>[,<LISTNAME>...]
+# exclude = <bitmask>[,<bitmask>...]
+# ignore = <bitfield>
+# <bitmask> = <cname> | !<cname> | :<cname> | !<cname0>!<cname1>
+# <bitfield> = <datatype>,<dataformat>,<bitfieldname>[,<LISTNAME>[,options...]]
+# end
+#
+# - include (optional): See constlist above.
+# - exclude (optional): See constlist above.
+# - ignore (optional): See flagslist above.
+# - <bitmask>: See flagslist above.
+# - <bitfield>: The mask of the embedded bitfield. Must be a value with
+# exactly one sequence of at least 2 consecutive bits.
+# - <datatype>: [u]int8 | [u]int16 | [u]int32 | [u]int64 | float | double
+# - <dataformat>: dec | hex | shorthex | bin | fix | bool
+# - <bitfieldname>: The name of the embedded bitfield.
+# - <LISTAME>: Optional name list with names for the values of the embedded
+# bitfield.
+# - options: Additional options for this bitfield:
+# - filter = <filterbitfield>~<filtervalue>: If set, the entire bitfield
+# will only be written, if the complete data item currently dumped
+# contains exactly the value specified in <filtervalue> in the bitfield
+# specified in <filterbitfield>. Otherwise, nothing is written. It is
+# possible to specify multiple filter rules for this bitfield. In that
+# case, the bitfield will be written, if at least one filter rule
+# applies for the current data item.
+# - noshift = <bool>: If set to 'true', the extracted value will be
+# shifted to the right (normalized). If set to 'false', the value will
+# be written unshifted. Default is 'true'.
+#
+# ----------------------------------------------------------------------------
+#
+# unitconverter
+#
+# Converts values and appends a unit name.
+#
+# Syntax:
+#
+# unitconverter = <LISTNAME>,[/]<factor>[,<unitname>]
+#
+# ----------------------------------------------------------------------------
+
+unitconverter=CONV-DEC,1
+unitconverter=CONV-PERCENT,1,%
+unitconverter=CONV-FLOAT-TO-PERC,100,%
+unitconverter=CONV-DEG,1,°
+unitconverter=CONV-HMM-TO-CM,/1000,cm
+unitconverter=CONV-INCH-TO-CM,2.54,cm
+unitconverter=CONV-PT-TO-CM,/28.346457,cm
+unitconverter=CONV-PT1616-TO-CM,/1857713.4,cm
+unitconverter=CONV-TWIP-TO-CM,/566.92913,cm
+unitconverter=CONV-TWIP-TO-PT,/20,pt
+unitconverter=CONV-EMU-TO-CM,/36000,cm
+
+constlist=BOOLEAN
+ 0=FALSE
+ default=TRUE
+end
+
+combilist=RK-FLAGS
+ 0x00000001=div-100
+ 0x00000002=integer
+ 0xFFFFFFFC=int32,hex,value
+end
+
+constlist=CHARSET
+ 0=win-1252-latin-1
+ 1=system-default
+ 2=symbol
+ 77=apple-roman
+ 128=win-932-japanese-shift-jis
+ 129=win-949-korean-hangul
+ 130=win-1361-korean-johab
+ 134=win-936-chinese-simplified-gbk
+ 136=win-950-chinese-traditional-big5
+ 161=win-1253-greek
+ 162=win-1254-turkish
+ 163=win-1258-vietnamese
+ 177=win-1255-hebrew
+ 178=win-1256-arabic
+ 186=win-1257-baltic
+ 204=win-1251-cyrillic
+ 222=win-874-thai
+ 238=win-1250-latin-2-central-european
+ 255=ibm-850-latin-1
+end
+
+combilist=FONT-PITCHFAMILY
+ 0x0F=uint8,dec,pitch,FONT-PITCH
+ 0xF0=uint8,dec,family,FONT-FAMILY
+end
+
+constlist=FONT-WEIGHT
+ 400=normal
+ 700=bold
+end
+
+shortlist=FONT-PITCH,0,unknown,fixed,variable
+shortlist=FONT-FAMILY,0,unknown,roman,swiss,modern,script,decorative
+
+constlist=CODEPAGES
+ 367=ascii
+ 437=ibm-437-us
+ 708=iso-8859-6
+ 720=ibm-720-arabic
+ 737=ibm-737-greek
+ 775=ibm-775-baltic
+ 850=ibm-850-latin-1
+ 852=ibm-852-latin-2-central-european
+ 855=ibm-855-cyrillic
+ 857=ibm-857-turkish
+ 858=ibm-858-multilingual-latin-1-with-euro
+ 860=ibm-860-portuguese
+ 861=ibm-861-icelandic
+ 862=ibm-862-hebrew
+ 863=ibm-863-canadian-french
+ 864=ibm-864-arabic
+ 865=ibm-865-nordic
+ 866=ibm-866-cyrillic-russian
+ 869=ibm-869-greek-modern
+ 874=win-874-thai
+ 932=win-932-japanese-shift-jis
+ 936=win-936-chinese-simplified-gbk
+ 949=win-949-korean-wansung
+ 950=win-950-chinese-traditional-big5
+ 1200=utf-16
+ 1250=win-1250-latin-2-central-european
+ 1251=win-1251-cyrillic
+ 1252=win-1252-latin-1
+ 1253=win-1253-greek
+ 1254=win-1254-turkish
+ 1255=win-1255-hebrew
+ 1256=win-1256-arabic
+ 1257=win-1257-baltic
+ 1258=win-1258-vietnamese
+ 1361=win-1361-korean-johab
+ 10000=apple-roman
+ 10001=apple-japanese
+ 10002=apple-chinese-traditional
+ 10003=apple-korean
+ 10004=apple-arabic
+ 10005=apple-hebrew
+ 10006=apple-greek
+ 10007=apple-cyrillic
+ 10008=apple-chinese-simplified
+ 10010=apple-romanian
+ 10017=apple-ukrainian
+ 10029=apple-central-european-with-euro
+ 10079=apple-icelandic
+ 10081=apple-turkish
+ 10082=apple-croatian
+ 20127=ascii
+ 20866=koi8-r
+ 21866=koi8-u
+ 28591=iso-8859-1
+ 28592=iso-8859-2
+ 28593=iso-8859-3
+ 28594=iso-8859-4
+ 28595=iso-8859-5
+ 28596=iso-8859-6
+ 28597=iso-8859-7
+ 28598=iso-8859-8
+ 28599=iso-8859-9
+ 28605=iso-8859-15
+ 32768=apple-romanian
+ 32769=win-1252-latin-1
+ 50220=iso-2022-jp
+ 50225=iso-2022-kr
+ 51932=euc-jp
+ 51936=euc-cn
+ 51949=euc-kr
+ 65000=utf-7
+ 65001=utf-8
+end
+
+multilist=COUNTRY
+ 1=usa,canada,latin-america,,,,russia
+ 20=egypt
+ 30=greece,netherlands,belgium,france,spain,,hungary,,,italy
+ 40=,switzerland,,austria,uk,denmark,sweden,norway,poland,germany
+ 50=,,mexico,,,brazil
+ 60=,australia,,,new-zealand,,thailand
+ 80=,japan,korea,,vietnam,,china
+ 90=turkey
+ 210=,,,algeria,,,morocco,,libya
+ 350=,portugal,,,iceland,,,,finland
+ 420=czech
+ 880=,,,,,,taiwan
+ 960=,lebanon,jordan,syria,iraq,kuwait,saudi-arabia
+ 970=,uae,israel,,qatar
+ 980=,iran
+end
+
+multilist=SYSTEMCOLOR
+ 0x00=scrollbar,desktop,active-title,inactive-title,menu,window-back,window-frame,menu-text
+ 0x08=window-text,active-title-text,active-border,inactive-border,app-workspace,highlight,highlight-text,button-face
+ 0x10=button-shadow,disabled-text,button-text,inactive-title-text,button-highlight,button-dark-shadow,button-light-shadow,tooltip-text
+ 0x18=tooltip-back,,hot-light,active-title-2,inactive-title-2,menu-highlight,menubar
+end
+
+# ============================================================================
diff --git a/oox/source/dump/oledumper.cxx b/oox/source/dump/oledumper.cxx
new file mode 100644
index 000000000..92e67c045
--- /dev/null
+++ b/oox/source/dump/oledumper.cxx
@@ -0,0 +1,2085 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <oox/dump/oledumper.hxx>
+
+#include <rtl/tencinfo.h>
+#include <o3tl/string_view.hxx>
+#include <oox/ole/vbainputstream.hxx>
+
+#ifdef DBG_UTIL
+
+namespace oox::dump {
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::uno;
+
+OUString OleInputObjectBase::dumpAnsiString32( const String& rName )
+{
+ return dumpCharArray( rName, mxStrm->readInt32(), RTL_TEXTENCODING_MS_1252 );
+}
+
+OUString OleInputObjectBase::dumpUniString32( const String& rName )
+{
+ return dumpUnicodeArray( rName, mxStrm->readInt32() );
+}
+
+sal_Int32 OleInputObjectBase::dumpStdClipboardFormat( const String& rName )
+{
+ return dumpDec< sal_Int32 >( rName( "clipboard-format" ), "OLE-STD-CLIPBOARD-FORMAT" );
+}
+
+OUString OleInputObjectBase::dumpAnsiString32OrStdClip( const String& rName )
+{
+ sal_Int32 nLen = mxStrm->readInt32();
+ return (nLen < 0) ? OUString::number( dumpStdClipboardFormat( rName ) ) : dumpCharArray( rName, nLen, RTL_TEXTENCODING_MS_1252 );
+}
+
+OUString OleInputObjectBase::dumpUniString32OrStdClip( const String& rName )
+{
+ sal_Int32 nLen = mxStrm->readInt32();
+ return (nLen < 0) ? OUString::number( dumpStdClipboardFormat( rName ) ) : dumpUnicodeArray( rName, nLen );
+}
+
+void OleInputObjectBase::writeOleColorItem( const String& rName, sal_uInt32 nColor )
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeHexItem( rName, nColor, "OLE-COLOR" );
+}
+
+sal_uInt32 OleInputObjectBase::dumpOleColor( const String& rName )
+{
+ sal_uInt32 nOleColor = mxStrm->readuInt32();
+ writeOleColorItem( rName, nOleColor );
+ return nOleColor;
+}
+
+StdFontObject::StdFontObject( const InputObjectBase& rParent )
+{
+ construct( rParent );
+}
+
+void StdFontObject::implDump()
+{
+ dumpDec< sal_uInt8 >( "version" );
+ dumpDec< sal_uInt16 >( "charset", "CHARSET" );
+ dumpHex< sal_uInt8 >( "flags", "STDFONT-FLAGS" );
+ dumpDec< sal_uInt16 >( "weight", "FONT-WEIGHT" );
+ dumpDec< sal_uInt32 >( "height", "STDFONT-HEIGHT" );
+ dumpCharArray( "name", mxStrm->readuInt8(), RTL_TEXTENCODING_ASCII_US );
+}
+
+StdPicObject::StdPicObject( const InputObjectBase& rParent )
+{
+ construct( rParent );
+}
+
+void StdPicObject::implDump()
+{
+ dumpHex< sal_uInt32 >( "identifier", "STDPIC-ID" );
+ sal_uInt32 nSize = dumpHex< sal_uInt32 >( "image-size", "CONV-DEC" );
+ dumpBinary( "image-data", nSize );
+}
+
+OleStreamObject::OleStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
+{
+ construct( rParent, rxStrm, rSysFileName );
+}
+
+OleCompObjObject::OleCompObjObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName ) :
+ OleStreamObject( rParent, rxStrm, rSysFileName )
+{
+}
+
+void OleCompObjObject::implDump()
+{
+ dumpUnused( 4 );
+ dumpDec< sal_uInt32 >( "version" );
+ dumpUnused( 20 );
+ dumpAnsiString32( "ansi-display-name" );
+ dumpAnsiString32OrStdClip( "ansi-clipboard-format" );
+ if( mxStrm->getRemaining() >= 4 )
+ {
+ sal_Int32 nLen = mxStrm->readInt32();
+ if( (0 <= nLen) && (nLen <= 40) )
+ {
+ dumpCharArray( "ansi-unused", nLen, RTL_TEXTENCODING_MS_1252 );
+ if( (mxStrm->getRemaining() >= 4) && (dumpHex< sal_Int32 >( "unicode-marker" ) == 0x71B239F4) )
+ {
+ dumpUniString32( "unicode-display-name" );
+ dumpUniString32OrStdClip( "unicode-clipboard-format" );
+ dumpUniString32( "unicode-unused" );
+ }
+ }
+ else
+ writeDecItem( "length", nLen );
+ }
+ dumpRemainingStream();
+}
+
+namespace {
+
+const sal_Int32 OLEPROP_ID_DICTIONARY = 0;
+const sal_Int32 OLEPROP_ID_CODEPAGE = 1;
+
+const sal_uInt16 OLEPROP_TYPE_INT16 = 2;
+const sal_uInt16 OLEPROP_TYPE_INT32 = 3;
+const sal_uInt16 OLEPROP_TYPE_FLOAT = 4;
+const sal_uInt16 OLEPROP_TYPE_DOUBLE = 5;
+const sal_uInt16 OLEPROP_TYPE_DATE = 7;
+const sal_uInt16 OLEPROP_TYPE_STRING = 8;
+const sal_uInt16 OLEPROP_TYPE_STATUS = 10;
+const sal_uInt16 OLEPROP_TYPE_BOOL = 11;
+const sal_uInt16 OLEPROP_TYPE_VARIANT = 12;
+const sal_uInt16 OLEPROP_TYPE_INT8 = 16;
+const sal_uInt16 OLEPROP_TYPE_UINT8 = 17;
+const sal_uInt16 OLEPROP_TYPE_UINT16 = 18;
+const sal_uInt16 OLEPROP_TYPE_UINT32 = 19;
+const sal_uInt16 OLEPROP_TYPE_INT64 = 20;
+const sal_uInt16 OLEPROP_TYPE_UINT64 = 21;
+const sal_uInt16 OLEPROP_TYPE_STRING8 = 30;
+const sal_uInt16 OLEPROP_TYPE_STRING16 = 31;
+const sal_uInt16 OLEPROP_TYPE_FILETIME = 64;
+const sal_uInt16 OLEPROP_TYPE_BLOB = 65;
+const sal_uInt16 OLEPROP_TYPE_STREAM = 66;
+const sal_uInt16 OLEPROP_TYPE_STORAGE = 67;
+const sal_uInt16 OLEPROP_TYPE_CLIPFMT = 71;
+
+const sal_uInt16 OLEPROP_TYPE_SIMPLE = 0x0000;
+const sal_uInt16 OLEPROP_TYPE_VECTOR = 0x1000;
+const sal_uInt16 OLEPROP_TYPE_ARRAY = 0x2000;
+
+const sal_uInt16 CODEPAGE_UNICODE = 1200;
+
+const sal_uInt32 AX_STRING_COMPRESSED = 0x80000000;
+
+} // namespace
+
+OlePropertyStreamObject::OlePropertyStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
+{
+ construct( rParent, rxStrm, rSysFileName );
+}
+
+void OlePropertyStreamObject::implDump()
+{
+ OUStringVector aGuidVec;
+ ::std::vector< sal_uInt32 > aStartPosVec;
+
+ // dump header
+ writeEmptyItem( "HEADER" );
+ {
+ IndentGuard aIndGuard( mxOut );
+ dumpHex< sal_uInt16 >( "byte-order", "OLEPROP-BYTE-ORDER" );
+ dumpDec< sal_uInt16 >( "version" );
+ dumpDec< sal_uInt16 >( "os-minor" );
+ dumpDec< sal_uInt16 >( "os-type", "OLEPROP-OSTYPE" );
+ dumpGuid( "guid" );
+ sal_Int32 nSectCount = dumpDec< sal_Int32 >( "section-count" );
+
+ // dump table of section positions
+ {
+ TableGuard aTabGuard( mxOut, 15, 60 );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nSectIdx = 0; !mxStrm->isEof() && (nSectIdx < nSectCount); ++nSectIdx )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( "#section" );
+ aGuidVec.push_back( dumpGuid( "guid" ) );
+ aStartPosVec.push_back( dumpHex< sal_uInt32 >( "start-pos", "CONV-DEC" ) );
+ }
+ }
+ }
+ mxOut->emptyLine();
+
+ // dump sections
+ for( size_t nSectIdx = 0; !mxStrm->isEof() && (nSectIdx < aStartPosVec.size()); ++nSectIdx )
+ dumpSection( aGuidVec[ nSectIdx ], aStartPosVec[ nSectIdx ] );
+}
+
+void OlePropertyStreamObject::dumpSection( const OUString& rGuid, sal_uInt32 nStartPos )
+{
+ // property ID names
+ mxPropIds = cfg().createNameList< ConstList >( "OLEPROP-IDS" );
+ OUString aGuidName = cfg().getStringOption( rGuid, OUString() );
+ if ( aGuidName == "GlobalDocProp" )
+ mxPropIds->includeList( cfg().getNameList( "OLEPROP-GLOBALIDS" ) );
+ else if ( aGuidName == "BuiltinDocProp" )
+ mxPropIds->includeList( cfg().getNameList( "OLEPROP-BUILTINIDS" ) );
+ else
+ mxPropIds->includeList( cfg().getNameList( "OLEPROP-BASEIDS" ) );
+
+ // property ID/position map
+ typedef ::std::map< sal_Int32, sal_uInt32 > PropertyPosMap;
+ PropertyPosMap aPropMap;
+
+ // dump section header line
+ writeSectionHeader( rGuid, nStartPos );
+
+ // seek to section
+ IndentGuard aIndGuard( mxOut );
+ if( startElement( nStartPos ) )
+ {
+ // dump section header
+ dumpDec< sal_Int32 >( "size" );
+ sal_Int32 nPropCount = dumpDec< sal_Int32 >( "property-count" );
+
+ // dump table of property positions
+ {
+ TableGuard aTabGuard( mxOut, 15, 25 );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nPropIdx = 0; !mxStrm->isEof() && (nPropIdx < nPropCount); ++nPropIdx )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( "#property" );
+ sal_Int32 nPropId = dumpDec< sal_Int32 >( "id", mxPropIds );
+ sal_uInt32 nPropPos = nStartPos + dumpHex< sal_uInt32 >( "start-pos", "CONV-DEC" );
+ aPropMap[ nPropId ] = nPropPos;
+ }
+ }
+ }
+ mxOut->emptyLine();
+
+ // code page property
+ meTextEnc = RTL_TEXTENCODING_MS_1252;
+ mbIsUnicode = false;
+ PropertyPosMap::iterator aCodePageIt = aPropMap.find( OLEPROP_ID_CODEPAGE );
+ if( aCodePageIt != aPropMap.end() )
+ {
+ dumpCodePageProperty( aCodePageIt->second );
+ aPropMap.erase( aCodePageIt );
+ }
+
+ // dictionary property
+ PropertyPosMap::iterator aDictIt = aPropMap.find( OLEPROP_ID_DICTIONARY );
+ if( aDictIt != aPropMap.end() )
+ {
+ dumpDictionaryProperty( aDictIt->second );
+ aPropMap.erase( aDictIt );
+ }
+
+ // other properties
+ for (auto const& elem : aPropMap)
+ dumpProperty( elem.first, elem.second );
+
+ // remove the user defined list of property ID names
+ cfg().eraseNameList( "OLEPROP-IDS" );
+}
+
+void OlePropertyStreamObject::dumpProperty( sal_Int32 nPropId, sal_uInt32 nStartPos )
+{
+ writePropertyHeader( nPropId, nStartPos );
+ IndentGuard aIndGuard( mxOut );
+ if( startElement( nStartPos ) )
+ dumpPropertyContents( nPropId );
+ mxOut->emptyLine();
+}
+
+void OlePropertyStreamObject::dumpCodePageProperty( sal_uInt32 nStartPos )
+{
+ writePropertyHeader( OLEPROP_ID_CODEPAGE, nStartPos );
+ IndentGuard aIndGuard( mxOut );
+ if( startElement( nStartPos ) )
+ {
+ sal_uInt16 nType = dumpPropertyType();
+ if( nType == OLEPROP_TYPE_INT16 )
+ {
+ sal_uInt16 nCodePage = dumpDec< sal_uInt16 >( "codepage", "CODEPAGES" );
+ rtl_TextEncoding eNewTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage );
+ if( eNewTextEnc != RTL_TEXTENCODING_DONTKNOW )
+ meTextEnc = eNewTextEnc;
+ mbIsUnicode = nCodePage == CODEPAGE_UNICODE;
+ }
+ else
+ dumpPropertyContents( OLEPROP_ID_CODEPAGE );
+ }
+ mxOut->emptyLine();
+}
+
+void OlePropertyStreamObject::dumpDictionaryProperty( sal_uInt32 nStartPos )
+{
+ writePropertyHeader( OLEPROP_ID_DICTIONARY, nStartPos );
+ IndentGuard aIndGuard( mxOut );
+ if( startElement( nStartPos ) )
+ {
+ sal_Int32 nCount = dumpDec< sal_Int32 >( "count" );
+ for( sal_Int32 nIdx = 0; !mxStrm->isEof() && (nIdx < nCount); ++nIdx )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ TableGuard aTabGuard( mxOut, 10, 20 );
+ sal_Int32 nId = dumpDec< sal_Int32 >( "id" );
+ OUString aName = dumpString8( "name" );
+ if( mxPropIds )
+ mxPropIds->setName( nId, aName );
+ }
+ }
+ mxOut->emptyLine();
+}
+
+sal_uInt16 OlePropertyStreamObject::dumpPropertyContents( sal_Int32 nPropId )
+{
+ sal_uInt16 nType = dumpPropertyType();
+ sal_uInt16 nBaseType = static_cast< sal_uInt16 >( nType & 0x0FFF );
+ sal_uInt16 nArrayType = static_cast< sal_uInt16 >( nType & 0xF000 );
+ switch( nArrayType )
+ {
+ case OLEPROP_TYPE_SIMPLE: dumpPropertyValue( nPropId, nBaseType ); break;
+ case OLEPROP_TYPE_VECTOR: dumpPropertyVector( nPropId, nBaseType ); break;
+ case OLEPROP_TYPE_ARRAY: /*TODO*/; break;
+ }
+ return nType;
+}
+
+void OlePropertyStreamObject::dumpPropertyValue( sal_Int32 nPropId, sal_uInt16 nBaseType )
+{
+ switch( nBaseType )
+ {
+ case OLEPROP_TYPE_INT16: dumpDec< sal_Int16 >( "value" ); break;
+ case OLEPROP_TYPE_INT32: dumpDec< sal_Int32 >( "value" ); break;
+ case OLEPROP_TYPE_FLOAT: dumpDec< float >( "value" ); break;
+ case OLEPROP_TYPE_DOUBLE: dumpDec< double >( "value" ); break;
+ case OLEPROP_TYPE_DATE: dumpDec< double >( "date" ); break;
+ case OLEPROP_TYPE_STRING: dumpString8( "value" ); break;
+ case OLEPROP_TYPE_STATUS: dumpHex< sal_Int32 >( "status" ); break;
+ case OLEPROP_TYPE_BOOL: dumpBool< sal_Int16 >( "value" ); break;
+ case OLEPROP_TYPE_VARIANT: dumpPropertyContents( nPropId ); break;
+ case OLEPROP_TYPE_INT8: dumpDec< sal_Int8 >( "value" ); break;
+ case OLEPROP_TYPE_UINT8: dumpDec< sal_uInt8 >( "value" ); break;
+ case OLEPROP_TYPE_UINT16: dumpDec< sal_uInt16 >( "value" ); break;
+ case OLEPROP_TYPE_UINT32: dumpDec< sal_uInt32 >( "value" ); break;
+ case OLEPROP_TYPE_INT64: dumpDec< sal_Int64 >( "value" ); break;
+ case OLEPROP_TYPE_UINT64: dumpDec< sal_uInt64 >( "value" ); break;
+ case OLEPROP_TYPE_STRING8: dumpString8( "value" ); break;
+ case OLEPROP_TYPE_STRING16: dumpString16( "value" ); break;
+ case OLEPROP_TYPE_FILETIME: dumpFileTime( "file-time" ); break;
+ case OLEPROP_TYPE_BLOB: dumpBlob( nPropId, "data" ); break;
+ case OLEPROP_TYPE_STREAM: dumpString8( "stream-name" ); break;
+ case OLEPROP_TYPE_STORAGE: dumpString8( "storage-name" ); break;
+ case OLEPROP_TYPE_CLIPFMT: dumpBlob( nPropId, "clip-data" ); break;
+ }
+}
+
+void OlePropertyStreamObject::dumpPropertyVector( sal_Int32 nPropId, sal_uInt16 nBaseType )
+{
+ sal_Int32 nElemCount = dumpDec< sal_Int32 >( "element-count" );
+ for( sal_Int32 nElemIdx = 0; !mxStrm->isEof() && (nElemIdx < nElemCount); ++nElemIdx )
+ {
+ mxOut->resetItemIndex( nElemIdx );
+ writeEmptyItem( "#element" );
+ IndentGuard aIndGuard( mxOut );
+ dumpPropertyValue( nPropId, nBaseType );
+ }
+}
+
+sal_uInt16 OlePropertyStreamObject::dumpPropertyType()
+{
+ return static_cast< sal_uInt16 >( dumpHex< sal_Int32 >( "type", "OLEPROP-TYPE" ) & 0xFFFF );
+}
+
+void OlePropertyStreamObject::dumpBlob( sal_Int32 nPropId, const String& rName )
+{
+ sal_Int32 nSize = dumpDec< sal_Int32 >( "data-size" );
+ if( nSize > 0 )
+ {
+ OUString aPropName = mxPropIds->getName( cfg(), nPropId );
+ if( aPropName == "'_PID_HLINKS'" )
+ dumpHlinks( nSize );
+ else
+ dumpBinary( rName, nSize );
+ }
+}
+
+OUString OlePropertyStreamObject::dumpString8( const String& rName )
+{
+ sal_Int32 nLen = dumpDec< sal_Int32 >( "string-len" );
+ return mbIsUnicode ? dumpCharArray16( rName, nLen ) : dumpCharArray8( rName, nLen );
+}
+
+OUString OlePropertyStreamObject::dumpCharArray8( const String& rName, sal_Int32 nLen )
+{
+ sal_Int32 nNewLen = getLimitedValue< sal_Int32, sal_Int32 >( nLen, 0, 1024 );
+ OUString aData = mxStrm->readCharArrayUC( nNewLen, meTextEnc );
+ writeStringItem( rName, aData );
+ return aData;
+}
+
+OUString OlePropertyStreamObject::dumpString16( const String& rName )
+{
+ sal_Int32 nLen = dumpDec< sal_Int32 >( "string-len" );
+ return dumpCharArray16( rName, nLen );
+}
+
+OUString OlePropertyStreamObject::dumpCharArray16( const String& rName, sal_Int32 nLen )
+{
+ sal_Int32 nNewLen = getLimitedValue< sal_Int32, sal_Int32 >( nLen, 0, 1024 );
+ OUString aData = mxStrm->readUnicodeArray( nNewLen );
+ writeStringItem( rName, aData );
+ if( nNewLen & 1 ) dumpUnused( 2 ); // always padding to 32bit
+ return aData;
+}
+
+bool OlePropertyStreamObject::dumpTypedProperty( const String& rName, sal_uInt16 nExpectedType )
+{
+ writeEmptyItem( rName );
+ IndentGuard aIndGuard( mxOut );
+ return (dumpPropertyContents( -1 ) == nExpectedType) && !mxStrm->isEof();
+}
+
+void OlePropertyStreamObject::dumpHlinks( sal_Int32 nSize )
+{
+ sal_Int64 nEndPos = mxStrm->tell() + nSize;
+ sal_Int32 nCount = dumpDec< sal_Int32 >( "property-count" );
+ bool bValid = true;
+ for( sal_Int32 nHlinkIndex = 0, nHlinkCount = nCount / 6; bValid && !mxStrm->isEof() && (nHlinkIndex < nHlinkCount); ++nHlinkIndex )
+ {
+ writeEmptyItem( "HYPERLINK" );
+ IndentGuard aIndGuard( mxOut );
+ bValid =
+ dumpTypedProperty( "hash", OLEPROP_TYPE_INT32 ) &&
+ dumpTypedProperty( "app", OLEPROP_TYPE_INT32 ) &&
+ dumpTypedProperty( "shape-id", OLEPROP_TYPE_INT32 ) &&
+ dumpTypedProperty( "info", OLEPROP_TYPE_INT32 ) &&
+ dumpTypedProperty( "target", OLEPROP_TYPE_STRING16 ) &&
+ dumpTypedProperty( "location", OLEPROP_TYPE_STRING16 );
+ }
+ dumpRemainingTo( nEndPos );
+}
+
+bool OlePropertyStreamObject::startElement( sal_uInt32 nStartPos )
+{
+ mxStrm->seek( nStartPos );
+ if( mxStrm->isEof() )
+ writeInfoItem( "stream-state", OOX_DUMP_ERR_STREAM );
+ return !mxStrm->isEof();
+}
+
+void OlePropertyStreamObject::writeSectionHeader( const OUString& rGuid, sal_uInt32 nStartPos )
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( "SECTION" );
+ writeHexItem( "pos", nStartPos, "CONV-DEC" );
+ writeGuidItem( "guid", rGuid );
+}
+
+void OlePropertyStreamObject::writePropertyHeader( sal_Int32 nPropId, sal_uInt32 nStartPos )
+{
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( "PROPERTY" );
+ writeHexItem( "pos", nStartPos, "CONV-DEC" );
+ writeDecItem( "id", nPropId, mxPropIds );
+}
+
+OleStorageObject::OleStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath )
+{
+ construct( rParent, rxStrg, rSysPath );
+}
+
+void OleStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& /*rStrgPath*/, const OUString& rStrmName, const OUString& rSysFileName )
+{
+ if ( rStrmName == "\001CompObj" )
+ OleCompObjObject( *this, rxStrm, rSysFileName ).dump();
+ else if( rStrmName == "\005SummaryInformation" || rStrmName == "\005DocumentSummaryInformation" )
+ OlePropertyStreamObject( *this, rxStrm, rSysFileName ).dump();
+ else
+ BinaryStreamObject( *this, rxStrm, rSysFileName ).dump();
+}
+
+ComCtlObjectBase::ComCtlObjectBase( const InputObjectBase& rParent,
+ sal_uInt32 nDataId5, sal_uInt32 nDataId6, sal_uInt16 nVersion, bool bCommonPart, bool bComplexPart ) :
+ mnDataId5( nDataId5 ),
+ mnDataId6( nDataId6 ),
+ mnVersion( nVersion ),
+ mbCommonPart( bCommonPart ),
+ mbComplexPart( bComplexPart )
+{
+ construct( rParent );
+}
+
+void ComCtlObjectBase::implDump()
+{
+ sal_uInt32 nCommonSize = 0;
+ dumpComCtlSize() && dumpComCtlData( nCommonSize ) && (!mbCommonPart || dumpComCtlCommon( nCommonSize )) && (!mbComplexPart || dumpComCtlComplex());
+}
+
+void ComCtlObjectBase::implDumpCommonExtra( sal_Int64 /*nEndPos*/ )
+{
+}
+
+void ComCtlObjectBase::implDumpCommonTrailing()
+{
+}
+
+bool ComCtlObjectBase::dumpComCtlHeader( sal_uInt32 nExpId, sal_uInt16 nExpMajor, sal_uInt16 nExpMinor )
+{
+ // no idea if all this is correct...
+ sal_uInt32 nId = dumpHex< sal_uInt32 >( "header-id", "COMCTL-HEADER-IDS" );
+ ItemGuard aItem( mxOut, "version" );
+ sal_uInt16 nMinor = mxStrm->readuInt16();
+ sal_uInt16 nMajor = mxStrm->readuInt16();
+ mxOut->writeDec( nMajor );
+ mxOut->writeChar( '.' );
+ mxOut->writeDec( nMinor );
+ return !mxStrm->isEof() && (nId == nExpId) && ((nExpMajor == SAL_MAX_UINT16) || (nExpMajor == nMajor)) && ((nExpMinor == SAL_MAX_UINT16) || (nExpMinor == nMinor));
+}
+
+bool ComCtlObjectBase::dumpComCtlSize()
+{
+ if( dumpComCtlHeader( 0x12344321, 0, 8 ) )
+ {
+ IndentGuard aIndGuard( mxOut );
+ dumpDec< sal_Int32 >( "width", "CONV-HMM-TO-CM" );
+ dumpDec< sal_Int32 >( "height", "CONV-HMM-TO-CM" );
+ return !mxStrm->isEof();
+ }
+ return false;
+}
+
+bool ComCtlObjectBase::dumpComCtlData( sal_uInt32& ornCommonPartSize )
+{
+ if( dumpComCtlHeader( (mnVersion == 5) ? mnDataId5 : mnDataId6, mnVersion ) )
+ {
+ IndentGuard aIndGuard( mxOut );
+ if( mbCommonPart )
+ ornCommonPartSize = dumpDec< sal_uInt32 >( "common-part-size" );
+ implDumpProperties();
+ return !mxStrm->isEof();
+ }
+ return false;
+}
+
+bool ComCtlObjectBase::dumpComCtlCommon( sal_uInt32 nPartSize )
+{
+ sal_Int64 nEndPos = mxStrm->tell() + nPartSize;
+ if( (nPartSize >= 16) && dumpComCtlHeader( 0xABCDEF01, 5, 0 ) )
+ {
+ IndentGuard aIndGuard( mxOut );
+ dumpUnknown( 4 );
+ dumpHex< sal_uInt32 >( "common-flags", "COMCTL-COMMON-FLAGS" );
+ implDumpCommonExtra( nEndPos );
+ dumpRemainingTo( nEndPos );
+ implDumpCommonTrailing();
+ return !mxStrm->isEof();
+ }
+ return false;
+}
+
+bool ComCtlObjectBase::dumpComCtlComplex()
+{
+ if( dumpComCtlHeader( 0xBDECDE1F, 5, 1 ) )
+ {
+ IndentGuard aIndGuard( mxOut );
+ sal_uInt32 nFlags = dumpHex< sal_uInt32 >( "comctl-complex-flags", "COMCTL-COMPLEX-FLAGS" );
+ if( !mxStrm->isEof() && (nFlags & 0x01) )
+ {
+ writeEmptyItem( "font" );
+ IndentGuard aIndGuard2( mxOut );
+ OUString aClassName = cfg().getStringOption( dumpGuid(), OUString() );
+ if ( aClassName == "StdFont" )
+ StdFontObject( *this ).dump();
+ }
+ if( !mxStrm->isEof() && (nFlags & 0x02) )
+ {
+ writeEmptyItem( "mouse-icon" );
+ IndentGuard aIndGuard2( mxOut );
+ OUString aClassName = cfg().getStringOption( dumpGuid(), OUString() );
+ if ( aClassName == "StdPic" )
+ StdPicObject( *this ).dump();
+ }
+ return !mxStrm->isEof();
+ }
+ return false;
+}
+
+ComCtlScrollBarObject::ComCtlScrollBarObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
+ ComCtlObjectBase( rParent, SAL_MAX_UINT32, 0x99470A83, nVersion, true, true )
+{
+}
+
+void ComCtlScrollBarObject::implDumpProperties()
+{
+ dumpHex< sal_uInt32 >( "flags", "COMCTL-SCROLLBAR-FLAGS" );
+ dumpDec< sal_Int32 >( "large-change" );
+ dumpDec< sal_Int32 >( "small-change" );
+ dumpDec< sal_Int32 >( "min" );
+ dumpDec< sal_Int32 >( "max" );
+ dumpDec< sal_Int32 >( "value" );
+}
+
+ComCtlProgressBarObject::ComCtlProgressBarObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
+ ComCtlObjectBase( rParent, 0xE6E17E84, 0x97AB8A01, nVersion, true, true )
+{
+}
+
+void ComCtlProgressBarObject::implDumpProperties()
+{
+ dumpDec< float >( "min" );
+ dumpDec< float >( "max" );
+ if( mnVersion == 6 )
+ {
+ dumpBool< sal_uInt16 >( "vertical" );
+ dumpBool< sal_uInt16 >( "smooth-scroll" );
+ }
+}
+
+ComCtlSliderObject::ComCtlSliderObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
+ ComCtlObjectBase( rParent, 0xE6E17E86, 0x0A2BAE11, nVersion, true, true )
+{
+}
+
+void ComCtlSliderObject::implDumpProperties()
+{
+ dumpBool< sal_Int32 >( "vertical" );
+ dumpDec< sal_Int32 >( "large-change" );
+ dumpDec< sal_Int32 >( "small-change" );
+ dumpDec< sal_Int32 >( "min" );
+ dumpDec< sal_Int32 >( "max" );
+ dumpDec< sal_Int16 >( "select-range", "COMCTL-SLIDER-SELECTRANGE" );
+ dumpUnused( 2 );
+ dumpDec< sal_Int32 >( "select-start" );
+ dumpDec< sal_Int32 >( "select-length" );
+ dumpDec< sal_Int32 >( "tick-style", "COMCTL-SLIDER-TICKSTYLE" );
+ dumpDec< sal_Int32 >( "tick-frequency" );
+ dumpDec< sal_Int32 >( "value" );
+ if( mnVersion == 6 )
+ dumpBool< sal_Int32 >( "tooltip-below" );
+}
+
+ComCtlUpDownObject::ComCtlUpDownObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
+ ComCtlObjectBase( rParent, 0xFF3626A0, 0xFF3626A0, nVersion, false, false )
+{
+}
+
+void ComCtlUpDownObject::implDumpProperties()
+{
+ dumpUnknown( 16 ); // buddy-property, somehow
+ dumpDec< sal_Int32 >( "buddy-control" );
+ dumpUnknown( 8 );
+ dumpDec< sal_Int32 >( "value" );
+ dumpUnknown( 4 );
+ dumpDec< sal_Int32 >( "increment" );
+ dumpDec< sal_Int32 >( "max" );
+ dumpDec< sal_Int32 >( "min" );
+ dumpHex< sal_uInt32 >( "flags-1", "COMCTL-UPDOWN-FLAGS1" );
+ dumpHex< sal_uInt32 >( "flags-2", "COMCTL-UPDOWN-FLAGS2" );
+ dumpUnknown( 4 );
+}
+
+ComCtlImageListObject::ComCtlImageListObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
+ ComCtlObjectBase( rParent, 0xE6E17E80, 0xE6E17E80, nVersion, true, false )
+{
+}
+
+void ComCtlImageListObject::implDumpProperties()
+{
+ dumpDec< sal_uInt16 >( "image-width" );
+ dumpDec< sal_uInt16 >( "image-height" );
+ dumpOleColor( "mask-color" );
+ dumpBool< sal_Int16 >( "use-mask-color" );
+ dumpUnknown( 2 );
+}
+
+void ComCtlImageListObject::implDumpCommonExtra( sal_Int64 /*nEndPos*/ )
+{
+ dumpUnknown( 4 );
+ dumpOleColor( "back-color" );
+ dumpUnknown( 4 );
+ sal_Int32 nImageCount = dumpDec< sal_Int32 >( "image-count" );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nImageIndex = 0; (nImageIndex < nImageCount) && !mxStrm->isEof(); ++nImageIndex )
+ {
+ writeEmptyItem( "#image" );
+ IndentGuard aIndGuard( mxOut );
+ sal_uInt8 nFlags = dumpHex< sal_uInt8 >( "text-flags", "COMCTL-IMAGELIST-TEXTFLAGS" );
+ if( nFlags & 0x01 ) dumpUniString32( "caption" );
+ if( nFlags & 0x02 ) dumpUniString32( "key" );
+ }
+}
+
+void ComCtlImageListObject::implDumpCommonTrailing()
+{
+ sal_Int32 nImageCount = dumpDec< sal_Int32 >( "image-count" );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nImageIndex = 0; (nImageIndex < nImageCount) && !mxStrm->isEof(); ++nImageIndex )
+ {
+ writeEmptyItem( "#image" );
+ IndentGuard aIndGuard( mxOut );
+ dumpDec< sal_Int32 >( "index" );
+ StdPicObject( *this ).dump();
+ }
+}
+
+ComCtlTabStripObject::ComCtlTabStripObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
+ ComCtlObjectBase( rParent, 0xE6E17E8A, 0xD12A7AC1, nVersion, true, true )
+{
+}
+
+void ComCtlTabStripObject::implDumpProperties()
+{
+ dumpHex< sal_uInt32 >( "flags-1", "COMCTL-TABSTRIP-FLAGS1" );
+ dumpDec< sal_uInt16 >( "tab-fixed-width", "CONV-HMM-TO-CM" );
+ dumpDec< sal_uInt16 >( "tab-fixed-height", "CONV-HMM-TO-CM" );
+ if( mnVersion == 6 )
+ {
+ dumpHex< sal_uInt32 >( "flags-2", "COMCTL-TABSTRIP-FLAGS2" );
+ dumpDec< sal_uInt16 >( "tab-min-width", "CONV-HMM-TO-CM" );
+ dumpUnknown( 2 );
+ dumpHex< sal_uInt32 >( "flags-3", "COMCTL-TABSTRIP-FLAGS3" );
+ }
+}
+
+void ComCtlTabStripObject::implDumpCommonExtra( sal_Int64 /*nEndPos*/ )
+{
+ dumpUnknown( 12 );
+ dumpUniString32( "image-list" );
+ sal_Int32 nTabCount = dumpDec< sal_Int32 >( "tab-count" );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nTabIndex = 0; (nTabIndex < nTabCount) && !mxStrm->isEof(); ++nTabIndex )
+ {
+ writeEmptyItem( "#tab" );
+ IndentGuard aIndGuard( mxOut );
+ dumpUnknown( 4 );
+ sal_uInt32 nTabFlags = dumpHex< sal_uInt32 >( "tab-flags", "COMCTL-TABSTRIP-TABFLAGS" );
+ if( nTabFlags & 0x01 ) dumpUniString32( "caption" );
+ if( nTabFlags & 0x02 ) dumpUniString32( "key" );
+ if( nTabFlags & 0x04 ) dumpUniString32( "tag" );
+ if( nTabFlags & 0x08 ) dumpUniString32( "tooltip" );
+ dumpDec< sal_uInt16 >( "image-id" );
+ }
+}
+
+ComCtlTreeViewObject::ComCtlTreeViewObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
+ ComCtlObjectBase( rParent, 0xE6E17E8E, 0x6AC13CB1, nVersion, true, true ),
+ mnStringFlags( 0 )
+{
+}
+
+void ComCtlTreeViewObject::implDumpProperties()
+{
+ dumpHex< sal_uInt32 >( "flags", "COMCTL-TREEVIEW-FLAGS" );
+ dumpDec< sal_Int32 >( "indentation", "CONV-HMM-TO-CM" );
+ if( mnVersion == 6 )
+ dumpHex< sal_uInt32 >( "flags-2", "COMCTL-TREEVIEW-FLAGS2" );
+ mnStringFlags = dumpHex< sal_uInt32 >( "string-flags", "COMCTL-TREEVIEW-STRINGFLAGS" );
+}
+
+void ComCtlTreeViewObject::implDumpCommonExtra( sal_Int64 /*nEndPos*/ )
+{
+ dumpOleColor( "text-color" );
+ dumpOleColor( "back-color" );
+ dumpUnknown( 4 );
+ if( mnStringFlags & 0x02 )
+ dumpUniString32( "image-list" );
+ dumpUniString32( "path-separator" );
+}
+
+ComCtlStatusBarObject::ComCtlStatusBarObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
+ ComCtlObjectBase( rParent, 0xE6E17E88, SAL_MAX_UINT32, nVersion, true, true )
+{
+}
+
+void ComCtlStatusBarObject::implDumpProperties()
+{
+ dumpBool< sal_Int32 >( "style-simple-text" );
+ dumpBool< sal_Int16 >( "show-tips" );
+ dumpUnknown( 2 );
+}
+
+void ComCtlStatusBarObject::implDumpCommonExtra( sal_Int64 /*nEndPos*/ )
+{
+ dumpUnknown( 12 );
+ dumpUniString32( "simple-text" );
+ sal_Int32 nPanelCount = dumpDec< sal_Int32 >( "panel-count" );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nPanelIndex = 0; (nPanelIndex < nPanelCount) && !mxStrm->isEof(); ++nPanelIndex )
+ {
+ writeEmptyItem( "#panel" );
+ IndentGuard aIndGuard( mxOut );
+ dumpHex< sal_uInt32 >( "panel-flags", "COMCTL-STATUSBAR-PANELFLAGS" );
+ dumpDec< sal_Int32 >( "current-width", "CONV-HMM-TO-CM" );
+ dumpDec< sal_Int32 >( "minimal-width", "CONV-HMM-TO-CM" );
+ sal_uInt32 nTextFlags = dumpHex< sal_uInt32 >( "text-flags", "COMCTL-STATUSBAR-TEXTFLAGS" );
+ if( nTextFlags & 0x01 ) dumpUniString32( "text" );
+ if( nTextFlags & 0x02 ) dumpUniString32( "vis-text" );
+ if( nTextFlags & 0x04 ) dumpUniString32( "key" );
+ if( nTextFlags & 0x08 ) dumpUniString32( "tag" );
+ if( nTextFlags & 0x10 ) dumpUniString32( "tooltip" );
+ }
+}
+
+void ComCtlStatusBarObject::implDumpCommonTrailing()
+{
+ sal_Int32 nImageCount = dumpDec< sal_Int32 >( "image-count" );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nImageIndex = 0; (nImageIndex < nImageCount) && !mxStrm->isEof(); ++nImageIndex )
+ {
+ writeEmptyItem( "#image" );
+ IndentGuard aIndGuard( mxOut );
+ dumpDec< sal_Int32 >( "panel-index" );
+ StdPicObject( *this ).dump();
+ }
+}
+
+void AxPropertyObjectBase::construct( const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, const String& rPropNameList, bool b64BitPropFlags )
+{
+ OleInputObjectBase::construct( rParent, rxStrm, rSysFileName );
+ constructAxPropObj( rPropNameList, b64BitPropFlags );
+}
+
+void AxPropertyObjectBase::construct( const InputObjectBase& rParent,
+ const String& rPropNameList, bool b64BitPropFlags )
+{
+ OleInputObjectBase::construct( rParent );
+ constructAxPropObj( rPropNameList, b64BitPropFlags );
+}
+
+bool AxPropertyObjectBase::implIsValid() const
+{
+ return OleInputObjectBase::implIsValid() && mxStrm->isSeekable();
+}
+
+void AxPropertyObjectBase::implDump()
+{
+ mbValid = true;
+ // header
+ setAlignAnchor();
+ dumpVersion();
+ sal_uInt16 nSize = dumpDec< sal_uInt16 >( "size" );
+ mnPropertiesEnd = mxStrm->tell() + nSize;
+ // property flags
+ maLargeProps.clear();
+ maStreamProps.clear();
+ mnPropFlags = dumpHex< sal_Int64, sal_uInt32 >( mb64BitPropFlags, "properties", mxPropNames );
+ mnCurrProp = 0;
+ // properties
+ dumpShortProperties();
+ dumpLargeProperties();
+ setAlignAnchor();
+ if( ensureValid() )
+ implDumpExtended();
+}
+
+void AxPropertyObjectBase::implDumpShortProperties()
+{
+}
+
+void AxPropertyObjectBase::implDumpExtended()
+{
+}
+
+bool AxPropertyObjectBase::ensureValid( bool bCondition )
+{
+ if( mbValid && (!bCondition || mxStrm->isEof()) )
+ {
+ if( !bCondition )
+ writeInfoItem( "state", OOX_DUMP_ERRASCII( "format-error" ) );
+ mbValid = false;
+ }
+ return mbValid;
+}
+
+void AxPropertyObjectBase::setAlignAnchor()
+{
+ mnPropertiesStart = mxStrm->tell();
+}
+
+bool AxPropertyObjectBase::startNextProperty()
+{
+ if( mnCurrProp == 0 ) mnCurrProp = 1; else mnCurrProp <<= 1;
+ bool bHasProp = getFlag( mnPropFlags, mnCurrProp );
+ setFlag( mnPropFlags, mnCurrProp, false );
+ return ensureValid() && bHasProp;
+}
+
+OUString AxPropertyObjectBase::getPropertyName() const
+{
+ return cfg().getName( mxPropNames, mnCurrProp );
+}
+
+sal_uInt32 AxPropertyObjectBase::dumpFlagsProperty( sal_uInt32 nDefault, const char* pcNameList )
+{
+ if( startNextProperty() )
+ {
+ alignInput< sal_uInt32 >();
+ return dumpHex< sal_uInt32 >( getPropertyName(), pcNameList );
+ }
+ return nDefault;
+}
+
+sal_uInt32 AxPropertyObjectBase::dumpColorProperty( sal_uInt32 nDefault )
+{
+ if( startNextProperty() )
+ {
+ alignInput< sal_uInt32 >();
+ return dumpOleColor( getPropertyName() );
+ }
+ return nDefault;
+}
+
+sal_Unicode AxPropertyObjectBase::dumpUnicodeProperty()
+{
+ if( startNextProperty() )
+ {
+ alignInput< sal_uInt16 >();
+ return dumpUnicode( getPropertyName() );
+ }
+ return '\0';
+}
+
+void AxPropertyObjectBase::dumpUnknownProperty()
+{
+ if( startNextProperty() )
+ ensureValid( false );
+}
+
+void AxPropertyObjectBase::dumpPosProperty()
+{
+ if( startNextProperty() )
+ maLargeProps.emplace_back( LargeProperty::PROPTYPE_POS, getPropertyName(), 8 );
+}
+
+void AxPropertyObjectBase::dumpSizeProperty()
+{
+ if( startNextProperty() )
+ maLargeProps.emplace_back( LargeProperty::PROPTYPE_SIZE, getPropertyName(), 8 );
+}
+
+void AxPropertyObjectBase::dumpGuidProperty( OUString* pValue )
+{
+ if( startNextProperty() )
+ maLargeProps.emplace_back( LargeProperty::PROPTYPE_GUID, getPropertyName(), 16, pValue );
+}
+
+void AxPropertyObjectBase::dumpStringProperty( OUString* pValue )
+{
+ if( startNextProperty() )
+ {
+ alignInput< sal_uInt32 >();
+ sal_uInt32 nLen = dumpHex< sal_uInt32 >( getPropertyName(), "AX-STRINGLEN" );
+ maLargeProps.emplace_back( LargeProperty::PROPTYPE_STRING, getPropertyName(), nLen, pValue );
+ }
+}
+
+void AxPropertyObjectBase::dumpStringArrayProperty()
+{
+ if( startNextProperty() )
+ {
+ alignInput< sal_uInt32 >();
+ sal_uInt32 nLen = dumpHex< sal_uInt32 >( getPropertyName(), "CONV-DEC" );
+ maLargeProps.emplace_back( LargeProperty::PROPTYPE_STRINGARRAY, getPropertyName(), nLen );
+ }
+}
+
+void AxPropertyObjectBase::dumpStreamProperty()
+{
+ if( startNextProperty() )
+ {
+ alignInput< sal_uInt16 >();
+ sal_uInt16 nData = dumpHex< sal_uInt16 >( getPropertyName() );
+ maStreamProps.emplace_back( getPropertyName(), nData );
+ }
+}
+
+void AxPropertyObjectBase::dumpEmbeddedFont()
+{
+ if( ensureValid() )
+ {
+ writeEmptyItem( "embedded-fontdata" );
+ IndentGuard aIndGuard( mxOut );
+ AxCFontNewObject( *this ).dump();
+ }
+}
+
+void AxPropertyObjectBase::dumpToPosition( sal_Int64 nPos )
+{
+ dumpRemainingTo( nPos );
+ mbValid = true;
+ ensureValid();
+}
+
+void AxPropertyObjectBase::constructAxPropObj( const String& rPropNameList, bool b64BitPropFlags )
+{
+ if( OleInputObjectBase::implIsValid() )
+ {
+ mxPropNames = cfg().getNameList( rPropNameList );
+ mb64BitPropFlags = b64BitPropFlags;
+ mbValid = true;
+ }
+}
+
+void AxPropertyObjectBase::dumpVersion()
+{
+ ItemGuard aItem( mxOut, "version" );
+ sal_uInt8 nMinor = mxStrm->readuChar();
+ sal_uInt8 nMajor = mxStrm->readuChar();
+ mxOut->writeDec( nMajor );
+ mxOut->writeChar( '.' );
+ mxOut->writeDec( nMinor );
+}
+
+OUString AxPropertyObjectBase::dumpString( const String& rName, sal_uInt32 nSize, bool bArray )
+{
+ bool bCompressed = getFlag( nSize, AX_STRING_COMPRESSED );
+ sal_uInt32 nBufSize = extractValue< sal_uInt32 >( nSize, 0, 31 );
+ OUString aString = bCompressed ?
+ dumpCharArray( rName, nBufSize, RTL_TEXTENCODING_ISO_8859_1 ) :
+ dumpUnicodeArray( rName, bArray ? nBufSize : (nBufSize / 2) );
+ alignInput< sal_Int32 >();
+ return aString;
+}
+
+void AxPropertyObjectBase::dumpShortProperties()
+{
+ if( ensureValid() )
+ {
+ writeEmptyItem( "short-properties" );
+ IndentGuard aIndGuard( mxOut );
+ implDumpShortProperties();
+ alignInput< sal_uInt32 >();
+ }
+}
+
+void AxPropertyObjectBase::dumpLargeProperties()
+{
+ if( ensureValid( mnPropFlags == 0 ) && !maLargeProps.empty() )
+ {
+ writeEmptyItem( "large-properties" );
+ IndentGuard aIndGuard( mxOut );
+ for (auto const& largeProp : maLargeProps)
+ {
+ if (!ensureValid())
+ break;
+ switch( largeProp.mePropType )
+ {
+ case LargeProperty::PROPTYPE_POS:
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( largeProp.maItemName );
+ dumpDec< sal_Int32 >( "top", "CONV-HMM-TO-CM" );
+ dumpDec< sal_Int32 >( "left", "CONV-HMM-TO-CM" );
+ }
+ break;
+ case LargeProperty::PROPTYPE_SIZE:
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ writeEmptyItem( largeProp.maItemName );
+ dumpDec< sal_Int32 >( "width", "CONV-HMM-TO-CM" );
+ dumpDec< sal_Int32 >( "height", "CONV-HMM-TO-CM" );
+ }
+ break;
+ case LargeProperty::PROPTYPE_GUID:
+ {
+ OUString aGuid = dumpGuid( largeProp.maItemName );
+ if( largeProp.mpItemValue )
+ *largeProp.mpItemValue = cfg().getStringOption( aGuid, OUString() );
+ }
+ break;
+ case LargeProperty::PROPTYPE_STRING:
+ {
+ OUString aString = dumpString( largeProp.maItemName, largeProp.mnDataSize, false );
+ if( largeProp.mpItemValue )
+ *largeProp.mpItemValue = aString;
+ }
+ break;
+ case LargeProperty::PROPTYPE_STRINGARRAY:
+ {
+ writeEmptyItem( largeProp.maItemName );
+ IndentGuard aIndGuard2( mxOut );
+ mxOut->resetItemIndex();
+ sal_Int64 nEndPos = mxStrm->tell() + largeProp.mnDataSize;
+ while( mxStrm->tell() < nEndPos )
+ {
+ MultiItemsGuard aMultiGuard( mxOut );
+ sal_uInt32 nDataSize = dumpHex< sal_uInt32 >( "#flags", "AX-ARRAYSTRINGLEN" );
+ dumpString( "string", nDataSize, true );
+ }
+ dumpToPosition( nEndPos );
+ }
+ break;
+ }
+ }
+ }
+ dumpToPosition( mnPropertiesEnd );
+
+ if( !ensureValid() || maStreamProps.empty() )
+ return;
+
+ writeEmptyItem( "stream-properties" );
+ IndentGuard aIndGuard( mxOut );
+ for (auto const& streamProp : maStreamProps)
+ {
+ if (!ensureValid())
+ break;
+ writeEmptyItem( streamProp.maItemName );
+ if( ensureValid( streamProp.mnData == 0xFFFF ) )
+ {
+ IndentGuard aIndGuard2( mxOut );
+ OUString aClassName = cfg().getStringOption( dumpGuid(), OUString() );
+ if ( aClassName == "StdFont" )
+ StdFontObject( *this ).dump();
+ else if ( aClassName == "StdPic" )
+ StdPicObject( *this ).dump();
+ else if ( aClassName == "CFontNew" )
+ AxCFontNewObject( *this ).dump();
+ else
+ ensureValid( false );
+ }
+ }
+}
+
+AxCFontNewObject::AxCFontNewObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-CFONTNEW-PROPERTIES" );
+}
+
+void AxCFontNewObject::implDumpShortProperties()
+{
+ dumpStringProperty();
+ dumpFlagsProperty( 0, "AX-CFONTNEW-FLAGS" );
+ dumpDecProperty< sal_Int32 >( 160 );
+ dumpDecProperty< sal_Int32 >( 0 );
+ dumpDecProperty< sal_uInt8 >( WINDOWS_CHARSET_DEFAULT, "CHARSET" );
+ dumpDecProperty< sal_uInt8 >( 0, "FONT-PITCHFAMILY" );
+ dumpDecProperty< sal_uInt8 >( 1, "AX-CFONTNEW-ALIGNMENT" );
+ dumpDecProperty< sal_uInt16 >( 400, "FONT-WEIGHT" );
+}
+
+AxColumnInfoObject::AxColumnInfoObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-COLUMNINFO-PROPERTIES" );
+}
+
+void AxColumnInfoObject::implDumpShortProperties()
+{
+ dumpDecProperty< sal_Int32 >( -1, "CONV-HMM-TO-CM" );
+}
+
+AxCommandButtonObject::AxCommandButtonObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-COMMANDBUTTON-PROPERTIES" );
+}
+
+void AxCommandButtonObject::implDumpShortProperties()
+{
+ dumpColorProperty( 0x80000012 );
+ dumpColorProperty( 0x80000008 );
+ dumpFlagsProperty( 0x0000001B );
+ dumpStringProperty();
+ dumpImagePosProperty();
+ dumpSizeProperty();
+ dumpMousePtrProperty();
+ dumpStreamProperty();
+ dumpUnicodeProperty();
+ dumpBoolProperty();
+ dumpStreamProperty();
+}
+
+void AxCommandButtonObject::implDumpExtended()
+{
+ dumpEmbeddedFont();
+}
+
+AxMorphControlObject::AxMorphControlObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-MORPH-PROPERTIES", true );
+}
+
+void AxMorphControlObject::implDumpShortProperties()
+{
+ dumpFlagsProperty( 0x2C80081B );
+ dumpColorProperty( 0x80000005 );
+ dumpColorProperty( 0x80000008 );
+ dumpDecProperty< sal_uInt32 >( 0 );
+ dumpBorderStyleProperty< sal_uInt8 >( 0 );
+ dumpDecProperty< sal_uInt8 >( 0, "AX-MORPH-SCROLLBARS" );
+ mnCtrlType = dumpDecProperty< sal_uInt8 >( 1, "AX-MORPH-CONTROLTYPE" );
+ dumpMousePtrProperty();
+ dumpSizeProperty();
+ dumpUnicodeProperty();
+ dumpDecProperty< sal_uInt32 >( 0, "CONV-HMM-TO-CM" );
+ dumpDecProperty< sal_uInt16 >( 1, "AX-MORPH-BOUNDCOLUMN" );
+ dumpDecProperty< sal_Int16 >( -1, "AX-MORPH-TEXTCOLUMN" );
+ dumpDecProperty< sal_Int16 >( 1, "AX-MORPH-COLUMNCOUNT" );
+ dumpDecProperty< sal_uInt16 >( 8 );
+ mnColInfoCount = dumpDecProperty< sal_uInt16 >( 1 );
+ dumpDecProperty< sal_uInt8 >( 2, "AX-MORPH-MATCHENTRYTYPE" );
+ dumpDecProperty< sal_uInt8 >( 0, "AX-MORPH-LISTSTYLE" );
+ dumpDecProperty< sal_uInt8 >( 0, "AX-MORPH-SHOWDROPDOWNMODE" );
+ dumpUnknownProperty();
+ dumpDecProperty< sal_uInt8 >( 1, "AX-MORPH-DROPDOWNSTYLE" );
+ dumpDecProperty< sal_uInt8 >( 0, "AX-MORPH-SELECTIONTYPE" );
+ dumpStringProperty();
+ dumpStringProperty();
+ dumpImagePosProperty();
+ dumpColorProperty( 0x80000006 );
+ dumpSpecialEffectProperty< sal_uInt32 >( 2 );
+ dumpStreamProperty();
+ dumpStreamProperty();
+ dumpUnicodeProperty();
+ dumpUnknownProperty();
+ dumpBoolProperty();
+ dumpStringProperty();
+}
+
+void AxMorphControlObject::implDumpExtended()
+{
+ dumpEmbeddedFont();
+ dumpColumnInfos();
+}
+
+void AxMorphControlObject::dumpColumnInfos()
+{
+ if( ensureValid() && (mnColInfoCount > 0) && ((mnCtrlType == 2) || (mnCtrlType == 3)) )
+ {
+ mxOut->resetItemIndex();
+ for( sal_uInt16 nIdx = 0; ensureValid() && (nIdx < mnColInfoCount); ++nIdx )
+ {
+ writeEmptyItem( "#column-info" );
+ IndentGuard aIndGuard( mxOut );
+ AxColumnInfoObject( *this ).dump();
+ }
+ }
+}
+
+AxLabelObject::AxLabelObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-LABEL-PROPERTIES" );
+}
+
+void AxLabelObject::implDumpShortProperties()
+{
+ dumpColorProperty( 0x80000012 );
+ dumpColorProperty( 0x8000000F );
+ dumpFlagsProperty( 0x0080001B );
+ dumpStringProperty();
+ dumpImagePosProperty();
+ dumpSizeProperty();
+ dumpMousePtrProperty();
+ dumpColorProperty( 0x80000006 );
+ dumpBorderStyleProperty< sal_uInt16 >( 0 );
+ dumpSpecialEffectProperty< sal_uInt16 >( 0 );
+ dumpStreamProperty();
+ dumpUnicodeProperty();
+ dumpStreamProperty();
+}
+
+void AxLabelObject::implDumpExtended()
+{
+ dumpEmbeddedFont();
+}
+
+AxImageObject::AxImageObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-IMAGE-PROPERTIES" );
+}
+
+void AxImageObject::implDumpShortProperties()
+{
+ dumpUnknownProperty();
+ dumpUnknownProperty();
+ dumpBoolProperty();
+ dumpColorProperty( 0x80000006 );
+ dumpColorProperty( 0x8000000F );
+ dumpBorderStyleProperty< sal_uInt8 >( 1 );
+ dumpMousePtrProperty();
+ dumpImageSizeModeProperty();
+ dumpSpecialEffectProperty< sal_uInt8 >( 0 );
+ dumpSizeProperty();
+ dumpStreamProperty();
+ dumpImageAlignProperty();
+ dumpBoolProperty();
+ dumpFlagsProperty( 0x0000001B );
+ dumpStreamProperty();
+}
+
+AxScrollBarObject::AxScrollBarObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-SCROLLBAR-PROPERTIES" );
+}
+
+void AxScrollBarObject::implDumpShortProperties()
+{
+ dumpColorProperty( 0x80000012 );
+ dumpColorProperty( 0x8000000F );
+ dumpFlagsProperty( 0x0000001B );
+ dumpSizeProperty();
+ dumpMousePtrProperty();
+ dumpDecProperty< sal_Int32 >( 0 );
+ dumpDecProperty< sal_Int32 >( 32767 );
+ dumpDecProperty< sal_Int32 >( 0 );
+ dumpHexProperty< sal_uInt32 >( 0 );
+ dumpEnabledProperty();
+ dumpEnabledProperty();
+ dumpDecProperty< sal_Int32 >( 1 );
+ dumpDecProperty< sal_Int32 >( 1 );
+ dumpOrientationProperty();
+ dumpDecProperty< sal_Int16 >( -1, "AX-SCROLLBAR-PROPTHUMB" );
+ dumpDelayProperty();
+ dumpStreamProperty();
+}
+
+AxSpinButtonObject::AxSpinButtonObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-SPINBUTTON-PROPERTIES" );
+}
+
+void AxSpinButtonObject::implDumpShortProperties()
+{
+ dumpColorProperty( 0x80000012 );
+ dumpColorProperty( 0x8000000F );
+ dumpFlagsProperty( 0x0000001B );
+ dumpSizeProperty();
+ dumpHexProperty< sal_uInt32 >( 0 );
+ dumpDecProperty< sal_Int32 >( 0 );
+ dumpDecProperty< sal_Int32 >( 100 );
+ dumpDecProperty< sal_Int32 >( 0 );
+ dumpEnabledProperty();
+ dumpEnabledProperty();
+ dumpDecProperty< sal_Int32 >( 1 );
+ dumpOrientationProperty();
+ dumpDelayProperty();
+ dumpStreamProperty();
+ dumpMousePtrProperty();
+}
+
+AxTabStripObject::AxTabStripObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "AX-TABSTRIP-PROPERTIES" );
+}
+
+void AxTabStripObject::implDumpShortProperties()
+{
+ dumpDecProperty< sal_Int32 >( -1 );
+ dumpColorProperty( 0x8000000F );
+ dumpColorProperty( 0x80000012 );
+ dumpUnknownProperty();
+ dumpSizeProperty();
+ dumpStringArrayProperty();
+ dumpMousePtrProperty();
+ dumpUnknownProperty();
+ dumpDecProperty< sal_uInt32 >( 0, "AX-TABSTRIP-ORIENTATION" );
+ dumpDecProperty< sal_uInt32 >( 0, "AX-TABSTRIP-TABSTYLE" );
+ dumpBoolProperty();
+ dumpHmmProperty();
+ dumpHmmProperty();
+ dumpBoolProperty();
+ dumpUnknownProperty();
+ dumpStringArrayProperty();
+ dumpUnknownProperty();
+ dumpStringArrayProperty();
+ dumpFlagsProperty( 0x0000001B );
+ dumpBoolProperty();
+ dumpDecProperty< sal_uInt32 >( 0 );
+ dumpStringArrayProperty();
+ mnTabFlagCount = dumpDecProperty< sal_Int32 >( 0 );
+ dumpStringArrayProperty();
+ dumpStreamProperty();
+}
+
+void AxTabStripObject::implDumpExtended()
+{
+ dumpEmbeddedFont();
+ if( mnTabFlagCount > 0 )
+ {
+ writeEmptyItem( "tab-flags" );
+ IndentGuard aIndGuard( mxOut );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nIdx = 0; ensureValid() && (nIdx < mnTabFlagCount); ++nIdx )
+ dumpHex< sal_uInt32 >( "#flags", "AX-TABSTRIP-FLAGS" );
+ }
+}
+
+FormControlStreamObject::FormControlStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, const OUString* pProgId )
+{
+ construct( rParent, rxStrm, rSysFileName );
+ constructFormCtrlStrmObj( pProgId );
+}
+
+FormControlStreamObject::FormControlStreamObject( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString* pProgId )
+{
+ construct( rParent, rxStrm );
+ constructFormCtrlStrmObj( pProgId );
+}
+
+void FormControlStreamObject::implDump()
+{
+ if( mbReadGuid )
+ maProgId = cfg().getStringOption( dumpGuid(), OUString() );
+
+ if( !maProgId.isEmpty() && !mxStrm->isEof() )
+ {
+ if ( maProgId == "Forms.CommandButton.1" )
+ AxCommandButtonObject( *this ).dump();
+ else if( maProgId == "Forms.TextBox.1" ||
+ maProgId == "Forms.ListBox.1" ||
+ maProgId == "Forms.ComboBox.1" ||
+ maProgId == "Forms.CheckBox.1" ||
+ maProgId == "Forms.OptionButton.1" ||
+ maProgId == "Forms.ToggleButton.1" ||
+ maProgId == "RefEdit.Ctrl" )
+ AxMorphControlObject( *this ).dump();
+ else if ( maProgId == "Forms.Label.1" )
+ AxLabelObject( *this ).dump();
+ else if ( maProgId == "Forms.Image.1" )
+ AxImageObject( *this ).dump();
+ else if ( maProgId == "Forms.ScrollBar.1" )
+ AxScrollBarObject( *this ).dump();
+ else if ( maProgId == "Forms.SpinButton.1" )
+ AxSpinButtonObject( *this ).dump();
+ else if ( maProgId == "Forms.TabStrip.1" )
+ AxTabStripObject( *this ).dump();
+ else if ( maProgId == "MSComCtl2.FlatScrollBar.2" )
+ ComCtlScrollBarObject( *this, 6 ).dump();
+ else if ( maProgId == "COMCTL.ProgCtrl.1" )
+ ComCtlProgressBarObject( *this, 5 ).dump();
+ else if ( maProgId == "MSComctlLib.ProgCtrl.2" )
+ ComCtlProgressBarObject( *this, 6 ).dump();
+ else if ( maProgId == "COMCTL.Slider.1" )
+ ComCtlSliderObject( *this, 5 ).dump();
+ else if ( maProgId == "MSComctlLib.Slider.2" )
+ ComCtlSliderObject( *this, 6 ).dump();
+ else if ( maProgId == "ComCtl2.UpDown.1" )
+ ComCtlUpDownObject( *this, 5 ).dump();
+ else if ( maProgId == "MSComCtl2.UpDown.2" )
+ ComCtlUpDownObject( *this, 6 ).dump();
+ else if ( maProgId == "COMCTL.ImageListCtrl.1" )
+ ComCtlImageListObject( *this, 5 ).dump();
+ else if ( maProgId == "MSComctlLib.ImageListCtrl.2" )
+ ComCtlImageListObject( *this, 6 ).dump();
+ else if ( maProgId == "COMCTL.TabStrip.1" )
+ ComCtlTabStripObject( *this, 5 ).dump();
+ else if ( maProgId == "MSComctlLib.TabStrip.2" )
+ ComCtlTabStripObject( *this, 6 ).dump();
+ else if ( maProgId == "COMCTL.TreeCtrl.1" )
+ ComCtlTreeViewObject( *this, 5 ).dump();
+ else if ( maProgId == "MSComctlLib.TreeCtrl.2" )
+ ComCtlTreeViewObject( *this, 6 ).dump();
+ else if ( maProgId == "COMCTL.SBarCtrl.1" )
+ ComCtlStatusBarObject( *this, 5 ).dump();
+ else if ( maProgId == "StdPic" )
+ StdPicObject( *this ).dump();
+ }
+ dumpRemainingStream();
+}
+
+void FormControlStreamObject::constructFormCtrlStrmObj( const OUString* pProgId )
+{
+ mbReadGuid = pProgId == nullptr;
+ if( pProgId )
+ maProgId = *pProgId;
+}
+
+VbaFormClassInfoObject::VbaFormClassInfoObject( const InputObjectBase& rParent, VbaFormSharedData& rFormData ) :
+ mrFormData( rFormData )
+{
+ AxPropertyObjectBase::construct( rParent, "VBA-CLASSINFO-PROPERTIES" );
+}
+
+void VbaFormClassInfoObject::implDumpShortProperties()
+{
+ mrFormData.maClassInfoProgIds.emplace_back( );
+ dumpGuidProperty( &mrFormData.maClassInfoProgIds.back() );
+ dumpGuidProperty();
+ dumpUnknownProperty();
+ dumpGuidProperty();
+ dumpFlagsProperty( 0, "VBA-CLASSINFO-FLAGS" );
+ dumpDecProperty< sal_uInt32 >( 0 );
+ dumpDecProperty< sal_Int32 >( -1 );
+ dumpDecProperty< sal_uInt16 >( 0 );
+ dumpDecProperty< sal_uInt16 >( 0 );
+ dumpDecProperty< sal_uInt16 >( 0, "OLEPROP-TYPE" );
+ dumpDecProperty< sal_uInt16 >( 0 );
+ dumpDecProperty< sal_uInt16 >( 0 );
+ dumpDecProperty< sal_uInt16 >( 0, "OLEPROP-TYPE" );
+ dumpDecProperty< sal_Int32 >( -1 );
+ dumpDecProperty< sal_uInt16 >( 0 );
+}
+
+namespace {
+
+const sal_uInt32 VBA_FORMSITE_OBJSTREAM = 0x0010;
+
+const sal_uInt16 VBA_FORMSITE_CLASSTABLEINDEX = 0x8000;
+const sal_uInt16 VBA_FORMSITE_CLASSTABLEMASK = 0x7FFF;
+
+} // namespace
+
+VbaFormSiteObject::VbaFormSiteObject( const InputObjectBase& rParent, VbaFormSharedData& rFormData ) :
+ mrFormData( rFormData )
+{
+ AxPropertyObjectBase::construct( rParent, "VBA-FORMSITE-PROPERTIES" );
+}
+
+void VbaFormSiteObject::implDumpShortProperties()
+{
+ VbaFormSiteInfo aSiteInfo;
+ dumpStringProperty();
+ dumpStringProperty();
+ sal_Int32 nId = dumpDecProperty< sal_Int32 >( 0 );
+ dumpDecProperty< sal_Int32 >( 0 );
+ sal_uInt32 nFlags = dumpFlagsProperty( 0x00000033, "VBA-FORMSITE-FLAGS" );
+ sal_uInt32 nLength = dumpDecProperty< sal_uInt32 >( 0 );
+ dumpDecProperty< sal_Int16 >( -1 );
+ sal_uInt16 nClassId = dumpHexProperty< sal_uInt16 >( 0x7FFF, "VBA-FORMSITE-CLASSIDCACHE" );
+ dumpPosProperty();
+ dumpDecProperty< sal_uInt16 >( 0 );
+ dumpUnknownProperty();
+ dumpStringProperty();
+ dumpStringProperty();
+ dumpStringProperty();
+ dumpStringProperty();
+
+ sal_uInt16 nIndex = nClassId & VBA_FORMSITE_CLASSTABLEMASK;
+ if( getFlag( nClassId, VBA_FORMSITE_CLASSTABLEINDEX ) )
+ {
+ if( nIndex < mrFormData.maClassInfoProgIds.size() )
+ aSiteInfo.maProgId = mrFormData.maClassInfoProgIds[ nIndex ];
+ }
+ else
+ {
+ if( cfg().hasName( "VBA-FORMSITE-CLASSNAMES", nIndex ) )
+ aSiteInfo.maProgId = cfg().getName( "VBA-FORMSITE-CLASSNAMES", nIndex );
+ }
+ aSiteInfo.mnId = nId;
+ aSiteInfo.mnLength = nLength;
+ aSiteInfo.mbInStream = getFlag( nFlags, VBA_FORMSITE_OBJSTREAM );
+
+ mrFormData.maSiteInfos.push_back( aSiteInfo );
+}
+
+VbaFormDesignExtObject::VbaFormDesignExtObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "VBA-FORMDESIGNEXT-PROPERTIES" );
+}
+
+void VbaFormDesignExtObject::implDumpShortProperties()
+{
+ dumpFlagsProperty( 0x00015F55, "VBA-FORMDESIGNEXT-FLAGS" );
+ dumpHmmProperty();
+ dumpHmmProperty();
+ dumpDecProperty< sal_Int8 >( 0, "VBA-FORMDESIGNEXT-CLICKCTRLMODE" );
+ dumpDecProperty< sal_Int8 >( 0, "VBA-FORMDESIGNEXT-DBLCLICKCTRLMODE" );
+}
+
+namespace {
+
+const sal_uInt32 AX_FORM_HASDESIGNEXTENDER = 0x00004000;
+const sal_uInt32 AX_FORM_SKIPCLASSTABLE = 0x00008000;
+
+const sal_uInt8 AX_FORM_SITECOUNTTYPE_COUNT = 0x80;
+const sal_uInt8 AX_FORM_SITECOUNTTYPE_MASK = 0x7F;
+
+} // namespace
+
+VbaFStreamObject::VbaFStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, VbaFormSharedData& rFormData ) :
+ mrFormData( rFormData )
+{
+ AxPropertyObjectBase::construct( rParent, rxStrm, rSysFileName, "VBA-FORM-PROPERTIES" );
+}
+
+void VbaFStreamObject::implDumpShortProperties()
+{
+ dumpUnknownProperty();
+ dumpColorProperty( 0x8000000F );
+ dumpColorProperty( 0x80000012 );
+ dumpDecProperty< sal_uInt32 >( 0 );
+ dumpUnknownProperty();
+ dumpUnknownProperty();
+ mnFlags = dumpFlagsProperty( 0x00000004, "VBA-FORM-FLAGS" );
+ dumpBorderStyleProperty< sal_uInt8 >( 0 );
+ dumpMousePtrProperty();
+ dumpHexProperty< sal_uInt8 >( 0x0C, "VBA-FORM-SCROLLBARS" );
+ dumpSizeProperty();
+ dumpSizeProperty();
+ dumpPosProperty();
+ dumpDecProperty< sal_uInt32 >( 0 );
+ dumpUnknownProperty();
+ dumpStreamProperty();
+ dumpDecProperty< sal_uInt8 >( 0, "VBA-FORM-CYCLE" );
+ dumpSpecialEffectProperty< sal_uInt8 >( 0 );
+ dumpColorProperty( 0x80000012 );
+ dumpStringProperty();
+ dumpStreamProperty();
+ dumpStreamProperty();
+ dumpDecProperty< sal_Int32 >( 100, "CONV-PERCENT" );
+ dumpImageAlignProperty();
+ dumpBoolProperty();
+ dumpImageSizeModeProperty();
+ dumpDecProperty< sal_uInt32 >( 0 );
+ dumpDecProperty< sal_uInt32 >( 0 );
+}
+
+void VbaFStreamObject::implDumpExtended()
+{
+ dumpClassInfos();
+ dumpSiteData();
+ dumpDesignExtender();
+ dumpRemainingStream();
+}
+
+void VbaFStreamObject::dumpClassInfos()
+{
+ if( ensureValid() && !getFlag( mnFlags, AX_FORM_SKIPCLASSTABLE ) )
+ {
+ mxOut->emptyLine();
+ sal_uInt16 nCount = dumpDec< sal_uInt16 >( "class-info-count" );
+ mxOut->resetItemIndex();
+ for( sal_uInt16 nIdx = 0; ensureValid() && (nIdx < nCount); ++nIdx )
+ {
+ writeEmptyItem( "#class-info" );
+ IndentGuard aIndGuard( mxOut );
+ VbaFormClassInfoObject( *this, mrFormData ).dump();
+ }
+ }
+}
+
+void VbaFStreamObject::dumpFormSites( sal_uInt32 nCount )
+{
+ mxOut->resetItemIndex();
+ for( sal_uInt32 nIdx = 0; ensureValid() && (nIdx < nCount); ++nIdx )
+ {
+ mxOut->emptyLine();
+ writeEmptyItem( "#form-site" );
+ IndentGuard aIndGuard( mxOut );
+ VbaFormSiteObject( *this, mrFormData ).dump();
+ }
+}
+
+void VbaFStreamObject::dumpSiteData()
+{
+ if( !ensureValid() )
+ return;
+
+ mxOut->emptyLine();
+ setAlignAnchor();
+ sal_uInt32 nSiteCount = dumpDec< sal_uInt32 >( "site-count" );
+ sal_uInt32 nSiteLength = dumpDec< sal_uInt32 >( "site-data-size" );
+ sal_Int64 nEndPos = mxStrm->tell() + nSiteLength;
+ if( !ensureValid( nEndPos <= mxStrm->size() ) )
+ return;
+
+ mxOut->resetItemIndex();
+ sal_uInt32 nSiteIdx = 0;
+ while( ensureValid() && (nSiteIdx < nSiteCount) )
+ {
+ mxOut->emptyLine();
+ writeEmptyItem( "#site-info" );
+ IndentGuard aIndGuard( mxOut );
+ dumpDec< sal_uInt8 >( "depth" );
+ sal_uInt8 nTypeCount = dumpHex< sal_uInt8 >( "type-count", "VBA-FORM-SITE-TYPECOUNT" );
+ if( getFlag( nTypeCount, AX_FORM_SITECOUNTTYPE_COUNT ) )
+ {
+ dumpDec< sal_uInt8 >( "repeated-type" );
+ nSiteIdx += (nTypeCount & AX_FORM_SITECOUNTTYPE_MASK);
+ }
+ else
+ {
+ ++nSiteIdx;
+ }
+ }
+ alignInput< sal_uInt32 >();
+ dumpFormSites( nSiteCount );
+ dumpToPosition( nEndPos );
+}
+
+void VbaFStreamObject::dumpDesignExtender()
+{
+ if( ensureValid() && getFlag( mnFlags, AX_FORM_HASDESIGNEXTENDER ) )
+ {
+ mxOut->emptyLine();
+ writeEmptyItem( "design-extender" );
+ IndentGuard aIndGuard( mxOut );
+ VbaFormDesignExtObject( *this ).dump();
+ }
+}
+
+VbaOStreamObject::VbaOStreamObject( const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, VbaFormSharedData& rFormData ) :
+ mrFormData( rFormData )
+{
+ OleInputObjectBase::construct( rParent, rxStrm, rSysFileName );
+}
+
+void VbaOStreamObject::implDump()
+{
+ for (auto const& siteInfo : mrFormData.maSiteInfos)
+ {
+ if (mxStrm->isEof())
+ break;
+ if( (siteInfo.mbInStream) && (siteInfo.mnLength > 0) )
+ {
+ mxOut->emptyLine();
+ writeDecItem( "control-id", siteInfo.mnId );
+ writeInfoItem( "prog-id", siteInfo.maProgId );
+ IndentGuard aIndGuard( mxOut );
+ BinaryInputStreamRef xRelStrm( std::make_shared<RelativeInputStream>( *mxStrm, siteInfo.mnLength ) );
+ FormControlStreamObject( *this, xRelStrm, &siteInfo.maProgId ).dump();
+ }
+ }
+ dumpRemainingStream();
+}
+
+VbaPageObject::VbaPageObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "VBA-PAGE-PROPERTIES" );
+}
+
+void VbaPageObject::implDumpShortProperties()
+{
+ dumpUnknownProperty();
+ dumpDecProperty< sal_uInt32 >( 0, "VBA-PAGE-TRANSITIONEFFECT" );
+ dumpDecProperty< sal_uInt32 >( 0, "AX-CONV-MS" );
+}
+
+VbaMultiPageObject::VbaMultiPageObject( const InputObjectBase& rParent )
+{
+ AxPropertyObjectBase::construct( rParent, "VBA-MULTIPAGE-PROPERTIES" );
+}
+
+void VbaMultiPageObject::implDumpShortProperties()
+{
+ dumpUnknownProperty();
+ mnPageCount = dumpDecProperty< sal_Int32 >( 0 );
+ dumpDecProperty< sal_Int32 >( 0 );
+ dumpBoolProperty();
+}
+
+void VbaMultiPageObject::implDumpExtended()
+{
+ if( ensureValid() && (mnPageCount > 0) )
+ {
+ writeEmptyItem( "page-ids" );
+ IndentGuard aIndGuard( mxOut );
+ mxOut->resetItemIndex();
+ for( sal_Int32 nIdx = 0; ensureValid() && (nIdx < mnPageCount); ++nIdx )
+ dumpDec< sal_Int32 >( "#id" );
+ }
+}
+
+VbaXStreamObject::VbaXStreamObject( const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, VbaFormSharedData& rFormData ) :
+ mrFormData( rFormData )
+{
+ InputObjectBase::construct( rParent, rxStrm, rSysFileName );
+}
+
+void VbaXStreamObject::implDump()
+{
+ for( size_t nIdx = 0, nCount = mrFormData.maSiteInfos.size(); !mxStrm->isEof() && (nIdx < nCount); ++nIdx )
+ {
+ mxOut->emptyLine();
+ writeEmptyItem( "page" );
+ IndentGuard aIndGuard( mxOut );
+ VbaPageObject( *this ).dump();
+ }
+ if( !mxStrm->isEof() )
+ {
+ mxOut->emptyLine();
+ writeEmptyItem( "multi-page" );
+ IndentGuard aIndGuard( mxOut );
+ VbaMultiPageObject( *this ).dump();
+ }
+ dumpRemainingStream();
+}
+
+VbaContainerStorageObject::VbaContainerStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath ) :
+ OleStorageObject( rParent, rxStrg, rSysPath )
+{
+ addPreferredStream( "f" );
+}
+
+void VbaContainerStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
+{
+ if ( rStrmName == "f" )
+ VbaFStreamObject( *this, rxStrm, rSysFileName, maFormData ).dump();
+ else if ( rStrmName == "o" )
+ VbaOStreamObject( *this, rxStrm, rSysFileName, maFormData ).dump();
+ else if ( rStrmName == "x" )
+ VbaXStreamObject( *this, rxStrm, rSysFileName, maFormData ).dump();
+ else
+ OleStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName );
+}
+
+void VbaContainerStorageObject::implDumpStorage( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rSysPath )
+{
+ if( isFormStorage( rStrgPath ) )
+ VbaContainerStorageObject( *this, rxStrg, rSysPath ).dump();
+ else
+ OleStorageObject( *this, rxStrg, rSysPath ).dump();
+}
+
+bool VbaContainerStorageObject::isFormStorage( const OUString& rStrgPath ) const
+{
+ if( (rStrgPath.getLength() >= 3) && (rStrgPath[ 0 ] == 'i') )
+ {
+ std::u16string_view aId = rStrgPath.subView( 1 );
+ if( (aId.size() == 2) && (aId[ 0 ] == '0') )
+ aId = aId.substr( 1 );
+ sal_Int32 nId = o3tl::toInt32(aId);
+ if( (nId > 0) && (std::u16string_view(OUString::number( nId )) == aId) )
+ for (auto const& siteInfo : maFormData.maSiteInfos)
+ if( siteInfo.mnId == nId )
+ return true;
+ }
+ return false;
+}
+
+VbaSharedData::VbaSharedData() :
+ meTextEnc( RTL_TEXTENCODING_MS_1252 )
+{
+}
+
+bool VbaSharedData::isModuleStream( const OUString& rStrmName ) const
+{
+ return maStrmOffsets.count( rStrmName ) > 0;
+}
+
+sal_Int32 VbaSharedData::getStreamOffset( const OUString& rStrmName ) const
+{
+ StreamOffsetMap::const_iterator aIt = maStrmOffsets.find( rStrmName );
+ return (aIt == maStrmOffsets.end()) ? 0 : aIt->second;
+}
+
+VbaDirStreamObject::VbaDirStreamObject( const ObjectBase& rParent,
+ const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, VbaSharedData& rVbaData ) :
+ mrVbaData( rVbaData )
+{
+ mxInStrm = rxStrm;
+ if( mxInStrm )
+ {
+ BinaryInputStreamRef xVbaStrm( std::make_shared<::oox::ole::VbaInputStream>( *mxInStrm ) );
+ SequenceRecordObjectBase::construct( rParent, xVbaStrm, rSysFileName, "VBA-DIR-RECORD-NAMES", "VBA-DIR-SIMPLE-RECORDS" );
+ }
+}
+
+bool VbaDirStreamObject::implIsValid() const
+{
+ return mxInStrm && SequenceRecordObjectBase::implIsValid();
+}
+
+bool VbaDirStreamObject::implReadRecordHeader( BinaryInputStream& rBaseStrm, sal_Int64& ornRecId, sal_Int64& ornRecSize )
+{
+ ornRecId = rBaseStrm.readuInt16();
+ ornRecSize = rBaseStrm.readInt32();
+
+ // for no obvious reason, PROJECTVERSION record contains size field of 4, but is 6 bytes long
+ if( ornRecId == 9 )
+ ornRecSize = 6;
+
+ return !rBaseStrm.isEof();
+}
+
+void VbaDirStreamObject::implDumpRecordBody()
+{
+ switch( getRecId() )
+ {
+ case 0x0003:
+ mrVbaData.meTextEnc = rtl_getTextEncodingFromWindowsCodePage( dumpDec< sal_uInt16 >( "codepage", "CODEPAGES" ) );
+ break;
+ case 0x0004:
+ dumpByteString( "name" );
+ break;
+ case 0x0005:
+ dumpByteString( "description" );
+ break;
+ case 0x0006:
+ dumpByteString( "helpfile-path" );
+ break;
+ case 0x0009:
+ dumpDec< sal_uInt32 >( "major" );
+ dumpDec< sal_uInt16 >( "minor" );
+ break;
+ case 0x000C:
+ dumpByteString( "constants" );
+ break;
+ case 0x000D:
+ dumpByteStringWithLength( "lib-id" );
+ dumpUnused( 6 );
+ break;
+ case 0x000E:
+ dumpByteStringWithLength( "lib-id-absolute" );
+ dumpByteStringWithLength( "lib-id-relative" );
+ dumpDec< sal_uInt32 >( "major" );
+ dumpDec< sal_uInt16 >( "minor" );
+ break;
+ case 0x0016:
+ dumpByteString( "name" );
+ break;
+ case 0x0019:
+ dumpByteString( "name" );
+ maCurrStream.clear();
+ mnCurrOffset = 0;
+ break;
+ case 0x001A:
+ maCurrStream = dumpByteString( "stream-name" );
+ break;
+ case 0x001C:
+ dumpByteString( "description" );
+ break;
+ case 0x002B:
+ if( !maCurrStream.isEmpty() )
+ mrVbaData.maStrmOffsets[ maCurrStream ] = mnCurrOffset;
+ maCurrStream.clear();
+ mnCurrOffset = 0;
+ break;
+ case 0x002F:
+ dumpByteStringWithLength( "lib-id-twiddled" );
+ dumpUnused( 6 );
+ break;
+ case 0x0030:
+ dumpByteStringWithLength( "lib-id-extended" );
+ dumpUnused( 6 );
+ dumpGuid( "original-typelib" );
+ dumpDec< sal_uInt32 >( "cookie" );
+ break;
+ case 0x0031:
+ mnCurrOffset = dumpHex< sal_Int32 >( "stream-offset", "CONV-DEC" );
+ break;
+ case 0x0032:
+ dumpUniString( "stream-name" );
+ break;
+ case 0x0033:
+ dumpByteString( "lib-id-original" );
+ break;
+ case 0x003C:
+ dumpUniString( "constants" );
+ break;
+ case 0x003D:
+ dumpByteString( "helpfile-path" );
+ break;
+ case 0x003E:
+ dumpUniString( "name" );
+ break;
+ case 0x0040:
+ dumpUniString( "description" );
+ break;
+ case 0x0047:
+ dumpUniString( "name" );
+ break;
+ case 0x0048:
+ dumpUniString( "description" );
+ break;
+ }
+}
+
+OUString VbaDirStreamObject::dumpByteString( const String& rName )
+{
+ return dumpCharArray( rName, static_cast< sal_Int32 >( getRecSize() ), mrVbaData.meTextEnc );
+}
+
+OUString VbaDirStreamObject::dumpUniString( const String& rName )
+{
+ return dumpUnicodeArray( rName, static_cast< sal_Int32 >( getRecSize() / 2 ) );
+}
+
+OUString VbaDirStreamObject::dumpByteStringWithLength( const String& rName )
+{
+ return dumpCharArray( rName, mxStrm->readInt32(), mrVbaData.meTextEnc );
+}
+
+VbaModuleStreamObject::VbaModuleStreamObject(
+ const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm,
+ const OUString& rSysFileName, VbaSharedData& rVbaData, sal_Int32 nStrmOffset ) :
+ mrVbaData( rVbaData ),
+ mnStrmOffset( nStrmOffset )
+{
+ InputObjectBase::construct( rParent, rxStrm, rSysFileName );
+}
+
+void VbaModuleStreamObject::implDump()
+{
+ dumpBinary( "perf-cache", mnStrmOffset );
+ mxOut->emptyLine();
+ writeEmptyItem( "source-code" );
+ IndentGuard aIndGuard( mxOut );
+ BinaryInputStreamRef xVbaStrm( std::make_shared<::oox::ole::VbaInputStream>( *mxStrm ) );
+ TextLineStreamObject( *this, xVbaStrm, mrVbaData.meTextEnc ).dump();
+}
+
+VbaStorageObject::VbaStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath, VbaSharedData& rVbaData ) :
+ OleStorageObject( rParent, rxStrg, rSysPath ),
+ mrVbaData( rVbaData )
+{
+ addPreferredStream( "dir" );
+}
+
+void VbaStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
+{
+ if( rStrgPath.isEmpty() && rStrmName == "dir" )
+ VbaDirStreamObject( *this, rxStrm, rSysFileName, mrVbaData ).dump();
+ else if( mrVbaData.isModuleStream( rStrmName ) )
+ VbaModuleStreamObject( *this, rxStrm, rSysFileName, mrVbaData, mrVbaData.getStreamOffset( rStrmName ) ).dump();
+ else
+ OleStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName );
+}
+
+VbaFormStorageObject::VbaFormStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath, VbaSharedData& rVbaData ) :
+ VbaContainerStorageObject( rParent, rxStrg, rSysPath ),
+ mrVbaData( rVbaData )
+{
+}
+
+void VbaFormStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
+{
+ if ( rStrmName == "\003VBFrame" )
+ TextLineStreamObject( *this, rxStrm, mrVbaData.meTextEnc, rSysFileName ).dump();
+ else
+ VbaContainerStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName );
+}
+
+VbaProjectStorageObject::VbaProjectStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath ) :
+ OleStorageObject( rParent, rxStrg, rSysPath )
+{
+ addPreferredStorage( "VBA" );
+}
+
+void VbaProjectStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
+{
+ if( rStrgPath.isEmpty() && rStrmName == "PROJECT" )
+ TextLineStreamObject( *this, rxStrm, maVbaData.meTextEnc, rSysFileName ).dump();
+ else
+ OleStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName );
+}
+
+void VbaProjectStorageObject::implDumpStorage( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rSysPath )
+{
+ if ( rStrgPath == "VBA" )
+ VbaStorageObject( *this, rxStrg, rSysPath, maVbaData ).dump();
+ else
+ VbaFormStorageObject( *this, rxStrg, rSysPath, maVbaData ).dump();
+}
+
+ActiveXStorageObject::ActiveXStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath ) :
+ VbaContainerStorageObject( rParent, rxStrg, rSysPath )
+{
+}
+
+void ActiveXStorageObject::implDumpBaseStream( const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
+{
+ FormControlStreamObject( *this, rxStrm, rSysFileName ).dump();
+}
+
+} // namespace oox
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/dump/oledumper.ini b/oox/source/dump/oledumper.ini
new file mode 100644
index 000000000..2d33c6c4f
--- /dev/null
+++ b/oox/source/dump/oledumper.ini
@@ -0,0 +1,904 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# dumper settings ============================================================
+
+# Path to additional configuration data, relative to this file.
+include-config-file=dumperbase.ini
+
+# OLE name lists =============================================================
+
+constlist=OLE-STD-CLIPBOARD-FORMAT
+ 2=bmp
+ 3=wmf
+ 8=dib
+ 14=emf
+end
+
+combilist=OLE-COLOR
+ 0x0000FFFF=uint32,dec,palette-index,,filter=0xFF000000~0x01000000
+ 0x000000FF=uint32,dec,red,,filter=0xFF000000~0x00000000,filter=0xFF000000~0x02000000
+ 0x0000FF00=uint32,dec,green,,filter=0xFF000000~0x00000000,filter=0xFF000000~0x02000000
+ 0x00FF0000=uint32,dec,blue,,filter=0xFF000000~0x00000000,filter=0xFF000000~0x02000000
+ 0x0000FFFF=uint32,dec,system-color,SYSTEMCOLOR,filter=0xFF000000~0x80000000
+ 0xFF000000=uint8,dec,type,OLE-COLORTYPE
+end
+
+constlist=OLE-COLORTYPE
+ 0x00=default
+ 0x01=palette
+ 0x02=rgb
+ 0x80=system-color
+end
+
+multilist=OLE-MOUSEPTR
+ 0=default,arrow,cross,i-beam
+ 6=size-diag-down,size-vert,size-diag-up,size-hor
+ 10=up-arrow,hour-glass,no-drop,app-starting,help,size-all
+ 99=custom
+end
+
+# StdFont --------------------------------------------------------------------
+
+{0BE35203-8F91-11CE-9DE3-00AA004BB851}=StdFont
+
+flagslist=STDFONT-FLAGS
+ 0x01=bold
+ 0x02=italic
+ 0x04=underline
+ 0x08=strikeout
+end
+
+unitconverter=STDFONT-HEIGHT,/10000,pt
+
+# StdPic ---------------------------------------------------------------------
+
+{0BE35204-8F91-11CE-9DE3-00AA004BB851}=StdPic
+
+shortlist=STDPIC-ID,0x0000746C,StdPic
+
+# StdHlink -------------------------------------------------------------------
+
+{79EAC9D0-BAF9-11CE-8C82-00AA004BA90B}=StdHlink
+{79EAC9E0-BAF9-11CE-8C82-00AA004BA90B}=URLMoniker
+{00000303-0000-0000-C000-000000000046}=FileMoniker
+{00000304-0000-0000-C000-000000000046}=ItemMoniker
+{00000305-0000-0000-C000-000000000046}=AntiMoniker
+{00000309-0000-0000-C000-000000000046}=CompositeMoniker
+
+flagslist=STDHLINK-FLAGS
+ 0x00000001=has-target
+ 0x00000002=!relative!absolute
+ 0x00000004=display-specified
+ 0x00000008=has-location
+ 0x00000010=has-display
+ 0x00000020=has-guid
+ 0x00000040=has-creation-time
+ 0x00000080=has-frame
+ 0x00000100=!as-guid!as-string
+ 0x00000200=has-abs-from-rel
+end
+
+flagslist=STDHLINK-URL-FLAGS
+ 0x00000001=allow-relative
+ 0x00000002=wildcard-scheme
+ 0x00000004=implicit-file-scheme
+ 0x00000008=no-fragment
+ 0x00000010=no-canonicalize
+ 0x00000020=canonicalize
+ 0x00000040=dos-path
+ 0x00000080=decode-extra-info
+ 0x00000100=no-decode-extra-info
+ 0x00000200=crack-unknown-schemes
+ 0x00000400=no-crack-unknown-schemes
+ 0x00000800=preprocess-html
+ 0x00001000=no-preprocess-html
+ 0x00002000=registry-settings
+ 0x00004000=no-registry-settings
+ 0x00008000=no-encode-forbidden-chars
+end
+
+# OLE property stream --------------------------------------------------------
+
+{F29F85E0-4FF9-1068-AB91-08002B27B3D9}=GlobalDocProp
+{D5CDD502-2E9C-101B-9397-08002B2CF9AE}=BuiltinDocProp
+{D5CDD505-2E9C-101B-9397-08002B2CF9AE}=CustomDocProp
+
+constlist=OLEPROP-BYTE-ORDER
+ 0xFEFF=big-endian
+ 0xFFFE=little-endian
+end
+
+shortlist=OLEPROP-OSTYPE,0,dos,mac,win32,unix
+
+multilist=OLEPROP-BASEIDS
+ quote-names=1
+ default=
+ 0=dictionary,codepage
+end
+
+multilist=OLEPROP-GLOBALIDS
+ include=OLEPROP-BASEIDS
+ 2=title,subject,author,keywords,comments,template,last-author,rev-number
+ 10=edit-time,last-printed,create-time,last-saved,page-count,word-count,char-count,thumbnail,appname,security
+end
+
+multilist=OLEPROP-BUILTINIDS
+ include=OLEPROP-BASEIDS
+ 2=category,pres-target,byte-count,line-count,para-count,slide-count,note-count,hidden-slide-count
+ 10=clips,scale-crop,heading-pairs,part-titles,manager,company,links-uptodate
+end
+
+multilist=OLEPROP-TYPE-SIMPLE
+ 0=empty,null,int16,int32,float,double,currency,date,string8,dispatch
+ 10=error,bool,variant,unknown,decimal,int8,uint8,uint16,uint32
+ 20=int64,uint64,int,uint,void,hresult,ptr,savearray,c-array,userdef
+ 30=string8,string16,,,,,record,intptr,uintptr
+ 64=time-stamp,blob,stream,storage,stream-obj,storage-obj
+ 70=blob-obj,clip-fmt,guid,vers-stream
+ 0x0FFF=str8-blob
+end
+
+combilist=OLEPROP-TYPE
+ 0x0FFF=int32,dec,base-type,OLEPROP-TYPE-SIMPLE
+ 0x1000=vector
+ 0x2000=array
+ 0x4000=byref
+end
+
+# ComCtl controls ============================================================
+
+constlist=COMCTL-HEADER-IDS
+ 0x0A2BAE11=COMCTL_SLIDER_60
+ 0x12344321=COMCTL_SIZE
+ 0x6AC13CB1=COMCTL_TREEVIEW_60
+ 0x97AB8A01=COMCTL_PROGRESSBAR_60
+ 0x99470A83=COMCTL_SCROLLBAR_60
+ 0xABCDEF01=COMCTL_COMMONDATA
+ 0xBDECDE1F=COMCTL_COMPLEXDATA
+ 0xD12A7AC1=COMCTL_TABSTRIP_60
+ 0xE6E17E80=COMCTL_IMAGELIST_50_60
+ 0xE6E17E84=COMCTL_PROGRESSBAR_50
+ 0xE6E17E86=COMCTL_SLIDER_50
+ 0xE6E17E88=COMCTL_STATUSBAR_50
+ 0xE6E17E8A=COMCTL_TABSTRIP_50
+ 0xE6E17E8E=COMCTL_TREEVIEW_50
+ 0xFF3626A0=COMCTL_UPDOWN_50_60
+end
+
+combilist=COMCTL-COMMON-FLAGS
+ ignore=0xFFFF8000
+ 0x00000001=flat-border
+ 0x00000002=enabled
+ 0x00000004=3d-border
+ 0x000007F8=uint8,dec,mouse-ptr,OLE-MOUSEPTR
+ 0x00000800=ole-drag-auto
+ 0x00002000=ole-drop-manual
+end
+
+flagslist=COMCTL-COMPLEX-FLAGS
+ ignore=0xFFFFFFFC
+ 0x00000001=font
+ 0x00000002=mouse-icon
+end
+
+# flat scrollbar -------------------------------------------------------------
+
+{FE38753A-44A3-11D1-B5B7-0000C09000C4}=MSComCtl2.FlatScrollBar.2
+
+combilist=COMCTL-SCROLLBAR-FLAGS
+ 0x00000003=uint8,dec,appearance,COMCTL-SCROLLBAR-APPEARANCE
+ 0x0000000C=uint8,dec,arrows,COMCTL-SCROLLBAR-ARROWS
+ 0x00000010=!vertical!horizontal
+end
+
+shortlist=COMCTL-SCROLLBAR-APPEARANCE,0,3d,flat,track-3d
+shortlist=COMCTL-SCROLLBAR-ARROWS,0,both,left-up,right-down
+
+# progress bar ---------------------------------------------------------------
+
+{0713E8D2-850A-101B-AFC0-4210102A8DA7}=COMCTL.ProgCtrl.1
+{35053A22-8589-11D1-B16A-00C0F0283628}=MSComctlLib.ProgCtrl.2
+
+# slider ---------------------------------------------------------------------
+
+{373FF7F0-EB8B-11CD-8820-08002B2F4F5A}=COMCTL.Slider.1
+{F08DF954-8592-11D1-B16A-00C0F0283628}=MSComctlLib.Slider.2
+
+constlist=COMCTL-SLIDER-SELECTRANGE
+ 0x00000000=off
+ 0x0000FFFF=on
+end
+
+shortlist=COMCTL-SLIDER-TICKSTYLE,0,bottom-right,top-left,both,no-ticks
+
+# updown ---------------------------------------------------------------------
+
+{026371C0-1B7C-11CF-9D53-00AA003C9CB6}=ComCtl2.UpDown.1
+{603C7E80-87C2-11D1-8BE3-0000F8754DA1}=MSComCtl2.UpDown.2
+
+flagslist=COMCTL-UPDOWN-FLAGS1
+ 0x00000001=!align-left!align-right
+ 0x00000004=!vertical!horizontal
+end
+
+flagslist=COMCTL-UPDOWN-FLAGS2
+ 0x00000004=wrap
+ 0x00000020=ole-drop-manual
+ 0x00000080=enabled
+end
+
+# image list -----------------------------------------------------------------
+
+{58DA8D8F-9D6A-101B-AFC0-4210102A8DA7}=COMCTL.ImageListCtrl.1
+{2C247F23-8591-11D1-B16A-00C0F0283628}=MSComctlLib.ImageListCtrl.2
+
+flagslist=COMCTL-IMAGELIST-TEXTFLAGS
+ 0x01=key
+ 0x02=tag
+end
+
+# tab strip ------------------------------------------------------------------
+
+{9ED94440-E5E8-101B-B9B5-444553540000}=COMCTL.TabStrip.1
+{1EFB6596-857C-11D1-B16A-00C0F0283628}=MSComctlLib.TabStrip.2
+
+combilist=COMCTL-TABSTRIP-FLAGS1
+ ignore=0xFFFFFFE0
+ 0x00000001=multi-row
+ 0x00000002=show-tooltips
+ 0x00000018=uint8,dec,tab-width-style,COMCTL-TABSTRIP-TABWIDTHSTYLE
+end
+
+combilist=COMCTL-TABSTRIP-FLAGS2
+ ignore=0xFFFF0000
+ 0x00000003=uint8,dec,style,COMCTL-TABSTRIP-STYLE
+ 0x00000004=hot-tracking
+ 0x00000008=multi-select
+ 0x00000030=uint8,dec,placement,COMCTL-TABSTRIP-PLACEMENT
+ 0x00000040=separators
+end
+
+flagslist=COMCTL-TABSTRIP-FLAGS3
+ ignore=0xFFFF0000
+ 0x00000001=tabstyle-opposite
+end
+
+shortlist=COMCTL-TABSTRIP-TABWIDTHSTYLE,0,justified,non-justified,fixed
+shortlist=COMCTL-TABSTRIP-STYLE,0,tabs,tab-buttons,flat-buttons
+shortlist=COMCTL-TABSTRIP-PLACEMENT,0,top,bottom,left,right
+
+flagslist=COMCTL-TABSTRIP-TABFLAGS
+ 0x00000001=caption
+ 0x00000002=key
+ 0x00000004=tag
+ 0x00000008=tooltip
+end
+
+# tree view ------------------------------------------------------------------
+
+{0713E8A2-850A-101B-AFC0-4210102A8DA7}=COMCTL.TreeCtrl.1
+{C74190B6-8589-11D1-B16A-00C0F0283628}=MSComctlLib.TreeCtrl.2
+
+combilist=COMCTL-TREEVIEW-FLAGS
+ ignore=0xFFFF0000
+ 0x00000001=!tree-lines!root-lines
+ 0x0000001C=uint8,dec,style,COMCTL-TREEVIEW-STYLE
+ 0x00000020=label-edit
+ 0x00000080=hide-selection
+ 0x00000100=sorted
+end
+
+flagslist=COMCTL-TREEVIEW-STRINGFLAGS
+ ignore=0xFFFFFFF8
+ 0x00000001=separator
+ 0x00000002=image-list
+end
+
+shortlist=COMCTL-TREEVIEW-STYLE,0,text,pic-text,plusminus-text,plusminus-pic-text,treelines-text,treelines-pic-text,treelines-plusminus-text,treelines-plusminus-pic-text
+
+flagslist=COMCTL-TREEVIEW-FLAGS2
+ 0x00000001=checkboxes
+ 0x00000002=full-row-select
+ 0x00000004=hot-tracking
+ 0x00000008=scroll
+ 0x00000010=single-select
+end
+
+# status bar -----------------------------------------------------------------
+
+{6B7E638F-850A-101B-AFC0-4210102A8DA7}=COMCTL.SBarCtrl.1
+
+combilist=COMCTL-STATUSBAR-PANELFLAGS
+ ignore=0xFFFFF000
+ 0x00000007=uint8,dec,style,COMCTL-STATUSBAR-STYLE
+ 0x00000018=uint8,dec,alignment,COMCTL-STATUSBAR-ALIGN
+ 0x00000060=uint8,dec,bevel,COMCTL-STATUSBAR-BEVEL
+ 0x00000080=enabled
+ 0x00000300=uint8,dec,autosize,COMCTL-STATUSBAR-AUTOSIZE
+ 0x00000400=visible
+end
+
+shortlist=COMCTL-STATUSBAR-STYLE,0,text,caps,num,ins,scrl,time,date,kana
+shortlist=COMCTL-STATUSBAR-ALIGN,0,left,center,right
+shortlist=COMCTL-STATUSBAR-BEVEL,0,no-bevel,inset,raised
+shortlist=COMCTL-STATUSBAR-AUTOSIZE,0,no-auto,spring,content
+
+flagslist=COMCTL-STATUSBAR-TEXTFLAGS
+ 0x00000001=text
+ 0x00000002=vis-text
+ 0x00000004=key
+ 0x00000008=tag
+ 0x00000010=tooltip
+end
+
+# other controls =============================================================
+
+# Microsoft Web Browser
+{8856F961-340A-11D0-A96B-00C04FD705A2}=Shell.Explorer.2
+
+# ActiveX name lists =========================================================
+
+combilist=AX-STRINGLEN
+ 0x80000000=!unicode!compressed
+ 0x7FFFFFFF=int32,dec,buffer-size
+end
+
+combilist=AX-ARRAYSTRINGLEN
+ 0x80000000=!unicode!compressed
+ 0x7FFFFFFF=int32,dec,len
+end
+
+combilist=AX-FLAGS
+ 0x00000001=reserved-1
+ 0x00000002=enabled
+ 0x00000004=locked
+ 0x00000008=opaque
+ 0x00000010=reserved-2
+ 0x00000400=column-heads
+ 0x00000800=entire-rows
+ 0x00001000=existing-entries-only
+ 0x00002000=caption-left
+ 0x00004000=editable
+ 0x00078000=uint8,dec,ime-mode,AX-IMEMODE
+ 0x00080000=drag-enabled
+ 0x00100000=enter-as-newline
+ 0x00200000=keep-selection
+ 0x00400000=tab-as-character
+ 0x00800000=word-wrap
+ 0x02000000=borders-suppressed
+ 0x04000000=select-line
+ 0x08000000=single-char-select
+ 0x10000000=auto-size
+ 0x20000000=hide-selection
+ 0x40000000=maxlength-autotab
+ 0x80000000=multi-line
+end
+
+multilist=AX-IMEMODE
+ 0=no-control,on,off,disabled
+ 4=hiragana,fillwidth-katakana,halfwidth-katakana
+ 7=fullwidth-alpha,halfwidth-alpha
+ 9=fullwidth-hangul,halfwidth-hangul
+ 11=fullwidth-hanzi,halfwidth-hanzi
+end
+
+combilist=AX-IMAGEPOS
+ 0x0000FFFF=uint16,dec,image,AX-POS
+ 0xFFFF0000=uint16,dec,label,AX-POS
+end
+
+unitconverter=AX-CONV-MS,1,ms
+
+shortlist=AX-ENABLED,0,disabled,enabled
+shortlist=AX-BORDERSTYLE,0,none,single
+shortlist=AX-SPECIALEFFECT,0,flat,raised,sunken,etched,,,bump
+shortlist=AX-ORIENTATION,-1,auto,vertical,horizontal
+shortlist=AX-POS,0,top-left,top,top-right,left,center,right,bottom-left,bottom,bottom-right
+shortlist=AX-IMAGEALIGN,0,top-left,top-right,center,bottom-left,bottom-right
+shortlist=AX-IMAGESIZEMODE,0,clip,stretch,,stretch-ratio
+
+# CFontNew -------------------------------------------------------------------
+
+{AFC20920-DA4E-11CE-B94300AA006887B4}=CFontNew
+
+flagslist=AX-CFONTNEW-PROPERTIES
+ 0x0001=font-name
+ 0x0002=flags
+ 0x0004=font-size
+ 0x0008=font-offset
+ 0x0010=charset
+ 0x0020=pitch-family
+ 0x0040=alignment
+ 0x0080=font-weight
+end
+
+flagslist=AX-CFONTNEW-FLAGS
+ 0x00000001=bold
+ 0x00000002=italic
+ 0x00000004=underline
+ 0x00000008=strikeout
+ 0x00002000=sunken
+ 0x00002000=sunken
+ 0x40000000=auto-color
+end
+
+shortlist=AX-CFONTNEW-ALIGNMENT,1,left,right,center
+
+# column info ----------------------------------------------------------------
+
+flagslist=AX-COLUMNINFO-PROPERTIES
+ 0x00000001=column-width
+end
+
+# command button -------------------------------------------------------------
+
+{D7053240-CE69-11CD-A777-00DD01143C57}=Forms.CommandButton.1
+
+flagslist=AX-COMMANDBUTTON-PROPERTIES
+ 0x00000001=text-color
+ 0x00000002=fill-color
+ 0x00000004=flags
+ 0x00000008=caption
+ 0x00000010=image-pos
+ 0x00000020=size
+ 0x00000040=mouse-ptr
+ 0x00000080=image
+ 0x00000100=accelerator
+ 0x00000200=no-take-focus
+ 0x00000400=mouse-icon
+end
+
+# toggle button, check box, option button, text box, list box, combo box -----
+
+{8BD21D10-EC42-11CE-9E0D-00AA006002F3}=Forms.TextBox.1
+{8BD21D20-EC42-11CE-9E0D-00AA006002F3}=Forms.ListBox.1
+{8BD21D30-EC42-11CE-9E0D-00AA006002F3}=Forms.ComboBox.1
+{8BD21D40-EC42-11CE-9E0D-00AA006002F3}=Forms.CheckBox.1
+{8BD21D50-EC42-11CE-9E0D-00AA006002F3}=Forms.OptionButton.1
+{8BD21D60-EC42-11CE-9E0D-00AA006002F3}=Forms.ToggleButton.1
+{00024512-0000-0000-C000-000000000046}=RefEdit.Ctrl
+
+flagslist=AX-MORPH-PROPERTIES
+ 0x0000000000000001=flags
+ 0x0000000000000002=fill-color
+ 0x0000000000000004=text-color
+ 0x0000000000000008=max-length
+ 0x0000000000000010=border-style
+ 0x0000000000000020=scrollbars
+ 0x0000000000000040=control-type
+ 0x0000000000000080=mouse-ptr
+ 0x0000000000000100=size
+ 0x0000000000000200=password-char
+ 0x0000000000000400=list-width
+ 0x0000000000000800=bound-column
+ 0x0000000000001000=text-column
+ 0x0000000000002000=column-count
+ 0x0000000000004000=list-rowcount
+ 0x0000000000008000=column-info-count
+ 0x0000000000010000=match-entry-mode
+ 0x0000000000020000=list-style
+ 0x0000000000040000=show-dropdown-mode
+ 0x0000000000100000=dropdown-style
+ 0x0000000000200000=selection-type
+ 0x0000000000400000=value
+ 0x0000000000800000=caption
+ 0x0000000001000000=image-pos
+ 0x0000000002000000=border-color
+ 0x0000000004000000=special-effect
+ 0x0000000008000000=mouse-icon
+ 0x0000000010000000=image
+ 0x0000000020000000=accelerator
+ 0x0000000080000000=reserved
+ 0x0000000100000000=groupname
+end
+
+shortlist=AX-MORPH-SCROLLBARS,0,none,horizontal,vertical,both
+shortlist=AX-MORPH-CONTROLTYPE,1,edit,listbox,combobox,checkbox,optionbutton,togglebutton,dropdown-listbox
+shortlist=AX-MORPH-MATCHENTRYTYPE,0,first-letter,complete,none
+shortlist=AX-MORPH-LISTSTYLE,0,plain,with-buttons
+shortlist=AX-MORPH-SHOWDROPDOWNMODE,0,never,on-focus,always
+shortlist=AX-MORPH-DROPDOWNSTYLE,0,no-symbol,arrow,ellipsis,underline
+shortlist=AX-MORPH-SELECTIONTYPE,0,single,multi,range
+
+constlist=AX-MORPH-BOUNDCOLUMN
+ default=
+ 0=value-is-row-index
+end
+
+constlist=AX-MORPH-TEXTCOLUMN
+ default=
+ -1=first-column-with-width
+ 0=row-numbers
+end
+
+constlist=AX-MORPH-COLUMNCOUNT
+ default=
+ -1=all-columns
+end
+
+# label ----------------------------------------------------------------------
+
+{978C9E23-D4B0-11CE-BF2D-00AA003F40D0}=Forms.Label.1
+
+flagslist=AX-LABEL-PROPERTIES
+ 0x00000001=text-color
+ 0x00000002=fill-color
+ 0x00000004=flags
+ 0x00000008=caption
+ 0x00000010=image-pos
+ 0x00000020=size
+ 0x00000040=mouse-ptr
+ 0x00000080=border-color
+ 0x00000100=border-style
+ 0x00000200=special-effect
+ 0x00000400=image
+ 0x00000800=accelerator
+ 0x00001000=mouse-icon
+end
+
+# image ----------------------------------------------------------------------
+
+{4C599241-6926-101B-9992-00000B65C6F9}=Forms.Image.1
+
+flagslist=AX-IMAGE-PROPERTIES
+ 0x00000004=auto-size
+ 0x00000008=border-color
+ 0x00000010=fill-color
+ 0x00000020=border-style
+ 0x00000040=mouse-ptr
+ 0x00000080=image-size-mode
+ 0x00000100=special-effect
+ 0x00000200=size
+ 0x00000400=image
+ 0x00000800=image-align
+ 0x00001000=image-tiling
+ 0x00002000=flags
+ 0x00004000=mouse-icon
+end
+
+# scroll bar -----------------------------------------------------------------
+
+{DFD181E0-5E2F-11CE-A449-00AA004A803D}=Forms.ScrollBar.1
+
+flagslist=AX-SCROLLBAR-PROPERTIES
+ 0x00000001=arrow-color
+ 0x00000002=fill-color
+ 0x00000004=flags
+ 0x00000008=size
+ 0x00000010=mouse-ptr
+ 0x00000020=min
+ 0x00000040=max
+ 0x00000080=value
+ 0x00000100=unused
+ 0x00000200=prev-enabled
+ 0x00000400=next-enabled
+ 0x00000800=step
+ 0x00001000=page-step
+ 0x00002000=orientation
+ 0x00004000=prop-thumb
+ 0x00008000=delay
+ 0x00010000=mouse-icon
+end
+
+shortlist=AX-SCROLLBAR-PROPTHUMB,-1,proportional,fixed
+
+# spin button ----------------------------------------------------------------
+
+{79176FB0-B7F2-11CE-97EF-00AA006D2776}=Forms.SpinButton.1
+
+flagslist=AX-SPINBUTTON-PROPERTIES
+ 0x00000001=arrow-color
+ 0x00000002=fill-color
+ 0x00000004=flags
+ 0x00000008=size
+ 0x00000010=unused
+ 0x00000020=min
+ 0x00000040=max
+ 0x00000080=value
+ 0x00000100=prev-enabled
+ 0x00000200=next-enabled
+ 0x00000400=step
+ 0x00000800=orientation
+ 0x00001000=delay
+ 0x00002000=mouse-icon
+ 0x00004000=mouse-ptr
+end
+
+# tab strip ------------------------------------------------------------------
+
+{EAE50EB0-4A62-11CE-BED6-00AA00611080}=Forms.TabStrip.1
+
+flagslist=AX-TABSTRIP-PROPERTIES
+ 0x00000001=selected-tab
+ 0x00000002=fill-color
+ 0x00000004=text-color
+ 0x00000010=size
+ 0x00000020=tab-captions
+ 0x00000040=mouse-ptr
+ 0x00000100=tab-orientation
+ 0x00000200=tab-style
+ 0x00000400=multi-row
+ 0x00000800=tab-fixed-width
+ 0x00001000=tab-fixed-height
+ 0x00002000=tooltips
+ 0x00008000=tooltip-strings
+ 0x00020000=tab-names
+ 0x00040000=flags
+ 0x00080000=new-version
+ 0x00100000=tabs-allocated
+ 0x00200000=tags
+ 0x00400000=tab-flag-count
+ 0x00800000=accelerators
+ 0x01000000=mouse-icon
+end
+
+shortlist=AX-TABSTRIP-ORIENTATION,0,top,bottom,left,right
+shortlist=AX-TABSTRIP-TABSTYLE,0,tabs,buttons,none
+
+flagslist=AX-TABSTRIP-FLAGS
+ 0x00000001=visible
+ 0x00000002=enabled
+end
+
+# VBA forms ==================================================================
+
+# form class info ------------------------------------------------------------
+
+flagslist=VBA-CLASSINFO-PROPERTIES
+ 0x00000001=class-id
+ 0x00000002=disp-event
+ 0x00000008=default-prog
+ 0x00000010=class-flags
+ 0x00000020=method-count
+ 0x00000040=dispatch-id-bind
+ 0x00000080=get-bind-index
+ 0x00000100=put-bind-index
+ 0x00000200=bind-type
+ 0x00000400=get-value-index
+ 0x00000800=put-value-index
+ 0x00001000=value-type
+ 0x00002000=dispatch-id-rowset
+ 0x00004000=set-rowset
+end
+
+combilist=VBA-CLASSINFO-FLAGS
+ 0x0000FFFF=uint16,hex,classtable-flags,VBA-CLASSTABLE-CLASSFLAGS
+ 0xFFFF0000=uint16,hex,var-flags,VBA-CLASSTABLE-VARFLAGS
+end
+
+flagslist=VBA-CLASSTABLE-CLASSFLAGS
+ 0x0001=exclusive-value
+ 0x0002=dual-interface
+ 0x0004=no-aggregation
+end
+
+flagslist=VBA-CLASSTABLE-VARFLAGS
+ 0x0001=read-only
+ 0x0002=source
+ 0x0004=bindable
+ 0x0008=request-edit
+ 0x0010=display-bind
+ 0x0020=default-bind
+ 0x0040=hidden
+ 0x0080=restricted
+ 0x0100=default-coll-elem
+ 0x0200=ui-default
+ 0x0400=non-browsable
+ 0x0800=replaceable
+ 0x1000=immediate-bind
+end
+
+# form site ------------------------------------------------------------------
+
+flagslist=VBA-FORMSITE-PROPERTIES
+ 0x00000001=name
+ 0x00000002=tag
+ 0x00000004=id
+ 0x00000008=help-context-id
+ 0x00000010=flags
+ 0x00000020=stream-size
+ 0x00000040=tab-index
+ 0x00000080=class-id-cache-index
+ 0x00000100=pos
+ 0x00000200=group-id
+ 0x00000800=tool-tip
+ 0x00001000=licence-key
+ 0x00002000=control-source
+ 0x00004000=row-source
+end
+
+flagslist=VBA-FORMSITE-FLAGS
+ 0x00000001=tabstop
+ 0x00000002=visible
+ 0x00000004=default
+ 0x00000008=cancel
+ 0x00000010=!storage!obj-stream
+ 0x00000020=auto-size
+ 0x00000100=preserve-height
+ 0x00000200=fit-to-parent
+ 0x00002000=select-child
+ 0x00040000=container
+end
+
+combilist=VBA-FORMSITE-CLASSIDCACHE
+ 0x7FFF=uint16,dec,cache-idx,VBA-FORMSITE-CLASSIDCACHEINDEX,filter=0x8000~0x0000
+ 0x7FFF=uint16,dec,class-table-idx,,filter=0x8000~0x8000
+ 0x8000=!predefined-class-id!class-table-index
+end
+
+constlist=VBA-FORMSITE-CLASSNAMES
+ 7=Forms.Form.1
+ 12=Forms.Image.1
+ 14=Forms.Frame.1
+ 15=Internal.MorphData
+ 16=Forms.SpinButton.1
+ 17=Forms.CommandButton.1
+ 18=Forms.TabStrip.1
+ 21=Forms.Label.1
+ 23=Forms.TextBox.1
+ 24=Forms.ListBox.1
+ 25=Forms.ComboBox.1
+ 26=Forms.CheckBox.1
+ 27=Forms.OptionButton.1
+ 28=Forms.ToggleButton.1
+ 47=Forms.ScrollBar.1
+ 57=Forms.MultiPage.1
+end
+
+constlist=VBA-FORMSITE-CLASSIDCACHEINDEX
+ include=VBA-FORMSITE-CLASSNAMES
+ 0x7FFF=invalid
+end
+
+# form design extender ------------------------------------------------------
+
+flagslist=VBA-FORMDESIGNEXT-PROPERTIES
+ 0x00000001=flags
+ 0x00000002=grid-x
+ 0x00000004=grid-y
+ 0x00000008=click-control-mode
+ 0x00000010=dblclick-control-mode
+end
+
+flagslist=VBA-FORMDESIGNEXT-FLAGS
+ 0x00000001=inherit-design-mode
+ 0x00000002=design-mode
+ 0x00000004=inherit-show-toolbox
+ 0x00000008=show-toolbox
+ 0x00000010=inherit-show-grid
+ 0x00000020=show-grid
+ 0x00000040=inherit-snap-to-grid
+ 0x00000080=snap-to-grid
+ 0x00000100=inherit-grid-x
+ 0x00000200=inherit-grid-y
+ 0x00000400=inherit-click-control-mode
+ 0x00000800=inherit-dblclick-control-mode
+ 0x00001000=inherit-show-invisible
+ 0x00002000=show-invisible
+ 0x00004000=inherit-show-tooltips
+ 0x00008000=show-tooltips
+ 0x00010000=inherit-immediate-layout
+ 0x00020000=immediate-layout
+end
+
+shortlist=VBA-FORMDESIGNEXT-CLICKCTRLMODE,-2,inherit,default,insertion-point,select-then-insert
+shortlist=VBA-FORMDESIGNEXT-DBLCLICKCTRLMODE,-2,inherit,,select-text,edit-code,edit-properties
+
+# form -----------------------------------------------------------------------
+
+{C62A69F0-16DC-11CE-9E98-00AA00574A4F}=Forms.Form.1
+{6E182020-F460-11CE-9BCD-00AA00608E01}=Forms.Frame.1
+
+flagslist=VBA-FORM-PROPERTIES
+ 0x00000002=fill-color
+ 0x00000004=text-color
+ 0x00000008=next-available-id
+ 0x00000040=flags
+ 0x00000080=border-style
+ 0x00000100=mouse-ptr
+ 0x00000200=scrollbars
+ 0x00000400=display-size
+ 0x00000800=logical-size
+ 0x00001000=scroll-pos
+ 0x00002000=group-count
+ 0x00008000=mouse-icon
+ 0x00010000=cycle
+ 0x00020000=special-effect
+ 0x00040000=border-color
+ 0x00080000=caption
+ 0x00100000=font
+ 0x00200000=image
+ 0x00400000=zoom
+ 0x00800000=image-align
+ 0x01000000=image-tiling
+ 0x02000000=image-sizemode
+ 0x04000000=shape-cookie
+ 0x08000000=draw-buffer
+end
+
+flagslist=VBA-FORM-FLAGS
+ 0x00000004=enabled
+ 0x00004000=has-design-extender
+ 0x00008000=!has-class-table!skip-class-table
+end
+
+flagslist=VBA-FORM-SCROLLBARS
+ 0x01=horizontal
+ 0x02=vertical
+ 0x04=keep-horizontal
+ 0x08=keep-vertical
+ 0x10=vertical-left
+end
+
+shortlist=VBA-FORM-CYCLE,0,all-forms,,current-form
+
+combilist=VBA-FORM-SITE-TYPECOUNT
+ 0x7F=uint8,dec,type-count
+ 0x80=!type!count
+end
+
+# page -----------------------------------------------------------------------
+
+flagslist=VBA-PAGE-PROPERTIES
+ 0x00000002=transition-effect
+ 0x00000004=transition-period
+end
+
+shortlist=VBA-PAGE-TRANSITIONEFFECT,0,none,cover-up,cover-right-up,cover-right,cover-right-down,cover-down,cover-left-down,cover-left,cover-left-up,push-up,push-right,push-down,push-left
+
+# multi page -----------------------------------------------------------------
+
+{46E31370-3F7A-11CE-BED6-00AA00611080}=Forms.MultiPage.1
+
+flagslist=VBA-MULTIPAGE-PROPERTIES
+ 0x00000002=page-count
+ 0x00000004=id
+ 0x00000008=enabled
+end
+
+# VBA project name lists =====================================================
+
+multilist=VBA-DIR-RECORD-NAMES
+ 0x0000=,PROJECTSYSKIND,PROJECTLCID,PROJECTCODEPAGE,PROJECTNAME,PROJECTDOCSTRING,PROJECTHELPFILEPATH1,PROJECTHELPCONTEXT
+ 0x0008=PROJECTLIBFLAGS,PROJECTVERSION,,,PROJECTCONSTANTS,REFERENCEREGISTERED,REFERENCEPROJECT,PROJECTMODULES
+ 0x0010=PROJECTEND,,,PROJECTCOOKIE,PROJECTLCIDINVOKE,,REFERENCENAME,
+ 0x0018=,MODULENAME,MODULESTREAMNAME,,MODULEDOCSTRING,,MODULEHELPCONTEXT,
+ 0x0020=,MODULETYPEPROCEDURAL,MODULETYPEDOCUMENT,,,MODULEREADONLY,,
+ 0x0028=MODULEPRIVATE,,,MODULEEND,MODULECOOKIE,,,REFERENCECONTROL
+ 0x0030=REFERENCEEXTENDED,MODULEOFFSET,MODULESTREAMNAMEUNICODE,REFERENCEORIGINAL,,,,
+ 0x0038=,,,,PROJECTCONSTANTSUNICODE,PROJECTHELPFILEPATH2,REFERENCENAMEUNICODE,
+ 0x0040=PROJECTDOCSTRINGUNICODE,,,,,,,MODULENAMEUNICODE
+ 0x0048=MODULEDOCSTRINGUNICODE,,,,,,,
+end
+
+constlist=VBA-DIR-SIMPLE-RECORDS
+ 0x0001=uint32,dec,platform,VBA-DIR-PROJECTSYSKIND-PLATFORM
+ 0x0002=uint32,hex,lang-id
+ 0x0007=uint32,dec,help-context-id
+ 0x0008=uint32,hex,libflags
+ 0x000F=uint16,dec,module-count
+ 0x0013=int16,dec,cookie
+ 0x0014=uint32,hex,lang-id
+ 0x001E=uint32,dec,help-context-id
+ 0x002C=int16,dec,cookie
+end
+
+shortlist=VBA-DIR-PROJECTSYSKIND-PLATFORM,0,16-bit-windows,32-bit-windows,macintosh
+
+# ============================================================================
diff --git a/oox/source/dump/pptxdumper.cxx b/oox/source/dump/pptxdumper.cxx
new file mode 100644
index 000000000..c65b79206
--- /dev/null
+++ b/oox/source/dump/pptxdumper.cxx
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <oox/dump/pptxdumper.hxx>
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <oox/dump/oledumper.hxx>
+#include <oox/dump/xlsbdumper.hxx>
+#include <oox/helper/zipstorage.hxx>
+#include <oox/ole/olestorage.hxx>
+#include <o3tl/string_view.hxx>
+
+#ifdef DBG_UTIL
+
+namespace oox::dump::pptx {
+
+using namespace ::com::sun::star::io;
+//using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+using ::oox::core::FilterBase;
+
+RootStorageObject::RootStorageObject( const DumperBase& rParent )
+{
+ StorageObjectBase::construct( rParent );
+}
+
+void RootStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
+{
+ std::u16string_view aExt( InputOutputHelper::getFileNameExtension( rStrmName ) );
+ if( o3tl::equalsIgnoreAsciiCase(aExt, u"pptx") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"potx") )
+ {
+ Dumper( getContext(), rxStrm, rSysFileName ).dump();
+ }
+#ifdef FIXME
+ else if(
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xlsb") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xlsm") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xlsx") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xltm") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xltx") )
+ {
+ ::oox::dump::xlsb::Dumper( getContext(), rxStrm, rSysFileName ).dump();
+ }
+ else if(
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xla") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xlc") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xlm") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xls") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xlt") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xlw") )
+ {
+ ::oox::dump::biff::Dumper( getContext(), rxStrm, rSysFileName ).dump();
+ }
+#endif
+ else if(
+ o3tl::equalsIgnoreAsciiCase(aExt, u"xml") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"vml") ||
+ o3tl::equalsIgnoreAsciiCase(aExt, u"rels") )
+ {
+ XmlStreamObject( *this, rxStrm, rSysFileName ).dump();
+ }
+ else if( o3tl::equalsIgnoreAsciiCase(aExt, u"bin") )
+ {
+ if( rStrgPath == "ppt" && rStrmName == "vbaProject.bin" )
+ {
+ StorageRef xStrg = std::make_shared<::oox::ole::OleStorage>( getContext(), rxStrm, false );
+ VbaProjectStorageObject( *this, xStrg, rSysFileName ).dump();
+ }
+ else if ( rStrgPath == "ppt/embeddings" )
+ {
+ StorageRef xStrg = std::make_shared<::oox::ole::OleStorage>( getContext(), rxStrm, false );
+ OleStorageObject( *this, xStrg, rSysFileName ).dump();
+ }
+ else if ( rStrgPath == "ppt/activeX" )
+ {
+ StorageRef xStrg = std::make_shared<::oox::ole::OleStorage>( getContext(), rxStrm, true );
+ ActiveXStorageObject( *this, xStrg, rSysFileName ).dump();
+ }
+ else
+ {
+ BinaryStreamObject( *this, rxStrm, rSysFileName ).dump();
+ }
+ }
+}
+
+#define DUMP_PPTX_CONFIG_ENVVAR "OOO_PPTXDUMPER"
+
+Dumper::Dumper( const FilterBase& rFilter )
+{
+ ConfigRef xCfg = std::make_shared<Config>( DUMP_PPTX_CONFIG_ENVVAR, rFilter );
+ DumperBase::construct( xCfg );
+}
+
+Dumper::Dumper( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName )
+{
+ if( rxContext.is() && rxInStrm.is() )
+ {
+ StorageRef xStrg = std::make_shared<ZipStorage>( rxContext, rxInStrm );
+ ConfigRef xCfg = std::make_shared<Config>( DUMP_PPTX_CONFIG_ENVVAR, rxContext, xStrg, rSysFileName );
+ DumperBase::construct( xCfg );
+ }
+}
+
+void Dumper::implDump()
+{
+ RootStorageObject( *this ).dump();
+}
+
+} // namespace oox::dump::pptx
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/dump/pptxdumper.ini b/oox/source/dump/pptxdumper.ini
new file mode 100644
index 000000000..5bfd267e7
--- /dev/null
+++ b/oox/source/dump/pptxdumper.ini
@@ -0,0 +1,35 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# dumper settings ============================================================
+
+# Path to additional configuration data, relative to this file.
+include-config-file=dumperbase.ini
+
+# Enable entire dumper (default=off). This option does not affect the option
+# 'enable-import'.
+# 0=off, 1=on, missing: setting from dumperbase.ini
+# enable-dumper=1
+
+# Enable import after dumping (default=on). Disabling this option allows
+# to dump a file without loading it. This option is independent from the
+# 'enable-dumper' option.
+# 0=off, 1=on, missing: setting from dumperbase.ini
+# enable-import=1
+
+# ============================================================================
diff --git a/oox/source/dump/xlsbdumper.ini b/oox/source/dump/xlsbdumper.ini
new file mode 100644
index 000000000..9a28f8268
--- /dev/null
+++ b/oox/source/dump/xlsbdumper.ini
@@ -0,0 +1,1204 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# dumper settings ============================================================
+
+# Path to additional configuration data, relative to this file.
+include-config-file=dumperbase.ini
+include-config-file=oledumper.ini
+
+# Enable entire dumper. This option does not affect the option 'enable-import'.
+# 0=off, 1=on, missing = use setting from dumperbase.ini
+# enable-dumper=1
+
+# Enable import after dumping. Disabling this option allows to dump a file
+# without loading it. This option is independent from the 'enable-dumper'
+# option.
+# 0=off, 1=on, missing = use setting from dumperbase.ini
+# enable-import=1
+
+# name lists =================================================================
+
+# common ---------------------------------------------------------------------
+
+unitconverter=CONV-TINT,/327.67,%
+unitconverter=CONV-COLWIDTH,/256,chars
+
+constlist=ERRORCODES
+ 0x00=#NULL!
+ 0x07=#DIV/0!
+ 0x0F=#VALUE!
+ 0x17=#REF!
+ 0x1D=#NAME?
+ 0x24=#NUM!
+ 0x2A=#N/A
+end
+
+flagslist=STRING-FLAGS
+ 0x01=rich-string
+ 0x02=phonetic-text
+end
+
+combilist=CELL-XFID
+ 0x00FFFFFF=int32,dec,xf-id
+ 0x01000000=show-phonetic
+end
+
+combilist=PHONETIC-FLAGS
+ ignore=0x0030
+ 0x0003=uint8,dec,type,PHONETICPR-TYPE
+ 0x000C=uint8,dec,alignment,PHONETICPR-ALIGNMENT
+end
+
+shortlist=COLOR-TYPE,0,auto,indexed,rgb,theme
+
+combilist=COLOR-FLAGS
+ 0x01=rgb-valid
+ 0xFE=uint8,dec,type,COLOR-TYPE
+end
+
+multilist=PALETTE-COLORS
+ default=
+ 0=ega-black,ega-white,ega-red,ega-green,ega-blue,ega-yellow,ega-magenta,ega-cyan
+ 64=sys-window-text
+ 65=sys-window-bg
+ 67=sys-button-face
+ 77=sys-window-text-chart
+ 78=sys-window-bg-chart
+ 79=auto-border-chart
+ 80=sys-tooltip-bg
+ 81=sys-tooltip-text
+end
+
+constlist=TEXTROTATION
+ default=
+ 255=stacked
+end
+
+multilist=BORDERSTYLES
+ 0=none,thin,medium,dash,dot
+ 5=thick,double,hair,medium-dash,thin-dash-dot
+ 10=medium-dash-dot,thin-dash-dot-dot,medium-dash-dot-dot,slant-dash-dot
+end
+
+multilist=FILLPATTERNS
+ 0=no-fill,solid-fill,50%-grey,75%-grey,25%-grey
+ 5=hor-stripe,ver-stripe,rev-diag-stripe,diag-stripe,diag-crosshatch
+ 10=thick-diag-crosshatch,thin-hor-stripe,thin-ver-stripe,thin-rev-diag-stripe,thin-diag-stripe
+ 15=thin-hor-crosshatch,thin-diag-crosshatch,12.5%-grey,6.25%-grey
+ 40=gradient
+end
+
+# formulas -------------------------------------------------------------------
+
+flagslist=FORMULA-FLAGS
+ 0x0002=recalc-always
+end
+
+multilist=BASETOKENS
+ 0x00=,tExp,tTbl,tAdd,tSub,tMul,tDiv,tPower
+ 0x08=tConcat,tLT,tLE,tEQ,tGE,tGT,tNE,tIsect
+ 0x10=tList,tRange,tUplus,tUminus,tPercent,tParen,tMissArg,tStr
+ 0x18=tTable,tAttr,,,tErr,tBool,tInt,tNum
+end
+
+constlist=TOKENCLASSES
+ 0x20=R
+ 0x40=V
+ 0x60=A
+end
+
+multilist=CLASSTOKENS
+ 0x00=tArray,tFunc,tFuncVar,tName,tRef,tArea,tMemArea,tMemErr
+ 0x08=tMemNoMem,tMemFunc,tRefErr,tAreaErr,tRefN,tAreaN,tMemAreaN,tMemNoMemN
+ 0x18=,tNameX,tRef3d,tArea3d,tRefErr3d,tAreaErr3d
+end
+
+combilist=FUNCID
+ 0x7FFF=uint16,dec,func-id
+ 0x8000=command
+end
+
+combilist=PARAMCOUNT-CMD
+ 0x7F=uint8,dec,count
+ 0x80=prompt
+end
+
+combilist=REFRELFLAGS
+ 0x3FFF=uint16,dec,value
+ 0x4000=col-rel
+ 0x8000=row-rel
+end
+
+flagslist=TABLEFLAGS
+ 0x0001=single-column
+ 0x0002=column-range
+ 0x0004=#all
+ 0x0008=#headers
+ 0x0010=#data
+ 0x0020=#totals
+ 0x0040=#this-row
+ 0x0080=bracket-spaces
+ 0x0100=sep-spaces
+ 0x0200=single-row
+ 0x0400=single-cell
+end
+
+flagslist=ATTRTYPES
+ 0x01=volatile
+ 0x02=if
+ 0x04=choose
+ 0x08=skip
+ 0x10=sum
+ 0x20=assign
+ 0x40=space
+ 0x80=iferror
+end
+
+shortlist=ATTRSPACETYPES,0,space-before-token,cr-before-token,space-before-open,cr-before-open,space-before-close,cr-before-close,leading-space
+
+shortlist=ARRAYVALUE-TYPE,0,number,string,boolean,,error
+
+# record names ---------------------------------------------------------------
+
+multilist=RECORD-NAMES
+ 0x0000=ROW,CELL_BLANK,CELL_RK,CELL_ERROR,CELL_BOOL,CELL_DOUBLE,CELL_STRING,CELL_SI
+ 0x0008=FORMULA_STRING,FORMULA_DOUBLE,FORMULA_BOOL,FORMULA_ERROR,MULTCELL_BLANK,MULTCELL_RK,MULTCELL_ERROR,MULTCELL_BOOL
+ 0x0010=MULTCELL_DOUBLE,MULTCELL_STRING,MULTCELL_SI,SI,PCITEM_MISSING,PCITEM_DOUBLE,PCITEM_BOOL,PCITEM_ERROR
+ 0x0018=PCITEM_STRING,PCITEM_DATE,PCITEM_INDEX,PCITEMA_MISSING,PCITEMA_DOUBLE,PCITEMA_BOOL,PCITEMA_ERROR,PCITEMA_STRING
+ 0x0020=PCITEMA_DATE,PCRECORD,PCRECORDDT,FRT,FRT_END,,,DEFINEDNAME
+ 0x0028=BINARYINDEXROWS,,BINARYINDEXBLOCK,FONT,NUMFMT,FILL,BORDER,XF
+ 0x0030=CELLSTYLE,,,,,,,
+ 0x0038=,,,,COL,MULTCELL_RSTRING,CELL_RSTRING,CALCCHAINCELL
+ 0x0040=DATAVALIDATION,,,,,,,
+
+ 0x0080=FILEVERSION,WORKSHEET,WORKSHEET_END,WORKBOOK,WORKBOOK_END,SHEETVIEWS,SHEETVIEWS_END,BOOKVIEWS
+ 0x0088=BOOKVIEWS_END,SHEETVIEW,SHEETVIEW_END,CHARTSHEETVIEWS,CHARTSHEETVIEWS_END,CHARTSHEETVIEW,CHARTSHEETVIEW_END,SHEETS
+ 0x0090=SHEETS_END,SHEETDATA,SHEETDATA_END,SHEETPR,DIMENSION,,,PANE
+ 0x0098=SELECTION,WORKBOOKPR,SMARTTAGPR,FILERECOVERYPR,SHEET,CALCPR,WORKBOOKVIEW,SST
+ 0x00A0=SST_END,AUTOFILTER,AUTOFILTER_END,FILTERCOLUMN,FILTERCOLUMN_END,DISCRETEFILTERS,DISCRETEFILTERS_END,DISCRETEFILTER
+ 0x00A8=COLORFILTER,ICONFILTER,TOP10FILTER,DYNAMICFILTER,CUSTOMFILTERS,CUSTOMFILTERS_END,CUSTOMFILTER,AFDATEGROUPITEM
+ 0x00B0=MERGECELL,MERGECELLS,MERGECELLS_END,PCDEFINITION,PCDEFINITION_END,PCDFIELDS,PCDFIELDS_END,PCDFIELD
+ 0x00B8=PCDFIELD_END,PCDSOURCE,PCDSOURCE_END,PCDSHEETSOURCE,PCDSHEETSOURCE_END,PCDFSHAREDITEMS,PCDFSHAREDITEMS_END,PCITEM_ARRAY
+ 0x00C0=PCITEM_ARRAY_END,PCRECORDS,PCRECORDS_END,,,,,
+ 0x00C8=,CONNECTION,CONNECTION_END,,,,,
+
+ 0x00D8=,,,PCDFIELDGROUP,PCDFIELDGROUP_END,PCDFGROUPITEMS,PCDFGROUPITEMS_END,PCDFRANGEPR
+ 0x00E0=PCDFRANGEPR_END,PCDFDISCRETEPR,PCDFDISCRETEPR_END,,,,,
+
+ 0x00F0=,,,,,,,PIVOTAREA
+ 0x00F8=PIVOTAREA_END,PTREFERENCES,PTREFERENCES_END,PTREFERENCE,PTREFERENCE_END,,,
+ 0x0100=,,,,,WEBPR,WEBPR_END,WEBPRTABLES
+ 0x0108=WEBPRTABLES_END,,,,,,,
+ 0x0110=,,,,,BINARYINDEX_END,STYLESHEET,STYLESHEET_END
+ 0x0118=PTDEFINITION,PTFITEM_END,PTFITEM,PTFITEMS,PTFITEMS_END,PTFIELD,PTFIELD_END,PTFIELDS
+ 0x0120=PTFIELDS_END,PTPAGEFIELD,PTPAGEFIELD_END,PTPAGEFIELDS,PTPAGEFIELDS_END,PTDATAFIELD,PTDATAFIELD_END,PTDATAFIELDS
+ 0x0128=PTDATAFIELDS_END,,,,,,,
+ 0x0130=,,,,,PTROWFIELDS,PTROWFIELDS_END,PTCOLFIELDS
+ 0x0138=PTCOLFIELDS_END,PTLOCATION_END,PTLOCATION,PTDEFINITION_END,,,,
+
+ 0x0150=,,,,,,,TABLE
+ 0x0158=TABLE_END,TABLECOLUMNS,TABLECOLUMNS_END,TABLECOLUMN,TABLECOLUMN_END,,,CALCEDCOLUMNFMLA
+ 0x0160=,EXTERNALREFS,EXTERNALREFS_END,EXTERNALREF,,EXTERNALSELF,EXTERNALSAME,EXTSHEETNAMES
+ 0x0168=EXTERNALBOOK,,EXTERNALSHEETS,EXTSHEETDATA,EXTSHEETDATA_END,,EXTROW,EXTCELL_BLANK
+ 0x0170=EXTCELL_DOUBLE,EXTCELL_BOOL,EXTCELL_ERROR,EXTCELL_STRING,,,,
+ 0x0178=,,,,,,PTREFERENCEITEM,PTREFERENCEITEM_END
+ 0x0180=PIVOTCACHES,PIVOTCACHES_END,PIVOTCACHE,PIVOTCACHE_END,,,COLS,COLS_END
+ 0x0188=ROWBREAKS,ROWBREAKS_END,COLBREAKS,COLBREAKS_END,BRK,CUSTOMWORKBOOKVIEW,,
+
+ 0x01A0=,,,,,,CUSTOMSHEETVIEWS,CUSTOMSHEETVIEW
+ 0x01A8=CUSTOMSHEETVIEW_END,CUSTOMSHEETVIEWS_END,ARRAY,SHAREDFMLA,DATATABLE,CONNECTIONS,CONNECTIONS_END,
+
+ 0x01B8=,,,,,,,QUERYTABLE
+ 0x01C0=QUERYTABLE_END,QUERYTABLEREFRESH,QUERYTABLEREFRESH_END,,,,,
+ 0x01C8=,,,AUTOSORTSCOPE,AUTOSORTSCOPE_END,CONDFORMATTING,CONDFORMATTING_END,CFRULE
+ 0x01D0=CFRULE_END,ICONSET,ICONSET_END,DATABAR,DATABAR_END,COLORSCALE,COLORSCALE_END,CFVO
+ 0x01D8=,COLORS,COLORS_END,RGBCOLOR,PAGEMARGINS,PRINTOPTIONS,PAGESETUP,HEADERFOOTER
+ 0x01E0=HEADERFOOTER_END,PTCHARTFORMAT,PTCHARTFORMAT_END,PTCHARTFORMATS,PTCHARTFORMATS_END,SHEETFORMATPR,,
+ 0x01E8=,,,,,,HYPERLINK,
+ 0x01F0=,,,,SCENARIOS,SCENARIOS_END,SCENARIO,SCENARIO_END
+ 0x01F8=INPUTCELLS,DXFS,DXFS_END,DXF,TABLESTYLES,TABLESTYLES_END,,
+ 0x0200=,TABLESTYLEINFO,VOLTYPES,VOLTYPES_END,VOLTYPE,VOLTYPE_END,VOLTYPEMAIN,VOLTYPEMAIN_END
+ 0x0208=VOLTYPETP,VOLTYPETP_END,VOLTYPESTP,VOLTYPETR,,VOLTYPE_ERROR,,
+ 0x0210=CALCCHAIN,CALCCHAIN_END,,,,,,SHEETPROTECTION
+ 0x0218=,PHONETICPR,,,,,,
+ 0x0220=,,,,,OLESIZE,DRAWING,LEGACYDRAWING
+
+ 0x0230=,,PICTURE,,CFCOLOR,INDEXEDCOLORS,INDEXEDCOLORS_END,
+ 0x0238=,MRUCOLORS,MRUCOLORS_END,,COLOR,DATAVALIDATIONS,DATAVALIDATIONS_END,
+ 0x0240=,EXTERNALNAME,DDEITEMVALUES,DDEITEMVALUES_END,DDEITEM_DOUBLE,DDEITEM_ERROR,DDEITEM_STRING,DDEITEM_EMPTY
+ 0x0248=DDEITEM_BOOL,EXTERNALNAMEREF,EXTERNALNAMEFLAGS,EXTERNALNAME_END,EXTERNALBOOK_END,,,
+ 0x0250=,,,,,,,PTFILTERS
+ 0x0258=PTFILTERS_END,PTFILTER,PTFILTER_END,FILLS,FILLS_END,,,
+ 0x0260=,,,FONTS,FONTS_END,BORDERS,BORDERS_END,NUMFMTS
+ 0x0268=NUMFMTS_END,CELLXFS,CELLXFS_END,CELLSTYLES,CELLSTYLES_END,,,
+ 0x0270=,,CELLSTYLEXFS,CELLSTYLEXFS_END,COMMENTS,COMMENTS_END,COMMENTAUTHORS,COMMENTAUTHORS_END
+ 0x0278=COMMENTAUTHOR,COMMENTLIST,COMMENTLIST_END,COMMENT,COMMENT_END,COMMENTTEXT,OLEOBJECTS,OLEOBJECT
+ 0x0280=OLEOBJECTS_END,,,CONTROLS,CONTROL,CONTROLS_END,,
+ 0x0288=,,,CHARTSHEETPR,CHARTPAGESETUP,CUSTOMCHARTVIEWS,CUSTOMCHARTVIEWS_END,CUSTOMCHARTVIEW
+ 0x0290=CUSTOMCHARTVIEW_END,,,,TABLEPARTS,TABLEPART,TABLEPARTS_END,SHEETCALCPR
+ 0x0298=FUNCTIONGROUPS,FUNCTIONGROUP,FUNCTIONGROUPS_END,EXTERNALADDIN,,CHARTPROTECTION,,
+end
+
+# simple records -------------------------------------------------------------
+
+constlist=SIMPLE-RECORDS
+ 0x001A=int32,dec,item-index
+ 0x00AC=int32,dec,relation,CUSTOMFILTERS-RELATION
+ 0x00B5=int32,dec,count
+ 0x00C1=int32,dec,count
+ 0x00DD=int32,dec,count
+ 0x00E1=int32,dec,count
+ 0x00F9=int32,dec,count
+ 0x0107=int32,dec,count
+ 0x011B=int32,dec,count
+ 0x011F=int32,dec,count
+ 0x0123=int32,dec,count
+ 0x0159=int32,dec,count
+ 0x017E=int32,dec,item-index
+ 0x01DD=uint16,hex,flags,PRINTOPTIONS-FLAGS
+ 0x01E3=int32,dec,count
+ 0x01F9=int32,dec,count
+ 0x0204=int32,dec,type,VOLTYPE-TYPE
+ 0x020D=uint8,dec,error-code,ERRORCODES
+ 0x0244=double,dec,value
+ 0x0245=uint8,dec,error-code,ERRORCODES
+ 0x0248=uint8,dec,value,BOOLEAN
+ 0x0257=int32,dec,count
+ 0x025B=int32,dec,count
+ 0x0263=int32,dec,count
+ 0x0265=int32,dec,count
+ 0x0267=int32,dec,count
+ 0x0269=int32,dec,count
+ 0x026B=int32,dec,count
+ 0x0272=int32,dec,count
+ 0x0294=int32,dec,count
+ 0x0297=uint8,hex,flags,SHEETCALCPR-FLAGS
+ 0x0298=uint8,dec,builtin-count
+end
+
+# ARRAY ----------------------------------------------------------------------
+
+flagslist=ARRAY-FLAGS
+ ignore=0xFE
+ 0x01=recalc-always
+end
+
+# BORDER ---------------------------------------------------------------------
+
+flagslist=BORDER-FLAGS
+ 0x01=diag-tl-to-br
+ 0x02=diag-bl-to-tr
+end
+
+# CALCPR ---------------------------------------------------------------------
+
+shortlist=CALCPR-CALCMODE,0,manual,auto,auto-no-tables
+
+flagslist=CALCPR-FLAGS
+ 0x0001=calc-on-load
+ 0x0002=a1
+ 0x0004=iterate
+ 0x0008=full-precision
+ 0x0010=calc-complete
+ 0x0020=calc-on-save
+ 0x0040=concurrent
+ 0x0080=manual-processors
+ 0x0100=force-full-calc
+end
+
+# CELLSTYLE ------------------------------------------------------------------
+
+flagslist=CELLSTYLE-FLAGS
+ 0x0001=builtin
+ 0x0002=hidden
+ 0x0004=custom
+end
+
+multilist=CELLSTYLE-BUILTIN
+ 0=normal,rowlevel,collevel,comma,currency,percent,comma-0,currency-0,hyperlink,followed-hyperlink
+ 10=note,warning-text,,,,title,heading-1,heading-2,heading-3,heading-4
+ 20=input,output,calculation,check-cell,linked-cell,total,good,bad,neutral,accent1
+ 30=20%-accent1,40%-accent1,60%-accent1,accent2,20%-accent2,40%-accent2,60%-accent2,accent3,20%-accent3,40%-accent3
+ 40=60%-accent3,accent4,20%-accent4,40%-accent4,60%-accent4,accent5,20%-accent5,40%-accent5,60%-accent5,accent6
+ 50=20%-accent6,40%-accent6,60%-accent6,explanatory-text
+end
+
+# CFRULE ---------------------------------------------------------------------
+
+shortlist=CFRULE-TYPE,1,cell-is,expression,color-scale,data-bar,top-ten,icon-set
+
+multilist=CFRULE-SUBTYPE
+ 0=cell-is,expression,color-scale,data-bar,icon-set,top-ten,,unique-values,contains-text,contains-blanks
+ 10=not-contains-blanks,contains-errors,not-contains-errors,,,today,tomorrow,yesterday,last-7-days,last-month
+ 20=next-month,this-week,next-week,last-week,this-month,above-average,below-average,duplicate-values,,equal-above-average
+ 30=equal-below-average
+end
+
+shortlist=CFRULE-CELL-OPERATOR,1,between,not-between,equal,not-equal,greater-than,less-than,greater-equal,less-equal
+shortlist=CFRULE-TEXT-OPERATOR,0,contains,not-contains,begins-with,ends-with
+shortlist=CFRULE-DATE-OPERATOR,0,today,yesterday,last-7-days,this-week,last-week,last-month,tomorrow,next-week,next-month,this-month
+shortlist=CFRULE-OTHER-OPERATOR,0,none
+
+flagslist=CFRULE-FLAGS
+ 0x0001=table-row
+ 0x0002=stop-if-true
+ 0x0004=above-average
+ 0x0008=bottom
+ 0x0010=percent
+end
+
+# CHARTPAGESETUP ------------------------------------------------------------------
+
+combilist=CHARTPAGESETUP-FLAGS
+ 0x0001=landscape
+ 0x0002=uninitialized
+ 0x0004=black-and-white
+ 0x0008=default-orientation
+ 0x0010=use-first-page
+ 0x0020=draft-quality
+end
+
+# CHARTSHEETPR ---------------------------------------------------------------
+
+flagslist=CHARTSHEETPR-FLAGS
+ 0x0001=published
+end
+
+# CHARTSHEETVIEW -------------------------------------------------------------
+
+flagslist=CHARTSHEETVIEW-FLAGS
+ 0x0001=selected
+ 0x0002=zoom-to-fit
+end
+
+# COL ------------------------------------------------------------------------
+
+combilist=COL-FLAGS
+ 0x0001=hidden
+ 0x0002=custom-width
+ 0x0004=best-fit
+ 0x0008=show-phonetic
+ 0x0700=uint8,dec,outline-level
+ 0x1000=outline-collapsed
+end
+
+# CONNECTION -----------------------------------------------------------------
+
+shortlist=CONNECTION-SAVEPASSWORD,1,on,off
+unitconverter=CONNECTION-INTERVAL,60,sec
+shortlist=CONNECTION-SOURCETYPE,1,odbc,dao,file,html,ole-db,text,ado,dsp
+shortlist=CONNECTION-RECONNECTTYPE,1,as-required,always,never
+shortlist=CONNECTION-CREDENTIALS,0,integrated,none,stored-sso,prompt
+
+flagslist=CONNECTION-FLAGS
+ 0x0001=keep-alive
+ 0x0002=new
+ 0x0004=deleted
+ 0x0008=only-use-conn-file
+ 0x0010=background
+ 0x0020=refresh-on-load
+ 0x0040=save-data
+end
+
+flagslist=CONNECTION-STRINGFLAGS
+ 0x0001=has-source-file
+ 0x0002=has-source-conn-file
+ 0x0004=has-description
+ 0x0008=has-name
+ 0x0010=has-sso-id
+end
+
+# CUSTOMFILTER ---------------------------------------------------------------
+
+constlist=CUSTOMFILTER-DATATYPE
+ 4=double
+ 6=string
+ 8=boolean
+ 12=blank
+ 14=not-blank
+end
+
+shortlist=CUSTOMFILTER-OPERATOR,1,less,equal,less-equal,greater,not-equal,greater-equal
+
+# CUSTOMFILTERS --------------------------------------------------------------
+
+shortlist=CUSTOMFILTERS-RELATION,0,and,or
+
+# DATATABLE ------------------------------------------------------------------
+
+flagslist=DATATABLE-FLAGS
+ 0x01=row-table
+ 0x02=table-2d
+ 0x04=ref1-deleted
+ 0x08=ref2-deleted
+ 0x10=recalc-always
+end
+
+# DATAVALIDATION -------------------------------------------------------------
+
+combilist=DATAVALIDATION-FLAGS
+ 0x0000000F=uint8,dec,type,DATAVALIDATION-TYPE
+ 0x00000070=uint8,dec,error-style,DATAVALIDATION-ERRORSTYLE
+ 0x00000080=string-list
+ 0x00000100=ignore-empty
+ 0x00000200=no-dropdown
+ 0x00040000=show-input-box
+ 0x00080000=show-error-box
+ 0x00F00000=uint8,dec,operator,DATAVALIDATION-OPERATOR
+end
+
+shortlist=DATAVALIDATION-TYPE,0,any,whole,decimal,list,date,time,text-length,custom
+shortlist=DATAVALIDATION-OPERATOR,0,between,not-between,equal,not-equal,greater-than,less-than,greater-equal,less-equal
+shortlist=DATAVALIDATION-ERRORSTYLE,0,error,warning,info
+
+# DATAVALIDATIONS ------------------------------------------------------------
+
+combilist=DATAVALIDATIONS-FLAGS
+ 0x0001=disable-prompts
+end
+
+# DEFINEDNAME ----------------------------------------------------------------
+
+combilist=DEFINEDNAME-FLAGS
+ 0x00000001=hidden
+ 0x00000002=function
+ 0x00000004=vba
+ 0x00000008=macro
+ 0x00000010=complex
+ 0x00000020=built-in
+ 0x00007FC0=int32,dec,func-group,DEFINEDNAME-FUNCGROUP
+ 0x00008000=published
+ 0x00010000=workbook-param
+end
+
+shortlist=DEFINEDNAME-FUNCGROUP,0,none,financial,date-time,math-trig,statistical,lookup-ref,database,text,logical,information,commands,customizing,macro-control,dde-external,user-definded
+
+constlist=DEFINEDNAME-SHEETID
+ default=
+ -1=global
+end
+
+# DISCRETEFILTERS --------------------------------------------------------------------
+
+shortlist=DISCRETEFILTERS-CALTYPE,0,none,gregorian,gregorian-us,japan,taiwan,korea,hijri,thai,hebrew,gregorian-mideast-fr,gregorian-ar,gregorian-xlit-en,gregorian-xlit-fr
+
+# DXF ------------------------------------------------------------------------
+
+flagslist=DXF-FLAGS
+ 0x00008000=border-outline
+end
+
+multilist=DXF-SUBREC
+ 0=FILL-PATTERN,FILL-FGCOLOR,FILL-BGCOLOR,FILL-GRADIENT,FILL-STOP
+ 5=FONT-COLOR,BORDER-TOP,BORDER-BOTTOM,BORDER-LEFT,BORDER-RIGHT
+ 10=BORDER-DIAGONAL,BORDER-VERTICAL,BORDER-HORIZONTAL,BORDER-DIAGUP,BORDER-DIAGDOWN
+ 15=ALIGN-HORIZONTAL,ALIGN-VERTICAL,ALIGN-ROTATION,ALIGN-INDENT,ALIGN-READINGORDER
+ 20=ALIGN-WRAPTEXT,ALIGN-JUSTLASTLINE,ALIGN-SHRINKTOFIT,,FONT-NAME
+ 25=FONT-WEIGHT,FONT-UNDERLINE,FONT-ESCAPEMENT,FONT-ITALIC,FONT-STRIKE
+ 30=FONT-OUTLINE,FONT-SHADOW,FONT-CONDENSE,FONT-EXTEND,FONT-CHARSET
+ 35=FONT-PITCHFAMILY,FONT-HEIGHT,FONT-SCHEME,NUMFMT-CODE,
+ 40=,NUMFMT-ID,ALIGN-RELINDENT,PROT-LOCKED,PROT-HIDDEN
+end
+
+# EXTERNALBOOK ---------------------------------------------------------------
+
+shortlist=EXTERNALBOOK-TYPE,0,book,dde-link,ole-link
+
+# EXTERNALNAMEFLAGS ----------------------------------------------------------
+
+flagslist=EXTERNALNAMEFLAGS-FLAGS
+ 0x0002=automatic
+ 0x0004=pic-link
+ 0x0008=dde-stddocumentname
+ 0x0010=ole-link
+ 0x0020=iconified
+end
+
+# EXTERNALSHEETS -------------------------------------------------------------
+
+constlist=EXTERNALSHEETS-ID
+ default=
+ -1=deleted
+ -2=special
+end
+
+# EXTSHEETDATA ---------------------------------------------------------------
+
+flagslist=EXTSHEETDATA-FLAGS
+ 0x01=refresh-error
+end
+
+# FILL -----------------------------------------------------------------------
+
+shortlist=FILL-GRADIENTTYPE,0,linear,path
+
+# FILTERCOLUMN ---------------------------------------------------------------
+
+flagslist=FILTERCOLUMN-FLAGS
+ 0x0001=hidden-button
+ 0x0002=show-button
+end
+
+# FONT -----------------------------------------------------------------------
+
+flagslist=FONT-FLAGS
+ 0x0001=bold
+ 0x0002=italic
+ 0x0004=underline
+ 0x0008=strikeout
+ 0x0010=outline
+ 0x0020=shadow
+ 0x0040=condense
+ 0x0080=extend
+end
+
+multilist=FONT-UNDERLINE
+ 0x00=none,single,double
+ 0x21=single-acc,double-acc
+end
+
+shortlist=FONT-SCHEME,0,none,major,minor
+shortlist=FONT-ESCAPEMENT,0,none,superscript,subscript
+
+# HEADERFOOTER ---------------------------------------------------------------
+
+flagslist=HEADERFOOTER-FLAGS
+ 0x0001=diff-odd-even
+ 0x0002=diff-dirst
+ 0x0004=scale-with-doc
+ 0x0008=align-with-margins
+end
+
+# OLEOBJECT ------------------------------------------------------------------
+
+shortlist=OLEOBJECT-ASPECT,1,content,,,icon
+shortlist=OLEOBJECT-UPDATE,0,na,automatic,,manual
+
+flagslist=OLEOBJECT-FLAGS
+ 0x0001=linked
+ 0x0002=auto-load
+end
+
+# PAGESETUP ------------------------------------------------------------------
+
+multilist=PAGESETUP-PAPERSIZE
+ 0=undefined,letter,letter-small,tabloid,ledger,legal,statement,executive,a3,a4
+ 10=a4-small,a5,b4,b5,folio,quarto,10x14,11x17,note,envelope-9
+ 20=envelope-10,envelope-11,envelope-12,envelope-14,c,d,e,envelope-dl,envelope-c5,envelope-c3
+ 30=envelope-c4,envelope-c6,envelope-c65,envelope-b4,envelope-b5,envelope-b6,envelope-italy,envelope-monarch,envelope-6-3/4,us-standard-fanfold
+ 40=german-standard-fanfold,german-legal-fanfold,b4,japanese-dbl-postcaed,9x11,10x11,15x11,,
+ 50=envelope-invite,letter-extra,legal-extra,tabloid-extra,a4-extra,letter-transverse,a4-transverse,letter-extra-transverse,super-a-a4,super-b-a3,letter-plus
+ 60=a4-plus,a5-transverse,jis-b5-transverse,a3-extra,a5-extra,b5-extra,a2,a3-transverse,a3-extra-transverse
+end
+
+constlist=PAGESETUP-SCALETOPAGES
+ default=
+ 0=automatic
+end
+
+combilist=PAGESETUP-FLAGS
+ 0x0001=print-in-rows
+ 0x0002=landscape
+ 0x0004=uninitialized
+ 0x0008=black-and-white
+ 0x0010=draft-quality
+ 0x0020=print-notes
+ 0x0040=default-orientation
+ 0x0080=use-first-page
+ 0x0100=print-notes-at-end
+ 0x0600=uint8,dec,print-errors,PAGESETUP-PRINTERRORS
+end
+
+shortlist=PAGESETUP-PRINTERRORS,0,displayed,none,as-dashes,as-na
+
+unitconverter=PAGESETUP-DPI,1,dpi
+
+# PANE -----------------------------------------------------------------------
+
+shortlist=PANE-ID,0,bottom-right,top-right,bottom-left,top-left
+
+flagslist=PANE-FLAGS
+ 0x01=frozen
+ 0x02=remove-split-with-freeze
+end
+
+# PCDEFINITION ---------------------------------------------------------------
+
+flagslist=PCDEFINITION-FLAGS1
+ 0x01=save-data
+ 0x02=invalid
+ 0x04=refresh-on-load
+ 0x08=optimize-memory
+ 0x10=enable-refresh
+ 0x20=background-query
+ 0x40=upgrade-on-refresh
+ 0x80=tuple-cache
+end
+
+constlist=PCDEFINITION-MISSINGITEMS
+ default=
+ -1=clear-automatic
+ 0=clear-always
+end
+
+flagslist=PCDEFINITION-FLAGS2
+ 0x01=has-username
+ 0x02=has-rel-id
+ 0x04=support-subquery
+ 0x08=support-drilldown
+end
+
+# PCDFIELD -------------------------------------------------------------------
+
+flagslist=PCDFIELD-FLAGS
+ 0x0001=server-field
+ 0x0002=no-unique-items
+ 0x0004=database-field
+ 0x0008=has-caption
+ 0x0010=member-property-field
+ 0x0100=has-formula
+ 0x0200=has-property-name
+end
+
+# PCDFRANGEPR ----------------------------------------------------------------
+
+shortlist=PCDFRANGEPR-GROUPBY,0,numeric,seconds,minutes,hours,days,months,quarters,years
+
+flagslist=PCDFRANGEPR-FLAGS
+ 0x01=auto-start
+ 0x02=auto-end
+ 0x04=date-group
+end
+
+# PCDFSHAREDITEMS ------------------------------------------------------------
+
+flagslist=PCDFSHAREDITEMS-FLAGS
+ 0x0001=has-semi-mixed-types
+ 0x0002=has-non-date
+ 0x0004=has-date
+ 0x0008=has-string-bool-err
+ 0x0010=has-blank
+ 0x0020=has-mixed-types
+ 0x0040=is-numeric
+ 0x0080=is-integer
+ 0x0100=has-min-max
+ 0x0200=long-text
+end
+
+# PCDSOURCE ------------------------------------------------------------------
+
+shortlist=PCDSOURCE-TYPE,0,worksheet,external,consolidation,scenario
+
+# PCDWORKSHEETSOURCE ---------------------------------------------------------
+
+flagslist=PCDWORKSHEETSOURCE-FLAGS
+ 0x01=has-rel-id
+ 0x02=has-sheet
+end
+
+# PCITEM_ARRAY ---------------------------------------------------------------
+
+constlist=PCITEM_ARRAY-TYPE
+ 0x0001=double
+ 0x0002=string
+ 0x0010=error
+ 0x0020=date
+end
+
+# PHONETICPR -----------------------------------------------------------------
+
+shortlist=PHONETICPR-TYPE,0,halfwidth-katakana,fullwidth-katakana,hiragana,no-conversion
+shortlist=PHONETICPR-ALIGNMENT,0,no-control,left,center,distributed
+
+# PIVOTAREA ------------------------------------------------------------------
+
+shortlist=PIVOTAREA-TYPE,0,none,normal,data,all,origin,button,top-right
+
+flagslist=PIVOTAREA-FLAGS1
+ 0x01=data-only
+ 0x02=label-only
+ 0x04=grand-row
+ 0x08=grand-col
+ 0x10=cache-based
+ 0x20=line-mode
+ 0x40=part
+ 0x80=fuzzy
+end
+
+combilist=PIVOTAREA-FLAGS2
+ 0x0001=row
+ 0x0002=col
+ 0x0004=page
+ 0x0008=data
+ 0x0FF0=uint8,dec,pos-on-axis
+end
+
+# PRINTOPTIONS ---------------------------------------------------------------
+
+flagslist=PRINTOPTIONS-FLAGS
+ 0x0001=horizontal-centered
+ 0x0002=vertical-centered
+ 0x0004=print-headings
+ 0x0008=print-gridlines
+ 0x0010=gridlines-set
+end
+
+# Pivot table globals --------------------------------------------------------
+
+constlist=PT-FIELDINDEX
+ default=
+ -2=data-field
+end
+
+# PTDATAFIELD ----------------------------------------------------------------
+
+shortlist=PTDATAFIELD-SUBTOTAL,0,sum,count-all,average,max,min,product,count-num,std-dev,std-dev-p,var,var-p
+shortlist=PTDATAFIELD-SHOWDATAAS,0,normal,difference,percent,percent-diff,run-total,percent-of-row,percent-of-col,percent-of-total,index
+
+constlist=PTDATAFIELD-BASEITEM
+ default=
+ 0x001000FC=previous-item
+ 0x001000FD=next-item
+end
+
+# PTDEFINITION ---------------------------------------------------------------
+
+flagslist=PTDEFINITION-FLAGS1
+ 0x01=show-items
+ 0x02=edit-data
+ 0x04=disable-field-list
+ 0x08=refresh-on-load
+ 0x10=hide-calc-members
+ 0x20=with-hidden-totals
+ 0x40=show-multiple-label
+end
+
+combilist=PTDEFINITION-FLAGS2
+ 0x0001=hide-data-drop-down
+ 0x0010=hide-drill
+ 0x0020=print-drill
+ 0x0040=show-member-prop-tips
+ 0x0080=hide-data-tips
+ 0x7F00=uint8,dec,indent
+ 0x8000=hide-headers
+end
+
+flagslist=PTDEFINITION-FLAGS3
+ ignore=0x00010000
+ 0x00000001=hide-drop-zones
+ 0x00000002=no-asterisk-totals
+ 0x00000004=show-empty-row
+ 0x00000008=show-empty-col
+ 0x00000010=enable-wizard
+ 0x00000020=enable-drill
+ 0x00000040=enable-field-props
+ 0x00000080=preserve-formatting
+ 0x00000100=use-auto-formatting
+ 0x00000200=show-error
+ 0x00000400=show-missing
+ 0x00000800=page-over-then-down
+ 0x00001000=multiple-page-items
+ 0x00002000=row-grand-totals
+ 0x00004000=col-grand-totals
+ 0x00008000=field-print-titles
+ 0x00020000=item-print-titles
+ 0x00040000=merge-item
+ 0x00080000=has-data-caption
+ 0x00100000=has-grand-total-caption
+ 0x00200000=has-page-field-style
+ 0x00400000=has-pivot-table-style
+ 0x00800000=has-vacated-style
+ 0x01000000=apply-num-fmt
+ 0x02000000=apply-font
+ 0x04000000=apply-alignment
+ 0x08000000=apply-border
+ 0x10000000=apply-fill
+ 0x20000000=apply-protection
+ 0x40000000=has-tag
+end
+
+flagslist=PTDEFINITION-FLAGS4
+ 0x00000001=compact
+ 0x00000002=outline
+ 0x00000004=outline-data
+ 0x00000008=compact-data
+ 0x00000010=no-grid-drop-zones
+ 0x00000020=published
+ 0x00000040=!has-error-caption
+ 0x00000080=!has-missing-caption
+ 0x00000100=immersive-off
+ 0x00000200=single-field-filters
+ 0x00000400=has-row-header-caption
+ 0x00000800=has-col-header-caption
+ 0x00001000=field-list-sort-asc
+ 0x00004000=no-custom-list-sort
+end
+
+shortlist=PTDEFINITION-DATAFIELD-AXIS,1,row-axis,col-axis
+
+constlist=PTDEFINITION-DATAFIELD-POS
+ default=
+ -1=append
+end
+
+# PTFIELD --------------------------------------------------------------------
+
+flagslist=PTFIELD-FLAGS1
+ 0x00000001=row
+ 0x00000002=col
+ 0x00000004=page
+ 0x00000008=data
+ 0x00000100=default
+ 0x00000200=sum
+ 0x00000400=count-all
+ 0x00000800=average
+ 0x00001000=max
+ 0x00002000=min
+ 0x00004000=product
+ 0x00008000=count-num
+ 0x00010000=std-dev
+ 0x00020000=std-dev-p
+ 0x00040000=variance
+ 0x00080000=variance-p
+ 0x01000000=drilled-level
+ 0x02000000=hide-dropdown
+ 0x04000000=hidden-level
+ 0x08000000=has-member-prop-caption
+ 0x10000000=compact
+ 0x20000000=has-display-name
+ 0x40000000=has-subtotal-caption
+ 0x80000000=source-ordered
+end
+
+flagslist=PTFIELD-FLAGS2
+ 0x00000001=drag-to-row
+ 0x00000002=drag-to-col
+ 0x00000004=drag-to-page
+ 0x00000008=drag-to-hide
+ 0x00000010=drag-to-data
+ 0x00000020=show-all-items
+ 0x00000040=outline
+ 0x00000080=insert-blank-row
+ 0x00000100=subtotal-top
+ 0x00000200=server-based
+ 0x00000800=insert-page-break
+ 0x00001000=autosort
+ 0x00002000=ascend-sort
+ 0x00004000=autoshow
+ 0x00008000=autoshow-top
+ 0x00010000=hide-new-items
+ 0x00020000=has-value-filter
+ 0x00040000=exclude-new-items
+ 0x00080000=multiple-page-items
+ 0x00100000=simple-data-sort
+ 0x00200000=show-member-prop-report
+ 0x00400000=show-member-prop-tooltip
+ 0x00800000=show-member-prop-caption
+ 0x01000000=items-drilled
+end
+
+# PTFILTER -------------------------------------------------------------------
+
+multilist=PTFILTER-TYPE
+ 0=unknown,count,percent,sum,caption-equal,caption-not-equal,caption-begins-width,caption-not-begins-with,caption-ends-width,caption-not-ends-with
+ 10=caption-contains,caption-not-contains,caption-greater-than,caption-greater-equal,caption-less-than,caption-less-equal,caption-between,caption-not-between,value-equal,value-not-equal
+ 20=value-greater-than,value-greater-equal,value-less-than,value-less-equal,value-between,value-not-between,date-equal,date-older-than,date-newer-than,date-between
+ 30=date-tomorrow,date-today,date-yesterday,date-next-week,date-this-week,date-last-week,date-next-month,date-this-month,date-last-month,date-next-quarter
+ 40=date-this-quarter,date-last-quarter,date-next-year,date-this-year,date-last-year,year-to-date,date-q1,date-q2,date-q3,date-q4
+ 50=date-jan,date-feb,date-mar,date-apr,date-may,date-jun,date-jul,date-aug,date-sep,date-oct
+ 60=date-nov,date-dec,date-not-equal,date-older-equal,date-newer-equal,date-not-between
+end
+
+flagslist=PTFILTER-FLAGS
+ 0x0001=has-name
+ 0x0002=has-description
+ 0x0004=has-str-value1
+ 0x0008=has-str-value2
+end
+
+# PTFITEM --------------------------------------------------------------------
+
+shortlist=PTFITEM-TYPE,0,data,default,sum,count-all,average,max,min,product,count-numbers,std-dev,std-dev-p,var,var-p,grand-total,blank
+
+flagslist=PTFITEM-FLAGS
+ 0x0001=hidden
+ 0x0002=hide-detail
+ 0x0004=calculated
+ 0x0008=missing
+ 0x0010=has-name
+ 0x0020=drilled-member
+ 0x0040=can-have-children
+ 0x0080=collapsed-member
+ 0x0100=olap-filter-selected
+end
+
+# PTPAGEFIELD ----------------------------------------------------------------
+
+constlist=PTPAGEFIELD-ITEM
+ default=
+ 0x001000FE=multiple-items
+end
+
+flagslist=PTPAGEFIELD-FLAGS
+ 0x01=has-unique-name
+ 0x02=has-member-caption
+end
+
+# PTREFERENCE ----------------------------------------------------------------
+
+flagslist=PTREFERENCE-FLAGS1
+ 0x0001=data
+ 0x0002=default
+ 0x0004=sum
+ 0x0008=count-all
+ 0x0010=average
+ 0x0020=max
+ 0x0040=min
+ 0x0080=product
+ 0x0100=count-num
+ 0x0200=std-dev
+ 0x0400=std-dev-p
+ 0x0800=variance
+ 0x1000=variance-p
+end
+
+flagslist=PTREFERENCE-FLAGS2
+ 0x01=selected
+end
+
+# QUERYTABLE -----------------------------------------------------------------
+
+combilist=QUERYTABLE-FLAGS
+ 0x00000001=headers
+ 0x00000002=row-numbers
+ 0x00000004=disable-refresh
+ 0x00000008=background
+ 0x00000010=first-background
+ 0x00000020=refresh-on-load
+ 0x000000C0=uint8,dec,grow-shrink,QUERYTABLE-GROWSHRINK
+ 0x00000100=fill-formulas
+ 0x00000200=save-data
+ 0x00000400=disable-edit
+ 0x00000800=preserve-formatting
+ 0x00001000=adjust-column-width
+ 0x00002000=intermediate
+ 0x00004000=apply-num-fmt
+ 0x00008000=apply-font
+ 0x00010000=apply-alignment
+ 0x00020000=apply-border
+ 0x00040000=apply-fill
+ 0x00080000=apply-protection
+end
+
+shortlist=QUERYTABLE-GROWSHRINK,0,insert-clear,insert-delete,overwrite-clear
+
+# ROW ------------------------------------------------------------------------
+
+combilist=ROW-FLAGS1
+ 0x0001=thick-top
+ 0x0002=thick-bottom
+ 0x0700=uint8,dec,outline-level
+ 0x0800=outline-collapsed
+ 0x1000=hidden
+ 0x2000=custom-height
+ 0x4000=custom-format
+end
+
+flagslist=ROW-FLAGS2
+ 0x01=show-phonetic
+end
+
+# SHEET ----------------------------------------------------------------------
+
+shortlist=SHEET-STATE,0,visible,hidden,very-hidden
+
+# SHEETCALCPR ----------------------------------------------------------------
+
+flagslist=SHEETCALCPR-FLAGS
+ 0x01=calc-on-load
+end
+
+# SHEETFORMATPR --------------------------------------------------------------
+
+flagslist=SHEETFORMATPR-FLAGS
+ 0x0001=custom-row-height
+ 0x0002=rows-hidden
+end
+
+# SHEETPR --------------------------------------------------------------------
+
+flagslist=SHEETPR-FLAGS1
+ 0x0001=show-autopagebreaks
+ 0x0008=published
+ 0x0010=dialog-sheet
+ 0x0020=outline-auto-style
+ 0x0040=row-symbols-below
+ 0x0080=column-symbols-right
+ 0x0100=fit-to-pages
+ 0x0400=show-outline-symbols
+ 0x1000=is-row-synched
+ 0x2000=is-col-synched
+ 0x4000=lotus-formula-eval
+ 0x8000=lotus-formula-entry
+end
+
+flagslist=SHEETPR-FLAGS2
+ 0x01=is-filtered
+ 0x02=eval-cond-formats
+end
+
+# SHEETVIEW ------------------------------------------------------------------
+
+flagslist=SHEETVIEW-FLAGS
+ 0x0001=window-protected
+ 0x0002=show-formulas
+ 0x0004=show-gridlines
+ 0x0008=show-headings
+ 0x0010=show-zeros
+ 0x0020=right-to-left
+ 0x0040=selected
+ 0x0080=show-ruler
+ 0x0100=show-outline-symbols
+ 0x0200=default-gridcolor
+ 0x0400=show-whitespace
+end
+
+shortlist=SHEETVIEW-TYPE,0,normal,pagebreak-preview,page-layout
+
+# TABLE ----------------------------------------------------------------------
+
+shortlist=TABLE-TYPE,0,worksheet,,,query-table
+
+flagslist=TABLE-FLAGS
+ 0x00000001=totals-row-shown
+ 0x00000002=published
+ 0x00000004=insert-row
+ 0x00000008=insert-row-shift
+end
+
+# TABLESTYLEINFO -------------------------------------------------------------
+
+flagslist=TABLESTYLEINFO-FLAGS
+ 0x0001=show-first-column
+ 0x0002=show-last-column
+ 0x0004=show-row-stripes
+ 0x0008=show-column-stripes
+ 0x0010=show-row-headers
+ 0x0020=show-column-headers
+end
+
+# TOP10FILTER ----------------------------------------------------------------
+
+flagslist=TOP10FILTER-FLAGS
+ 0x01=!bottom!top
+ 0x02=percent
+ 0x04=applied
+end
+
+# VOLTYPE --------------------------------------------------------------------
+
+shortlist=VOLTYPE-TYPE,0,realtime-data,olap-functions
+
+# WEBPR ----------------------------------------------------------------------
+
+combilist=WEBPR-FLAGS
+ 0x000000FF=uint8,dec,html-format,WEBPR-HTMLFORMAT
+ 0x00000100=xml
+ 0x00000200=source-data
+ 0x00000400=parse-pre
+ 0x00000800=consecutive-delimiters
+ 0x00001000=first-row
+ 0x00002000=xl97-created
+ 0x00004000=text-dates
+ 0x00008000=xl2000-refreshed
+ 0x00010000=html-tables
+end
+
+shortlist=WEBPR-HTMLFORMAT,0,none,rtf,all
+
+flagslist=WEBPR-STRINGFLAGS
+ 0x01=has-post-method
+ 0x02=has-edit-page
+ 0x04=has-url
+end
+
+# WORKBBOKPR -----------------------------------------------------------------
+
+combilist=WORKBBOKPR-FLAGS
+ 0x00000001=date-1904
+ 0x00000004=hide-border-unsel-tables
+ 0x00000008=filter-privacy
+ 0x00000010=prompted-solutions
+ 0x00000020=show-ink-annotation
+ 0x00000040=backup-file
+ 0x00000080=strip-extlink-values
+ 0x00000300=uint8,dec,update-links,WORKBBOKPR-UPDATELINKS
+ 0x00000400=hide-pivot-fieldlist
+ 0x00000800=publish-items
+ 0x00001000=check-compatibility
+ 0x00006000=uint8,dec,show-objects,WORKBBOKPR-SHOWOBJECTS
+ 0x00008000=show-pivotchart-filter
+ 0x00010000=autocompress-pic
+ 0x00020000=refresh-all-links
+end
+
+shortlist=WORKBBOKPR-UPDATELINKS,0,ask-user,never,always
+shortlist=WORKBBOKPR-SHOWOBJECTS,0,show,placeholder,hide
+
+# WORKBOOKVIEW ---------------------------------------------------------------
+
+flagslist=WORKBOOKVIEW-FLAGS
+ 0x01=hidden
+ 0x02=minimized
+ 0x08=show-horizontal-scroll
+ 0x10=show-vertical-scroll
+ 0x20=show-tabbar
+ 0x40=autofilter-date-grouping
+end
+
+# XF -------------------------------------------------------------------------
+
+shortlist=XF-HORALIGN,0,general,left,center,right,fill,block,center-across-sel,distribute
+shortlist=XF-VERALIGN,0,top,center,bottom,justify,distribute
+shortlist=XF-TEXTDIRECTION,0,context,left-to-right,right-to-left
+
+combilist=XF-ALIGNMENT
+ 0x000000FF=uint8,dec,rotation,TEXTROTATION
+ 0x0000FF00=uint8,dec,indent
+ 0x00070000=uint8,dec,hor-align,XF-HORALIGN
+ 0x00380000=uint8,dec,ver-align,XF-VERALIGN
+ 0x00400000=text-wrap
+ 0x00800000=justify-lastline
+ 0x01000000=shrink-to-fit
+ 0x0C000000=uint8,dec,text-dir,XF-TEXTDIRECTION
+ 0x10000000=locked
+ 0x20000000=formula-hidden
+ 0x80000000=quote-prefix
+end
+
+flagslist=XF-USEDFLAGS
+ 0x0001=format
+ 0x0002=font
+ 0x0004=alignment
+ 0x0008=border
+ 0x0010=fill
+ 0x0020=protection
+end
+
+# ============================================================================