internal List <PacketReader> GetList() { var src = list; if (src != null) { return(src); } if ((tag & TagArray) != 0) { throw PacketException.Overflow(); } tag |= TagArray; var lst = new List <PacketReader>(); var max = element.Max; var idx = element.offset; var buf = element.buffer; var len = 0; while (idx != max) { if (buf.MoveNext(max, ref idx, out len) == false) { throw PacketException.Overflow(); } var rea = new PacketReader(buf, idx, len, converters); lst.Add(rea); idx += len; } list = lst; return(lst); }
private static List <T> GetList <T>(PacketReader reader, IPacketConverter converter) { var itm = reader.GetList(); var len = itm.Count; if (len < 1) { return(new List <T>()); } var lst = new List <T>(len); var gen = converter as IPacketConverter <T>; try { if (gen != null) { for (int i = 0; i < len; i++) { lst.Add(gen.GetValue(itm[i].element)); } } else { for (int i = 0; i < len; i++) { lst.Add((T)converter.GetValue(itm[i].element)); } } } catch (Exception ex) when(PacketException.WrapFilter(ex)) { throw PacketException.ConvertError(ex); } return(lst); }
private static T[] GetArray <T>(PacketReader reader, IPacketConverter converter) { var itm = reader.GetList(); var len = itm.Count; if (len < 1) { return(new T[0]); } var arr = new T[len]; var gen = converter as IPacketConverter <T>; try { if (gen != null) { for (int i = 0; i < len; i++) { arr[i] = gen.GetValue(itm[i].element); } } else { for (int i = 0; i < len; i++) { arr[i] = (T)converter.GetValue(itm[i].element); } } } catch (Exception ex) when(PacketException.WrapFilter(ex)) { throw PacketException.ConvertError(ex); } return(arr); }
internal object GetValue(Type type, int level) { PacketException.VerifyRecursionError(ref level); var info = Cache.GetConverterOrInfo(this.converters, type, out var converter); return(info == null ? converter.GetObjectChecked(this.block, true) : this.GetValueMatch(type, level, info)); }
internal void MoveNext(int define, ref int index, out int length) { var max = Max; if ((define > 0 && index + define > max) || (define < 1 && buffer.MoveNext(max, ref index, out define) == false)) { throw PacketException.Overflow(); } length = define; }
internal static T GetValueWrap <T>(this IPacketConverter <T> converter, Element element) { try { return(converter.GetValue(element.buffer, element.offset, element.length)); } catch (Exception ex) when(PacketException.WrapFilter(ex)) { throw PacketException.ConvertError(ex); } }
internal static T GetValueWrap <T>(this IPacketConverter <T> converter, byte[] buffer, int offset, int length) { try { return(converter.GetValue(buffer, offset, length)); } catch (Exception ex) when(PacketException.WrapFilter(ex)) { throw PacketException.ConvertError(ex); } }
internal object GetValueMatch(Type valueType, int level, Info valueInfo) { PacketException.VerifyRecursionError(ref level); return(valueInfo.To switch { InfoFlags.Reader => this, InfoFlags.RawReader => new PacketRawReader(this), InfoFlags.Collection => this.GetValueCollection(level, valueInfo), InfoFlags.Enumerable => this.GetValueEnumerable(level, valueInfo), InfoFlags.Dictionary => this.GetValueDictionary(level, valueInfo), _ => this.GetValueDefault(valueType, level), });
private static Token GetToken(ConverterDictionary converters, object value, int level) { PacketException.VerifyRecursionError(ref level); if (value == null) { return(Token.Empty); } var type = value.GetType(); var info = Cache.GetConverterOrInfo(converters, type, out var converter); return(info == null ? new Value(converter.GetBytesChecked(value)) : GetTokenMatch(converters, value, level, info)); }
private static Token GetTokenMatch(ConverterDictionary converters, object value, int level, Info valueInfo) { PacketException.VerifyRecursionError(ref level); return(valueInfo.From switch { InfoFlags.Writer => ((PacketWriter)value).token, InfoFlags.RawWriter => new Value(((PacketRawWriter)value).stream.ToArray()), InfoFlags.Bytes => new Value(((ICollection <byte>)value).ToBytes()), InfoFlags.SBytes => new Value(((ICollection <sbyte>)value).ToBytes()), InfoFlags.Enumerable => GetTokenEnumerable(converters, value, level, valueInfo), InfoFlags.Dictionary => GetTokenDictionary(converters, value, level, valueInfo), InfoFlags.Expando => GetTokenExpando(converters, value, level), _ => GetTokenDefault(converters, value, level, valueInfo), });
internal static void FinshInternal(this Stream stream, long source) { var dst = stream.Position; var len = dst - source - sizeof(int); if (len > int.MaxValue) { throw PacketException.Overflow(); } stream.Position = source; var buf = BitConverter.GetBytes((int)len); stream.Write(buf, 0, buf.Length); stream.Position = dst; }
internal static object GetValueWrap(this IPacketConverter converter, byte[] buffer, int offset, int length, bool check = false) { try { if (check && converter.Length > length) { throw PacketException.Overflow(); } return(converter.GetValue(buffer, offset, length)); } catch (Exception ex) when(PacketException.WrapFilter(ex)) { throw PacketException.ConvertError(ex); } }
internal List <T> ToList <T>(IPacketConverter converter) { if (length < 1) { return(new List <T>()); } if (typeof(T) == typeof(byte)) { return(new List <T>((T[])GetByteArray())); } else if (typeof(T) == typeof(sbyte)) { return(new List <T>((T[])GetSByteArray())); } var def = converter.Length; var sum = Math.DivRem(length, def, out var rem); if (rem != 0) { throw PacketException.Overflow(); } var lst = new List <T>(sum); var gen = converter as IPacketConverter <T>; try { if (gen != null) { for (int idx = 0; idx < sum; idx++) { lst.Add(gen.GetValue(buffer, offset + idx * def, def)); } } else { for (int idx = 0; idx < sum; idx++) { lst.Add((T)converter.GetValue(buffer, offset + idx * def, def)); } } } catch (Exception ex) when(PacketException.WrapFilter(ex)) { throw PacketException.ConvertError(ex); } return(lst); }
IEnumerator IEnumerable.GetEnumerator() { var def = converter.Length; if (def < 1) { return(Enumerator(reader.GetList(), converter)); } var ele = reader.element; var sum = Math.DivRem(ele.length, def, out var rem); if (rem != 0) { throw PacketException.Overflow(); } return(Enumerator(ele.buffer, ele.offset, sum, def, converter)); }
internal static byte[] Span(byte[] buffer, int offset, int length) { if (offset == 0 && length == buffer.Length) { return(buffer); } if (offset < 0 || length < 0 || buffer.Length - offset < length) { throw PacketException.Overflow(); } if (length == 0) { return(s_empty_bytes); } var buf = new byte[length]; Buffer.BlockCopy(buffer, offset, buf, 0, length); return(buf); }
private List <PacketReader> InitializeList() { if ((this.flags & Flags.List) != 0) { throw PacketException.Overflow(); } this.flags |= Flags.List; var collection = new List <PacketReader>(); var vernier = (Vernier)this.block; while (vernier.Any) { vernier.Flush(); collection.Add(new PacketReader((Block)vernier, this.converters)); } this.list = collection; return(collection); }
internal static byte[] GetBytesWrap <T>(this IPacketConverter <T> converter, T value) { try { var buf = converter.GetBytes(value); if (buf == null) { buf = s_empty_bytes; } var len = converter.Length; if (len > 0 && len != buf.Length) { throw PacketException.ConvertMismatch(len); } return(buf); } catch (Exception ex) when(PacketException.WrapFilter(ex)) { throw PacketException.ConvertError(ex); } }
internal static IPacketConverter GetConverter(ConverterDictionary converters, Type type, bool nothrow) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (converters != null && converters.TryGetValue(type, out var val)) { if (val == null) { goto fail; } else { return(val); } } if (s_converters.TryGetValue(type, out val)) { return(val); } var inf = GetInfo(type); if (inf.Flag == Info.Enum) { return(s_converters[inf.ElementType]); } fail: if (nothrow == true) { return(null); } throw PacketException.InvalidType(type); }
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); } } }
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)); } } }
internal void ToDictionary <TK, TV>(IPacketConverter indexConverter, IPacketConverter elementConverter, DictionaryAbstract <TK, TV> dictionary) { if (length == 0) { return; } var keygen = indexConverter as IPacketConverter <TK>; var valgen = elementConverter as IPacketConverter <TV>; var keylen = indexConverter.Length; var vallen = elementConverter.Length; var max = Max; var idx = offset; var len = 0; try { while (true) { var sub = max - idx; if (sub == 0) { break; } if (keylen > 0) { if (sub < keylen) { goto fail; } else { len = keylen; } } else if (buffer.MoveNext(max, ref idx, out len) == false) { goto fail; } var key = (keygen != null ? keygen.GetValue(buffer, idx, len) : (TK)indexConverter.GetValue(buffer, idx, len)); idx += len; sub = max - idx; if (vallen > 0) { if (sub < vallen) { goto fail; } else { len = vallen; } } else if (buffer.MoveNext(max, ref idx, out len) == false) { goto fail; } var val = (valgen != null ? valgen.GetValue(buffer, idx, len) : (TV)elementConverter.GetValue(buffer, idx, len)); idx += len; dictionary.Add(key, val); } } catch (Exception ex) when(PacketException.WrapFilter(ex)) { throw PacketException.ConvertError(ex); } return; fail: throw PacketException.Overflow(); }