示例#1
0
        /// <summary>
        /// Parses the given StreamReader to retrieve a LVL struct
        /// </summary>
        /// <param name="bytes"></param>
        public ListLevel(VirtualStreamReader reader, int length)
            : base(reader, length)
        {
            long startPos = this._reader.BaseStream.Position;

            //parse the fix part
            this.iStartAt = this._reader.ReadInt32();
            this.nfc      = this._reader.ReadByte();
            int flag = this._reader.ReadByte();

            this.jc         = (byte)(flag & 0x03);
            this.fLegal     = Utils.BitmaskToBool(flag, 0x04);
            this.fNoRestart = Utils.BitmaskToBool(flag, 0x08);
            this.fPrev      = Utils.BitmaskToBool(flag, 0x10);
            this.fPrevSpace = Utils.BitmaskToBool(flag, 0x20);
            this.fWord6     = Utils.BitmaskToBool(flag, 0x40);
            this.rgbxchNums = new byte[9];
            for (int i = 0; i < 9; i++)
            {
                this.rgbxchNums[i] = this._reader.ReadByte();
            }
            this.ixchFollow = (FollowingChar)this._reader.ReadByte();

            this.dxaSpace  = this._reader.ReadInt32();
            this.dxaIndent = this._reader.ReadInt32();

            this.cbGrpprlChpx = this._reader.ReadByte();
            this.cbGrpprlPapx = this._reader.ReadByte();

            this.ilvlRestartLim = this._reader.ReadByte();
            this.grfhic         = this._reader.ReadByte();

            //parse the variable part

            //read the group of papx sprms
            //this papx has no istd, so use PX to parse it
            var px = new PropertyExceptions(this._reader.ReadBytes(this.cbGrpprlPapx));

            this.grpprlPapx = new ParagraphPropertyExceptions
            {
                grpprl = px.grpprl
            };

            //read the group of chpx sprms
            this.grpprlChpx = new CharacterPropertyExceptions(this._reader.ReadBytes(this.cbGrpprlChpx));

            //read the number text
            short strLen = this._reader.ReadInt16();

            this.xst = Encoding.Unicode.GetString(this._reader.ReadBytes(strLen * 2));

            long endPos = this._reader.BaseStream.Position;

            this._reader.BaseStream.Seek(startPos, System.IO.SeekOrigin.Begin);
            this._rawBytes = this._reader.ReadBytes((int)(endPos - startPos));
        }
        /// <summary>
        /// Extracts the TAPX SPRMs out of a PAPX
        /// </summary>
        /// <param name="papx"></param>
        public TablePropertyExceptions(ParagraphPropertyExceptions papx, VirtualStream dataStream)
        {
            this.grpprl = new List <SinglePropertyModifier>();
            foreach (var sprm in papx.grpprl)
            {
                if (sprm.Type == SinglePropertyModifier.SprmType.TAP)
                {
                    this.grpprl.Add(sprm);
                }
                else if ((int)sprm.OpCode == 0x646b)
                {
                    IStreamReader reader = new VirtualStreamReader(dataStream);

                    //there is a native TAP in the data stream
                    uint fc = System.BitConverter.ToUInt32(sprm.Arguments, 0);

                    //get the size of the following grpprl
                    //byte[] sizebytes = new byte[2];
                    //dataStream.Read(sizebytes, 2, (int)fc);
                    var    sizebytes  = reader.ReadBytes(fc, 2);
                    ushort grpprlSize = System.BitConverter.ToUInt16(sizebytes, 0);

                    //read the grpprl
                    //byte[] grpprlBytes = new byte[grpprlSize];
                    //dataStream.Read(grpprlBytes);
                    var grpprlBytes = reader.ReadBytes(grpprlSize);

                    //parse the grpprl
                    var externalPx = new PropertyExceptions(grpprlBytes);

                    foreach (var sprmExternal in externalPx.grpprl)
                    {
                        if (sprmExternal.Type == SinglePropertyModifier.SprmType.TAP)
                        {
                            this.grpprl.Add(sprmExternal);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Builds a CHP based on a CHPX
        /// </summary>
        /// <param name="styles">The stylesheet</param>
        /// <param name="chpx">The CHPX</param>
        public CharacterProperties(CharacterPropertyExceptions chpx, ParagraphPropertyExceptions parentPapx, WordDocument parentDocument)
        {
            setDefaultValues();

            //get all CHPX in the hierarchy
            var chpxHierarchy = new List <CharacterPropertyExceptions>();

            chpxHierarchy.Add(chpx);

            //add parent character styles
            buildHierarchy(chpxHierarchy, parentDocument.Styles, (ushort)getIsdt(chpx));

            //add parent paragraph styles
            buildHierarchy(chpxHierarchy, parentDocument.Styles, parentPapx.istd);

            chpxHierarchy.Reverse();

            //apply the CHPX hierarchy to this CHP
            foreach (var c in chpxHierarchy)
            {
                applyChpx(c, parentDocument);
            }
        }
        /// <summary>
        /// Parses the bytes to retrieve a StyleSheetDescription
        /// </summary>
        /// <param name="bytes">The bytes</param>
        /// <param name="cbStdBase"></param>
        /// <param name="dataStream">The "Data" stream (optional, can be null)</param>
        public StyleSheetDescription(byte[] bytes, int cbStdBase, VirtualStream dataStream)
        {
            var bits = new BitArray(bytes);

            //parsing the base (fix part)

            if (cbStdBase >= 2)
            {
                //sti
                var stiBits = Utils.BitArrayCopy(bits, 0, 12);
                this.sti = (StyleIdentifier)Utils.BitArrayToUInt32(stiBits);
                //flags
                this.fScratch     = bits[12];
                this.fInvalHeight = bits[13];
                this.fHasUpe      = bits[14];
                this.fMassCopy    = bits[15];
            }
            if (cbStdBase >= 4)
            {
                //stk
                var stkBits = Utils.BitArrayCopy(bits, 16, 4);
                this.stk = (StyleKind)Utils.BitArrayToUInt32(stkBits);
                //istdBase
                var istdBits = Utils.BitArrayCopy(bits, 20, 12);
                this.istdBase = (uint)Utils.BitArrayToUInt32(istdBits);
            }
            if (cbStdBase >= 6)
            {
                //cupx
                var cupxBits = Utils.BitArrayCopy(bits, 32, 4);
                this.cupx = (ushort)Utils.BitArrayToUInt32(cupxBits);
                //istdNext
                var istdNextBits = Utils.BitArrayCopy(bits, 36, 12);
                this.istdNext = (uint)Utils.BitArrayToUInt32(istdNextBits);
            }
            if (cbStdBase >= 8)
            {
                //bchUpe
                var bchBits = Utils.BitArrayCopy(bits, 48, 16);
                this.bchUpe = (ushort)Utils.BitArrayToUInt32(bchBits);
            }
            if (cbStdBase >= 10)
            {
                //flags
                this.fAutoRedef       = bits[64];
                this.fHidden          = bits[65];
                this.f97LidsSet       = bits[66];
                this.fCopyLang        = bits[67];
                this.fPersonalCompose = bits[68];
                this.fPersonalReply   = bits[69];
                this.fPersonal        = bits[70];
                this.fNoHtmlExport    = bits[71];
                this.fSemiHidden      = bits[72];
                this.fLocked          = bits[73];
                this.fInternalUse     = bits[74];
            }
            if (cbStdBase >= 12)
            {
                //istdLink
                var istdLinkBits = Utils.BitArrayCopy(bits, 80, 12);
                this.istdLink = (uint)Utils.BitArrayToUInt32(istdLinkBits);
                //fHasOriginalStyle
                this.fHasOriginalStyle = bits[92];
            }
            if (cbStdBase >= 16)
            {
                //rsid
                var rsidBits = Utils.BitArrayCopy(bits, 96, 32);
                this.rsid = Utils.BitArrayToUInt32(rsidBits);
            }

            //parsing the variable part

            //xstz
            byte characterCount = bytes[cbStdBase];
            //characters are zero-terminated, so 1 char has 2 bytes:
            var name = new byte[characterCount * 2];

            Array.Copy(bytes, cbStdBase + 2, name, 0, name.Length);
            //remove zero-termination
            this.xstzName = Encoding.Unicode.GetString(name);

            //parse the UPX structs
            int upxOffset = cbStdBase + 1 + (characterCount * 2) + 2;

            for (int i = 0; i < this.cupx; i++)
            {
                //find the next even byte border
                if (upxOffset % 2 != 0)
                {
                    upxOffset++;
                }

                //get the count of bytes for UPX
                ushort cbUPX = System.BitConverter.ToUInt16(bytes, upxOffset);

                if (cbUPX > 0)
                {
                    //copy the bytes
                    var upxBytes = new byte[cbUPX];
                    Array.Copy(bytes, upxOffset + 2, upxBytes, 0, upxBytes.Length);

                    if (this.stk == StyleKind.table)
                    {
                        //first upx is TAPX; second PAPX, third CHPX
                        switch (i)
                        {
                        case 0:
                            this.tapx = new TablePropertyExceptions(upxBytes);
                            break;

                        case 1:
                            this.papx = new ParagraphPropertyExceptions(upxBytes, dataStream);
                            break;

                        case 2:
                            this.chpx = new CharacterPropertyExceptions(upxBytes);
                            break;
                        }
                    }
                    else if (this.stk == StyleKind.paragraph)
                    {
                        //first upx is PAPX, second CHPX
                        switch (i)
                        {
                        case 0:
                            this.papx = new ParagraphPropertyExceptions(upxBytes, dataStream);
                            break;

                        case 1:
                            this.chpx = new CharacterPropertyExceptions(upxBytes);
                            break;
                        }
                    }
                    else if (this.stk == StyleKind.list)
                    {
                        //list styles have only one PAPX
                        switch (i)
                        {
                        case 0: this.papx = new ParagraphPropertyExceptions(upxBytes, dataStream); break;
                        }
                    }
                    else if (this.stk == StyleKind.character)
                    {
                        //character styles have only one CHPX
                        switch (i)
                        {
                        case 0: this.chpx = new CharacterPropertyExceptions(upxBytes); break;
                        }
                    }
                }

                //increase the offset for the next run
                upxOffset += (2 + cbUPX);
            }
        }