Пример #1
0
        public void Serialize(BinaryStream stream, int baseOffset = 0)
        {
            if (Type == DataType.RML)
            {
                throw new InvalidOperationException("Cannot serialize RML data directly!");
            }

            var ptr     = (int)stream.Position;
            var oldSize = Size;

            if (Size > 0)
            {
                var writeData = true;

                if (CanBeCached)
                {
                    if (WriteCache.IsCached(this))
                    {
                        var cache = WriteCache.GetData(this);

                        if (cache.Size == Size)
                        {
                            stream.Position = (cache.Offset + 1);
                            var buf = stream.ReadBytes(cache.Size);

                            var key    = Memory.GetCRC32(Buffer);
                            var bufKey = Memory.GetCRC32(buf);

                            stream.Position = ptr;

                            // slow as f**k, but there's no room for error
                            if (key == bufKey)
                            {
                                var nD = DescriptorTag.CreateReference(cache.Offset, ReferenceType.Offset);
                                nD.WriteTo(stream, baseOffset);

                                writeData = false;
                            }
                        }
                    }
                    else
                    {
                        WriteCache.Cache(ptr, this);
                    }
                }

                if (writeData)
                {
                    var nD = DescriptorTag.Create(Size);
                    nD.WriteTo(stream, baseOffset);

                    stream.Write(Buffer);
                }
            }
            else
            {
                // nothing to write!
                stream.WriteByte(0);
            }
        }
Пример #2
0
        private void WriteAttributeHashes(BinaryStream stream)
        {
            var ptr    = (int)stream.Position;
            var nAttrs = Attributes.Count;

            if (nAttrs > 0)
            {
                var attrHBuf = new byte[(nAttrs * 4) + 1];

                using (var buf = new BinaryStream(attrHBuf))
                {
                    buf.WriteByte(nAttrs);

                    foreach (var attr in Attributes)
                    {
                        attr.Serialize(buf, true);
                    }
                }

                if (WriteCache.IsCached(attrHBuf, nAttrs))
                {
                    var cache = WriteCache.GetData(attrHBuf, nAttrs);

                    var nhD = DescriptorTag.CreateReference(cache.Offset, ReferenceType.Offset);
                    nhD.WriteTo(stream);
                }
                else
                {
                    WriteCache.Cache(ptr, attrHBuf, nAttrs);
                    stream.Write(attrHBuf);
                }
            }
            else
            {
                // nothing to write
                stream.WriteByte(0);
            }
        }
Пример #3
0
        public override void Serialize(BinaryStream stream)
        {
            Offset = (int)stream.Position;

            var nChildren   = Children.Count;
            var nAttributes = Attributes.Count;

            var writeData = true;

            if (Size > 16)
            {
                if (WriteCache.IsCached(this))
                {
                    var cache = WriteCache.GetData(this);
                    var obj   = cache.Object as NodeClass;

                    if ((obj != null) && obj.Equals(this))
                    {
                        Debug.WriteLine($">> [Class:{Offset:X8}] Instance cached @ {cache.Offset:X8} with key {cache.Checksum:X8}");

                        var nD = DescriptorTag.CreateReference(cache.Offset, ReferenceType.Offset);
                        nD.WriteTo(stream);

                        writeData = false;
                    }
                    else
                    {
                        Debug.WriteLine($">> [Class:{Offset:X8}] !!! FALSE POSITIVE !!!");
                    }
                }
                else
                {
                    Debug.WriteLine($">> [Class:{Offset:X8}] Caching new instance with key {GetHashCode():X8}");
                    WriteCache.Cache(Offset, this);
                }
            }

            if (writeData)
            {
                var nD = DescriptorTag.Create(nChildren);
                nD.WriteTo(stream);

                stream.Write(Hash);

                // skip size parameter for now
                stream.Position += 2;

                var attrsPtr = stream.Position;

                if (nAttributes > 0)
                {
                    WriteAttributeHashes(stream);

                    // write attribute data
                    foreach (var attribute in Attributes)
                    {
                        attribute.Serialize(stream);
                    }
                }
                else
                {
                    // no attributes to write!
                    stream.WriteByte(0);
                }

                var childrenPtr = stream.Position;
                var attrsSize   = (int)(childrenPtr - attrsPtr);

                if (attrsSize > 65535)
                {
                    throw new InvalidOperationException("Attribute data too large.");
                }

                // write attributes size
                stream.Position = (attrsPtr - 2);
                stream.Write((short)attrsSize);

                // now write the children out
                stream.Position = childrenPtr;

                foreach (var child in Children)
                {
                    child.Serialize(stream);
                }
            }
        }