from filetypes.base import *
import malcat
import struct

#http://bio.gsi.de/DOCS/AIX/wword8.html#57
class WordFIB(Struct):

    def parse(self):
        magic = yield UInt16(name="Magic")
        if magic != 0xA5EC:
            raise FatalError
        version = yield UInt16(name="Version", comment="FIB version written. This will be >= 101 for all Word 6.0 for Windows and after documents.")
        yield UInt16(name="Product", comment="product version written by")
        yield UInt16(name="Lid", comment="language stamp -- localized version. In pre-WinWord 2.0 files this value was the nLocale. If value is < 999, then it is the nLocale, otherwise it is the lid.", values=LanguageId.ALL)
        yield UInt16(name="Next", comment="specifies the offset in the WordDocument stream of the FIB for the document which contains all the AutoText items. If this value is 0, there are no AutoText items attached. Otherwise the FIB is found at file location pnNext×512")
        flags = yield BitsField(
            Bit(name="Dot", comment="this document is a template"),
            Bit(name="Glossary", comment="this document is a glossary"),
            Bit(name="Complex", comment="file is in complex, fast-saved format"),
            Bit(name="HasPic", comment="file contains 1 or more pictures"),
            Bit(name="QuickSave0", comment="number of times the files was quicksaved"),
            Bit(name="QuickSave1", comment="number of times the files was quicksaved"),
            Bit(name="QuickSave2", comment="number of times the files was quicksaved"),
            Bit(name="QuickSave3", comment="number of times the files was quicksaved"),
            Bit(name="Encrypted", comment="file is encrypted"),
            Bit(name="WhichTblStm", comment="when 0, this fib refers to the table stream named 0Table, when 1, this fib refers to the table stream named 1Table. Normally, a file will have only one table stream, but under unusual circumstances a file may have table streams with both names. In that case, this flag must be used to decide which table stream is valid"),
            Bit(name="ReadOnlyRecommended", comment="user has recommended that file be read read-only"),
            Bit(name="WriteReservation", comment="file owner has made the file write reserved"),
            Bit(name="ExtChar", comment="must be set"),
            Bit(name="LoadOverride", comment="override the language information and font that are specified in the paragraph style at istd 0 (the normal style) with the defaults that are appropriate for the installation language of the application"),
            Bit(name="FarEast", comment="installation language of the application that created the document was an East Asian language"),
            Bit(name="Obfuscated", comment="document is obfuscated by using XOR obfuscation"),
            name="Flags", comment="document attributes")
        fb = yield UInt16(name="FibBack", comment="file format it compatible with readers that understand nFib at or above this value")
        if fb not in (0xBF, 0xC1):
            raise FatalError("Invalid FIBBack")
        yield UInt32(name="Key", comment="If fEncrypted is 1 and fObfuscation is 1, this value specifies the XOR obfuscation (section 2.2.6.1) password verifier. If fEncrypted is 1 and fObfuscation is 0, this value specifies the size of the EncryptionHeader that is stored at the beginning of the Table stream as described in Encryption and Obfuscation")
        yield UInt8(name="Environment", values=[
            ("Windows", 0),
            ("Mac", 1),
            ])
        yield BitsField(
            Bit(name="Mac", comment="this document is a template"),
            Bit(name="EmptySpecial", comment=""),
            Bit(name="LoadOverridePage", comment="override the section properties for page size, orientation, and margins with the defaults that are appropriate for the installation language of the application"),
            Bit(name="FutureSavedUndo", comment=""),
            Bit(name="Word97Saved", comment=""),
            name="SaveFlags", comment="")
        yield UInt16(name="CharacterSet", comment="extended character set id for text in document stream")
        yield UInt16(name="CharacterSetTables", comment="extended character set id for text in internal data structures 0 by default characters stored in internal data structures should be interpreted using the ANSI character set used by Windows 256 characters stored in internal data structures should be interpreted using the Macintosh character set")
        yield UInt32(name="Min", comment="file offset of first character of text. In non-complex files a CP can be transformed into an FC by the following transformation: fc = cp + fib.fcMin")
        yield UInt32(name="Max", comment="file offset of last character of text in document text stream + 1")
        numshorts = yield UInt16(name="NumberOfWords", comment="count of 16-bit values corresponding to fibRgW that follow")
        if numshorts != 0xE:
            raise FatalError("NumberOfWords")
        yield UInt16(name="MagicCreated", comment="unique number Identifying the File's creator 0x6A62 is the creator ID for Word and is reserved. Other creators should choose a different value")
        yield UInt16(name="MagicRevised", comment="unique number Identifying the File's last modifier 0x6A62 is the creator ID for Word and is reserved. Other creators should choose a different value")
        for i in range(11):
            yield UInt16(name="WordReserved{}".format(i), comment="reserved")
        yield UInt16(name="LidFE", comment="Language id if document was written by Far East version of Word", values=LanguageId.ALL)
        numlongs = yield UInt16(name="NumberOfLongs", comment="count of 32-bit values corresponding to fibRgLw that follow")
        if numlongs != 0x16:
            raise FatalError("NumberOfLongs")
        yield UInt32(name="cbMac", comment="file offset of last byte written to file + 1.")
        yield UInt32(name="lProductCreated", comment="contains the build date of the creator. 10695 indicates the creator program was compiled on Jan 6, 1995")
        yield UInt32(name="lProductRevised", comment="contains the build date of the File's last modifier")
        yield UInt32(name="ccpText", comment="length of main document text stream")
        yield UInt32(name="ccpFtn", comment="length of footnote subdocument text stream")
        yield UInt32(name="ccpHdd", comment="length of header subdocument text stream")
        yield UInt32(name="ccpMcr", comment="length of macro subdocument text stream, which should now always be 0.")
        yield UInt32(name="ccpAtn", comment="length of annotation subdocument text stream")
        yield UInt32(name="ccpEdn", comment="length of endnote subdocument text stream")
        yield UInt32(name="ccpTxbx", comment="length of textbox subdocument text stream")
        yield UInt32(name="ccpHdrTxbx", comment="length of header textbox subdocument text stream.")
        yield UInt32(name="pnFbpChpFirst", comment="when there was insufficient memory for Word to expand the plcfbte at save time, the plcfbte is written to the file in a linked list of 512-byte pieces starting with this pn")
        yield UInt32(name="pnChpFirst", comment="the page number of the lowest numbered page in the document that records CHPX FKP information")
        yield UInt32(name="cpnBteChp", comment="count of CHPX FKPs recorded in file. In non-complex files if the number of entries in the plcfbteChpx is less than this, the plcfbteChpx is incomplete.")
        yield UInt32(name="pnFbpPapFirst", comment="when there was insufficient memory for Word to expand the plcfbte at save time, the plcfbte is written to the file in a linked list of 512-byte pieces starting with this pn")
        yield UInt32(name="pnPapFirst", comment="the page number of the lowest numbered page in the document that records PAPX FKP information")
        yield UInt32(name="cpnBtePap", comment="count of PAPX FKPs recorded in file. In non-complex files if the number of entries in the plcfbtePapx is less than this, the plcfbtePapx is incomplete.")
        yield UInt32(name="pnFbpLvcFirst", comment="when there was insufficient memory for Word to expand the plcfbte at save time, the plcfbte is written to the file in a linked list of 512-byte pieces starting with this pn")
        yield UInt32(name="pnLvcFirst", comment="the page number of the lowest numbered page in the document that records LVC FKP information")
        yield UInt32(name="cpnBteLvc", comment="count of LVC FKPs recorded in file. In non-complex files if the number of entries in the plcfbtePapx is less than this, the plcfbtePapx is incomplete.")
        yield UInt32(name="fcIslandFirst", comment="")
        yield UInt32(name="fcIslandLim", comment="")
        numfcb = yield UInt16(name="NumberOfFcbPairs", comment="fields in the array of FC/LCB pairs")
        if numfcb not in (0x5d, 0x6c, 0x88, 0xa4, 0xb7):
            raise FatalError("NumberOfFcbPairs: 0x{:x}".format(numfcb))
        yield UInt32(name="fcStshfOrig", comment="file offset of original allocation for STSH in table stream. During fast save Word will attempt to reuse this allocation if STSH is small enough to fit.")
        yield UInt32(name="lcbStshfOrig", comment="count of bytes of original STSH allocation")
        yield UInt32(name="fcStshf", comment="offset of STSH in table stream.")
        yield UInt32(name="lcbStshf", comment="count of bytes of current STSH allocation")
        yield UInt32(name="fcPlcffndRef", comment="offset in table stream of footnote reference PLCF of FRD structures. CPs in PLC are relative to main document text stream and give location of footnote references.")
        yield UInt32(name="lcbPlcffndRef", comment="count of bytes of footnote reference PLC== 0 if no footnotes defined in document.")
        yield UInt32(name="fcPlcffndTxt", comment="offset in table stream of footnote text PLC. CPs in PLC are relative to footnote subdocument text stream and give location of beginnings of footnote text for corresponding references recorded in plcffndRef. No structure is stored in this plc. There will just be n+1 FC entries in this PLC when there are n footnotes")
        yield UInt32(name="lcbPlcffndTxt", comment="count of bytes of footnote text PLC. == 0 if no footnotes defined in document")
        yield UInt32(name="fcPlcfandRef", comment="offset in table stream of annotation reference ATRD PLC. The CPs recorded in this PLC give the offset of annotation references in the main document.")
        yield UInt32(name="lcbPlcfandRef", comment="count of bytes of annotation reference PLC.")
        yield UInt32(name="fcPlcfandTxt", comment="offset in table stream of annotation text PLC. The Cps recorded in this PLC give the offset of the annotation text in the annotation sub document corresponding to the references stored in the plcfandRef. There is a 1 to 1 correspondence between entries recorded in the plcfandTxt and the plcfandRef. No structure is stored in this PLC.")
        yield UInt32(name="lcbPlcfandTxt", comment="count of bytes of the annotation text PLC")
        yield UInt32(name="fcPlcfsed", comment="offset in table stream of section descriptor SED PLC. CPs in PLC are relative to main document.")
        yield UInt32(name="lcbPlcfsed", comment="count of bytes of section descriptor PLC.")
        yield UInt32(name="fcPlcpad", comment="no longer used")
        yield UInt32(name="lcbPlcpad", comment="no longer used")
        yield UInt32(name="fcPlcfphe", comment="offset in table stream of PHE PLC of paragraph heights. CPs in PLC are relative to main document text stream. Only written for files in complex format. Should not be written by third party creators of Word files.")
        yield UInt32(name="lcbPlcfphe", comment="count of bytes of paragraph height PLC. ==0 when file is non-complex.")
        yield UInt32(name="fcSttbfglsy", comment="offset in table stream of glossary string table. This table consists of Pascal style strings (strings stored prefixed with a length byte) concatenated one after another.")
        yield UInt32(name="lcbSttbfglsy", comment="count of bytes of glossary string table. == 0 for non-glossary documents.!=0 for glossary documents.")
        yield UInt32(name="fcPlcfglsy", comment="offset in table stream of glossary PLC. CPs in PLC are relative to main document and mark the beginnings of glossary entries and are in 1-1 correspondence with entries of sttbfglsy. No structure is stored in this PLC. There will be n+1 FC entries in this PLC when there are n glossary entries.")
        yield UInt32(name="lcbPlcfglsy", comment="count of bytes of glossary PLC.== 0 for non-glossary documents.!=0 for glossary documents.")
        yield UInt32(name="fcPlcfhdd", comment="byte offset in table stream of header HDD PLC. CPs are relative to header subdocument and mark the beginnings of individual headers in the header subdocument. No structure is stored in this PLC. There will be n+1 FC entries in this PLC when there are n headers stored for the document.")
        yield UInt32(name="lcbPlcfhdd", comment="count of bytes of header PLC.")
        yield UInt32(name="fcPlcfbteChpx", comment="offset in table stream of character property bin table.PLC. FCs in PLC are file offsets in the main stream. Describes text of main document and all subdocuments.")
        yield UInt32(name="lcbPlcfbteChpx", comment="count of bytes of character property bin table PLC.")
        yield UInt32(name="fcPlcfbtePapx", comment="offset in table stream of paragraph property bin table.PLC. FCs in PLC are file offsets in the main stream. Describes text of main document and all subdocuments.")
        yield UInt32(name="lcbPlcfbtePapx", comment="count of bytes of paragraph property bin table PLC")
        yield UInt32(name="fcPlcfsea", comment="offset in table stream of PLC reserved for private use. The SEA is 6 bytes long.")
        yield UInt32(name="lcbPlcfsea", comment="count of bytes of private use PLC.")
        yield UInt32(name="fcSttbfffn", comment="offset in table stream of font information STTBF. The sttbfffn is a STTBF where is string is actually an FFN structure. The nth entry in the STTBF describes the font that will be displayed when the chp.ftc for text is equal to n. See the FFN file structure definition.")
        yield UInt32(name="lcbSttbfffn", comment="count of bytes in sttbfffn.")
        yield UInt32(name="fcPlcffldMom", comment="offset in table stream to the FLD PLC of field positions in the main document. The CPs point to the beginning CP of a field, the CP of field separator character inside a field and the ending CP of the field. A field may be nested within another field. 20 levels of field nesting are allowed.")
        yield UInt32(name="lcbPlcffldMom", comment="count of bytes in plcffldMom")
        yield UInt32(name="fcPlcffldHdr", comment="offset in table stream to the FLD PLC of field positions in the header subdocument.")
        yield UInt32(name="lcbPlcffldHdr", comment="count of bytes in plcffldHdr")
        yield UInt32(name="fcPlcffldFtn", comment="offset in table stream to the FLD PLC of field positions in the footnote subdocument.")
        yield UInt32(name="lcbPlcffldFtn", comment="count of bytes in plcffldFtn")
        yield UInt32(name="fcPlcffldAtn", comment="offset in table stream to the FLD PLC of field positions in the annotation subdocument.")
        yield UInt32(name="lcbPlcffldAtn", comment="count of bytes in plcffldAtn")
        yield UInt32(name="fcPlcffldMcr", comment="no longer used")
        yield UInt32(name="lcbPlcffldMcr", comment="no longer used")
        yield UInt32(name="fcSttbfbkmk", comment="offset in table stream of the STTBF that records bookmark names in the main document")
        yield UInt32(name="lcbSttbfbkmk", comment="")
        yield UInt32(name="fcPlcfbkf", comment="offset in table stream of the PLCF that records the beginning CP offsets of bookmarks in the main document. See BKF structure definition")
        yield UInt32(name="lcbPlcfbkf", comment="")
        yield UInt32(name="fcPlcfbkl", comment="offset in table stream of the PLCF that records the ending CP offsets of bookmarks recorded in the main document. No structure is stored in this PLCF.")
        yield UInt32(name="lcbPlcfbkl", comment="")
        yield UInt32(name="fcCmds", comment="offset in table stream of the macro commands. These commands are private and undocumented.")
        yield UInt32(name="lcbCmds", comment="undocument size of undocument structure not documented above")
        yield UInt32(name="fcPlcmcr", comment="no longer used")
        yield UInt32(name="lcbPlcmcr", comment="")
        yield UInt32(name="fcSttbfmcr", comment="no longer used")
        yield UInt32(name="lcbSttbfmcr", comment="")
        yield UInt32(name="fcPrDrvr", comment="offset in table stream of the printer driver information (names of drivers, port, etc.)")
        yield UInt32(name="lcbPrDrvr", comment="count of bytes of the printer driver information (names of drivers, port, etc.)")
        yield UInt32(name="fcPrEnvPort", comment="offset in table stream of the print environment in portrait mode.")
        yield UInt32(name="lcbPrEnvPort", comment="count of bytes of the print environment in portrait mode.")
        yield UInt32(name="fcPrEnvLand", comment="offset in table stream of the print environment in landscape mode.")
        yield UInt32(name="lcbPrEnvLand", comment="count of bytes of the print environment in landscape mode.")
        yield UInt32(name="fcWss", comment="offset in table stream of Window Save State data structure. WSS contains dimensions of document's main text window and the last selection made by Word user.")
        yield UInt32(name="lcbWss", comment="count of bytes of WSS. ==0 if unable to store the window state. Should not be written by third party creators of Word files.")
        yield UInt32(name="fcDop", comment="offset in table stream of document property data structure.")
        yield UInt32(name="lcbDop", comment="count of bytes of document properties.")
        yield UInt32(name="fcSttbfAssoc", comment="offset in table stream of STTBF of associated strings. The strings in this table specify document summary info and the paths to special documents related to this document. See documentation of the STTBFASSOC.")
        yield UInt32(name="lcbSttbfAssoc", comment="")
        yield UInt32(name="fcClx", comment="offset in table stream of beginning of information for complex files. Consists of an encoding of all of the prms quoted by the document followed by the plcpcd (piece table) for the document.")
        yield UInt32(name="lcbClx", comment="count of bytes of complex file information == 0 if file is non-complex.")
        yield UInt32(name="fcPlcfpgdFtn", comment="not used")
        yield UInt32(name="lcbPlcfpgdFtn", comment="")
        yield UInt32(name="fcAutosaveSource", comment="offset in table stream of the name of the original file. fcAutosaveSource and cbAutosaveSource should both be 0 if autosave is off.")
        yield UInt32(name="lcbAutosaveSource", comment="count of bytes of the name of the original file.")
        yield UInt32(name="fcGrpXstAtnOwners", comment="offset in table stream of group of strings recording the names of the owners of annotations stored in the document")
        yield UInt32(name="lcbGrpXstAtnOwners", comment="count of bytes of the group of strings")
        yield UInt32(name="fcSttbfAtnbkmk", comment="offset in table stream of the sttbf that records names of bookmarks for the annotation subdocument")
        yield UInt32(name="lcbSttbfAtnbkmk", comment="length in bytes of the sttbf that records names of bookmarks for the annotation subdocument")
        yield UInt32(name="fcPlcdoaMom", comment="no longer used")
        yield UInt32(name="lcbPlcdoaMom", comment="")
        yield UInt32(name="fcPlcdoaHdr", comment="no longer used")
        yield UInt32(name="lcbPlcdoaHdr", comment="")
        yield UInt32(name="fcPlcspaMom", comment="offset in table stream of the FSPA PLC for main document. == 0 if document has no office art objects.")
        yield UInt32(name="lcbPlcspaMom", comment="length in bytes of the FSPA PLC of the main document.")
        yield UInt32(name="fcPlcspaHdr", comment="offset in table stream of the FSPA PLC for header document. == 0 if document has no office art objects.")
        yield UInt32(name="lcbPlcspaHdr", comment="length in bytes of the FSPA PLC of the header document.")
        yield UInt32(name="fcPlcfAtnbkf", comment="offset in table stream of BKF (bookmark first) PLC of the annotation subdocument")
        yield UInt32(name="lcbPlcfAtnbkf", comment="length in bytes of BKF (bookmark first) PLC of the annotation subdocument")
        yield UInt32(name="fcPlcfAtnbkl", comment="offset in table stream of BKL (bookmark last) PLC of the annotation subdocument")
        yield UInt32(name="lcbPlcfAtnbkl", comment="length in bytes of PLC marking the CP limits of the annotation bookmarks. No structure is stored in this PLC.")
        yield UInt32(name="fcPms", comment="offset in table stream of PMS (Print Merge State) information block. This contains the current state of a print merge operation")
        yield UInt32(name="lcbPms", comment="length in bytes of PMS. ==0 if no current print merge state. Should not be written by third party creators of Word files.")
        yield UInt32(name="fcFormFldSttbs", comment="offset in table stream of form field Sttbf which contains strings used in form field dropdown controls")
        yield UInt32(name="lcbFormFldSttbs", comment="length in bytes of form field Sttbf")
        yield UInt32(name="fcPlcfendRef", comment="offset in table stream of endnote reference PLCF of FRD structures. CPs in PLCF are relative to main document text stream and give location of endnote references.")
        yield UInt32(name="lcbPlcfendRef", comment="")
        yield UInt32(name="fcPlcfendTxt", comment="offset in table stream of PlcfendRef which points to endnote text in the endnote document stream which corresponds with the plcfendRef. No structure is stored in this PLC.")
        yield UInt32(name="lcbPlcfendTxt", comment="")
        yield UInt32(name="fcPlcffldEdn", comment="offset in table stream to FLD PLCF of field positions in the endnote subdoc")
        yield UInt32(name="lcbPlcffldEdn", comment="")
        yield UInt32(name="fcPlcfpgdEdn", comment="not used")
        yield UInt32(name="lcbPlcfpgdEdn", comment="")
        yield UInt32(name="fcDggInfo", comment="offset in table stream of the office art object table data. The format of office art object table data is found in a separate document.")
        yield UInt32(name="lcbDggInfo", comment="length in bytes of the office art object table data")
        yield UInt32(name="fcSttbfRMark", comment="offset in table stream to STTBF that records the author abbreviations for authors who have made revisions in the document.")
        yield UInt32(name="lcbSttbfRMark", comment="")
        yield UInt32(name="fcSttbCaption", comment="offset in table stream to STTBF that records caption titles used in the document.")
        yield UInt32(name="lcbSttbCaption", comment="")
        yield UInt32(name="fcSttbAutoCaption", comment="offset in table stream to the STTBF that records the object names and indices into the caption STTBF for objects which get auto captions.")
        yield UInt32(name="lcbSttbAutoCaption", comment="")
        yield UInt32(name="fcPlcfwkb", comment="offset in table stream to WKB PLCF that describes the boundaries of contributing documents in a master document")
        yield UInt32(name="lcbPlcfwkb", comment="")
        yield UInt32(name="fcPlcfspl", comment="offset in table stream of PLCF (of SPLS structures) that records spell check state")
        yield UInt32(name="lcbPlcfspl", comment="")
        yield UInt32(name="fcPlcftxbxTxt", comment="offset in table stream of PLCF that records the beginning CP in the text box subdoc of the text of individual text box entries. No structure is stored in this PLCF")
        yield UInt32(name="lcbPlcftxbxTxt", comment="")
        yield UInt32(name="fcPlcffldTxbx", comment="offset in table stream of the FLD PLCF that records field boundaries recorded in the textbox subdoc.")
        yield UInt32(name="lcbPlcffldTxbx", comment="")
        yield UInt32(name="fcPlcfhdrtxbxTxt", comment="offset in table stream of PLCF that records the beginning CP in the header text box subdoc of the text of individual header text box entries. No structure is stored in this PLC.")
        yield UInt32(name="lcbPlcfhdrtxbxTxt", comment="")
        yield UInt32(name="fcPlcffldHdrTxbx", comment="offset in table stream of the FLD PLCF that records field boundaries recorded in the header textbox subdoc.")
        yield UInt32(name="lcbPlcffldHdrTxbx", comment="")
        yield UInt32(name="fcStwUser", comment="Macro User storage")
        yield UInt32(name="lcbStwUser", comment="")
        yield UInt32(name="fcSttbttmbd", comment="offset in table stream of embedded true type font data.")
        yield UInt32(name="cbSttbttmbd", comment="")
        yield UInt32(name="fcUnused", comment="")
        yield UInt32(name="lcbUnused", comment="")
        yield UInt32(name="fcPgdMother", comment="offset in table stream of the PLF that records the page descriptors for the main text of the doc.")
        yield UInt32(name="lcbPgdMother", comment="")
        yield UInt32(name="fcBkdMother", comment="offset in table stream of the PLCF that records the break descriptors for the main text of the doc.")
        yield UInt32(name="lcbBkdMother", comment="")
        yield UInt32(name="fcPgdFtn", comment="offset in table stream of the PLF that records the page descriptors for the footnote text of the doc.")
        yield UInt32(name="lcbPgdFtn", comment="")
        yield UInt32(name="fcBkdFtn", comment="offset in table stream of the PLCF that records the break descriptors for the footnote text of the doc.")
        yield UInt32(name="lcbBkdFtn", comment="")
        yield UInt32(name="fcPgdEdn", comment="offset in table stream of the PLF that records the page descriptors for the endnote text of the doc.")
        yield UInt32(name="lcbPgdEdn", comment="")
        yield UInt32(name="fcBkdEdn", comment="offset in table stream of the PLCF that records the break descriptors for the endnote text of the doc.")
        yield UInt32(name="lcbBkdEdn", comment="")
        yield UInt32(name="fcSttbfIntlFld", comment="offset in table stream of the STTBF containing field keywords. This is only used in a small number of the international versions of word. This field is no longer written to the file for nFib >= 167.")
        yield UInt32(name="lcbSttbfIntlFld", comment="Always 0 for nFib >= 167.")
        yield UInt32(name="fcRouteSlip", comment="offset in table stream of a mailer routing slip.")
        yield UInt32(name="lcbRouteSlip", comment="")
        yield UInt32(name="fcSttbSavedBy", comment="offset in table stream of STTBF recording the names of the users who have saved this document alternating with the save locations.")
        yield UInt32(name="lcbSttbSavedBy", comment="")
        yield UInt32(name="fcSttbFnm", comment="offset in table stream of STTBF recording filenames of documents which are referenced by this document.")
        yield UInt32(name="lcbSttbFnm", comment="")
        yield UInt32(name="fcPlcfLst", comment="offset in the table stream of list format information.")
        yield UInt32(name="lcbPlcfLst", comment="")
        yield UInt32(name="fcPlfLfo", comment="offset in the table stream of list format override information.")
        yield UInt32(name="lcbPlfLfo", comment="")
        yield UInt32(name="fcPlcftxbxBkd", comment="offset in the table stream of the textbox break table (a PLCF of BKDs) for the main document")
        yield UInt32(name="lcbPlcftxbxBkd", comment="")
        yield UInt32(name="fcPlcftxbxHdrBkd", comment="offset in the table stream of the textbox break table (a PLCF of BKDs) for the header subdocument")
        yield UInt32(name="lcbPlcftxbxHdrBkd", comment="")
        yield UInt32(name="fcDocUndo", comment="offset in main stream of undocumented undo / versioning data")
        yield UInt32(name="lcbDocUndo", comment="")
        yield UInt32(name="fcRgbuse", comment="offset in main stream of undocumented undo / versioning data")
        yield UInt32(name="lcbRgbuse", comment="")
        yield UInt32(name="fcUsp", comment="offset in main stream of undocumented undo / versioning data")
        yield UInt32(name="lcbUsp", comment="")
        yield UInt32(name="fcUskf", comment="offset in table stream of undocumented undo / versioning data")
        yield UInt32(name="lcbUskf", comment="")
        yield UInt32(name="fcPlcupcRgbuse", comment="offset in table stream of undocumented undo / versioning data")
        yield UInt32(name="lcbPlcupcRgbuse", comment="")
        yield UInt32(name="fcPlcupcUsp", comment="offset in table stream of undocumented undo / versioning data")
        yield UInt32(name="lcbPlcupcUsp", comment="")
        yield UInt32(name="fcSttbGlsyStyle", comment="offset in table stream of string table of style names for glossary entries")
        yield UInt32(name="lcbSttbGlsyStyle", comment="")
        yield UInt32(name="fcPlgosl", comment="offset in table stream of undocumented grammar options PL")
        yield UInt32(name="lcbPlgosl", comment="")
        yield UInt32(name="fcPlcocx", comment="offset in table stream of undocumented ocx data")
        yield UInt32(name="lcbPlcocx", comment="")
        yield UInt32(name="fcPlcfbteLvc", comment="offset in table stream of character property bin table.PLC. FCs in PLC are file offsets. Describes text of main document and all subdocuments.")
        yield UInt32(name="lcbPlcfbteLvc", comment="")
        yield UInt32(name="dwLowDateTime", comment="")
        yield UInt32(name="dwHighDateTime", comment="")
        yield UInt32(name="fcPlcflvc", comment="offset in table stream of LVC PLCF")
        yield UInt32(name="lcbPlcflvc", comment="size of LVC PLCF, ==0 for non-complex files")
        yield UInt32(name="fcPlcasumy", comment="offset in table stream of autosummary ASUMY PLCF.")
        yield UInt32(name="lcbPlcasumy", comment="")
        yield UInt32(name="fcPlcfgram", comment="offset in table stream of PLCF (of SPLS structures) which records grammar check state")
        yield UInt32(name="lcbPlcfgram", comment="")
        yield UInt32(name="fcSttbListNames", comment="offset in table stream of list names string table")
        yield UInt32(name="lcbSttbListNames", comment="")
        yield UInt32(name="fcSttbfUssr", comment="offset in table stream of undocumented undo / versioning data")
        yield UInt32(name="lcbSttbfUssr", comment="")
        if numfcb >= 0x6c:
            yield UInt32(name="fcPlcfTch", comment="An unsigned integer that specifies an offset in the Table Stream. a PlcfTch begins at this offset and specifies a cache of table characters")
            yield UInt32(name="lcbPlcfTch", comment="size")
            yield UInt32(name="fcRmdThreading", comment="An unsigned integer that specifies an offset in the Table Stream. An RmdThreading that specifies the data concerning the e-mail messages and their authors in this document begins at this offset")
            yield UInt32(name="lcbRmdThreading", comment="size")
            yield UInt32(name="fcMid", comment="An unsigned integer that specifies an offset in the Table Stream. A double-byte character Unicode string that specifies the message identifier of the document begins at this offset")
            yield UInt32(name="lcbMid", comment="size")
            yield UInt32(name="fcSttbRgtplc", comment="An unsigned integer that specifies an offset in the Table Stream. A SttbRgtplc that specifies the styles of lists in the document begins at this offset")
            yield UInt32(name="lcbSttbRgtplc", comment="size")
            yield UInt32(name="fcMsoEnvelope", comment="An unsigned integer that specifies an offset in the Table Stream. An MsoEnvelopeCLSID, which specifies the envelope data as specified by [MS-OSHARED] section 2.3.8.1, begins at this offset")
            yield UInt32(name="lcbMsoEnvelope", comment="size")
            yield UInt32(name="fcPlcfLad", comment="An unsigned integer that specifies an offset in the Table Stream. An unsigned integer that specifies an offset in the Table Stream. A Plcflad begins at this offset and specifies the language auto-detect state of each text range")
            yield UInt32(name="lcbPlcfLad", comment="size")
            yield UInt32(name="fcRgDofr", comment="An unsigned integer that specifies an offset in the Table Stream. A variable-length array with elements of type Dofrh begins at that offset. The elements of this array are records that support the frame set and list style features")
            yield UInt32(name="lcbRgDofr", comment="size")
            yield UInt32(name="fcPlcosl", comment="An unsigned integer that specifies an offset in the Table Stream. A PlfCosl begins at the offset")
            yield UInt32(name="lcbPlcosl", comment="size")
            yield UInt32(name="fcPlcfCookieOld", comment="An unsigned integer that specifies an offset in the Table Stream. A PlcfcookieOld begins at this offset")
            yield UInt32(name="lcbPlcfCookieOld", comment="size")
            yield UInt32(name="fcPgdMotherOld", comment="An unsigned integer that specifies an offset in the Table Stream. The deprecated document page layout cache begins at this offset")
            yield UInt32(name="lcbPgdMotherOld", comment="size")
            yield UInt32(name="fcBkdMotherOld", comment="An unsigned integer that specifies an offset in the Table Stream. The deprecated document text flow break cache begins at this offset")
            yield UInt32(name="lcbBkdMotherOld", comment="size")
            yield UInt32(name="fcPgdFtnOld", comment="An unsigned integer that specifies an offset in the Table Stream. The deprecated footnote layout cache begins at this offset")
            yield UInt32(name="lcbPgdFtnOld", comment="size")
            yield UInt32(name="fcBkdFtnOld", comment="An unsigned integer that specifies an offset in the Table Stream. The deprecated footnote text flow break cache begins at this offset")
            yield UInt32(name="lcbBkdFtnOld", comment="size")
            yield UInt32(name="fcPgdEdnOld", comment="An unsigned integer that specifies an offset in the Table Stream. The deprecated endnote layout cache begins at this offset")
            yield UInt32(name="lcbPgdEdnOld", comment="size")
            yield UInt32(name="fcBkdEdnOld", comment="An unsigned integer that specifies an offset in the Table Stream. The deprecated endnote text flow break cache begins at this offset")
            yield UInt32(name="lcbBkdEdnOld", comment="size")


class WordDocumentAnalyzer(FileTypeAnalyzer):
    category = malcat.FileType.DOCUMENT
    name = "Office.Word"
    regexp = r"\xEC\xA5\xC1\x00........[\xBF\xC1]\x00" 

    def parse(self, hint):
        fib = yield WordFIB(name="FIB")
        self.confirm()
        if not fib["Flags"]["Complex"]:
            start_text = fib.offset + fib["Min"]
            end_text = fib.offset + fib["Max"]
            if end_text > start_text:
                self.jump(start_text)
                yield Bytes(end_text - start_text, name="WordUserText", category=Type.DATA)

