Exemple #1
0
        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="reader">Reader to parse the document </param>
        /// <param name="id">BiffRecord ID</param>
        /// <param name="length">The lengt of the biffrecord </param>
        public SST(IStreamReader binreader, RecordType id, ushort length, LinkedList <VirtualStreamReader> contstreamlist)
            : base(binreader, id, length)
        {
            // assert that the correct record type is instantiated
            Debug.Assert(this.Id == ID);
            this.contStreamlist = contstreamlist;
            this.StringList     = new List <string>();
            this.FormatList     = new List <StringFormatAssignment>();
            var buffer = new byte[length];
            int counti = 0;

            this.cstTotal  = (uint)this.Reader.ReadUInt32();
            this.cstUnique = this.Reader.ReadUInt32();

            try
            {
                // run over the different strings
                // there are x strings where x = cstUnique
                for (int i = 0; i < this.cstUnique; i++)
                {
                    counti++;
                    if (this.Reader.BaseStream.Position == this.Reader.BaseStream.Length)
                    {
                        this.switchStream();
                    }
                    // first get the char count of this string
                    ushort cch = this.Reader.ReadUInt16();
                    // get the grbit mask
                    byte grbit = this.Reader.ReadByte();
                    bool isCompressedString = false;
                    bool isExtString        = false;
                    bool isRichString       = false;

                    int cRun     = 0;
                    int cbExtRst = 0;

                    // demask the grbit
                    isCompressedString = !Utils.BitmaskToBool((int)grbit, 0x0001);
                    isExtString        = Utils.BitmaskToBool((int)grbit, 0x0004);
                    isRichString       = Utils.BitmaskToBool((int)grbit, 0x0008);



                    if (isRichString)
                    {
                        cRun = this.Reader.ReadUInt16();
                    }

                    if (isExtString)
                    {
                        cbExtRst = this.Reader.ReadInt32();
                    }

                    // switch stream
                    if (this.Reader.BaseStream.Position == this.Reader.BaseStream.Length)
                    {
                        this.switchStream();
                    }


                    // read characters from the string
                    int charcount = 0;
                    if (isCompressedString)
                    {
                        charcount = 1;
                    }
                    else
                    {
                        charcount = 2;
                    }
                    string stringbuffer = "";
                    // read chars !!!
                    while (this.Reader.BaseStream.Length < this.Reader.BaseStream.Position + cch * charcount)
                    {
                        ushort currentLength = (ushort)(this.Reader.BaseStream.Length - this.Reader.BaseStream.Position);
                        cch -= (ushort)(currentLength / charcount);
                        for (int j = 0; j < currentLength / charcount; j++)
                        {
                            if (isCompressedString)
                            {
                                stringbuffer += (char)this.Reader.ReadByte();
                            }
                            else
                            {
                                stringbuffer += System.BitConverter.ToChar(this.Reader.ReadBytes(2), 0);
                            }
                        }
                        // switch to next stream !!
                        this.switchStream();
                        // read compressed/uncompressed byte value
                        byte grbit2 = this.Reader.ReadByte();
                        if (grbit2 > 0)
                        {
                            isCompressedString = false;
                        }
                        else
                        {
                            isCompressedString = true;
                        }
                    }

                    for (int j = 0; j < cch; j++)
                    {
                        if (isCompressedString)
                        {
                            stringbuffer += (char)this.Reader.ReadByte();
                        }
                        else
                        {
                            stringbuffer += System.BitConverter.ToChar(this.Reader.ReadBytes(2), 0);
                        }
                    }
                    this.StringList.Add(stringbuffer);

                    // read formatting runs!!
                    if (isRichString)
                    {
                        int countFormatingRuns = cRun;
                        while (this.Reader.BaseStream.Length < this.Reader.BaseStream.Position + countFormatingRuns * 4)
                        {
                            ushort currentLength = (ushort)(this.Reader.BaseStream.Length - this.Reader.BaseStream.Position);
                            countFormatingRuns -= (ushort)(currentLength / 4);
                            // get formating data
                            for (int j = 0; j < currentLength / 4; j++)
                            {
                                var format = new StringFormatAssignment();
                                format.StringNumber = counti;
                                format.CharNumber   = this.Reader.ReadUInt16();



                                format.FontRecord = this.Reader.ReadUInt16();
                                if (format.CharNumber < stringbuffer.Length)
                                {
                                    this.FormatList.Add(format);
                                }
                            }
                            // switch to next stream !!
                            this.switchStream();
                            // read compressed/uncompressed byte value
                            // this.Reader.ReadByte();
                        }
                        // get formating data
                        for (int j = 0; j < countFormatingRuns; j++)
                        {
                            var format = new StringFormatAssignment();
                            format.StringNumber = counti;
                            format.CharNumber   = this.Reader.ReadUInt16();
                            format.FontRecord   = this.Reader.ReadUInt16();

                            if (format.FontRecord > 4)
                            {
                                format.FontRecord--;
                            }

                            /// ToDo: Check why some charNumbers are greater then string length
                            if (format.CharNumber < stringbuffer.Length)
                            {
                                this.FormatList.Add(format);
                            }
                        }
                    }

                    if (isExtString)
                    {
                        int    cchExtRst = cbExtRst;
                        byte[] ExtRst;
                        while (this.Reader.BaseStream.Length < this.Reader.BaseStream.Position + cchExtRst)
                        {
                            ushort currentLength = (ushort)(this.Reader.BaseStream.Length - this.Reader.BaseStream.Position);
                            cchExtRst -= (currentLength);
                            ExtRst     = this.Reader.ReadBytes(currentLength);
                            // switch to next stream !!
                            this.switchStream();
                            // read compressed/uncompressed byte value
                            // this.Reader.ReadByte();
                        }

                        ExtRst = this.Reader.ReadBytes(cchExtRst);
                    }
                }
            }
            catch (Exception ex)
            {
                TraceLogger.Error(ex.Message);
                TraceLogger.Debug(ex.ToString());
            }

            // assert that the correct number of bytes has been read from the stream
            // Debug.Assert(this.Offset + this.Length == this.Reader.BaseStream.Position);
        }
