Пример #1
0
    public static BonValue ToBon(object obj, HashSet <string> fields = null, Type declareType = null)
    {
        if (obj == null)
        {
            return(BonNull.value);
        }
        Type t = obj.GetType();

        switch (t.Name)
        {
        case "Byte": return((int)(byte)obj);

        case "SByte": return((int)(sbyte)obj);

        case "Int16": return((int)(short)obj);

        case "UInt16": return((int)(ushort)obj);

        case "Int32": return((int)obj);

        case "UInt32": return((int)(uint)obj);

        case "Int64": return((long)obj);

        case "UInt64": return((long)(ulong)obj);

        case "Single": return((float)obj);

        case "Double": return((double)obj);

        case "Boolean": return((bool)obj);

        case "String": return((string)obj);

        case "Byte[]": return((byte[])obj);

        default: {
            if (t.IsEnum)
            {
                return((int)obj);
            }
            break;
        }
        }

        switch (t.Name)
        {
        case "List`1": {
            Type     et  = t.GetGenericArguments()[0];
            BonArray arr = null;
            arr = new BonArray();
            IList list = (IList)obj;
            int   num  = list.Count;
            for (int i = 0; i < num; i++)
            {
                arr.Add(ToBon(list[i], fields, et));
            }
            return(arr);
        }

        case "Dictionary`2": {
            Type        et  = t.GetGenericArguments()[1];
            BonDocument doc = null;
            doc = new BonDocument();
            foreach (DictionaryEntry kv in (IDictionary)obj)
            {
                if (kv.Key.GetType().IsEnum)
                {
                    doc[((int)kv.Key).ToString()] = ToBon(kv.Value, fields, et);
                }
                else
                {
                    doc[kv.Key.ToString()] = ToBon(kv.Value, fields, et);
                }
            }
            return(doc);
        }

        default: {
            if (t.IsArray)
            {
                Type     et  = t.GetElementType();
                BonArray arr = null;
                arr = new BonArray();
                Array list = (Array)obj;
                int   num  = list.Length;
                for (int i = 0; i < num; i++)
                {
                    arr.Add(ToBon(list.GetValue(i), fields, et));
                }
                return(arr);
            }
            {
                if (obj is IBon)
                {
                    return(((IBon)obj).ToBon());
                }
                ClassInfo   ci  = ClassInfo.Get(t);
                BonDocument doc = new BonDocument();
                if (declareType != null && declareType != t)
                {
                    doc["_t_"] = t.FullName;
                }
                FldInfo[] fis = ci.fields.Values;
                for (int i = fis.Length; --i >= 0;)
                {
                    FldInfo fi = fis[i];
                    if (fields != null && !fields.Contains(fi.name))
                    {
                        continue;
                    }
                    doc[fi.name] = ToBon(fi.GetValue(obj), fi.subFields);
                }
                return(doc);
            }
        }
        }
    }
