public static void WriteValue(ByamlContext ctx, ByamlEntry entry, BinaryDataWriter bw) { switch (entry.NodeType) { case ByamlNodeType.StringValue: bw.Write(Array.IndexOf(ctx.Stringtable.ToArray(), (string)entry.Value)); break; case ByamlNodeType.BooleanValue: bw.Write((bool)entry.Value, BooleanDataFormat.Dword); break; case ByamlNodeType.IntegerValue: bw.Write((int)entry.Value); break; case ByamlNodeType.FloatValue: bw.Write((float)entry.Value); break; case ByamlNodeType.PathTable: case ByamlNodeType.StringTable: case ByamlNodeType.Array: case ByamlNodeType.Dictionary: case ByamlNodeType.PathValue: throw new ByamlException("Invalid Node Type"); default: throw new ByamlException("Invalid or unknown node type"); } }
public static object ProcessEntryDeserialization(ByamlEntry entry, Type t) { if ((!correctType.ContainsKey(entry.NodeType) || !correctType[entry.NodeType](t)) && t != typeof(object)) { throw new ByamlException($"Cannot convert {entry.NodeType} to {t.FullName}"); } switch (entry.NodeType) { case ByamlNodeType.Array: return(ProcessArrayDeserialization(entry, t)); case ByamlNodeType.Dictionary: return(ProcessDictionaryDeserialization(entry, t)); case ByamlNodeType.BooleanValue: case ByamlNodeType.StringValue: case ByamlNodeType.IntegerValue: case ByamlNodeType.FloatValue: return(entry.Value); case ByamlNodeType.PathValue: case ByamlNodeType.StringTable: case ByamlNodeType.PathTable: default: throw new ByamlException("Invalid or unsupported node type"); } }
public static object ProcessDictionaryDeserialization(ByamlEntry entry, Type t) { var o = Activator.CreateInstance(t); var byamlDict = (Dictionary <string, ByamlEntry>)entry.Value; foreach (var item in byamlDict) { if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { var dict = (IDictionary)o; dict.Add(item.Key, ProcessEntryDeserialization(item.Value, t.GetGenericArguments()[1])); } else { var props = t.GetProperties(); bool found = false; foreach (var prop in props) { ByamlKeyAttribute nameAttr = (ByamlKeyAttribute)prop.GetCustomAttribute(typeof(ByamlKeyAttribute)); string name = nameAttr?.Key ?? prop.Name; if (name == item.Key) { prop.SetValue(o, ProcessEntryDeserialization(item.Value, prop.PropertyType)); found = true; } } if (!found) { throw new ByamlException($"Could not find {item.Key} type : {item.Value.NodeType} in {t.FullName}"); } } } return(o); }
public static void WriteArray(ByamlContext ctx, ByamlEntry entry, BinaryDataWriter bw) { var list = (List <ByamlEntry>)entry.Value; bw.Write((byte)entry.NodeType); bw.WriteInt24(list.Count); List <long> tempOffs = new List <long>(); //node types foreach (var item in list) { bw.Write((byte)item.NodeType); } bw.Align(4); //values foreach (var item in list) { if (NodeIsValue(item.NodeType)) { WriteValue(ctx, item, bw); } else { tempOffs.Add(bw.Position); bw.Write(0); //temp } } //array/dictionary int index = 0; foreach (var item in list) { if (!NodeIsValue(item.NodeType)) { long curPos = bw.Position; using (bw.TemporarySeek(tempOffs[index++], SeekOrigin.Begin)) bw.Write((int)curPos); if (item.NodeType == ByamlNodeType.Array) { WriteArray(ctx, item, bw); } else if (item.NodeType == ByamlNodeType.Dictionary) { WriteDictionary(ctx, item, bw); } } } }
public static void WriteDictionary(ByamlContext ctx, ByamlEntry entry, BinaryDataWriter bw) { var dict = (Dictionary <string, ByamlEntry>)entry.Value; bw.Write((byte)entry.NodeType); bw.WriteInt24(dict.Count); List <long> tempOffs = new List <long>(); //value foreach (var item in dict) { bw.WriteInt24(Array.IndexOf(ctx.NameTable.ToArray(), item.Key)); bw.Write((byte)item.Value.NodeType); if (NodeIsValue(item.Value.NodeType)) { WriteValue(ctx, item.Value, bw); } else { tempOffs.Add(bw.Position); bw.Write(0); //temp } } //array/dictionary int index = 0; foreach (var item in dict) { if (!NodeIsValue(item.Value.NodeType)) { long curPos = bw.Position; using (bw.TemporarySeek(tempOffs[index++], SeekOrigin.Begin)) bw.Write((int)curPos); if (item.Value.NodeType == ByamlNodeType.Array) { WriteArray(ctx, item.Value, bw); } else if (item.Value.NodeType == ByamlNodeType.Dictionary) { WriteDictionary(ctx, item.Value, bw); } } } }
//deserialize byaml public static object ProcessArrayDeserialization(ByamlEntry entry, Type t) { if (!t.IsGenericType || t.GetGenericTypeDefinition() != typeof(List <>)) { throw new ByamlException("Invalid List"); } IList list = (IList)Activator.CreateInstance(t); var byamlArray = (List <ByamlEntry>)entry.Value; foreach (var item in byamlArray) { list.Add(ProcessEntryDeserialization(item, t.GetGenericArguments()[0])); } return(list); }
private static void AddToLists(List <string> names, List <string> strings, ByamlEntry entry) { switch (entry.NodeType) { case ByamlNodeType.StringValue: if (!strings.Contains((string)entry.Value)) { strings.Add((string)entry.Value); } break; case ByamlNodeType.Array: var array = (List <ByamlEntry>)entry.Value; foreach (var item in array) { AddToLists(names, strings, item); } break; case ByamlNodeType.Dictionary: var dict = (Dictionary <string, ByamlEntry>)entry.Value; foreach (var item in dict) { if (!names.Contains(item.Key)) { names.Add(item.Key); } AddToLists(names, strings, item.Value); } break; case ByamlNodeType.PathValue: case ByamlNodeType.StringTable: case ByamlNodeType.PathTable: case ByamlNodeType.BooleanValue: case ByamlNodeType.IntegerValue: case ByamlNodeType.FloatValue: break; default: break; } }
private void ReadByaml(BinaryDataReader br) { string magic = Encoding.ASCII.GetString(br.ReadBytes(2)); switch (magic) { case "BY": br.ByteOrder = ByteOrder.BigEndian; break; case "YB": br.ByteOrder = ByteOrder.LittleEndian; break; default: throw new ByamlException("Invalid Header"); } BOM = br.ByteOrder; ByamlVersion = br.ReadUInt16(); uint headerSize = br.ReadUInt32(); uint stringTableOffset = br.ReadUInt32(); uint dataOffset = br.ReadUInt32(); br.Seek(headerSize, SeekOrigin.Begin); NameTable = (List <string>)ByamlParser.ParseStringTable(this, br).Value; br.Seek(stringTableOffset, SeekOrigin.Begin); Stringtable = (List <string>)ByamlParser.ParseStringTable(this, br).Value; br.Seek(dataOffset, SeekOrigin.Begin); ByamlNodeType t = (ByamlNodeType)br.ReadByte(); switch (t) { case ByamlNodeType.Array: case ByamlNodeType.Dictionary: br.Position--; RootNode = ByamlParser.ParseEntry(this, t, br); break; default: throw new ByamlException("Invalid Root Node"); } }
public void SerializeObject(object obj) { RootNode = ByamlParser.ProcessEntrySerialization(obj); }
public ByamlTreeNode(ByamlEntry entry, string name) { ByamlNode = entry; Text = name; }