示例#1
0
        public VPackSlice Translate(int key)
        {
            VPackSlice slice = null;

            keyToAttribute.TryGetValue(key, out slice);
            return(slice);
        }
示例#2
0
        //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);
        }
示例#3
0
        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);
        }
示例#4
0
        public VPackSlice Translate(string attribute)
        {
            VPackSlice slice = null;

            attributeToKey.TryGetValue(attribute, out slice);
            return(slice);
        }
示例#5
0
 //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;
 }
示例#6
0
        //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);
        }
示例#7
0
            public ArraySliceState(VPackSlice slice)
            {
                if (slice.IsType(SliceType.Array) == false)
                {
                    throw new VPackValueTypeException(SliceType.Array);
                }

                Enumerator = slice.ArrayEnumerable().GetEnumerator();
            }
示例#8
0
        public SliceReader(byte[] buffer)
        {
            this.buffer = buffer;
            VPackSlice s = new VPackSlice(buffer);

            containerSlices = new List <object>();

            currentSlice = s;
        }
示例#9
0
            public ObjectSliceState(VPackSlice slice)
            {
                if (slice.IsType(SliceType.Object) == false)
                {
                    throw new VPackValueTypeException(SliceType.Object);
                }

                Enumerator = slice.ObjectEnumerable().GetEnumerator();
            }
示例#10
0
        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()));
        }
示例#11
0
        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;
            }
        }
示例#12
0
        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);
        }
示例#13
0
        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);
        }
示例#14
0
        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);
        }
示例#15
0
        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);
        }
示例#16
0
        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);
        }
示例#17
0
        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);
        }
示例#18
0
        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);
        }
示例#19
0
        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");
            }
        }
示例#20
0
        /// <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);
            }
        }
示例#21
0
 public VPackBuilder Add(VPackSlice value)
 {
     return(WrapAdd(value, () => AppendVPack(value)));
 }
示例#22
0
        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);
        }
示例#23
0
        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");
        }
示例#24
0
 public VPackBuilder Add(string attribute, VPackSlice value)
 {
     return(WrapAdd(attribute, value, () => AppendVPack(value)));
 }
示例#25
0
 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);
 }
示例#26
0
 public SortEntry(VPackSlice slice, int offset)
 {
     this.Slice = slice;
     Offset     = offset;
 }
示例#27
0
        //translates an integer key into a string, without checks
        VPackSlice TranslateUnchecked()
        {
            VPackSlice result = attributeTranslator.Translate(ToInt32().Value);

            return(result != null ? result : new VPackSlice());
        }