Пример #2
0
    private static object ReadObj(Type t, ReadArg arg)
    {
        DataReader br = arg.br;

        if (t == null)
        {
            int ti = br.Read7BitEncodedInt();
            switch (ti)
            {
            case TYPE_NULL: return(null);

            case TYPE_REF: return(arg.objRef[br.Read7BitEncodedInt()]);
            }
            t = arg.typeRef[ti];
        }
        switch (t.Name)
        {
        case "Int32": return(br.ReadInt32());

        case "Int64": return(br.ReadInt64());

        case "Single": return(br.ReadSingle());

        case "Double": return(br.ReadDouble());

        case "String": string s = br.ReadString(); arg.objRef.Add(s); return(s);

        case "UInt32": return(br.ReadUInt32());

        case "UInt64": return(br.ReadUInt64());

        case "Byte": return(br.ReadByte());

        case "SByte": return(br.ReadSByte());

        case "Int16": return(br.ReadInt16());

        case "UInt16": return(br.ReadUInt16());

        case "Boolean": return(br.ReadBoolean());

        case "DateTime": return(DateTime.FromBinary(br.ReadInt64()));

        case "Vector2": return(new Vector2(br.ReadSingle(), br.ReadSingle()));

        case "Vector3": return(new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()));

        default: {
            if (t.IsEnum)
            {
                return(Enum.ToObject(t, br.ReadInt32()));
            }
            if (t.IsArray)
            {
                Type  t2  = t.GetElementType();
                int   num = br.Read7BitEncodedInt();
                Array arr = Array.CreateInstance(t2, num);
                arg.objRef.Add(arr);
                Type rt = t2.IsClass ? null : t2;
                for (int i = 0; i < num; i++)
                {
                    arr.SetValue(ReadObj(rt, arg), i);
                }
                return(arr);
            }
            if (typeof(IList).IsAssignableFrom(t))
            {
                IList list = (IList)Activator.CreateInstance(t);
                arg.objRef.Add(list);
                Type t2 = null;
                if (t.IsGenericType)
                {
                    t2 = t.GetGenericArguments()[0];
                    if (t2.IsClass)
                    {
                        t2 = null;
                    }
                }
                int num = br.Read7BitEncodedInt();
                for (int i = 0; i < num; i++)
                {
                    list.Add(ReadObj(t2, arg));
                }
                return(list);
            }
            if (typeof(IDictionary).IsAssignableFrom(t))
            {
                IDictionary dic = (IDictionary)Activator.CreateInstance(t);
                arg.objRef.Add(dic);
                Type tk = null;
                Type tv = null;
                if (t.IsGenericType)
                {
                    Type[] ts = t.GetGenericArguments();
                    tk = ts[0];
                    tv = ts[1];
                    if (tk.IsClass)
                    {
                        tk = null;
                    }
                    if (tv.IsClass)
                    {
                        tv = null;
                    }
                }
                int num = br.Read7BitEncodedInt();
                for (int i = 0; i < num; i++)
                {
                    object key   = ReadObj(tk, arg);
                    object value = ReadObj(tv, arg);
                    dic[key] = value;
                }
                return(dic);
            }
            {
                object obj = Activator.CreateInstance(t);
                if (t.IsClass)
                {
                    arg.objRef.Add(obj);
                }
                ClassInfo ci  = ClassInfo.Get(t);
                int       num = br.Read7BitEncodedInt();
                for (int i = 0; i < num; i++)
                {
                    string  name = (string)ReadObj(null, arg);
                    object  v    = ReadObj(null, arg);
                    FldInfo fi;
                    if (ci.fields.TryGetValue(name, out fi))
                    {
                        if (v == null)
                        {
                            if (fi.type.IsClass)
                            {
                                fi.SetValue(obj, null);
                            }
                        }
                        else
                        {
                            Type vt = v.GetType();
                            if (fi.type.IsEnum && vt == typeof(int) || fi.type.IsAssignableFrom(vt))
                            {
                                fi.SetValue(obj, v);
                            }
                        }
                    }
                }
                return(obj);
            }
        }
        }
    }
