Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
 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;
 }
Ejemplo n.º 3
0
        /// <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);
        }
Ejemplo n.º 4
0
        /// <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);
        }
Ejemplo n.º 5
0
        /// <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());
        }
Ejemplo n.º 6
0
        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));
        }
Ejemplo n.º 7
0
 /// <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);
     }
 }
Ejemplo n.º 8
0
        /// <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);
                }
            }
        }
Ejemplo n.º 9
0
        /// <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);
        }
Ejemplo n.º 10
0
        /// <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);
        }
Ejemplo n.º 11
0
        /// <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);
        }
Ejemplo n.º 12
0
        /// <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);
        }
Ejemplo n.º 13
0
        /// <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);
        }
Ejemplo n.º 14
0
        /// <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);
        }
Ejemplo n.º 15
0
        /// <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);
        }
Ejemplo n.º 16
0
        /// <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));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 17
0
 /// <exception cref="VPackValueTypeException"/>
 protected SliceIterator(VPackSlice slice)
 {
     this.slice    = slice;
     this.size     = slice.GetLength();
     this.position = 0;
 }
Ejemplo n.º 18
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);
        }
Ejemplo n.º 19
0
        /// <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);
        }
Ejemplo n.º 20
0
 /// <exception cref="VPackException"/>
 public abstract T Deserialize(VPackSlice parent, VPackSlice vpack, VPackDeserializationContext context);
Ejemplo n.º 21
0
 /// <exception cref="VPackException"/>
 public virtual string ToJson(VPackSlice vpack)
 {
     return(this.ToJson(vpack, false));
 }
Ejemplo n.º 22
0
        /// <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());
        }
Ejemplo n.º 23
0
        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);
        }
Ejemplo n.º 24
0
 /// <exception cref="VPackBuilderException"/>
 public virtual VPackBuilder Add(string attribute, VPackSlice value)
 {
     return(this.AddInternal(attribute, VPACK, value));
 }
Ejemplo n.º 25
0
 /// <exception cref="VPackParserException"/>
 public T Deserialize <T>(VPackSlice vpack)
 {
     return(this._enclosing.Deserialize <T>(vpack));
 }
Ejemplo n.º 26
0
 object IVPackDeserializer.Deserialize(VPackSlice parent, VPackSlice vpack, VPackDeserializationContext context)
 {
     return(Deserialize(parent, vpack, context));
 }
Ejemplo n.º 27
0
        /// <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);
        }
Ejemplo n.º 28
0
        /// <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);
        }
Ejemplo n.º 29
0
 /// <exception cref="VPackBuilderException"/>
 public virtual VPackBuilder Add(VPackSlice value)
 {
     return(this.AddInternal(VPACK, value));
 }
Ejemplo n.º 30
0
        /// <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);
        }