Example #1
0
        internal object GetValueMatch(Type valueType, int level, Info valueInfo)
        {
            if (level > Cache.Limits)
            {
                throw new PacketException(PacketError.RecursiveError);
            }
            level += 1;

            switch (valueInfo.To)
            {
            case Info.Reader:
                return(this);

            case Info.RawReader:
                return(new PacketRawReader(this));

            case Info.Collection:
            {
                var inf = Cache.GetConverterOrInfo(converters, valueInfo.ElementType, out var con);
                if (inf == null)
                {
                    return(valueInfo.ToCollection(this, con));
                }
                var lst = GetList();
                var len = lst.Count;
                var arr = new object[len];
                for (int i = 0; i < len; i++)
                {
                    arr[i] = lst[i].GetValueMatch(valueInfo.ElementType, level, inf);
                }
                var res = valueInfo.ToCollectionCast(arr);
                return(res);
            }

            case Info.Enumerable:
            {
                var inf = Cache.GetConverterOrInfo(converters, valueInfo.ElementType, out var con);
                if (inf == null)
                {
                    return(valueInfo.ToEnumerable(this, con));
                }
                return(valueInfo.ToEnumerableAdapter(this, level, inf));
            }

            case Info.Dictionary:
            {
                var keycon = Cache.GetConverter(converters, valueInfo.IndexType, true);
                if (keycon == null)
                {
                    throw PacketException.InvalidKeyType(valueType);
                }
                var inf = Cache.GetConverterOrInfo(converters, valueInfo.ElementType, out var con);
                if (inf == null)
                {
                    return(valueInfo.ToDictionary(this, keycon, con));
                }

                var max    = element.Max;
                var idx    = element.offset;
                var buf    = element.buffer;
                var keylen = keycon.Length;
                var len    = 0;

                var lst = new List <object>();
                while (true)
                {
                    var res = max - idx;
                    if (res == 0)
                    {
                        break;
                    }
                    if (keylen > 0)
                    {
                        if (res < keylen)
                        {
                            goto fail;
                        }
                        else
                        {
                            len = keylen;
                        }
                    }
                    else if (buf.MoveNext(max, ref idx, out len) == false)
                    {
                        goto fail;
                    }
                    // Wrap error non-check
                    var key = keycon.GetValueWrap(buf, idx, len);
                    idx += len;

                    if (buf.MoveNext(max, ref idx, out len) == false)
                    {
                        goto fail;
                    }
                    var rea = new PacketReader(buf, idx, len, converters);
                    var val = rea.GetValueMatch(valueInfo.ElementType, level, inf);

                    idx += len;
                    lst.Add(key);
                    lst.Add(val);
                }
                return(valueInfo.ToDictionaryCast(lst));

fail:
                throw PacketException.Overflow();
            }

            default:
            {
                var set = Cache.GetSetInfo(valueType);
                if (set == null)
                {
                    throw PacketException.InvalidType(valueType);
                }
                var arg = set.Arguments;
                var arr = new object[arg.Length];
                for (int i = 0; i < arg.Length; i++)
                {
                    var rea = GetItem(arg[i].Key, false);
                    var val = rea.GetValue(arg[i].Value, level);
                    arr[i] = val;
                }

                var res = set.GetObject(arr);
                return(res);
            }
            }
        }
Example #2
0
        private static Item GetItemMatch(ConverterDictionary converters, object value, int level, Info valueInfo)
        {
            if (level > Cache.Limits)
            {
                throw new PacketException(PacketError.RecursiveError);
            }
            level += 1;

            switch (valueInfo.From)
            {
            case Info.Writer:
                return(((PacketWriter)value).item);

            case Info.RawWriter:
                return(new Item(((PacketRawWriter)value).stream));

            case Info.Bytes:
                return(new Item(((ICollection <byte>)value).ToBytes()));

            case Info.SBytes:
                return(new Item(((ICollection <sbyte>)value).ToBytes()));

            case Info.Enumerable:
            {
                var ele = valueInfo.ElementType;
                var inf = Cache.GetConverterOrInfo(converters, ele, out var con);
                if (inf == null)
                {
                    return(new Item(valueInfo.FromEnumerable(con, value), con.Length));
                }

                var lst = new List <Item>();
                foreach (var i in ((IEnumerable)value))
                {
                    lst.Add(GetItemMatch(converters, i, level, inf));
                }
                return(new Item(lst));
            }

            case Info.Dictionary:
            {
                var key = Cache.GetConverter(converters, valueInfo.IndexType, true);
                if (key == null)
                {
                    throw PacketException.InvalidKeyType(valueInfo.IndexType);
                }
                var ele = valueInfo.ElementType;
                var inf = Cache.GetConverterOrInfo(converters, ele, out var con);
                if (inf == null)
                {
                    return(new Item(valueInfo.FromDictionary(key, con, value), key.Length, con.Length));
                }

                var lst = new List <KeyValuePair <byte[], Item> >();
                var kvp = valueInfo.FromDictionaryAdapter(key, value);
                foreach (var i in kvp)
                {
                    var res = GetItemMatch(converters, i.Value, level, inf);
                    var tmp = new KeyValuePair <byte[], Item>(i.Key, res);
                    lst.Add(tmp);
                }
                return(new Item(lst, key.Length));
            }

            case Info.Map:
            {
                var dic = (IDictionary <string, object>)value;
                var lst = new Dictionary <string, PacketWriter>();
                foreach (var i in dic)
                {
                    lst[i.Key] = GetWriter(converters, i.Value, level);
                }
                return(new Item(lst));
            }

            default:
            {
                var lst = new Dictionary <string, PacketWriter>();
                var get = Cache.GetGetInfo(valueInfo.Type);
                var val = get.GetValues(value);
                var arg = get.Arguments;
                for (int i = 0; i < arg.Length; i++)
                {
                    lst[arg[i].Key] = GetWriter(converters, val[i], level);
                }
                return(new Item(lst));
            }
            }
        }