public VPackSlice Translate(int key) { VPackSlice slice = null; keyToAttribute.TryGetValue(key, out slice); return(slice); }
//Return the offset for the nth member from a compact Array or Object type int GetNthOffsetFromCompact(int index) { long end = NumberUtil.ReadVariableValueLength(vpack, start + 1, false); long n = NumberUtil.ReadVariableValueLength(vpack, (int)(start + end - 1), true); if (index >= n) { throw new IndexOutOfRangeException(); } byte head = TypeCode; long offset = 1 + NumberUtil.GetVariableValueLength(end); long current = 0; while (current != index) { long byteSize = new VPackSlice(vpack, (int)(start + offset)).GetByteSize(); offset += byteSize; if (head == 0x14) { offset += byteSize; } ++current; } return((int)offset); }
public override bool Equals(object obj) { if (this == obj) { return(true); } if (obj == null) { return(false); } if (GetType() != obj.GetType()) { return(false); } VPackSlice other = (VPackSlice)obj; if (start != other.start) { return(false); } if (!GetRawVPack().SequenceEqual(other.GetRawVPack())) { return(false); } return(true); }
public VPackSlice Translate(string attribute) { VPackSlice slice = null; attributeToKey.TryGetValue(attribute, out slice); return(slice); }
//appendVPack(VPackSlice value) void AppendVPack(VPackSlice value) { byte[] vpack = value.GetRawVPack(); EnsureCapacity(size + vpack.Length); System.Buffer.BlockCopy(vpack, 0, buffer, size, vpack.Length); size += vpack.Length; }
//Return the offset for the nth member from an Array or Object type int GetNthOffset(int index) { int offset; byte head = TypeCode; if (head == 0x13 || head == 0x14) { // compact Array or Object offset = GetNthOffsetFromCompact(index); } else if (head == 0x01 || head == 0x0a) { // special case: empty Array or empty Object throw new IndexOutOfRangeException(); } else { long n; int offsetsize = ObjectArrayUtil.GetOffsetSize(head); long end = NumberUtil.ToLong(vpack, start + 1, offsetsize); int dataOffset = FindDataOffset(); if (head <= 0x05) { // array with no offset table or length VPackSlice first = new VPackSlice(vpack, start + dataOffset); n = (end - dataOffset) / first.GetByteSize(); } else if (offsetsize < 8) { n = NumberUtil.ToLong(vpack, start + 1 + offsetsize, offsetsize); } else { n = NumberUtil.ToLong(vpack, (int)(start + end - offsetsize), offsetsize); } if (index >= n) { throw new IndexOutOfRangeException(); } if (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 = FindDataOffset(); } offset = dataOffset + index * new VPackSlice(vpack, start + dataOffset).GetByteSize(); } else { long ieBase = end - n * offsetsize + index * offsetsize - (offsetsize == 8 ? 8 : 0); offset = (int)NumberUtil.ToLong(vpack, (int)(start + ieBase), offsetsize); } } return(offset); }
public ArraySliceState(VPackSlice slice) { if (slice.IsType(SliceType.Array) == false) { throw new VPackValueTypeException(SliceType.Array); } Enumerator = slice.ArrayEnumerable().GetEnumerator(); }
public SliceReader(byte[] buffer) { this.buffer = buffer; VPackSlice s = new VPackSlice(buffer); containerSlices = new List <object>(); currentSlice = s; }
public ObjectSliceState(VPackSlice slice) { if (slice.IsType(SliceType.Object) == false) { throw new VPackValueTypeException(SliceType.Object); } Enumerator = slice.ObjectEnumerable().GetEnumerator(); }
public VPackSlice ValueAt(int index) { if (!IsType(SliceType.Object)) { throw new VPackValueTypeException(SliceType.Object); } VPackSlice key = GetNthKey(index); return(new VPackSlice(vpack, key.start + key.GetByteSize())); }
public void Seal() { if (builder == null) { return; } builder.Close(); VPackSlice slice = builder.Slice(); for (int i = 0; i < slice.Length; i++) { VPackSlice key = slice.KeyAt(i); VPackSlice value = slice.ValueAt(i); attributeToKey[key.ToStringUnchecked()] = value; keyToAttribute[value.ToInt32().Value] = key; } }
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(vpack, (int)(start + offset), offsetsize); VPackSlice key = new VPackSlice(vpack, (int)(start + keyIndex)); if (key.IsType(SliceType.String)) { 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(vpack, key.start + key.GetByteSize()); break; } return(result); }
public override DateTimeOffset?ReadAsDateTimeOffset() { if (currentSlice == null) { SetCurrentFromArray(); } if (currentSlice == null) { return(null); } var value = currentSlice.ToDateTimeOffset(); SetToken(JsonToken.Date, value); currentSlice = null; return(value); }
public override byte[] ReadAsBytes() { if (currentSlice == null) { SetCurrentFromArray(); } if (currentSlice == null) { return(null); } var value = currentSlice.ToBinary(); SetToken(JsonToken.Bytes, value); currentSlice = null; return(value); }
public override bool?ReadAsBoolean() { if (currentSlice == null) { SetCurrentFromArray(); } if (currentSlice == null) { return(null); } var value = currentSlice.ToBoolean(); SetToken(JsonToken.Boolean, value); currentSlice = null; return(value); }
public override int?ReadAsInt32() { if (currentSlice == null) { SetCurrentFromArray(); } if (currentSlice == null) { return(null); } var value = currentSlice.ToInt32(); SetToken(JsonToken.Integer, value); currentSlice = null; return(value); }
public override string ReadAsString() { if (currentSlice == null) { SetCurrentFromArray(); } if (currentSlice == null) { return(null); } var value = currentSlice.ToStringValue(); SetToken(JsonToken.String, value); currentSlice = null; return(value); }
public override double?ReadAsDouble() { if (currentSlice == null) { SetCurrentFromArray(); } if (currentSlice == null) { return(null); } var value = currentSlice.ToDouble(); SetToken(JsonToken.Float, value); currentSlice = null; return(value); }
public void SetCurrentFromArray() { var arraySlice = currentContainerSlice as ArraySliceState; if (arraySlice != null) { if (arraySlice.MoveNext()) { currentSlice = arraySlice.Slice; } else { containerSlices.Remove(arraySlice); SetToken(JsonToken.EndArray); } } else { throw new InvalidOperationException($"Expected ArraySliceState"); } }
/// <summary> /// Return object by attribute name /// </summary> /// <param name="attribute"></param> /// <returns></returns> public VPackSlice this[string attribute] { get { if (!IsType(SliceType.Object)) { throw new VPackValueTypeException(SliceType.Object); } byte head = TypeCode; VPackSlice result = new VPackSlice(); if (head == 0x0a) { // special case, empty object result = new VPackSlice(); } else if (head == 0x14) { // compact Object result = GetFromCompactObject(attribute); } else { int offsetsize = ObjectArrayUtil.GetOffsetSize(head); long end = NumberUtil.ToLong(vpack, start + 1, offsetsize); long n; if (offsetsize < 8) { n = NumberUtil.ToLong(vpack, start + 1 + offsetsize, offsetsize); } else { n = NumberUtil.ToLong(vpack, (int)(start + end - offsetsize), offsetsize); } if (n == 1) { // Just one attribute, there is no index table! VPackSlice key = new VPackSlice(vpack, start + FindDataOffset()); if (key.IsType(SliceType.String)) { if (key.IsEqualString(attribute)) { result = new VPackSlice(vpack, key.start + key.GetByteSize()); } 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(vpack, key.start + key.GetByteSize()); } 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 && head <= 0x0e; if (sorted && n >= sortedSearchEntriesThreshold) { // This means, we have to handle the special case n == 1 // only in the linear search! result = SearchObjectKeyBinary(attribute, ieBase, offsetsize, n); } else { result = SearchObjectKeyLinear(attribute, ieBase, offsetsize, n); } } } return(result); } }
public VPackBuilder Add(VPackSlice value) { return(WrapAdd(value, () => AppendVPack(value))); }
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(vpack, (int)(start + offset), offsetsize); VPackSlice key = new VPackSlice(vpack, (int)(start + keyIndex)); int res = 0; if (key.IsType(SliceType.String)) { 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(vpack, key.start + key.GetByteSize()); 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); }
public override bool Read() { if (currentSlice == null) { // do nothing } else if (currentSlice.IsType(SliceType.Object)) { containerSlices.Add(new ObjectSliceState(currentSlice)); currentSlice = null; } else if (currentSlice.IsType(SliceType.Array)) { containerSlices.Add(new ArraySliceState(currentSlice)); currentSlice = null; } else { ParseValue(); currentSlice = null; return(true); } var objectSlice = currentContainerSlice as ObjectSliceState; if (objectSlice != null) { if (objectSlice.Initialized == false) { SetToken(JsonToken.StartObject); objectSlice.Initialized = true; return(true); } bool hasAnotherSlice = objectSlice.MoveNext(); if (hasAnotherSlice == false) { containerSlices.Remove(objectSlice); SetToken(JsonToken.EndObject); } else { SetToken(JsonToken.PropertyName, objectSlice.PropertyName); currentSlice = objectSlice.Slice; } return(true); } var arraySlice = currentContainerSlice as ArraySliceState; if (arraySlice != null) { if (arraySlice.Initialized == false) { SetToken(JsonToken.StartArray); arraySlice.Initialized = true; return(true); } bool hasAnotherSlice = arraySlice.MoveNext(); if (hasAnotherSlice == false) { containerSlices.Remove(arraySlice); SetToken(JsonToken.EndArray); } else { currentSlice = arraySlice.Slice; Read(); } return(true); } throw new InvalidOperationException($"Error at reading vpack slice"); }
public VPackBuilder Add(string attribute, VPackSlice value) { return(WrapAdd(attribute, value, () => AppendVPack(value))); }
VPackBuilder WrapAdd(string attribute, object value, Action append) { if (attribute != null) { bool haveReported = false; if (stack.Count != 0) { byte head = Head(); if (head != 0x0b && head != 0x14) { throw new VPackBuilderNeedOpenObjectException(); } if (keyWritten) { throw new VPackBuilderKeyAlreadyWrittenException(); } ReportAdd(); haveReported = true; } try { if (VelocyPack.VPackSlice.attributeTranslator != null) { VPackSlice translate = VelocyPack.VPackSlice.attributeTranslator.Translate(attribute); if (translate != null) { byte[] trValue = translate.GetRawVPack(); EnsureCapacity(size + trValue.Length); for (int i = 0; i < trValue.Length; i++) { WriteUnchecked(trValue[i]); } keyWritten = true; if (value == null) { AppendNull(); } else { append(); } return(this); } // otherwise fall through to regular behavior } AppendString(attribute); keyWritten = true; if (value == null) { AppendNull(); } else { append(); } } catch (VPackBuilderException e) { // clean up in case of an exception if (haveReported) { CleanupAdd(); } throw e; } finally { keyWritten = false; } } else { WrapAdd(value, append); } return(this); }
public SortEntry(VPackSlice slice, int offset) { this.Slice = slice; Offset = offset; }
//translates an integer key into a string, without checks VPackSlice TranslateUnchecked() { VPackSlice result = attributeTranslator.Translate(ToInt32().Value); return(result != null ? result : new VPackSlice()); }