Пример #3
0
    public static object ToObj(BonValue v, Type t, object old, HashSet <string> fields = null)
    {
        if (v == null)
        {
            return(null);
        }
        switch (t.Name)
        {
        case "Byte": return((byte)v.AsInt);

        case "SByte": return((sbyte)v.AsInt);

        case "Int16": return((short)v.AsInt);

        case "UInt16": return((ushort)v.AsInt);

        case "Int32": return(v.AsInt);

        case "UInt32": return((uint)v.AsInt);

        case "Int64": return(v.AsLong);

        case "UInt64": return((ulong)v.AsLong);

        case "Single": return(v.AsFloat);

        case "Double": return(v.AsDouble);

        case "Boolean": return(v.AsBoolean);

        case "String": return(v.AsString);

        case "Byte[]": return(v.AsBinary);

        case "List`1": {
            BonArray arr = v.AsBonArray;
            if (arr == null)
            {
                return(null);
            }
            int   num = arr.Count;
            IList l   = null;
            if (old != null)
            {
                l = (IList)old;
            }
            else
            {
                l = (IList)Activator.CreateInstance(t, num);
            }
            Type t2 = t.GetGenericArguments()[0];
            l.Clear();
            for (int i = 0; i < num; i++)
            {
                l.Add(ToObj(arr[i], t2, null, fields));
            }
            return(l);
        }

        case "Dictionary`2": {
            BonDocument doc = v.AsBonDocument;
            if (doc == null)
            {
                return(null);
            }
            int         num = doc.Count;
            IDictionary d   = null;
            if (old != null)
            {
                d = (IDictionary)old;
            }
            else
            {
                d = (IDictionary)Activator.CreateInstance(t, num);
            }
            Type[] t2s = t.GetGenericArguments();
            Type   tk  = t2s[0];
            Type   t2  = t2s[1];
            for (int i = 0; i < num; i++)
            {
                BonElement el  = doc[i];
                object     key = null;
                switch (tk.Name)
                {
                case "Int32": key = Convert.ToInt32(el.name); break;

                case "Int64": key = Convert.ToInt64(el.name); break;

                case "String": key = el.name; break;

                default: {
                    if (tk.IsEnum)
                    {
                        key = Enum.ToObject(tk, Convert.ToInt32(el.name));
                    }
                    break;
                }
                }
                if (key != null)
                {
                    BonValue v2  = el.value;
                    object   obj = null;
                    if (d.Contains(key))
                    {
                        obj = ToObj(v2, t2, d[key], fields);
                    }
                    else
                    {
                        obj = ToObj(v2, t2, null, fields);
                    }
                    if (obj == null)
                    {
                        d.Remove(key);
                    }
                    else
                    {
                        d[key] = obj;
                    }
                }
            }
            return(d);
        }

        default: {
            if (t.IsEnum)
            {
                return(Enum.ToObject(t, v.AsInt));
            }
            if (t.IsArray)
            {
                BonArray arr = v.AsBonArray;
                if (arr == null)
                {
                    return(null);
                }
                int  num = arr.Count;
                Type t2  = t.GetElementType();
                var  obj = Array.CreateInstance(t2, num);
                for (int i = 0; i < num; i++)
                {
                    obj.SetValue(ToObj(arr[i], t2, null, fields), i);
                }
                return(obj);
            }
            if (!v.IsBonDocument)
            {
                return(null);
            }
            {
                BonDocument doc = v.AsBonDocument;
                string      _t_ = doc.GetString("_t_");
                if (_t_ != null)
                {
                    try {
                        t = Type.GetType(_t_);
                    } catch (Exception) {
                        Debug.LogWarning("δÕÒµ½ÀàÐÍ: " + doc["_t_"].AsString);
                        return(null);
                    }
                }
                ClassInfo ci  = ClassInfo.Get(t);
                object    obj = old;
                Dictionary <string, List <DataMonitor> > dataMonitors = null;
                bool monitorObj = false;
                if (old != null)
                {
                    monitorObj = dataMonitor.TryGetValue(old, out dataMonitors);
                }
                if (obj == null)
                {
                    obj = Activator.CreateInstance(t);
                }
                if (obj is IBon)
                {
                    ((IBon)obj).FromBon(doc);
                    return(obj);
                }
                CachedDictionary <string, FldInfo> fis = ci.fields;
                bool isValueType = t.IsValueType;
                int  num         = doc.Count;
                for (int i = 0; i < num; i++)
                {
                    BonElement el = doc[i];
                    if (fields != null && !fields.Contains(el.name))
                    {
                        continue;
                    }
                    FldInfo fi;
                    if (fis.TryGetValue(el.name, out fi))
                    {
                        List <DataMonitor> fieldMonitors = null;
                        bool monitorField = monitorObj && dataMonitors.TryGetValue(fi.name, out fieldMonitors) && fieldMonitors.Count > 0;
                        if ((fi.type.IsValueType || fi.type == typeof(string) || fi.type.IsEnum) && !monitorField)
                        {
                            fi.SetValue(obj, ToObj(el.value, fi.type, null, fi.subFields));
                        }
                        else
                        {
                            object oldv = fi.GetValue(obj);
                            object newv = ToObj(el.value, fi.type, oldv, fi.subFields);
                            fi.SetValue(obj, newv);
                            if (monitorField && (fi.type.IsClass || oldv != newv))
                            {
                                dataChanged.AddRange(fieldMonitors);
                            }
                        }
                    }
                }
                return(obj);
            }
        }
        }
    }