Exemple #2
0
        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="reader">Reader to parse the document </param>
        /// <param name="id">BiffRecord ID</param>
        /// <param name="length">The lengt of the biffrecord </param>
        public SST(IStreamReader reader, RecordType id, UInt16 length)
            : base(reader, id, length)
        {
            // assert that the correct record type is instantiated
            Debug.Assert(this.Id == ID);

            this.StringList = new List <string>();
            this.FormatList = new List <StringFormatAssignment>();

            // copy data to a memory stream to cope with Continue records
            using (MemoryStream ms = new MemoryStream())
            {
                List <long> recordBorders = new List <long>();

                byte[] buffer = reader.ReadBytes(length);
                ms.Write(buffer, 0, length);

                while (BiffRecord.GetNextRecordType(reader) == RecordType.Continue)
                {
                    BiffHeader bh;
                    bh.id     = (RecordType)reader.ReadUInt16();
                    bh.length = reader.ReadUInt16();

                    recordBorders.Add(ms.Position);
                    buffer = reader.ReadBytes(bh.length);
                    ms.Write(buffer, 0, bh.length);
                }

                ms.Position = 0;

                VirtualStreamReader sr = new VirtualStreamReader(ms);

                try
                {
                    this.cstTotal  = sr.ReadUInt32();
                    this.cstUnique = sr.ReadUInt32();

                    // run over the different strings
                    // there are x strings where x = cstUnique
                    for (int i = 0; i < this.cstUnique; i++)
                    {
                        XLUnicodeRichExtendedString str = new XLUnicodeRichExtendedString(sr, recordBorders);

                        //// first get the char count of this string
                        //UInt16 cch = sr.ReadUInt16();
                        //// get the grbit mask
                        //Byte grbit = sr.ReadByte();
                        //bool isCompressedString = !Utils.BitmaskToBool((int)grbit, 0x0001);
                        //bool isExtString = Utils.BitmaskToBool((int)grbit, 0x0004);
                        //bool isRichString = Utils.BitmaskToBool((int)grbit, 0x0008);

                        //int cRun = 0;
                        //int cbExtRst = 0;

                        //if (isRichString)
                        //{
                        //    cRun = sr.ReadUInt16();
                        //}

                        //if (isExtString)
                        //{
                        //    cbExtRst = sr.ReadInt32();
                        //}

                        //// read characters from the string
                        //int charcount = 0;
                        //if (isCompressedString)
                        //    charcount = 1;
                        //else
                        //    charcount = 2;

                        //String stringbuffer = "";

                        //// read chars !!!
                        //while (sr.BaseStream.Length < sr.BaseStream.Position + cch * charcount)
                        //{
                        //    ushort currentLength = (ushort)(sr.BaseStream.Length - sr.BaseStream.Position);
                        //    cch -= (ushort)(currentLength / charcount);
                        //    for (int j = 0; j < currentLength / charcount; j++)
                        //    {
                        //        if (isCompressedString)
                        //        {
                        //            stringbuffer += (char)sr.ReadByte();
                        //        }
                        //        else
                        //        {
                        //            stringbuffer += System.BitConverter.ToChar(sr.ReadBytes(2), 0);
                        //        }
                        //    }

                        //    // read compressed/uncompressed byte value
                        //    byte grbit2 = sr.ReadByte();
                        //    if (grbit2 > 0)
                        //        isCompressedString = false;
                        //    else
                        //        isCompressedString = true;
                        //}

                        //for (int j = 0; j < cch; j++)
                        //{
                        //    if (isCompressedString)
                        //    {
                        //        stringbuffer += (char)sr.ReadByte();
                        //    }
                        //    else
                        //    {
                        //        stringbuffer += System.BitConverter.ToChar(sr.ReadBytes(2), 0);
                        //    }
                        //}
                        this.StringList.Add(str.Value);

                        if (str.fRichSt)
                        {
                            foreach (FormatRun formatRun in str.rgRun)
                            {
                                StringFormatAssignment format = new StringFormatAssignment();
                                format.StringNumber = i + 1;

                                format.CharNumber = formatRun.ich;
                                format.FontRecord = formatRun.ifnt;

                                // NOTE: If this value is less than 4, then it specifies a *zero-based* index of a Font record
                                //  in the collection of Font records in the globals substream. If this value is greater than 4,
                                //  then it specifies a *one-based* index of a Font record in the collection of Font records in
                                //  the globals substream.
                                //
                                if (format.FontRecord > 4)
                                {
                                    format.FontRecord--;
                                }

                                if (format.CharNumber < str.Value.Length)
                                {
                                    this.FormatList.Add(format);
                                }
                            }
                        }

                        //// read formatting runs!!
                        //if (isRichString)
                        //{
                        //    int countFormatingRuns = cRun;
                        //    while (sr.BaseStream.Length < sr.BaseStream.Position + countFormatingRuns * 4)
                        //    {
                        //        ushort currentLength = (ushort)(sr.BaseStream.Length - sr.BaseStream.Position);
                        //        countFormatingRuns -= (ushort)(currentLength / 4);
                        //        // get formating data
                        //        for (int j = 0; j < currentLength / 4; j++)
                        //        {
                        //            StringFormatAssignment format = new StringFormatAssignment();
                        //            format.StringNumber = i + 1;

                        //            format.CharNumber = sr.ReadUInt16();
                        //            format.FontRecord = sr.ReadUInt16();

                        //            if (format.CharNumber < stringbuffer.Length)
                        //            {
                        //                this.FormatList.Add(format);
                        //            }
                        //        }
                        //    }
                        //    // get formating data
                        //    for (int j = 0; j < countFormatingRuns; j++)
                        //    {
                        //        StringFormatAssignment format = new StringFormatAssignment();
                        //        format.StringNumber = i + 1;
                        //        format.CharNumber = sr.ReadUInt16();
                        //        format.FontRecord = sr.ReadUInt16();

                        //        if (format.FontRecord > 4)
                        //        {
                        //            format.FontRecord--;
                        //        }

                        //        /// ToDo: Check why some charNumbers are greater then string length
                        //        if (format.CharNumber < stringbuffer.Length)
                        //        {
                        //            this.FormatList.Add(format);
                        //        }
                        //    }
                        //}

                        //if (isExtString)
                        //{
                        //    int cchExtRst = cbExtRst;
                        //    byte[] ExtRst;
                        //    while (sr.BaseStream.Length < sr.BaseStream.Position + cchExtRst)
                        //    {
                        //        ushort currentLength = (ushort)(sr.BaseStream.Length - sr.BaseStream.Position);
                        //        cchExtRst -= (currentLength);
                        //        ExtRst = sr.ReadBytes(currentLength);
                        //    }

                        //    ExtRst = sr.ReadBytes(cchExtRst);
                        //}
                    }
                }
                catch (Exception ex)
                {
                    TraceLogger.Error(ex.Message);
                    TraceLogger.Debug(ex.ToString());
                }
            }
            // assert that the correct number of bytes has been read from the stream
            // Debug.Assert(this.Offset + this.Length == this.Reader.BaseStream.Position);
        }