Beispiel #1
0
 public static void SerializeTags(List <BBeBTag> tags, BBeBinaryWriter writer)
 {
     foreach (BBeBTag tag in tags)
     {
         SerializeTag(tag, writer);
     }
 }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        /// <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();
        }
Beispiel #6
0
        /// <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());
            }
        }