using System; using System.Collections.Generic; using System.Text; using System.IO; using QiHe.CodeLib; namespace HH.WMS.Utils.ExcelLibrary.CompoundDocumentFormat { public partial class CompoundDocument { private void WriteHeader() { this.FileStorage.Position = 0; WriteHeader(this.Writer, this.Header); } private static void WriteHeader(BinaryWriter writer, FileHeader header) { // header size is 512 bytes writer.Write(header.FileTypeIdentifier); writer.Write(header.FileIdentifier.ToByteArray()); writer.Write(header.RevisionNumber); writer.Write(header.VersionNumber); writer.Write(header.ByteOrderMark); writer.Write(header.SectorSizeInPot); writer.Write(header.ShortSectorSizeInPot); writer.Write(header.UnUsed10); writer.Write(header.NumberOfSATSectors); writer.Write(header.FirstSectorIDofDirectoryStream); writer.Write(header.UnUsed4); writer.Write(header.MinimumStreamSize); writer.Write(header.FirstSectorIDofShortSectorAllocationTable); writer.Write(header.NumberOfShortSectors); writer.Write(header.FirstSectorIDofMasterSectorAllocationTable); writer.Write(header.NumberOfMasterSectors); WriteArrayOfInt32(writer, header.MasterSectorAllocationTable); } private static void WriteDirectoryEntry(BinaryWriter writer, DirectoryEntry entry) { writer.Write(entry.NameBuffer); writer.Write(entry.NameDataSize); writer.Write(entry.EntryType); writer.Write(entry.NodeColor); writer.Write(entry.LeftChildDID); writer.Write(entry.RightChildDID); writer.Write(entry.MembersTreeNodeDID); writer.Write(entry.UniqueIdentifier.ToByteArray()); writer.Write(entry.UserFlags); writer.Write(entry.CreationTime.ToFileTime()); writer.Write(entry.LastModificationTime.ToFileTime()); writer.Write(entry.FirstSectorID); writer.Write(entry.StreamLength); writer.Write(entry.UnUsed); } //void WriteMasterSectorAllocationTable(BinaryWriter writer) //{ // int extraIDcount = MasterSectorAllocationTable.Count - Header.MasterSectorAllocationTable.Length; // if (extraIDcount <= 0) // { // Header.FirstSectorIDofMasterSectorAllocationTable = SID.EOC; // for (int i = 0; i < MasterSectorAllocationTable.Count; i++) // { // Header.MasterSectorAllocationTable[i] = MasterSectorAllocationTable[i]; // } // } // else // { // Header.FirstSectorIDofMasterSectorAllocationTable = 0; // for (int i = 0; i < Header.MasterSectorAllocationTable.Length; i++) // { // Header.MasterSectorAllocationTable[i] = MasterSectorAllocationTable[i]; // } // int sectorIDcount = SectorSize / 4 - 1; // int sectorIndex = Header.MasterSectorAllocationTable.Length; // int nextSectID = 1; // while (extraIDcount > sectorIDcount) // { // for (int i = 0; i < sectorIDcount; i++) // { // writer.Write(MasterSectorAllocationTable[sectorIndex]); // sectorIndex++; // } // writer.Write(nextSectID); // nextSectID++; // extraIDcount -= sectorIDcount; // } // for (int i = 0; i < extraIDcount; i++) // { // writer.Write(MasterSectorAllocationTable[sectorIndex]); // sectorIndex++; // } // for (int i = 0; i < sectorIDcount - extraIDcount; i++) // { // writer.Write(-1); // } // writer.Write(SID.EOC); // } //} public void WriteStreamData(string[] streamPath, byte[] data) { DirectoryEntry entry = GetOrCreateDirectoryEntry(streamPath); entry.EntryType = EntryType.Stream; entry.StreamLength = data.Length; if (entry.StreamLength < Header.MinimumStreamSize) { if (entry.FirstSectorID == SID.EOC) { entry.FirstSectorID = AllocateShortSector(); } WriteShortStreamData(entry.FirstSectorID, data); } else { if (entry.FirstSectorID == SID.EOC) { entry.FirstSectorID = AllocateDataSector(); } WriteStreamData(entry.FirstSectorID, data); } } internal void WriteStreamData(int startSID, byte[] data) { int prev_sid = SID.EOC; int sid = startSID; int index = 0; while (index < data.Length) { if (sid == SID.EOC) { if (prev_sid == SID.EOC) { sid = this.AllocateDataSector(); } else { sid = this.AllocateDataSectorAfter(prev_sid); } } int offset = GetSectorOffset(sid); Writer.BaseStream.Position = offset; if (index + SectorSize < data.Length) { Writer.Write(data, index, SectorSize); } else { Writer.Write(data, index, data.Length - index); } index += SectorSize; prev_sid = sid; sid = this.SectorAllocation.GetNextSectorID(prev_sid); } if (sid != SID.EOC && prev_sid != SID.EOC) { SectorAllocation.LinkSectorID(prev_sid, SID.EOC); while (sid != SID.EOC) { int next_sid = SectorAllocation.GetNextSectorID(sid); SectorAllocation.LinkSectorID(sid, SID.Free); sid = next_sid; } } } private void AppendStreamData(int startSID, int streamLength, byte[] data) { int sid = startSID; int next_sid = SectorAllocation.GetNextSectorID(sid); int index = 0; while (next_sid != SID.EOC) { sid = next_sid; next_sid = SectorAllocation.GetNextSectorID(sid); index += SectorSize; } if (index < streamLength) { int position = streamLength - index; int length = SectorSize - position; if (data.Length <= length) { WriteInSector(sid, position, data, 0, data.Length); } else { WriteInSector(sid, position, data, 0, length); next_sid = AllocateDataSectorAfter(sid); byte[] remained_data = new byte[data.Length - length]; Array.Copy(data, length, remained_data, 0, remained_data.Length); WriteStreamData(next_sid, remained_data); } } else { next_sid = AllocateDataSectorAfter(sid); WriteStreamData(next_sid, data); } } internal void WriteShortStreamData(int startSID, byte[] data) { int prev_sid = SID.EOC; int sid = startSID; int index = 0; while (index < data.Length) { if (sid == SID.EOC) { if (prev_sid == SID.EOC) { sid = this.ShortSectorAllocation.AllocateSector(); } else { sid = this.ShortSectorAllocation.AllocateSectorAfter(prev_sid); } } int offset = GetShortSectorOffset(sid); ShortStreamContainer.Position = offset; if (index + ShortSectorSize < data.Length) { ShortStreamContainer.Write(data, index, ShortSectorSize); } else { ShortStreamContainer.Write(data, index, data.Length - index); } index += ShortSectorSize; prev_sid = sid; sid = this.ShortSectorAllocation.GetNextSectorID(prev_sid); } if (sid != SID.EOC && prev_sid != SID.EOC) { ShortSectorAllocation.LinkSectorID(prev_sid, SID.EOC); while (sid != SID.EOC) { int next_sid = ShortSectorAllocation.GetNextSectorID(sid); ShortSectorAllocation.LinkSectorID(sid, SID.Free); sid = next_sid; } } } private DirectoryEntry GetOrCreateDirectoryEntry(string[] streamPath) { DirectoryEntry entry = this.RootStorage; foreach (string entryName in streamPath) { if (!entry.Members.ContainsKey(entryName)) { DirectoryEntry newEntry = new DirectoryEntry(this, entryName); newEntry.ID = this.DirectoryEntries.Count; this.DirectoryEntries.Add(newEntry.ID, newEntry); entry.AddChild(newEntry); } entry = entry.Members[entryName]; } return entry; } public void DeleteDirectoryEntry(string[] streamPath) { DirectoryEntry entry = GetOrCreateDirectoryEntry(streamPath); DeleteDirectoryEntry(entry); } public void DeleteDirectoryEntry(DirectoryEntry entry) { entry.EntryType = EntryType.Empty; entry.StreamLength = 0; entry.Parent.Members.Remove(entry.Name); } } }