Пример #4
0
    private static void WriteObj(object obj, bool writeType, WriteArg arg)
    {
        DataWriter bw = arg.bw;

        if (obj == null)
        {
            bw.Write(TYPE_NULL);
            return;
        }
        Type t = obj.GetType();

        if (t.IsClass)
        {
            int r;
            if (arg.objRef.TryGetValue(obj, out r))
            {
                bw.Write(TYPE_REF);
                bw.Write7BitEncodedInt(r);
                return;
            }
            else
            {
                arg.objRef[obj] = arg.objRef.Count;
            }
        }
        if (writeType)
        {
            bw.Write7BitEncodedInt(arg.AddType(t));
        }
        switch (t.Name)
        {
        case "Int32": bw.Write((int)obj); break;

        case "Int64": bw.Write((long)obj); break;

        case "Single": bw.Write((float)obj); break;

        case "Double": bw.Write((double)obj); break;

        case "String": bw.Write((string)obj); break;

        case "UInt32": bw.Write((uint)obj); break;

        case "UInt64": bw.Write((ulong)obj); break;

        case "Byte": bw.Write((byte)obj); break;

        case "SByte": bw.Write((sbyte)obj); break;

        case "Int16": bw.Write((short)obj); break;

        case "UInt16": bw.Write((ushort)obj); break;

        case "Boolean": bw.Write((bool)obj); break;

        case "DateTime": bw.Write(((DateTime)obj).ToBinary()); break;

        case "Vector2": {
            Vector2 v2 = (Vector2)obj;
            bw.Write(v2.x);
            bw.Write(v2.y);
            break;
        }

        case "Vector3": {
            Vector3 v3 = (Vector3)obj;
            bw.Write(v3.x);
            bw.Write(v3.y);
            bw.Write(v3.z);
            break;
        }

        default: {
            if (t.IsEnum)
            {
                bw.Write((int)obj);
                return;
            }
            if (t.IsArray)
            {
                Array arr = (Array)obj;
                Type  t2  = t.GetElementType();
                bw.Write7BitEncodedInt(arr.Length);
                foreach (object obj2 in arr)
                {
                    WriteObj(obj2, t2.IsClass, arg);
                }
                return;
            }
            if (typeof(IList).IsAssignableFrom(t))
            {
                IList list = (IList)obj;
                Type  t2   = null;
                if (t.IsGenericType)
                {
                    t2 = t.GetGenericArguments()[0];
                }
                bw.Write7BitEncodedInt(list.Count);
                bool wt = t2 == null || t2.IsClass;
                foreach (object obj2 in list)
                {
                    WriteObj(obj2, wt, arg);
                }
                return;
            }
            if (typeof(IDictionary).IsAssignableFrom(t))
            {
                Type tk = null;
                Type tv = null;
                if (t.IsGenericType)
                {
                    Type[] ts = t.GetGenericArguments();
                    tk = ts[0];
                    tv = ts[1];
                }
                IDictionary dic = (IDictionary)obj;
                bw.Write7BitEncodedInt(dic.Count);
                bool wtk = tk == null || tk.IsClass;
                bool wtv = tv == null || tv.IsClass;
                foreach (DictionaryEntry kv in dic)
                {
                    WriteObj(kv.Key, wtk, arg);
                    WriteObj(kv.Value, wtv, arg);
                }
                return;
            }
            {
                ClassInfo ci = ClassInfo.Get(t);
                bw.Write7BitEncodedInt(ci.fields.Count);
                foreach (FldInfo fi in ci.fields.Values)
                {
                    WriteObj(fi.name, true, arg);
                    WriteObj(fi.GetValue(obj), true, arg);
                }
            }
            break;
        }
        }
    }