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); } } }
public NodeClass(BinaryStream stream) { Deserialize(stream); }
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); } } }