private void SerializeHeader(BBeB book, BBeBinaryWriter writer) { BBeBHeader header = book.Header; TocObject tocObject = (TocObject)book.FindObject((ushort)header.dwTocObjectId); if (tocObject == null) { throw new InvalidBookException("Can't find the TOC object"); } writer.Write(header.signature); writer.Write(header.wVersion); writer.Write(header.wPseudoEncByte); writer.Write(header.dwRootObjectId); writer.Write(header.NumberOfObjects); m_dwIndexOffsetVal = writer.Position; writer.Write(header.ObjectIndexOffset); writer.Write(header.dwUnknown1); writer.Write(header.byBindingDir); writer.Write(header.byPadding1); writer.Write(header.wDPI); writer.Write(header.wPadding2); writer.Write(header.wScreenWidth); writer.Write(header.wScreenHeight); writer.Write(header.byColorDepth); writer.Write(header.byPadding3); writer.Write(header.byUnkonwn2); writer.Write(header.dwTocObjectId); writer.WriteStreamOffsetReference(tocObject); // This may seem a little wasteful as we actually serialize the MetaData object twice // Once here and onces when we actualy write it to the stream, however we need to set // the compressed size in the header and we can only do it by compressing it first. // Really we should store the compressed byte stream and just save that out // but its not very big so the overhead is quite small { MemoryStream mem = new MemoryStream(); BinaryWriter sw = new BinaryWriter(mem); header.wDocInfoCompSize = (ushort)(SerializeMetaData(book.MetaData, sw) + 4); } writer.Write(header.wDocInfoCompSize); Debug.Assert(writer.Position == 0x4E); if (header.wVersion >= 800) { writer.Write(header.wThumbnailFlags); writer.Write(header.dwThumbSize); Debug.Assert(writer.Position == 0x54); } }
public BBeB Deserialize(Stream bbebStream) { BinaryReader reader = new BinaryReader(bbebStream, Encoding.Unicode); BBeB book = new BBeB(); BBeBHeader header = DeserializeHeader(reader); header.Validate(); book.Header = header; book.MetaData = DeserializeMetaData(reader, header.wDocInfoCompSize); if (header.wVersion >= 800) { book.ThumbnailData = reader.ReadBytes((int)header.dwThumbSize); } // See http://www.sven.de/librie/Librie/LrfFormat for more information on this table. const ulong k_dwObjTableElementSize = 4 * sizeof(uint); ulong nTotalSize = 0; BBeBObjectFactory objFactory = new BBeBObjectFactory(); Debug.WriteLineIf(s_bDebugMode, "File contains " + header.NumberOfObjects + " objects"); for (ulong idxObj = 0; idxObj < header.NumberOfObjects; idxObj++) { reader.BaseStream.Seek((long)(header.ObjectIndexOffset + idxObj * k_dwObjTableElementSize), SeekOrigin.Begin); uint id = reader.ReadUInt32(); uint offset = reader.ReadUInt32(); uint size = reader.ReadUInt32(); nTotalSize += size; reader.BaseStream.Seek(offset, SeekOrigin.Begin); book.Objects.Add(objFactory.CreateObject(reader, id, size)); } Debug.WriteLineIf(s_bDebugMode, "Total size: " + nTotalSize); ConnectObjects(book); return(book); }
private BBeBHeader DeserializeHeader(BinaryReader reader) { Debug.WriteLineIf(s_bDebugMode, "Reading header"); BBeBHeader header = new BBeBHeader(); header.signature = reader.ReadChars(4); header.wVersion = reader.ReadUInt16(); header.wPseudoEncByte = reader.ReadUInt16(); header.dwRootObjectId = reader.ReadUInt32(); header.NumberOfObjects = reader.ReadUInt64(); header.ObjectIndexOffset = reader.ReadUInt64(); header.dwUnknown1 = reader.ReadUInt32(); header.byBindingDir = reader.ReadByte(); header.byPadding1 = reader.ReadByte(); header.wDPI = reader.ReadUInt16(); header.wPadding2 = reader.ReadUInt16(); header.wScreenWidth = reader.ReadUInt16(); header.wScreenHeight = reader.ReadUInt16(); header.byColorDepth = reader.ReadByte(); header.byPadding3 = reader.ReadByte(); header.byUnkonwn2 = reader.ReadBytes(0x14); header.dwTocObjectId = reader.ReadUInt32(); header.dwTocObjectOffset = reader.ReadUInt32(); header.wDocInfoCompSize = reader.ReadUInt16(); Debug.Assert(reader.BaseStream.Position == 0x4E); if (header.wVersion >= 800) { header.wThumbnailFlags = reader.ReadUInt16(); header.dwThumbSize = reader.ReadUInt32(); Debug.Assert(reader.BaseStream.Position == 0x54); } // Set the TextObject EncodingBytes (temporary hack) StreamTagSerializer.EncodingByte = header.wPseudoEncByte; return(header); }