protected NomadValue ReadRmlAttribute(BinaryStream _stream, NomadObject parent = null) { Context.State = ContextStateType.Member; Context.ObjectIndex++; var unk = (byte)_stream.ReadByte(); if (unk != 0) { throw new InvalidOperationException("Invalid RML attribute data."); } var nameIdx = DescriptorTag.Read(_stream, ReferenceType.Index); var valIdx = DescriptorTag.Read(_stream, ReferenceType.Index); var buffer = Utils.GetStringBuffer(_strings[valIdx]); var result = new NomadValue(DataType.RML, buffer) { Id = _strings[nameIdx], }; if (parent != null) { parent.Attributes.Add(result); } return(result); }
public 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); // move past offset stream.Position = (ptr + nD.Size); } else { var size = nD.Value; Buffer = new byte[size]; stream.Read(Buffer, 0, size); } }
protected NomadObject ReadRmlObject(BinaryStream _stream, NomadObject parent = null) { Context.State = ContextStateType.Object; Context.ObjectIndex++; var nameIdx = DescriptorTag.Read(_stream, ReferenceType.Index); var valIdx = DescriptorTag.Read(_stream, ReferenceType.Index); var nAttrs = DescriptorTag.Read(_stream, ReferenceType.Index); var nElems = DescriptorTag.Read(_stream, ReferenceType.Index); _attrCount += nAttrs; _elemCount += nElems; var result = new NomadObject(true) { Id = _strings[nameIdx], Tag = _strings[valIdx], }; if (parent != null) { parent.Children.Add(result); } for (int n = 0; n < nAttrs; n++) { ReadRmlAttribute(_stream, result); } for (int o = 0; o < nElems; o++) { ReadRmlObject(_stream, result); } return(result); }
public void Deserialize(BinaryStream stream, List <NodeObject> objRefs) { Offset = (int)stream.Position; // define reference type just in case we f**k up somehow var nD = DescriptorTag.Read(stream, ReferenceType.Index); if (nD.Type == DescriptorType.Reference) { throw new InvalidOperationException("Cannot deserialize an object reference directly!"); } var nChildren = nD.Value; Children = new List <NodeObject>(nChildren); var hash = stream.ReadInt32(); var name = StringHasher.ResolveHash(hash); if (name != null) { Name = name; } else { Hash = hash; } // add a reference to this object objRefs.Add(this); var aD = DescriptorTag.Read(stream, ReferenceType.Index); var nAttrs = aD.Value; Attributes = new List <NodeAttribute>(nAttrs); if (nAttrs > 0) { for (int i = 0; i < nAttrs; i++) { // hash and data inline var attr = new NodeAttribute(stream, Name); attr.Deserialize(stream); Attributes.Add(attr); } } if (nChildren > 0) { // read children for (int n = 0; n < nChildren; n++) { var cP = (int)stream.Position; var cD = DescriptorTag.Read(stream, ReferenceType.Index); // rip if (cD.IsIndex) { var idx = cD.Value; var childRef = objRefs[idx]; Children.Add(childRef); } else { // move back stream.Position = cP; var child = new NodeObject(stream, objRefs); Children.Add(child); } } } }
protected NomadObject ReadObject_FmtB(BinaryStream stream, NomadObject parent = null) { Context.State = ContextStateType.Object; Context.ObjectIndex++; var ptr = (int)stream.Position; var nD = DescriptorTag.Read(stream, ReferenceType.Offset); NomadObject result = null; if (nD.IsOffset) { result = Context.GetRefByPtr(nD.Value) as NomadObject; // this should never happen if (result == null) { throw new InvalidDataException("Malformed data!"); } } else { var nChildren = nD.Value; var hash = stream.ReadInt32(); var size = stream.ReadInt16(); if (size == 0) { throw new NotImplementedException("Zero-length nodes are not covered under TrumpCare(tm)."); } var id = StringId.Parse(hash); result = new NomadObject(id); Context.AddRef(result, ptr); var attrsPtr = (int)stream.Position; var next = (attrsPtr + size); var nhD = DescriptorTag.Read(stream, ReferenceType.Offset); var adjustPtr = false; if (nhD.IsOffset) { stream.Position = nhD.Value; // adjust ptr to attributes attrsPtr += nhD.Size; adjustPtr = true; // read again nhD = DescriptorTag.Read(stream, ReferenceType.Offset); if (nhD.IsOffset) { throw new InvalidOperationException("Cannot have nested offsets!"); } } var nAttrs = nhD.Value; var hashes = new int[nAttrs]; // read attribute hash list for (int i = 0; i < nAttrs; i++) { hashes[i] = stream.ReadInt32(); } // move to the attributes if needed if (adjustPtr) { stream.Position = attrsPtr; } // deserialize attributes if (nAttrs > 0) { ReadAttributes_FmtB(stream, result, hashes); } if (stream.Position != next) { Context.LogDebug($"Something went wrong when reading attributes for '{result.Id}':"); Context.LogDebug($" - Expected to read {size} bytes but only read {stream.Position - attrsPtr}"); foreach (var attr in result.Attributes) { Context.LogDebug($" - '{attr.Id}' : {attr.Data.Type} ({attr.Data.Size} bytes)"); } stream.Position = next; } // read children for (int n = 0; n < nChildren; n++) { ReadObject_FmtB(stream, result); } } if (parent != null) { parent.Children.Add(result); } return(result); }
protected NomadObject ReadObject_FmtA(BinaryStream stream, NomadObject parent = null) { Context.State = ContextStateType.Object; Context.ObjectIndex++; var ptr = (int)stream.Position; var nChildren = DescriptorTag.Read(stream, ReferenceType.Index); if (nChildren.Type == DescriptorType.Reference) { throw new InvalidOperationException("Cannot deserialize an object reference directly!"); } var hash = stream.ReadInt32(); var id = StringId.Parse(hash); var result = new NomadObject(id); Context.AddRef(result, ptr); if (result.IsRml) { var next = DescriptorTag.Read(stream, ReferenceType.Index); var rmlBase = (int)stream.Position; var rmlSize = stream.ReadInt32(); var rmlBuffer = stream.ReadBytes(rmlSize); using (var bs = new BinaryStream(rmlBuffer)) { var rmlData = new NomadRmlSerializer(); var rml = rmlData.Deserialize(bs); result.Children.Add(rml); } stream.Position = (rmlBase + next); } else { var nAttrs = DescriptorTag.Read(stream, ReferenceType.Index); for (int i = 0; i < nAttrs; i++) { ReadAttribute_FmtA(stream, result); } for (int i = 0; i < nChildren; i++) { var cP = (int)stream.Position; var cD = DescriptorTag.Read(stream, ReferenceType.Index); // rip if (cD.IsIndex) { var idx = cD.Value; var childRef = Context.GetRefByIdx(idx) as NomadObject; result.Children.Add(childRef); } else { // move back stream.Position = cP; ReadObject_FmtA(stream, result); } } } if (parent != null) { parent.Children.Add(result); } return(result); }
public override NomadObject Deserialize(Stream stream) { if (Context.State == ContextStateType.End) { Context.Reset(); } var _stream = (stream as BinaryStream) ?? new BinaryStream(stream); if (_stream.ReadByte() != 0) { throw new InvalidOperationException("Invalid RML data."); } Reserved = (byte)_stream.ReadByte(); var sD = DescriptorTag.Read(_stream, ReferenceType.Index); var strTableLen = sD.Value; var strTablePtr = (_stream.Length - strTableLen); var nElems = DescriptorTag.Read(_stream, ReferenceType.Index); var nAttrs = DescriptorTag.Read(_stream, ReferenceType.Index); // save position so we can parse strings first var rmlDataPtr = (int)_stream.Position; // move to beginning of string table _stream.Position = strTablePtr; var strPtr = 0; // read in all strings and store them by their relative offset // TODO: convert to more efficient reads from buffer while (strPtr < strTableLen) { var str = ""; var strLen = 1; // include null-terminator char c; while ((c = _stream.ReadChar()) != '\0') { str += c; ++strLen; } _strings.Add(strPtr, str); strPtr += strLen; } // parse RML data _stream.Position = rmlDataPtr; var rmlData = ReadRmlObject(_stream); var result = new NomadObject(true) { Id = "RML_DATA" }; result.Children.Add(rmlData); Context.State = ContextStateType.End; return(result); }
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); } } }