/// <summary> /// The constructor for the record. /// </summary> /// <param name="biff">The GenericBiff record that should contain the correct type and data for the SST record.</param> /// <param name="recordStream">The stream into the records to which the SST record belongs to. The record stream must be positioned just after the SST record.</param> /// <exception cref="InvalidRecordIdException"> /// An InvalidRecordIdException is thrown if biff contains an invalid type or invalid data. /// </exception> public SstRecord(GenericBiff biff, Stream recordStream) { if (biff.Id == (ushort)RecordType.Sst) { Stream stream = biff.GetDataStream(); BinaryReader reader = new BinaryReader(stream); /* uint totalStrings = */ reader.ReadUInt32(); uint totalUniqueStrings = reader.ReadUInt32(); _strings = new string[totalUniqueStrings]; StringBuilder sb = new StringBuilder(); for (int i = 0; i < totalUniqueStrings; ++i) { if (stream.Position >= stream.Length) { ContinueRecord cont = ReadContinue(recordStream); stream = cont.GetDataStream(); reader = new BinaryReader(stream); } ushort len = reader.ReadUInt16(); byte options = reader.ReadByte(); bool compressed = (options & 0x01) == 0; bool farEast = (options & 0x04) != 0; bool richText = (options & 0x08) != 0; ushort rtSize = 0; uint farEastSize = 0; if (richText) { rtSize = reader.ReadUInt16(); } if (farEast) { farEastSize = reader.ReadUInt32(); } sb.Length = 0; sb.EnsureCapacity(len); for (ushort n = 0; n < len; ++n) { if (stream.Position >= stream.Length) { ContinueRecord cont = ReadContinue(recordStream); stream = cont.GetDataStream(); reader = new BinaryReader(stream); compressed = (reader.ReadByte() & 0x01) == 0; } if (compressed) { sb.Append(Convert.ToChar(reader.ReadByte())); } else { sb.Append(Convert.ToChar(reader.ReadUInt16())); } } Debug.Assert(sb.Length == len); _strings[i] = sb.ToString(); long skip = (rtSize * 4) + farEastSize; while (skip > 0) { if (stream.Position >= stream.Length) { ContinueRecord cont = ReadContinue(recordStream); stream = cont.GetDataStream(); reader = new BinaryReader(stream); } long actualSkip = Math.Min(stream.Length - stream.Position, skip); stream.Seek(actualSkip, SeekOrigin.Current); skip -= actualSkip; } } } else { throw new InvalidRecordIdException(biff.Id, RecordType.Sst); } }
private Biff GetCorrectRecord(GenericBiff record, Stream stream, SstRecord sst) { Biff ret = record; switch (record.Id) { case (ushort)RecordType.Bof: BofRecord bof = new BofRecord(record); if (bof.Version < 0x0600) throw new Exception("Versions below Excel 97/2000 are currently not supported."); ret = bof; break; case (ushort)RecordType.Boundsheet: ret = new BoundSheetRecord(record); break; case (ushort)RecordType.Index: ret = new IndexRecord(record); break; case (ushort)RecordType.DbCell: ret = new DbCellRecord(record); break; case (ushort)RecordType.Row: ret = new RowRecord(record); break; case (ushort)RecordType.Continue: ret = new ContinueRecord(record); break; case (ushort)RecordType.Blank: ret = new BlankRecord(record); break; case (ushort)RecordType.BoolErr: ret = new BoolErrRecord(record); break; case (ushort)RecordType.Formula: ret = new FormulaRecord(record, stream); break; case (ushort)RecordType.Label: ret = new LabelRecord(record); break; case (ushort)RecordType.LabelSst: ret = new LabelSstRecord(record, sst); break; case (ushort)RecordType.MulBlank: ret = new MulBlankRecord(record); break; case (ushort)RecordType.MulRk: ret = new MulRkRecord(record); break; case (ushort)RecordType.String: ret = new StringValueRecord(record); break; case (ushort)RecordType.Xf: ret = new XfRecord(record); break; case (ushort)RecordType.Rk: ret = new RkRecord(record); break; case (ushort)RecordType.Number: ret = new NumberRecord(record); break; case (ushort)RecordType.Array: ret = new ArrayRecord(record); break; case (ushort)RecordType.ShrFmla: ret = new SharedFormulaRecord(record); break; case (ushort)RecordType.Table: ret = new TableRecord(record); break; case (ushort)RecordType.Sst: ret = new SstRecord(record, stream); break; case (ushort)RecordType.Eof: ret = new EofRecord(record); break; case (ushort)RecordType.Font: ret = new FontRecord(record); break; case (ushort)RecordType.Format: ret = new Net.SourceForge.Koogra.Excel.Records.FormatRecord(record); break; case (ushort)RecordType.Palette: ret = new PaletteRecord(record); break; case (ushort)RecordType.Hyperlink: ret = new HyperLinkRecord(record); break; } return ret; }