public override bool Equals(object obj) { if (this == obj) { return(true); } if (obj == null) { return(false); } if (this.GetType() != obj.GetType()) { return(false); } VPackSlice other = (VPackSlice)obj; if (this.start != other.start) { return(false); } if (!this.GetRawVPack().SequenceEqual(other.GetRawVPack())) { return(false); } return(true); }
private void AppendVPack(VPackSlice value) { byte[] vpack = value.GetRawVPack(); this.EnsureCapacity(this.size + vpack.Length); Array.Copy(vpack, 0, this.buffer, this.size, vpack.Length); this.size += vpack.Length; }
/// <returns>the offset for the nth member from a compact Array or Object type</returns> private int GetNthOffsetFromCompact(int index) { long end = NumberUtil.ReadVariableValueLength(this.vpack, this.start + 1, false); long n = NumberUtil.ReadVariableValueLength(this.vpack, (int)(this.start + end - 1), true); if (index >= n) { throw new IndexOutOfRangeException(); } byte head = Head; long offset = 1 + NumberUtil.GetVariableValueLength(end); long current = 0; while (current != index) { long byteSize = new VPackSlice(this.vpack, (int)(this.start + offset)).ByteSize; offset += byteSize; if (head == 0x14) { offset += byteSize; } ++current; } return((int)offset); }
/// <exception cref="java.lang.InstantiationException"/> /// <exception cref="java.lang.IllegalAccessException"/> /// <exception cref="System.MissingMethodException"/> /// <exception cref="java.lang.reflect.InvocationTargetException"/> /// <exception cref="VPackException"/> private IEnumerable DeserializeCollection(VPackSlice parent, VPackSlice vpack, Type type, Type contentType) { var info = type.GetTypeInfo(); long length = vpack.GetLength(); IList value; if (typeof(IList).GetTypeInfo().IsAssignableFrom(info) && info.IsClass) { value = (IList)CreateInstance(type); } else { value = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(contentType), (int)length); } if (length > 0) { for (int i = 0; i < length; i++) { value.Add(GetValue(parent, vpack.Get(i), contentType, null)); } } return(value); }
/// <exception cref="VPackException"/> public virtual string ToJson(VPackSlice vpack, bool includeNullValues) { StringBuilder json = new StringBuilder(); this.Parse(null, null, vpack, json, includeNullValues); return(json.ToString()); }
public virtual VPackSlice ValueAt(int index) { if (!this.IsObject) { throw new VPackValueTypeException(ValueType.OBJECT); } VPackSlice key = this.GetNthKey(index); return(new VPackSlice(this.vpack, key.start + key.ByteSize)); }
/// <exception cref="System.MissingMethodException"/> /// <exception cref="java.lang.IllegalAccessException"/> /// <exception cref="java.lang.reflect.InvocationTargetException"/> /// <exception cref="java.lang.InstantiationException"/> /// <exception cref="VPackException"/> private void DeserializeField( VPackSlice parent, VPackSlice vpack, object entity, VPackCache.FieldInfo fieldInfo) { if (!vpack.IsNone) { object value = GetValue(parent, vpack, fieldInfo.Type, fieldInfo.FieldName); fieldInfo.set(entity, value); } }
/// <exception cref="System.MissingMethodException"/> /// <exception cref="java.lang.IllegalAccessException"/> /// <exception cref="java.lang.reflect.InvocationTargetException"/> /// <exception cref="java.lang.InstantiationException"/> /// <exception cref="VPackException"/> private void DeserializeFields(object entity, VPackSlice vpack) { IDictionary <string, VPackCache.FieldInfo> fields = this.cache.getFields(entity.GetType()); for (IEnumerator <IEntry <string, VPackSlice> > iterator = vpack.ObjectIterator(); iterator.MoveNext();) { IEntry <string, VPackSlice> next = iterator.Current; VPackCache.FieldInfo fieldInfo = fields[next.Key]; if (fieldInfo != null && fieldInfo.IsDeserialize) { this.DeserializeField(vpack, next.Value, entity, fieldInfo); } } }
/// <exception cref="java.lang.InstantiationException"/> /// <exception cref="java.lang.IllegalAccessException"/> /// <exception cref="System.MissingMethodException"/> /// <exception cref="java.lang.reflect.InvocationTargetException"/> /// <exception cref="VPackException"/> private Array DeserializeArray(VPackSlice parent, VPackSlice vpack, Type type) { int length = vpack.GetLength(); Type subType = type.GetElementType(); Array value = Array.CreateInstance(subType, length); for (int i = 0; i < length; i++) { value.SetValue(GetValue(parent, vpack.Get(i), subType, null), i); } return(value); }
/// <exception cref="VPackValueTypeException"/> /// <exception cref="VPackNeedAttributeTranslatorException /// "/> private VPackSlice SearchObjectKeyLinear(string attribute, long ieBase, int offsetsize, long n) { bool useTranslator = attributeTranslator != null; VPackSlice result = new VPackSlice(); for (long index = 0; index < n; index++) { long offset = ieBase + index * offsetsize; long keyIndex = NumberUtil.ToLong(this.vpack, (int)(this.start + offset), offsetsize); VPackSlice key = new VPackSlice(this.vpack, (int)(this.start + keyIndex)); if (key.IsString) { if (!key.IsEqualString(attribute)) { continue; } } else { if (key.IsInteger) { // translate key if (!useTranslator) { // no attribute translator throw new VPackNeedAttributeTranslatorException(); } if (!key.TranslateUnchecked().IsEqualString(attribute)) { continue; } } else { // invalid key type result = new VPackSlice(); break; } } // key is identical. now return value result = new VPackSlice(this.vpack, key.start + key.ByteSize); break; } return(result); }
/// <exception cref="VPackParserException"/> public virtual T Deserialize <T>(VPackSlice vpack) { if (typeof(T) == typeof(VPackSlice)) { return((T)(object)vpack); } T entity; try { entity = (T)GetValue(null, vpack, typeof(T), null); } catch (Exception e) { throw new VPackParserException(e); } return(entity); }
/// <exception cref="java.lang.InstantiationException"/> /// <exception cref="java.lang.IllegalAccessException"/> /// <exception cref="System.MissingMethodException"/> /// <exception cref="java.lang.reflect.InvocationTargetException"/> /// <exception cref="VPackException"/> private IDictionary DeserializeMap(VPackSlice parent, VPackSlice vpack, Type type, Type keyType, Type valueType) { var info = type.GetTypeInfo(); int length = vpack.GetLength(); IDictionary value; if (typeof(IDictionary).GetTypeInfo().IsAssignableFrom(info) && info.IsClass) { value = (IDictionary)CreateInstance(type); } else { value = new Dictionary <object, object>(length); } if (length > 0) { IVPackKeyMapAdapter keyMapAdapter = this.GetKeyMapAdapter(keyType); if (keyMapAdapter != null) { for (IEnumerator <IEntry <string, VPackSlice> > iterator = vpack.ObjectIterator(); iterator.MoveNext();) { IEntry <string, VPackSlice> next = iterator.Current; object name = keyMapAdapter.Deserialize(next.Key); value[name] = GetValue(vpack, next.Value, valueType, name.ToString()); } } else { for (int i = 0; i < vpack.GetLength(); i++) { VPackSlice entry = vpack.Get(i); object mapKey = GetValue(parent, entry.Get(ATTR_KEY), keyType, null); object mapValue = GetValue(parent, entry.Get(ATTR_VALUE), valueType, null); value[mapKey] = mapValue; } } } return(value); }
/// <exception cref="VPackException"/> private void ParseArray(VPackSlice value, StringBuilder json, bool includeNullValues) { json.Append(ARRAY_OPEN); int added = 0; for (int i = 0; i < value.GetLength(); i++) { VPackSlice valueAt = value.Get(i); if (!valueAt.IsNull || includeNullValues) { if (added++ > 0) { json.Append(SEPARATOR); } this.Parse(value, null, valueAt, json, includeNullValues); } } json.Append(ARRAY_CLOSE); }
/// <exception cref="VPackException"/> private void ParseObject(VPackSlice value, StringBuilder json, bool includeNullValues) { json.Append(OBJECT_OPEN); int added = 0; for (IEnumerator <IEntry <string, VPackSlice> > iterator = value.ObjectIterator(); iterator.MoveNext();) { IEntry <string, VPackSlice> next = iterator.Current; VPackSlice nextValue = next.Value; if (!nextValue.IsNull || includeNullValues) { if (added++ > 0) { json.Append(SEPARATOR); } this.Parse(value, next.Key, nextValue, json, includeNullValues); } } json.Append(OBJECT_CLOSE); }
/// <exception cref="java.lang.InstantiationException"/> /// <exception cref="java.lang.IllegalAccessException"/> /// <exception cref="System.MissingMethodException"/> /// <exception cref="java.lang.reflect.InvocationTargetException"/> /// <exception cref="VPackException"/> private object DeserializeObject(VPackSlice parent, VPackSlice vpack, Type type, string fieldName) { object entity; IVPackDeserializer deserializer = this.GetDeserializer(fieldName, type); if (deserializer != null) { entity = deserializer.Deserialize(parent, vpack, this.deserializationContext); } else { if (type == typeof(object)) { entity = GetValue(parent, vpack, this.getType(vpack), fieldName); } else { entity = CreateInstance(type); this.DeserializeFields(entity, vpack); } } return(entity); }
/// <exception cref="VPackException"/> private void Parse( VPackSlice parent, string attribute, VPackSlice value, StringBuilder json, bool includeNullValues) { IVPackJsonDeserializer deserializer = null; if (attribute != null) { AppendField(attribute, json); deserializer = this.GetDeserializer(attribute, value.Type()); } if (deserializer != null) { deserializer.deserialize(parent, attribute, value, json); } else { if (value.IsObject) { this.ParseObject(value, json, includeNullValues); } else { if (value.IsArray) { this.ParseArray(value, json, includeNullValues); } else { if (value.IsBoolean) { json.Append(value.AsBoolean); } else { if (value.IsString) { json.Append(JsonConvert.ToString(value.AsString)); } else { if (value.IsNumber) { json.Append(value.AsNumber); } else { if (value.IsNull) { json.Append(NULL); } else { json.Append(JsonConvert.ToString(NON_REPRESENTABLE_TYPE)); } } } } } } } }
/// <exception cref="VPackValueTypeException"/> protected SliceIterator(VPackSlice slice) { this.slice = slice; this.size = slice.GetLength(); this.position = 0; }
/// <exception cref="VPackBuilderException"/> private VPackBuilder AddInternal <T>(string attribute, IAppender <T> appender, T value) { if (attribute != null) { bool haveReported = false; if (this.stack.Count > 0) { byte head = this.Head(); if (head != 0x0b && head != 0x14) { throw new VPackBuilderNeedOpenObjectException(); } if (this.keyWritten) { throw new VPackBuilderKeyAlreadyWrittenException(); } this.ReportAdd(); haveReported = true; } try { if (VPackSlice.attributeTranslator != null) { VPackSlice translate = VPackSlice.attributeTranslator.Translate(attribute); if (translate != null) { byte[] trValue = translate.GetRawVPack(); this.EnsureCapacity(this.size + trValue.Length); for (int i = 0; i < trValue.Length; i++) { this.AddUnchecked(trValue[i]); } this.keyWritten = true; if (value == null) { this.AppendNull(); } else { appender.Append(this, value); } return(this); } } // otherwise fall through to regular behavior STRING.Append(this, attribute); this.keyWritten = true; if (value == null) { this.AppendNull(); } else { appender.Append(this, value); } } catch (VPackBuilderException e) { // clean up in case of an exception if (haveReported) { this.CleanupAdd(); } throw; } finally { this.keyWritten = false; } } else { this.AddInternal(appender, value); } return(this); }
/// <returns>the offset for the nth member from an Array or Object type</returns> private int GetNthOffset(int index) { int offset; byte head = Head; if (head == 0x13 || head == 0x14) { // compact Array or Object offset = this.GetNthOffsetFromCompact(index); } else { if (head == 0x01 || head == 0x0a) { // special case: empty Array or empty Object throw new IndexOutOfRangeException(); } long n; int offsetsize = ObjectArrayUtil.GetOffsetSize(head); long end = NumberUtil.ToLong(this.vpack, this.start + 1, offsetsize); int dataOffset = this.FindDataOffset(); if ((sbyte)head <= 0x05) { // array with no offset table or length VPackSlice first = new VPackSlice(this.vpack, this.start + dataOffset); n = (end - dataOffset) / first.ByteSize; } else { if (offsetsize < 8) { n = NumberUtil.ToLong(this.vpack, this.start + 1 + offsetsize, offsetsize); } else { n = NumberUtil.ToLong(this.vpack, (int)(this.start + end - offsetsize), offsetsize); } } if (index >= n) { throw new IndexOutOfRangeException(); } if ((sbyte)head <= 0x05 || n == 1) { // no index table, but all array items have the same length // or only one item is in the array // now fetch first item and determine its length if (dataOffset == 0) { dataOffset = this.FindDataOffset(); } offset = dataOffset + index * new VPackSlice(this.vpack, this.start + dataOffset).ByteSize; } else { long ieBase = end - n * offsetsize + index * offsetsize - (offsetsize == 8 ? 8 : 0); offset = (int)NumberUtil.ToLong(this.vpack, (int)(this.start + ieBase), offsetsize); } } return(offset); }
/// <exception cref="VPackException"/> public abstract T Deserialize(VPackSlice parent, VPackSlice vpack, VPackDeserializationContext context);
/// <exception cref="VPackException"/> public virtual string ToJson(VPackSlice vpack) { return(this.ToJson(vpack, false)); }
/// <summary>translates an integer key into a string, without checks</summary> internal virtual VPackSlice TranslateUnchecked() { VPackSlice result = attributeTranslator.Translate(this.AsInt); return(result != null ? result : new VPackSlice()); }
private Type getType(VPackSlice vpack) { Type type; if (vpack.IsObject) { type = typeof(IDictionary); } else { if (vpack.IsString) { type = typeof(string); } else { if (vpack.IsBoolean) { type = typeof(bool); } else { if (vpack.IsArray) { type = typeof(ICollection); } else { if (vpack.IsDate) { type = typeof(DateTime); } else { if (vpack.IsDouble) { type = typeof(double); } else { if (vpack.IsNumber) { type = typeof(decimal); } else { if (vpack.IsCustom) { type = typeof(string); } else { type = null; } } } } } } } } return(type); }
/// <exception cref="VPackBuilderException"/> public virtual VPackBuilder Add(string attribute, VPackSlice value) { return(this.AddInternal(attribute, VPACK, value)); }
/// <exception cref="VPackParserException"/> public T Deserialize <T>(VPackSlice vpack) { return(this._enclosing.Deserialize <T>(vpack)); }
object IVPackDeserializer.Deserialize(VPackSlice parent, VPackSlice vpack, VPackDeserializationContext context) { return(Deserialize(parent, vpack, context)); }
/// <exception cref="VPackException"/> public virtual VPackSlice Get(string attribute) { if (!this.IsObject) { throw new VPackValueTypeException(ValueType.OBJECT); } byte head = Head; VPackSlice result = new VPackSlice(); if (head == 0x0a) { // special case, empty object result = new VPackSlice(); } else { if (head == 0x14) { // compact Object result = this.GetFromCompactObject(attribute); } else { int offsetsize = ObjectArrayUtil.GetOffsetSize(head); long end = NumberUtil.ToLong(this.vpack, this.start + 1, offsetsize); long n; if (offsetsize < 8) { n = NumberUtil.ToLong(this.vpack, this.start + 1 + offsetsize, offsetsize); } else { n = NumberUtil.ToLong(this.vpack, (int)(this.start + end - offsetsize), offsetsize); } if (n == 1) { // Just one attribute, there is no index table! VPackSlice key = new VPackSlice(this.vpack, this.start + this.FindDataOffset()); if (key.IsString) { if (key.IsEqualString(attribute)) { result = new VPackSlice(this.vpack, key.start + key.ByteSize); } else { // no match result = new VPackSlice(); } } else { if (key.IsInteger) { // translate key if (attributeTranslator == null) { throw new VPackNeedAttributeTranslatorException(); } if (key.TranslateUnchecked().IsEqualString(attribute)) { result = new VPackSlice(this.vpack, key.start + key.ByteSize); } else { // no match result = new VPackSlice(); } } else { // no match result = new VPackSlice(); } } } else { long ieBase = end - n * offsetsize - (offsetsize == 8 ? 8 : 0); // only use binary search for attributes if we have at least // this many entries // otherwise we'll always use the linear search long sortedSearchEntriesThreshold = 4; bool sorted = head >= 0x0b && (sbyte)head <= 0x0e; if (sorted && n >= sortedSearchEntriesThreshold) { // This means, we have to handle the special case n == 1 // only in the linear search! result = this.SearchObjectKeyBinary(attribute, ieBase, offsetsize, n); } else { result = this.SearchObjectKeyLinear(attribute, ieBase, offsetsize, n); } } } } return(result); }
/// <exception cref="java.lang.InstantiationException"/> /// <exception cref="java.lang.IllegalAccessException"/> /// <exception cref="System.MissingMethodException"/> /// <exception cref="java.lang.reflect.InvocationTargetException"/> /// <exception cref="VPackException"/> private object GetValue(VPackSlice parent, VPackSlice vpack, Type type, string fieldName) { object value; Type tmpType; if (vpack.IsNull) { value = null; } else { IVPackDeserializer deserializer = this.GetDeserializer(fieldName, type); if (deserializer != null) { value = deserializer.Deserialize(parent, vpack, this.deserializationContext); } else { var info = type.GetTypeInfo(); if (type.IsGenericParameter) { if (!type.IsConstructedGenericType) { throw new TypeLoadException(string.Format("Creating open generic types are not supported. ({0})", type)); } Type[] gens; if (typeof(IDictionary <,>).GetTypeInfo().IsAssignableFrom(info)) { gens = type.GetTargetType(typeof(IDictionary <,>)).GenericTypeArguments; value = DeserializeMap(parent, vpack, type, gens[0], gens[1]); } else if (typeof(IEnumerable <>).GetTypeInfo().IsAssignableFrom(info)) { gens = type.GetTargetType(typeof(IEnumerable <>)).GenericTypeArguments; value = DeserializeCollection(parent, vpack, type, gens[0]); } else { value = DeserializeObject(parent, vpack, type, fieldName); } } else { Type rawType = typeof(object); if (typeof(IDictionary).GetTypeInfo().IsAssignableFrom(info)) { value = DeserializeMap(parent, vpack, type, rawType, rawType); } else if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(info)) { value = DeserializeCollection(parent, vpack, type, rawType); } else if (info.IsArray) { value = DeserializeArray(parent, vpack, type); } else if (info.IsEnum) { value = Enum.Parse(type, vpack.AsString); } else { value = DeserializeObject(parent, vpack, type, fieldName); } } } } return(value); }
/// <exception cref="VPackBuilderException"/> public virtual VPackBuilder Add(VPackSlice value) { return(this.AddInternal(VPACK, value)); }
/// <exception cref="VPackValueTypeException"/> /// <exception cref="VPackNeedAttributeTranslatorException /// "/> private VPackSlice SearchObjectKeyBinary(string attribute, long ieBase, int offsetsize, long n) { bool useTranslator = attributeTranslator != null; VPackSlice result; long l = 0; long r = n - 1; for (;;) { // midpoint long index = l + (r - l) / 2; long offset = ieBase + index * offsetsize; long keyIndex = NumberUtil.ToLong(this.vpack, (int)(this.start + offset), offsetsize); VPackSlice key = new VPackSlice(this.vpack, (int)(this.start + keyIndex)); int res = 0; if (key.IsString) { res = key.CompareString(attribute); } else { if (key.IsInteger) { // translate key if (!useTranslator) { // no attribute translator throw new VPackNeedAttributeTranslatorException(); } res = key.TranslateUnchecked().CompareString(attribute); } else { // invalid key result = new VPackSlice(); break; } } if (res == 0) { // found result = new VPackSlice(this.vpack, key.start + key.ByteSize); break; } if (res > 0) { if (index == 0) { result = new VPackSlice(); break; } r = index - 1; } else { l = index + 1; } if (r < l) { result = new VPackSlice(); break; } } return(result); }