123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044 |
- using System;
- using System.Collections;
- using System.IO;
- using System.Runtime.InteropServices;
- namespace FastReport.Export.BIFF8
- {
- /// <summary>
- /// Provides API to binary stream
- /// </summary>
- public /*abstract*/ class StreamHelper : MemoryStream
- {
- internal void SkipBytes(int count)
- {
- base.Position = base.Position + count;
- }
- internal ushort ReadUshort()
- {
- byte hi, low;
- low = (byte)ReadByte();
- hi = (byte)ReadByte();
- return (ushort)((int)low + (int)(hi << 8));
- }
- internal uint ReadUint()
- {
- uint b0 = (uint)ReadByte();
- uint b1 = (uint)ReadByte();
- uint b2 = (uint)ReadByte();
- uint b3 = (uint)ReadByte();
- uint result = (b3 << 24) + (b2 << 16) + (b1 << 8) + b0;
- return result;
- }
- internal int ReadInt()
- {
- int b0 = ReadByte();
- int b1 = ReadByte();
- int b2 = ReadByte();
- int b3 = ReadByte();
- int result = (b3 << 24) + (b2 << 16) + (b1 << 8) + b0;
- return result;
- }
- internal double ReadDouble()
- {
- double[] result = new double[1];
- byte[] bytes = new byte[8];
- for (int i = 0; i < 8; i++) bytes[i] = (byte)ReadByte();
- IntPtr ptr = Marshal.AllocHGlobal(8);
- Marshal.Copy(bytes, 0, ptr, 8);
- Marshal.Copy(ptr, result, 0, 1);
- Marshal.FreeHGlobal(ptr);
- return result[0];
- }
- internal string ReadUnicodeString(bool short_len)
- {
- string str = "";
- int num_rich_runs = 0;
- UInt16 Char_Count = short_len ? (UInt16)ReadByte() : ReadUshort();
- byte options = (byte)ReadByte();
- if ((options & 0x8) != 0)
- num_rich_runs = ReadUshort();
- if ((options & 0x1) != 0)
- {
- for (int i = 0; i < Char_Count; i++)
- {
- char ch = (char)ReadUshort();
- str += ch;
- }
- }
- else
- {
- for (int i = 0; i < Char_Count; i++)
- {
- char ch = (char)ReadByte();
- str += ch;
- }
- }
- return str;
- }
- internal bool CanCompressString(string s)
- {
- int str_len = s.Length;
- for (int i = 0; i < str_len; i++)
- if (s[i] > 255) return false;
- return true;
- }
- internal void WriteUnicodeString(string FontName, bool short_len)
- {
- WriteUnicodeString(FontName, short_len, false);
- }
- internal void WriteUnicodeString(string FontName, bool short_len, bool compress)
- {
- int str_len = FontName.Length;
- if (short_len)
- {
- WriteByte((byte)str_len);
- }
- else
- {
- WriteUshort((ushort)str_len);
- }
- WriteByte(compress ? (byte)0 : (byte)0x001); // Uncompressed
- if (compress)
- {
- for (int i = 0; i < str_len; i++)
- {
- char ch = FontName[i];
- if (ch == 0xd)
- WriteByte((byte)0xa);
- else
- WriteByte((byte)ch);
- }
- }
- else
- {
- for (int i = 0; i < str_len; i++)
- {
- char ch = FontName[i];
- if (ch == 0xd)
- WriteUshort((ushort)0xa);
- else
- WriteUshort((ushort)ch);
- }
- }
- }
- internal int SizeUnicodeString(string FontName, bool short_len)
- {
- return SizeUnicodeString(FontName, short_len, false);
- }
- internal int SizeUnicodeString(string FontName, bool short_len, bool compress)
- {
- int str_len = FontName.Length;
- if (!compress)
- str_len *= 2;
- return str_len + (short_len ? 2 : 3);
- }
- internal byte[] ReadBytes(int count)
- {
- byte[] result = new byte[count];
- for (int i = 0; i < count; i++)
- result[i] = unchecked((byte)ReadByte());
- return result;
- }
- internal ushort[] ReadUshorts(int count)
- {
- ushort[] result = new ushort[count];
- for (int i = 0; i < count; i++) result[i] = ReadUshort();
- return result;
- }
- internal int[] ReadInts(int count)
- {
- int[] result = new int[count];
- for (int i = 0; i < count; i++) result[i] = ReadInt();
- return result;
- }
- internal void WriteUshort(ushort value)
- {
- unchecked
- {
- byte lo = (byte)(value);
- WriteByte(lo);
- byte hi = (byte)(value >> 8);
- WriteByte(hi);
- }
- }
- internal void WriteUint(uint value)
- {
- unchecked
- {
- byte b0 = (byte)value;
- byte b1 = (byte)(value >> 8);
- byte b2 = (byte)(value >> 16);
- byte b3 = (byte)(value >> 24);
- WriteByte(b0);
- WriteByte(b1);
- WriteByte(b2);
- WriteByte(b3);
- }
- }
- internal void WriteInt(int value)
- {
- unchecked
- {
- byte b0 = (byte)value;
- byte b1 = (byte)(value >> 8);
- byte b2 = (byte)(value >> 16);
- byte b3 = (byte)(value >> 24);
- WriteByte(b0);
- WriteByte(b1);
- WriteByte(b2);
- WriteByte(b3);
- }
- }
- internal void WriteDouble(double value)
- {
- double[] source = new double[1];
- source[0] = value;
- byte[] bytes = new byte[8];
- IntPtr ptr = Marshal.AllocHGlobal(8);
- Marshal.Copy(source, 0, ptr, 1);
- Marshal.Copy(ptr, bytes, 0, bytes.Length);
- Marshal.FreeHGlobal(ptr);
- for (int i = 0; i < 8; i++) WriteByte(bytes[i]);
- }
- internal void WriteBytes(byte[] values)
- {
- for (int i = 0; i < values.Length; i++) WriteByte(values[i]);
- }
- internal void WriteBytes(byte[] values, int start_index, int count)
- {
- for (int i = 0; i < count; i++) WriteByte(values[start_index + i]);
- }
- internal void WriteInts(int[] values)
- {
- WriteInts(values, 0);
- }
- internal void WriteInts(int[] values, int start_index)
- {
- for (int i = start_index; i < values.Length; i++) WriteInt(values[i]);
- }
- internal void WriteUints(uint[] values)
- {
- WriteUints(values, 0);
- }
- internal void WriteUints(uint[] values, int start_index)
- {
- for (int i = start_index; i < values.Length; i++) WriteUint(values[i]);
- }
- }
- internal class DirectoryEntry
- {
- internal enum DirEntryType
- {
- // Type of the entry:
- Empty = 0x00, // 00H = Empty
- UserStorage = 0x01, // 01H = User storage
- UseStream = 0x02, // 02H = User stream
- LockBytes = 0x03, // 03H = LockBytes (unknown)
- Property = 0x04, // 04H = Property (unknown)
- RootStorage = 0x05 // 05H = Root storage
- }
- #if false
- // 0 64
- // Character array of the name of the entry, always 16-bit Unicode characters, with trailing
- //zero character (results in a maximum name length of 31 characters)
- byte[] name = new byte[64];
- //64 2
- //Size of the used area of the character buffer of the name (not character count), including
- //the trailing zero character (e.g. 12 for a name with 5 characters: (5+1)∙2 = 12)
- ushort name_size;
- #else
- public string entry_name;
- #endif
- // 66 1
- // Type of the entry: 00H = Empty 03H = LockBytes (unknown)
- // 01H = User storage 04H = Property (unknown)
- // 02H = User stream 05H = Root storage
- internal DirEntryType type;
- // 67 1 Node colour of the entry: 00H = Red 01H = Black
- internal byte colour;
- // 68 4 DirID of the left child node inside the red-black tree of all direct members of the parent
- // storage (if this entry is a user storage or stream), –1 if there is no left child
- internal int leftChildDirID;
- //72 4 DirID of the right child node inside the red-black tree of all direct members of the parent
- //storage (if this entry is a user storage or stream), –1 if there is no right child
- internal int rightChildDirID;
- // 76 4 DirID of the root node entry of the red-black tree of all storage members (if this entry is a
- //storage,), –1 otherwise
- internal int rootDirID;
- // 80 16 Unique identifier, if this is a storage (not of interest in the following, may be all 0)
- private byte[] uid = new byte[16];
- // 96 4 User flags (not of interest in the following, may be all 0)
- private uint userFlags;
- // 100 8 Time stamp of creation of this entry.
- private byte[] creationTime = new byte[8];
- // 108 8 Time stamp of last modification of this entry
- private byte[] modificationTime = new byte[8];
- // 116 4 SecID of first sector or short-sector, if this entry refers to a stream
- public UInt32 bOF;
- //120 4 Total stream size in bytes, if this entry refers to a stream
- public UInt32 size;
- // 124 4 Not used
- public void Read(StreamHelper File)
- {
- entry_name = "";
- ushort name_size;
- for (int i = 0; i < 32; i++)
- {
- char ch = (char)File.ReadUshort();
- if (ch != '\0') entry_name += ch;
- }
- name_size = File.ReadUshort();
- type = (DirEntryType)File.ReadByte();
- colour = (byte)File.ReadByte();
- leftChildDirID = File.ReadInt();
- rightChildDirID = File.ReadInt();
- rootDirID = File.ReadInt();
- uid = File.ReadBytes(uid.Length);
- userFlags = File.ReadUint();
- creationTime = File.ReadBytes(creationTime.Length);
- modificationTime = File.ReadBytes(modificationTime.Length);
- bOF = File.ReadUint();
- size = File.ReadUint();
- File.SkipBytes(sizeof(UInt32));
- }
- public DirectoryEntry()
- {
- colour = 0x00; // Black
- leftChildDirID = -1;
- rightChildDirID = -1;
- rootDirID = -1;
- uid = new byte[16];
- // 96 4 User flags (not of interest in the following, may be all 0)
- userFlags = 0;
- // 100 8 Time stamp of creation of this entry. Most implementations do not write a valid
- // time stamp, but fill up this space with zero bytes.
- creationTime = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
- // 108 8 Time stamp of last modification of this entry. Most implementations do not write
- // a valid time stamp, but fill up this space with zero bytes.
- modificationTime = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
- // Fixed empry values
- this.bOF = 0;
- this.size = 0;
- this.type = DirEntryType.Empty;
- this.entry_name = "";
- }
- public DirectoryEntry(string name, DirEntryType type) : this()
- {
- this.type = type;
- this.entry_name = name;
- }
- internal void Write(StreamHelper File)
- {
- int name_len = entry_name.Length;
- if (name_len > 32) name_len = 32;
- for (int i = 0; i < name_len; i++)
- {
- char ch = entry_name[i];
- File.WriteUshort(ch);
- }
- for (int i = name_len; i < 32; i++)
- {
- File.WriteUshort(0);
- }
- File.WriteUshort((ushort)(2 + name_len * 2));
- File.WriteByte((byte)type);
- File.WriteByte(colour);
- File.WriteInt(leftChildDirID);
- File.WriteInt(rightChildDirID);
- File.WriteInt(rootDirID);
- File.WriteBytes(uid);
- File.WriteUint(userFlags);
- File.WriteBytes(creationTime);
- File.WriteBytes(modificationTime);
- File.WriteUint(bOF);
- File.WriteUint(size);
- File.SkipBytes(sizeof(UInt32));
- }
- }
- internal class CompoundDocumentHeader : StreamHelper
- {
- private byte[] id0 = new byte[8]; // Must be: D0 CF 11 E0 A1 B1 1A E1
- private byte[] uid = new byte[16];
- private ushort revision; // Might be: 3E
- private ushort version; // Might be: 03
- private ushort byteOrder; // Little-Endian: FE FF; Big-Endian: FF FE
- private ushort secSize; // Sector size is 2**SecSize bytes
- private ushort shortSecSize; // Short sector size is 2**ShortSecSize bytes
- // fixed byte NotUsed1[10];
- private uint satCount; // Count of sectors used for the SAT
- public int dir; // First sector of the directory stream
- // fixed byte NotUsed2[4];
- public UInt32 minStreamSize; // Streams that have sizes less than this value are stored in the short stream
- private int sSAT; // First sector of the SSAT
- private uint sSATCount; // Count of sectors used for the SSAT
- private int mSAT; // First sector of the MSAT
- private uint mSATCount; // Count of sectors used for the MSAT
- private int[] mSATSectors = new int[109]; // First 109 SecID values in the MSAT
- private ArrayList sat = new ArrayList();
- private ArrayList shortSAT = new ArrayList();
- private ArrayList additional_mSAT = new ArrayList();
- private uint totalAllocatedSectors;
- private uint totalAllocatedShortSectors;
- internal BIFF8_Container shortStreamContainer;
- public int SectorSize { get { return 1 << secSize; } }
- public int ShortSectorSize { get { return 1 << shortSecSize; } }
- internal int SectorOffset(int index)
- {
- int a = 512 + index * SectorSize;
- return a;
- }
- internal int ShortSectorOffset(int index)
- {
- int a = index * ShortSectorSize;
- return a;
- }
- internal int NextSector(int index)
- {
- return (int)sat[index];
- }
- internal int NextShortSector(int index)
- {
- return (int)shortSAT[index];
- }
- internal void Read()
- {
- id0 = ReadBytes(id0.Length);
- uid = ReadBytes(uid.Length);
- revision = ReadUshort();
- version = ReadUshort();
- byteOrder = ReadUshort();
- secSize = ReadUshort();
- shortSecSize = ReadUshort();
- SkipBytes(10);
- satCount = ReadUint();
- dir = ReadInt();
- SkipBytes(4);
- minStreamSize = ReadUint();
- sSAT = ReadInt();
- sSATCount = ReadUint();
- mSAT = ReadInt();
- mSATCount = ReadUint();
- mSATSectors = ReadInts(mSATSectors.Length);
- // Read SAT into memory
- for (int i = 0; i < satCount; i++)
- {
- if (i >= 109) throw new Exception("Huge SAT not implemented");
- int SAT_Sector = mSATSectors[i];
- int Position = SectorOffset(SAT_Sector);
- this.Position = Position;
- sat.AddRange(new ArrayList(ReadInts(this.SectorSize / sizeof(UInt32))));
- }
- // Read SSAT into memory
- int SSAT_Sector = sSAT;
- for (int i = 0; i < sSATCount; i++)
- {
- int Position = SectorOffset(SSAT_Sector);
- this.Position = Position;
- shortSAT.AddRange(new ArrayList(ReadInts(this.SectorSize / sizeof(UInt32))));
- SSAT_Sector = NextSector(SSAT_Sector);
- }
- }
- internal void Write()
- {
- this.Position = 0;
- WriteBytes(id0);
- WriteBytes(uid);
- WriteUshort(revision);
- WriteUshort(version);
- WriteUshort(byteOrder);
- WriteUshort(secSize);
- WriteUshort(shortSecSize);
- SkipBytes(10);
- WriteUint(satCount);
- WriteInt(dir);
- SkipBytes(4);
- WriteUint(minStreamSize);
- WriteInt(sSAT);
- WriteUint(sSATCount);
- WriteInt(mSAT);
- WriteUint(mSATCount);
- WriteInts(mSATSectors);
- // Write SSAT to memory
- int SSATEntriesPerSector = this.SectorSize / sizeof(UInt32);
- int SSAT_Sector = sSAT;
- for (int i = 0; i < sSATCount;)
- {
- this.Position = SectorOffset(SSAT_Sector);
- for (int j = 0; j < SSATEntriesPerSector; j++)
- {
- int value = (int)shortSAT[i * SSATEntriesPerSector + j];
- this.WriteInt(value);
- }
- i++;
- if (i == sSATCount) continue;
- SSAT_Sector = this.AllocateSector(SSAT_Sector);
- }
- // Write SAT to memory
- for (int i = 0; i < satCount; i++)
- {
- int SAT_Sector = 0;
- if (i >= 109) SAT_Sector = (int)this.additional_mSAT[i - 109];//throw new Exception("Huge SAT not implemented");
- else SAT_Sector = this.mSATSectors[i];
- this.Position = SectorOffset(SAT_Sector);
- for (int j = 0; j < this.SectorSize / sizeof(UInt32); j++)
- {
- int value = -1;
- int idx = i * this.SectorSize / sizeof(UInt32) + j;
- if (idx < sat.Count)
- value = (int)sat[idx];
- this.WriteInt(value);
- }
- }
- // Write MSAT to memory
- int MSATEntriesPerSector = this.SectorSize / sizeof(Int32);
- int MSAT_Sector = mSAT;
- for (int i = 0; i < mSATCount;)
- {
- this.Position = SectorOffset(MSAT_Sector);
- for (int j = 0; j < MSATEntriesPerSector; j++)
- {
- int n = i * SSATEntriesPerSector + j;
- int value = -1;
- if (n < satCount)
- value = n >= 109 ? (int)additional_mSAT[n - 109] : mSATSectors[n];
- this.WriteInt(value);
- }
- i++;
- if (i == mSATCount) continue;
- MSAT_Sector = this.AllocateSector(MSAT_Sector);
- }
- }
- internal void Reset()
- {
- id0 = new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 };
- revision = 0x003e;
- version = 0x0003;
- byteOrder = 0xfffe;
- secSize = 0x0009;
- shortSecSize = 0x0006;
- satCount = 0;
- minStreamSize = 0x00001000;
- mSAT = -2;
- mSATCount = 0;
- // Reset SAT table
- this.sat.Clear();
- // Reset SSAT table
- sSATCount = 0;
- this.shortSAT.Clear();
- // Reset MSAT table
- for (int i = 0; i < mSATSectors.Length; i++)
- {
- mSATSectors[i] = -1;
- }
- this.additional_mSAT.Clear();
- this.totalAllocatedSectors = 0;
- this.totalAllocatedShortSectors = 0;
- this.shortStreamContainer.SetLength(0);
- dir = AllocateSector();
- sSAT = AllocateSector();
- mSAT = AllocateSector();
- mSATCount = 1;
- }
- internal CompoundDocumentHeader(FileStream f)
- : base()
- {
- f.CopyTo(this, (int)f.Length);
- this.Position = 0;
- }
- internal CompoundDocumentHeader()
- : base()
- {
- shortStreamContainer = new BIFF8_Container();
- Reset();
- this.Position = 0;
- }
- internal void FinalWriteToStream(Stream f)
- {
- this.Position = 0;
- this.CopyTo(f, (int)this.Length);
- }
- internal void SetCurentSector(int Dir)
- {
- base.Position = SectorOffset(Dir);
- }
- internal void ReadShortStreamContainer(DirectoryEntry entry)
- {
- int StorePosition = (int)this.Position;
- int SectorOfContainer;
- shortStreamContainer = new BIFF8_Container();
- int idx = 0;
- for (
- SectorOfContainer = (int)entry.bOF;
- SectorOfContainer >= 0;
- SectorOfContainer = this.NextSector(SectorOfContainer)
- )
- {
- this.SetCurentSector(SectorOfContainer);
- for (int i = 0; i < this.SectorSize && idx < entry.size; i++)
- {
- shortStreamContainer.WriteByte((byte)ReadByte());
- }
- }
- this.Position = StorePosition;
- }
- internal int WriteShortStreamContainer()
- {
- int StorePosition = (int)this.Position;
- int FirstSectorOfContainer = this.AllocateSector();
- int ContainerSize = (int)shortStreamContainer.Length;
- shortStreamContainer.Position = 0;
- for (
- int SectorOfContainer = (int)FirstSectorOfContainer;
- ContainerSize > 0;
- SectorOfContainer = this.AllocateSector(SectorOfContainer)
- )
- {
- this.SetCurentSector(SectorOfContainer);
- for (int i = 0; i < this.SectorSize; i++)
- {
- byte value = 0xff;
- if (shortStreamContainer.Position < shortStreamContainer.Length)
- {
- value = (byte)shortStreamContainer.ReadByte();
- }
- this.WriteByte(value);
- }
- ContainerSize -= this.SectorSize;
- if (ContainerSize <= 0) break;
- }
- this.Position = StorePosition;
- return FirstSectorOfContainer;
- }
- internal int AllocateSector()
- {
- int new_sector;
- new_sector = sat.IndexOf(-1);
- if (new_sector == -1)
- {
- AllocateSATSector();
- new_sector = sat.IndexOf(-1);
- if (new_sector == -1)
- {
- throw new Exception("Unable allocate SAT sector");
- }
- sat[new_sector] = -2;
- int self = sat.IndexOf(-1);
- sat[self] = -3;
- if (satCount >= 109)
- {
- //throw new Exception("Huge SAT not implemented");
- this.additional_mSAT.Add(self);
- }
- else mSATSectors[satCount] = self;
- satCount++;
- }
- totalAllocatedSectors++;
- sat[new_sector] = -2;
- return new_sector;
- }
- internal int AllocateSector(int PrevSector)
- {
- int Sector = AllocateSector();
- sat[PrevSector] = Sector;
- return Sector;
- }
- internal int AllocateShortSector()
- {
- int new_sector;
- new_sector = shortSAT.IndexOf(-1);
- if (new_sector == -1)
- {
- AllocateSSATSector();
- new_sector = shortSAT.IndexOf(-1);
- if (new_sector == -1)
- {
- throw new Exception("Unable allocate SSAT sector");
- }
- }
- totalAllocatedShortSectors++;
- shortSAT[new_sector] = -2;
- return new_sector;
- }
- internal int AllocateShortSector(int PrevSector)
- {
- int Sector = AllocateShortSector();
- shortSAT[PrevSector] = Sector;
- return Sector;
- }
- private void AllocateSATSector()
- {
- if (satCount > 109)
- {
- //throw new Exception("Large MSAT does not implemented yet");
- }
- int SATEntriesPerSector = this.ShortSectorSize / sizeof(UInt32);
- ArrayList sat_new_sectors = new ArrayList();
- #if false // BIG DEAL
- sat_new_sectors.Add(-3); // Sector is used by SAT itself
- for (int i = 1; i < SATEntriesPerSector; i++)
- #else
- for (int i = 0; i < SATEntriesPerSector; i++)
- #endif
- {
- sat_new_sectors.Add(-1);
- }
- sat.AddRange(sat_new_sectors);
- int local = sat.Count / SATEntriesPerSector;
- // MSATSectors[SATCount] = (int)
- totalAllocatedSectors++;
- }
- private void AllocateSSATSector()
- {
- int SSATEntriesPerSector = this.SectorSize / sizeof(UInt32);
- ArrayList ssat_new_sectors = new ArrayList();
- // ssat_new_sectors.Add(-3); // Sector is used by SAT itself
- for (int i = 0; i < SSATEntriesPerSector; i++)
- {
- ssat_new_sectors.Add(-1);
- }
- this.shortSAT.AddRange(ssat_new_sectors);
- int local = shortSAT.Count / SSATEntriesPerSector;
- sSATCount++;
- }
- #if false
- internal int AllocateStream(int WriteQueueLength, bool non_packing_stream)
- {
- int BOF;
- int Sector;
- // int WriteQueueLength = Container.Length;
- if (WriteQueueLength == 0) return -1;
- if (WriteQueueLength >= this.MinStreamSize || non_packing_stream)
- {
- BOF = Sector = this.AllocateSector();
- // int SourceCopyIndex = 0;
- do
- {
- int CopyCount = (WriteQueueLength < this.SectorSize) ? WriteQueueLength : this.SectorSize;
- // this.SetCurentSector(Sector);
- // this.WriteBytes(Container, SourceCopyIndex, CopyCount);
- WriteQueueLength -= CopyCount;
- if (WriteQueueLength == 0) break;
- Sector = this.AllocateSector(Sector);
- } while (true);
- }
- else
- {
- BOF = Sector = AllocateShortSector();
- // int SourceCopyIndex = 0;
- do
- {
- int CopyCount = (WriteQueueLength < this.ShortSectorSize) ? WriteQueueLength : this.ShortSectorSize;
- // this.SetCurentSector(Sector);
- // this.WriteBytes(Container, SourceCopyIndex, CopyCount);
- WriteQueueLength -= CopyCount;
- if (WriteQueueLength == 0) break;
- Sector = this.AllocateShortSector(Sector);
- } while (true);
- }
- return BOF;
- }
- #endif
- }
- internal class DirectoryStream : ArrayList
- {
- private CompoundDocumentHeader documentHeader;
- internal new DirectoryEntry this[int index]
- {
- get
- {
- return base[index] as DirectoryEntry;
- }
- }
- internal void Reset()
- {
- for (int i = 0; i < this.Count; i++)
- {
- base[i] = 0;
- }
- base.Clear();
- }
- internal void Read(int Dir, StreamHelper file)
- {
- do
- {
- documentHeader.SetCurentSector(Dir);
- for (int i = 0; i < documentHeader.SectorSize / 128; i++)
- {
- DirectoryEntry entry = new DirectoryEntry();
- entry.Read(file);
- Add(entry);
- }
- Dir = documentHeader.NextSector(Dir);
- } while (Dir != -2);
- }
- internal void Write(int Dir, StreamHelper file)
- {
- int local_directory_index = 0;
- DirectoryEntry entry;
- documentHeader.SetCurentSector(Dir);
- for (int i = 0; i < documentHeader.SectorSize / 128; i++)
- {
- if (local_directory_index < this.Count)
- {
- entry = this[local_directory_index] as DirectoryEntry;
- }
- else
- {
- entry = new DirectoryEntry();
- }
- entry.Write(file);
- local_directory_index++;
- }
- }
- public DirectoryStream(CompoundDocumentHeader header)
- {
- documentHeader = header;
- }
- internal DirectoryEntry Add(
- string FileName,
- BIFF8_Stream stream,
- int left, int right)
- {
- DirectoryEntry entry = stream.streamDirEntry;
- entry.entry_name = FileName;
- entry.type = DirectoryEntry.DirEntryType.UseStream;
- entry.size = (uint)stream.Length;
- entry.leftChildDirID = left;
- entry.rightChildDirID = right;
- entry.colour = 0x01;
- stream.Position = 0;
- // byte[] payload = stream.ReadBytes((int) entry.Size);
- // entry.BOF = (uint)DocumentHeader.AllocateStream( payload.Length, false );
- stream.streamDirEntry = entry;
- this.Add(entry);
- return entry;
- }
- internal DirectoryEntry Add(string FileName)
- {
- BIFF8_Container Container = documentHeader.shortStreamContainer;
- DirectoryEntry entry = new DirectoryEntry();
- entry.entry_name = FileName;
- entry.type = DirectoryEntry.DirEntryType.RootStorage;
- entry.size = (uint)Container.Length;
- entry.bOF = (uint)documentHeader.WriteShortStreamContainer();
- entry.rootDirID = 3;
- entry.colour = 0x01;
- this.Add(entry);
- return entry;
- }
- }
- /// <summary>
- ///
- /// </summary>
- internal class BIFF8_Container : StreamHelper
- {
- }
- internal class BIFF8_Stream : StreamHelper
- {
- internal DirectoryEntry streamDirEntry;
- internal CompoundDocumentHeader documentHeader;
- private int ShortSectorSize { get { return documentHeader.ShortSectorSize; } }
- internal void Write()
- {
- this.Position = 0;
- int BytesCount = (int)this.Length;
- if (BytesCount < documentHeader.minStreamSize)
- {
- this.streamDirEntry.bOF = (uint)this.documentHeader.AllocateShortSector();
- int Sector = (int)this.streamDirEntry.bOF;
- while (BytesCount > 0)
- {
- int chunk_size = (BytesCount >= ShortSectorSize) ? ShortSectorSize : BytesCount;
- byte[] sector = this.ReadBytes(documentHeader.ShortSectorSize);
- documentHeader.shortStreamContainer.Position = documentHeader.ShortSectorOffset(Sector);
- documentHeader.shortStreamContainer.Write(sector, 0, chunk_size);
- BytesCount -= chunk_size;
- if (BytesCount <= 0) break;
- Sector = documentHeader.AllocateShortSector(Sector);
- }
- }
- else
- {
- this.streamDirEntry.bOF = (uint)this.documentHeader.AllocateSector();
- int Sector = (int)this.streamDirEntry.bOF;
- while (BytesCount > 0)
- {
- documentHeader.SetCurentSector(Sector);
- byte[] sector = this.ReadBytes(documentHeader.SectorSize);
- documentHeader.Write(sector, 0, documentHeader.SectorSize);
- BytesCount -= documentHeader.SectorSize;
- if (BytesCount <= 0) break;
- Sector = documentHeader.AllocateSector(Sector);
- }
- }
- }
- public BIFF8_Stream(CompoundDocumentHeader document_header, DirectoryEntry entry)
- {
- this.streamDirEntry = entry;
- this.documentHeader = document_header;
- int Sector = (int)entry.bOF;
- int BytesCount = (int)entry.size;
- if (BytesCount < documentHeader.minStreamSize)
- {
- while (BytesCount > 0)
- {
- int chunk_size = (BytesCount >= ShortSectorSize) ? ShortSectorSize : BytesCount;
- documentHeader.shortStreamContainer.Position = documentHeader.ShortSectorOffset(Sector);
- byte[] sector_data = documentHeader.shortStreamContainer.ReadBytes(chunk_size);
- this.Write(sector_data, 0, chunk_size);
- Sector = documentHeader.NextShortSector(Sector);
- BytesCount -= chunk_size;
- }
- }
- else
- {
- while (BytesCount > 0)
- {
- documentHeader.SetCurentSector(Sector);
- if (BytesCount >= documentHeader.SectorSize)
- {
- byte[] sector = documentHeader.ReadBytes(documentHeader.SectorSize);
- base.Write(sector, 0, documentHeader.SectorSize);
- BytesCount -= documentHeader.SectorSize;
- }
- else
- {
- byte[] sector = documentHeader.ReadBytes(BytesCount);
- base.Write(sector, 0, BytesCount);
- BytesCount -= documentHeader.SectorSize;
- }
- Sector = documentHeader.NextSector(Sector);
- }
- }
- base.Position = 0;
- }
- }
- }
|