示例#1
0
        public override void Deserialize(BinaryStream stream)
        {
            var ptr = (int)stream.Position;

            var nD = DescriptorTag.Read(stream, ReferenceType.Offset);

            if (nD.IsOffset)
            {
                stream.Position = nD.Value;
                Deserialize(stream);

                stream.Position = (ptr + nD.Size);
            }
            else
            {
                Offset = ptr;

                var nChildren = nD.Value;

                Children = new List <NodeClass>(nChildren);

                var hash = stream.ReadInt32();
                var size = stream.ReadInt16();

                var name = StringHasher.ResolveHash(hash);

                if (name != null)
                {
                    Name = name;
                }
                else
                {
                    Hash = hash;
                }

                var attrsPtr = (int)stream.Position;
                var next     = (attrsPtr + size);

                if (size != 0)
                {
                    var nhD = DescriptorTag.Read(stream, ReferenceType.Offset);

                    var adjustPtr = false;

                    if (nhD.IsOffset)
                    {
                        stream.Position = nhD.Value;

                        // read again
                        nhD = DescriptorTag.Read(stream, ReferenceType.Offset);

                        if (nhD.IsOffset)
                        {
                            throw new InvalidOperationException("Cannot have nested offsets!");
                        }

                        // adjust ptr to attributes
                        attrsPtr += nhD.Size;
                        adjustPtr = true;
                    }

                    var nAttrs = nhD.Value;

                    Attributes = new List <NodeAttribute>(nAttrs);

                    for (int i = 0; i < nAttrs; i++)
                    {
                        var attr = new NodeAttribute(stream, Name);
                        Attributes.Add(attr);
                    }

                    // move to the attributes if needed
                    if (adjustPtr)
                    {
                        stream.Position = attrsPtr;
                    }

                    // deserialize attribute data
                    foreach (var attr in Attributes)
                    {
                        attr.Deserialize(stream);
                    }
                }
                else
                {
                    throw new NotImplementedException("Zero-length nodes are not covered under TrumpCare™.");
                }

                if (stream.Position != next)
                {
                    throw new InvalidOperationException("You dun f****d up, son!");
                }

                // read children
                for (int n = 0; n < nChildren; n++)
                {
                    var child = new NodeClass(stream);
                    Children.Add(child);
                }
            }
        }
示例#2
0
 public NodeClass(BinaryStream stream)
 {
     Deserialize(stream);
 }
示例#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);
                }
            }
        }