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); }
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 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 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 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)); }
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[] 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); }
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); } } }
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(); }