예제 #1
0
        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);
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
                    }
                }
            }
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
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);
                }
            }
        }