예제 #1
0
            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");
                }
            }
예제 #2
0
            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");
                }
            }
예제 #3
0
            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);
            }
예제 #4
0
            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);
                        }
                    }
                }
            }
예제 #5
0
            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);
                        }
                    }
                }
            }
예제 #6
0
            //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);
            }
예제 #7
0
        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;
            }
        }
예제 #8
0
        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");
            }
        }
예제 #9
0
 public void SerializeObject(object obj)
 {
     RootNode = ByamlParser.ProcessEntrySerialization(obj);
 }
예제 #10
0
 public ByamlTreeNode(ByamlEntry entry, string name)
 {
     ByamlNode = entry;
     Text      = name;
 }