Пример #1
0
        public RbfStructure Load(Stream stream)
        {
            stack       = new Stack <RbfStructure>();
            descriptors = new List <RbfEntryDescription>();

            var reader = new DataReader(stream);
            var ident  = reader.ReadInt32();

            if (ident != RBF_IDENT)
            {
                throw new Exception("The file identifier does not match.");
            }

            while (reader.Position < reader.Length)
            {
                var descriptorIndex = reader.ReadByte();
                if (descriptorIndex == 0xFF) // close tag
                {
                    var b = reader.ReadByte();
                    if (b != 0xFF)
                    {
                        throw new Exception("Expected 0xFF but was " + b.ToString("X2"));
                    }

                    if (stack.Count > 0)
                    {
                        current = stack.Pop();
                    }
                    else
                    {
                        if (reader.Position != reader.Length)
                        {
                            throw new Exception("Expected end of stream but was not.");
                        }
                        return(current);
                    }
                }
                else if (descriptorIndex == 0xFD) // bytes
                {
                    var b = reader.ReadByte();
                    if (b != 0xFF)
                    {
                        throw new Exception("Expected 0xFF but was " + b.ToString("X2"));
                    }

                    var dataLength = reader.ReadInt32();
                    var data       = reader.ReadBytes(dataLength);

                    var bytesValue = new RbfBytes();
                    bytesValue.Value = data;
                    current.Children.Add(bytesValue);
                }
                else
                {
                    var dataType = reader.ReadByte();
                    if (descriptorIndex == descriptors.Count) // new descriptor + data
                    {
                        var nameLength = reader.ReadInt16();
                        var nameBytes  = reader.ReadBytes(nameLength);
                        var name       = Encoding.ASCII.GetString(nameBytes);

                        var descriptor = new RbfEntryDescription();
                        descriptor.Name = name;
                        descriptor.Type = dataType;
                        descriptors.Add(descriptor);

                        ParseElement(reader, descriptors.Count - 1, dataType);
                    }
                    else // existing descriptor + data
                    {
                        if (dataType != descriptors[descriptorIndex].Type)
                        {
                            //throw new Exception("Data type does not match. Expected "
                            //    + descriptors[descriptorIndex].Type.ToString() + " but found "
                            //    + dataType.ToString() + ". Descriptor: " + descriptors[descriptorIndex].Name);
                        }

                        ParseElement(reader, descriptorIndex, dataType);
                    }
                }
            }

            throw new Exception("Unexpected end of stream.");
        }
Пример #2
0
        private static IRbfType Traverse(XNode node)
        {
            if (node is XElement element)
            {
                if (element.Attribute("value") != null)
                {
                    var val = element.Attribute("value").Value;
                    if (!string.IsNullOrEmpty(val))
                    {
                        var rval = CreateValueNode(element.Name.LocalName, val);
                        if (rval != null)
                        {
                            return(rval);
                        }
                    }
                }
                else if ((element.Attributes().Count() == 3) && (element.Attribute("x") != null) && (element.Attribute("y") != null) && (element.Attribute("z") != null))
                {
                    FloatUtil.TryParse(element.Attribute("x").Value, out float x);
                    FloatUtil.TryParse(element.Attribute("y").Value, out float y);
                    FloatUtil.TryParse(element.Attribute("z").Value, out float z);
                    return(new RbfFloat3()
                    {
                        Name = element.Name.LocalName,
                        X = x,
                        Y = y,
                        Z = z
                    });
                }
                else if ((element.Elements().Count() == 0) && (element.Attributes().Count() == 0) && (!element.IsEmpty)) //else if (element.Name == "type" || element.Name == "key" || element.Name == "platform")
                {
                    var bytearr   = Encoding.ASCII.GetBytes(element.Value);
                    var bytearrnt = new byte[bytearr.Length + 1];
                    Buffer.BlockCopy(bytearr, 0, bytearrnt, 0, bytearr.Length);
                    var bytes = new RbfBytes()
                    {
                        Value = bytearrnt
                    };
                    var struc = new RbfStructure()
                    {
                        Name = element.Name.LocalName
                    };
                    struc.Children.Add(bytes);
                    return(struc);
                }

                var n = new RbfStructure();
                n.Name     = element.Name.LocalName;
                n.Children = element.Nodes().Select(c => Traverse(c)).ToList();

                foreach (var attr in element.Attributes())
                {
                    var val  = attr.Value;
                    var aval = CreateValueNode(attr.Name.LocalName, val);
                    if (aval != null)
                    {
                        n.Attributes.Add(aval);
                    }
                }

                return(n);
            }
            else if (node is XText text)
            {
                byte[] bytes       = null;
                var    contentAttr = node.Parent?.Attribute("content");
                if (contentAttr != null)
                {
                    if (contentAttr.Value == "char_array")
                    {
                        bytes = GetByteArray(text.Value);
                    }
                    else if (contentAttr.Value == "short_array")
                    {
                        bytes = GetUshortArray(text.Value);
                    }
                    else
                    {
                    }
                }
                else
                {
                    bytes = Encoding.ASCII.GetBytes(text.Value).Concat(new byte[] { 0x00 }).ToArray();
                }
                if (bytes != null)
                {
                    return(new RbfBytes()
                    {
                        Name = "",
                        Value = bytes
                    });
                }
            }

            return(null);
        }