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."); }
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); }