public static void SerializeTags(List <BBeBTag> tags, BBeBinaryWriter writer) { foreach (BBeBTag tag in tags) { SerializeTag(tag, writer); } }
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); } }
private void SerializeObject(BBeBObject obj, BBeBinaryWriter writer) { writer.WriteObjectStart(obj); writer.Write((ushort)obj.ID); writer.Write((ushort)0x0); // All objects have this // Write object type writer.Write((ushort)obj.Type); SerializeTags(obj.Tags, writer); writer.WriteObjectEnd(obj); }
public static void Serialize(BBeBinaryWriter writer, StreamTagGroup tagGroup) { writer.Write(TagId.StreamFlags); ushort wFlags = (ushort)((ushort)(tagGroup.Contents) | (ushort)(StreamFormatFlags.None)); writer.Write(wFlags); writer.Write(TagId.StreamSize); writer.Write((uint)tagGroup.Data.Length); writer.Write(TagId.StreamStart); writer.Write(tagGroup.Data); writer.Write(TagId.StreamEnd); }
/// <summary> /// Serialize the object to the supplied stream. /// </summary> /// <param name="stream">Write the serialized bytes of the book to this stream.</param> /// <param name="book">The book to serialize</param> public void Serialize(Stream stream, BBeB book) { m_dwIndexOffsetVal = 0; FixupHeaderForWriting(book); BBeBinaryWriter writer = new BBeBinaryWriter(stream); book.Header.Validate(); SerializeHeader(book, writer); SerializeMetaData(book.MetaData, writer); if (book.Header.wVersion >= 800) { writer.Write(book.ThumbnailData); } // Now go back and update the position of the object index now that we // know where its offset in the stream. long dwObjIdxStartOffset = writer.Position; writer.Position = m_dwIndexOffsetVal; writer.Write((ulong)dwObjIdxStartOffset); writer.Position = dwObjIdxStartOffset; // Write the object offset index table foreach (BBeBObject obj in book.Objects) { writer.Write((uint)obj.ID); writer.WriteStreamOffsetReference(obj); // Will be fixed up later writer.WriteStreamSizeReference(obj); // Will be fixed up later writer.Write((uint)0x0); // Unused and reserved } // Now write out all the objects foreach (BBeBObject obj in book.Objects) { SerializeObject(obj, writer); } writer.Flush(); writer.ResolveReferences(); }
/// <summary> /// Write the tag serialized data using the supplied writer. /// </summary> /// <remarks> /// This is a really KLUDGY routine. Even though it deals with primitive /// types it has knowledge of what those types mean. For example the UInt16ArrayTag /// doesn't have a length value written, but the UInt32ArrayTag does. This is /// a very brittle solution to this problem and needs to be fixed. The solution is /// to have a serialize method for each tag type (uggh) - so you see why I took /// this shortcut. /// </remarks> /// <param name="tag"></param> /// <param name="writer"></param> private static void SerializeTag(BBeBTag tag, BBeBinaryWriter writer) { ushort id = (ushort)(0xf500 + tag.Id); if (tag.GetType() == typeof(ByteTag)) { ByteTag t = (ByteTag)tag; writer.Write(id); writer.Write(t.Value); } else if (tag.GetType() == typeof(StreamTagGroup)) { StreamTagSerializer.Serialize(writer, (StreamTagGroup)tag); } else if (tag.GetType() == typeof(ByteArrayTag)) { ByteArrayTag t = (ByteArrayTag)tag; if (t.Id == TagId.StreamStart) { byte[] data = t.Value; writer.Write(BBeBLib.TagId.StreamSize); writer.Write((uint)data.Length); writer.Write(id); writer.Write(data); writer.Write(BBeBLib.TagId.StreamEnd); } else { writer.Write(id); writer.Write(t.Value); } } else if (tag.GetType() == typeof(UInt16Tag)) { UInt16Tag t = (UInt16Tag)tag; writer.Write(id); writer.Write(t.Value); } else if (tag.GetType() == typeof(UInt16ArrayTag)) { UInt16ArrayTag t = (UInt16ArrayTag)tag; writer.Write(id); foreach (ushort val in t.Value) { writer.Write(val); } } else if (tag.GetType() == typeof(UInt32Tag)) { UInt32Tag t = (UInt32Tag)tag; // StreamSize is written out by the StreamStart tag as the data may be compressed if (t.Id != TagId.StreamSize) { writer.Write(id); // Zero byte tags (but have hardcoded data associated with them if (t.Id != TagId.BaseButtonStart && t.Id != TagId.FocusinButtonStart && t.Id != TagId.PushButtonStart && t.Id != TagId.UpButtonStart) { writer.Write(t.Value); } } } else if (tag.GetType() == typeof(UInt32ArrayTag)) { UInt32ArrayTag t = (UInt32ArrayTag)tag; writer.Write(id); // JumpTo doesn't have a length set and is hardcoded to 2! if (t.Id != TagId.JumpTo) { writer.Write((ushort)t.Value.Length); } foreach (uint val in t.Value) { writer.Write(val); } } else if (tag.GetType() == typeof(StringTag)) { StringTag t = (StringTag)tag; writer.Write(id); writer.Write(t.Value); } else if (tag.GetType() == typeof(MessageTag)) { MessageTag t = (MessageTag)tag; writer.Write(id); writer.Write((ushort)t.parameters); byte[] data = System.Text.Encoding.Unicode.GetBytes(t.param1); writer.Write((ushort)data.Length); writer.Write(data); data = System.Text.Encoding.Unicode.GetBytes(t.param2); writer.Write((ushort)data.Length); writer.Write(data); } else if (tag.GetType() == typeof(EmpDotsCodeTag)) { EmpDotsCodeTag t = (EmpDotsCodeTag)tag; writer.Write(id); writer.Write((uint)t.Value); SerializeTag(t.FontFace, writer); writer.Write(t.DotsCode); } else if (tag.GetType() == typeof(IDOnlyTag)) { IDOnlyTag t = (IDOnlyTag)tag; if (t.Id != TagId.StreamEnd) { writer.Write(id); } } else if (tag.GetType() == typeof(BBeBTag)) { BBeBTag t = (BBeBTag)tag; if (t.Id != TagId.StreamEnd) { writer.Write(id); } } else { Debug.Assert(false, "Unknown tag type: " + tag.GetType().ToString()); } }