예제 #1
0
        /// <summary>
        /// Read a group of stream tags (which all come in order) from the BBeB reader.
        /// </summary>
        /// <param name="tagReader">The reader to do the reading with</param>
        /// <returns>A new tag representing the uncompressed data in the stream.</returns>
        public static StreamTagGroup Deserialize(BBeBinaryReader tagReader, ObjectType eObjectType)
        {
            ushort wFlags = tagReader.ReadUInt16();

            StreamFormatFlags eStreamFlags = (StreamFormatFlags)(wFlags & 0xff00);
            StreamContents    eContents    = (StreamContents)(wFlags & 0x00ff);

            TagId eTagId = tagReader.ReadTag();

            if (eTagId != TagId.StreamSize)
            {
                throw new UnexpectedTagException("Expected a StreamSize tag: " + eTagId.ToString());
            }

            uint dwStreamSize = tagReader.ReadUInt32();

            eTagId = tagReader.ReadTag();
            if (eTagId != TagId.StreamStart)
            {
                throw new UnexpectedTagException("Expected a StreamStart tag: " + eTagId.ToString());
            }

            byte[] streamData = tagReader.ReadBytes((int)dwStreamSize);

            try
            {
                eTagId = tagReader.ReadTag();
            }
            catch (InvalidTagException ex)
            {
                Debug.WriteLineIf(s_bDebugMode, "Not a tag at end of stream: 0x" + ex.Value.ToString("x"));
                // dataTag.AppendShort(ex.Value);

                // Temporarily
                eTagId = TagId.StreamEnd;
            }
            if (eTagId != TagId.StreamEnd)
            {
                throw new UnexpectedTagException("Expected a StreamEnd tag: " + eTagId.ToString());
            }

            StreamTagGroup tag = new StreamTagGroup();

            tag.Contents = eContents;

            StreamTagSerializer streamTagSerializer = new StreamTagSerializer();

            tag.Data = streamTagSerializer.Convert(streamData, eStreamFlags,
                                                   StreamFormatFlags.None, eObjectType);

            return(tag);
        }
예제 #2
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());
            }
        }