Esempio n. 1
0
        public bool EndsWith(string value)
        {
            if (IsDisposed)
            {
                ThrowAlreadyDisposed();
            }

            if (_string != null)
            {
                return(_string.EndsWith(value));
            }

            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }
            // Every UTF8 character uses at least 1 byte
            if (value.Length > Size)
            {
                return(false);
            }
            if (value.Length == 0)
            {
                return(true);
            }

            // We are assuming these values are going to be relatively constant throughout the object lifespan
            LazyStringValue converted = _context.GetLazyStringForFieldWithCaching(value);

            return(EndsWith(converted));
        }
Esempio n. 2
0
        public void WritePropertyName(string prop)
        {
            var lazyProp = _context.GetLazyStringForFieldWithCaching(prop);

            WriteString(lazyProp);
            EnsureBuffer(1);
            _buffer[_pos++] = Colon;
        }
Esempio n. 3
0
        public int GetPropertyId(LazyStringValue propName)
        {
            PropertyName prop;

            if (_propertyNameToId.TryGetValue(propName, out prop) == false)
            {
                var propIndex = _docPropNames.Count;
                propName = _context.GetLazyStringForFieldWithCaching(propName);
                prop     = new PropertyName
                {
                    Comparer        = propName,
                    GlobalSortOrder = -1,
                    PropertyId      = propIndex
                };

                _docPropNames.Add(prop);
                _propertiesSortOrder.Add(prop, prop);
                _propertyNameToId[propName] = prop;
                _propertiesNeedSorting      = true;
                if (_docPropNames.Count > PropertiesDiscovered + 1)
                {
                    prop = SwapPropertyIds(prop);
                }
                PropertiesDiscovered++;
            }
            else if (prop.PropertyId >= PropertiesDiscovered)
            {
                if (prop.PropertyId != PropertiesDiscovered)
                {
                    prop = SwapPropertyIds(prop);
                }
                PropertiesDiscovered++;
            }
            return(prop.PropertyId);
        }
Esempio n. 4
0
        public int WritePropertyNames(int rootOffset)
        {
            // Write the property names and register their positions
            var propertyArrayOffset = new int[_context.CachedProperties.PropertiesDiscovered];

            for (var index = 0; index < propertyArrayOffset.Length; index++)
            {
                propertyArrayOffset[index] = WriteValue(_context.GetLazyStringForFieldWithCaching(_context.CachedProperties.GetProperty(index)));
            }

            // Register the position of the properties offsets start
            var propertiesStart = _position;

            // Find the minimal space to store the offsets (byte,short,int) and raise the appropriate flag in the properties metadata
            BlittableJsonToken propertiesSizeMetadata = 0;
            var propertyNamesOffset = _position - rootOffset;
            var propertyArrayOffsetValueByteSize = SetOffsetSizeFlag(ref propertiesSizeMetadata, propertyNamesOffset);

            WriteNumber((int)propertiesSizeMetadata, sizeof(byte));

            // Write property names offsets
            foreach (int offset in propertyArrayOffset)
            {
                WriteNumber(propertiesStart - offset, propertyArrayOffsetValueByteSize);
            }
            return(propertiesStart);
        }
Esempio n. 5
0
        public void StartArrayDocument()
        {
            var currentState = new BuildingState
            {
                State = ContinuationState.ReadArrayDocument,
            };

            var fakeFieldName = _context.GetLazyStringForFieldWithCaching(UnderscoreSegment);
            var prop          = _writer.CachedProperties.GetProperty(fakeFieldName);

            currentState.CurrentProperty = prop;
            currentState.MaxPropertyId   = prop.PropertyId;
            currentState.FirstWrite      = _writer.Position;
            currentState.Properties      = _propertiesCache.Allocate();
            currentState.Properties.Add(new PropertyTag {
                Property = prop
            });
            _continuationState.Push(currentState);
        }
Esempio n. 6
0
        public void Renew(string debugTag, UsageMode mode)
        {
            Reset();
            _debugTag = debugTag;
            _mode     = mode;
            _writer.ResetAndRenew();
            _modifier?.Reset(_context);

            _fakeFieldName = _context.GetLazyStringForFieldWithCaching(UnderscoreSegment);
        }
Esempio n. 7
0
        public void Renew(string debugTag, UsageMode mode)
        {
            _writeToken = default(WriteToken);
            _debugTag   = debugTag;
            _mode       = mode;

            _continuationState.Clear();
            _cacheItem.Reset();

            _writer.ResetAndRenew();
            _modifier?.Reset(_context);

            _fakeFieldName = _context.GetLazyStringForFieldWithCaching(UnderscoreSegment);
        }
        public void StartArrayDocument()
        {
            var currentState = new BuildingState
            {
                State = ContinuationState.ReadArrayDocument
            };

            var fakeFieldName = _context.GetLazyStringForFieldWithCaching("_");
            var propIndex     = _context.CachedProperties.GetPropertyId(fakeFieldName);

            currentState.CurrentPropertyId = propIndex;
            currentState.MaxPropertyId     = propIndex;
            currentState.FirstWrite        = _writer.Position;
            currentState.Properties        = new List <PropertyTag>
            {
                new PropertyTag
                {
                    PropertyId = propIndex
                }
            };

            _continuationState.Push(currentState);
        }
Esempio n. 9
0
        private int WritePropertyNames(int rootOffset)
        {
            var cachedProperties     = _context.CachedProperties;
            int propertiesDiscovered = cachedProperties.PropertiesDiscovered;

            // Write the property names and register their positions
            if (_propertyArrayOffset == null || _propertyArrayOffset.Length < propertiesDiscovered)
            {
                _propertyArrayOffset = new int[Bits.NextPowerOf2(propertiesDiscovered)];
            }

            unsafe
            {
                for (var index = 0; index < propertiesDiscovered; index++)
                {
                    var str = _context.GetLazyStringForFieldWithCaching(cachedProperties.GetProperty(index));
                    if (str.EscapePositions == null || str.EscapePositions.Length == 0)
                    {
                        _propertyArrayOffset[index] = WriteValue(str.Buffer, str.Size);
                        continue;
                    }

                    _propertyArrayOffset[index] = WriteValue(str.Buffer, str.Size, str.EscapePositions);
                }
            }

            // Register the position of the properties offsets start
            var propertiesStart = _position;

            // Find the minimal space to store the offsets (byte,short,int) and raise the appropriate flag in the properties metadata
            BlittableJsonToken propertiesSizeMetadata = 0;
            var propertyNamesOffset = _position - rootOffset;
            var propertyArrayOffsetValueByteSize = SetOffsetSizeFlag(ref propertiesSizeMetadata, propertyNamesOffset);

            WriteNumber((int)propertiesSizeMetadata, sizeof(byte));

            // Write property names offsets
            // PERF: Using for to avoid the cost of the enumerator.
            for (int i = 0; i < propertiesDiscovered; i++)
            {
                int offset = _propertyArrayOffset[i];
                WriteNumber(propertiesStart - offset, propertyArrayOffsetValueByteSize);
            }

            return(propertiesStart);
        }
Esempio n. 10
0
        private PropertyName UnlikelyGetProperty(LazyStringValue propName)
        {
            var propIndex = _docPropNames.Count;

            propName = _context.GetLazyStringForFieldWithCaching(propName);

            // PERF: The hash for the property needs to be a hash code, if its not
            //       we will be paying the cost of hash collisions in the sort checks.
            var prop = new PropertyName(propName.GetHashCode(), propName, -1, propIndex);

            _docPropNames.Add(prop);
            _propertiesSortOrder.Add(prop, prop);
            _propertyNameToId[propName] = prop;
            _propertiesNeedSorting      = true;
            if (_docPropNames.Count > PropertiesDiscovered + 1)
            {
                prop = SwapPropertyIds(prop);
            }
            PropertiesDiscovered++;
            return(prop);
        }
Esempio n. 11
0
        private PropertyName UnlikelyGetProperty(LazyStringValue propName)
        {
            var propIndex = _docPropNames.Count;

            propName = _context.GetLazyStringForFieldWithCaching(propName);
            var prop = new PropertyName(_propertyNameCounter++)
            {
                Comparer        = propName,
                GlobalSortOrder = -1,
                PropertyId      = propIndex
            };

            _docPropNames.Add(prop);
            _propertiesSortOrder.Add(prop, prop);
            _propertyNameToId[propName] = prop;
            _propertiesNeedSorting      = true;
            if (_docPropNames.Count > PropertiesDiscovered + 1)
            {
                prop = SwapPropertyIds(prop);
            }
            PropertiesDiscovered++;
            return(prop);
        }
        public bool Read()
        {
            if (_continuationState.Count == 0)
            {
                return(false); //nothing to do
            }
            var currentState = _continuationState.Pop();

            while (true)
            {
                switch (currentState.State)
                {
                case ContinuationState.ReadObjectDocument:
                    if (_reader.Read() == false)
                    {
                        _continuationState.Push(currentState);
                        return(false);
                    }
                    currentState.State = ContinuationState.ReadObject;
                    continue;

                case ContinuationState.ReadArrayDocument:
                    if (_reader.Read() == false)
                    {
                        _continuationState.Push(currentState);
                        return(false);
                    }

                    var fakeFieldName = _context.GetLazyStringForFieldWithCaching("_");
                    var propIndex     = _context.CachedProperties.GetPropertyId(fakeFieldName);
                    currentState.CurrentPropertyId = propIndex;
                    currentState.MaxPropertyId     = propIndex;
                    currentState.FirstWrite        = _position;
                    currentState.Properties        = new List <PropertyTag>
                    {
                        new PropertyTag
                        {
                            PropertyId = propIndex
                        }
                    };
                    currentState.State = ContinuationState.CompleteDocumentArray;
                    _continuationState.Push(currentState);
                    currentState = new BuildingState
                    {
                        State = ContinuationState.ReadArray
                    };
                    continue;

                case ContinuationState.CompleteDocumentArray:
                    currentState.Properties[0].Type     = (byte)_writeToken.WrittenToken;
                    currentState.Properties[0].Position = _writeToken.ValuePos;

                    // Register property position, name id (PropertyId) and type (object type and metadata)
                    _writeToken = FinalizeObjectWrite(currentState.Properties, currentState.FirstWrite, currentState.MaxPropertyId);

                    return(true);

                case ContinuationState.ReadObject:
                    if (_state.CurrentTokenType != JsonParserToken.StartObject)
                    {
                        throw new InvalidDataException("Expected start of object, but got " + _state.CurrentTokenType);
                    }
                    currentState.State      = ContinuationState.ReadPropertyName;
                    currentState.Properties = new List <PropertyTag>();
                    currentState.FirstWrite = _position;
                    continue;

                case ContinuationState.ReadArray:
                    if (_state.CurrentTokenType != JsonParserToken.StartArray)
                    {
                        throw new InvalidDataException("Expected start of array, but got " + _state.CurrentTokenType);
                    }
                    currentState.Types     = new List <BlittableJsonToken>();
                    currentState.Positions = new List <int>();
                    currentState.State     = ContinuationState.ReadArrayValue;
                    continue;

                case ContinuationState.ReadArrayValue:
                    if (_reader.Read() == false)
                    {
                        _continuationState.Push(currentState);
                        return(false);
                    }
                    if (_state.CurrentTokenType == JsonParserToken.EndArray)
                    {
                        currentState.State = ContinuationState.CompleteArray;
                        continue;
                    }
                    currentState.State = ContinuationState.CompleteArrayValue;
                    _continuationState.Push(currentState);
                    currentState = new BuildingState
                    {
                        State = ContinuationState.ReadValue
                    };
                    continue;

                case ContinuationState.CompleteArrayValue:
                    currentState.Types.Add(_writeToken.WrittenToken);
                    currentState.Positions.Add(_writeToken.ValuePos);
                    currentState.State = ContinuationState.ReadArrayValue;
                    continue;

                case ContinuationState.CompleteArray:
                    var arrayInfoStart = _position;
                    var arrayToken     = BlittableJsonToken.StartArray;

                    _position += WriteVariableSizeInt(currentState.Positions.Count);
                    if (currentState.Positions.Count == 0)
                    {
                        arrayToken |= BlittableJsonToken.OffsetSizeByte;
                        _writeToken = new WriteToken
                        {
                            ValuePos     = arrayInfoStart,
                            WrittenToken = arrayToken
                        };
                    }
                    else
                    {
                        var distanceFromFirstItem = arrayInfoStart - currentState.Positions[0];
                        var distanceTypeSize      = SetOffsetSizeFlag(ref arrayToken, distanceFromFirstItem);

                        for (var i = 0; i < currentState.Positions.Count; i++)
                        {
                            WriteNumber(arrayInfoStart - currentState.Positions[i], distanceTypeSize);
                            _position += distanceTypeSize;

                            _stream.WriteByte((byte)currentState.Types[i]);
                            _position++;
                        }

                        _writeToken = new WriteToken
                        {
                            ValuePos     = arrayInfoStart,
                            WrittenToken = arrayToken
                        };
                    }
                    currentState = _continuationState.Pop();
                    continue;

                case ContinuationState.ReadPropertyName:
                    if (_reader.Read() == false)
                    {
                        _continuationState.Push(currentState);
                        return(false);
                    }

                    if (_state.CurrentTokenType == JsonParserToken.EndObject)
                    {
                        _writeToken = FinalizeObjectWrite(currentState.Properties, currentState.FirstWrite,
                                                          currentState.MaxPropertyId);
                        if (_continuationState.Count == 0)
                        {
                            return(true);
                        }
                        currentState = _continuationState.Pop();
                        continue;
                    }

                    if (_state.CurrentTokenType != JsonParserToken.String)
                    {
                        throw new InvalidDataException("Expected property, but got " + _state.CurrentTokenType);
                    }


                    var property = CreateLazyStringValueFromParserState();
                    if (_state.EscapePositions.Count > 0)
                    {
                        property.EscapePositions = _state.EscapePositions.ToArray();
                    }

                    currentState.CurrentPropertyId = _context.CachedProperties.GetPropertyId(property);
                    currentState.MaxPropertyId     = Math.Max(currentState.MaxPropertyId, currentState.CurrentPropertyId);
                    currentState.State             = ContinuationState.ReadPropertyValue;
                    continue;

                case ContinuationState.ReadPropertyValue:
                    if (_reader.Read() == false)
                    {
                        _continuationState.Push(currentState);
                        return(false);
                    }
                    currentState.State = ContinuationState.CompleteReadingPropertyValue;
                    _continuationState.Push(currentState);
                    currentState = new BuildingState
                    {
                        State = ContinuationState.ReadValue
                    };
                    continue;

                case ContinuationState.CompleteReadingPropertyValue:
                    // Register property position, name id (PropertyId) and type (object type and metadata)
                    currentState.Properties.Add(new PropertyTag
                    {
                        Position   = _writeToken.ValuePos,
                        Type       = (byte)_writeToken.WrittenToken,
                        PropertyId = currentState.CurrentPropertyId
                    });
                    currentState.State = ContinuationState.ReadPropertyName;
                    continue;

                case ContinuationState.ReadValue:
                    ReadJsonValue();
                    currentState = _continuationState.Pop();
                    break;
                }
            }
        }
Esempio n. 13
0
        public virtual bool Read()
        {
            if (_continuationState.Count == 0)
            {
                return(false); //nothing to do
            }
            var currentState = _continuationState.Pop();

            while (true)
            {
                switch (currentState.State)
                {
                case ContinuationState.ReadObjectDocument:
                    if (_reader.Read() == false)
                    {
                        _continuationState.Push(currentState);
                        return(false);
                    }
                    currentState.State = ContinuationState.ReadObject;
                    continue;

                case ContinuationState.ReadArrayDocument:
                    if (_reader.Read() == false)
                    {
                        _continuationState.Push(currentState);
                        return(false);
                    }

                    var fakeFieldName = _context.GetLazyStringForFieldWithCaching("_");
                    var propIndex     = _context.CachedProperties.GetPropertyId(fakeFieldName);
                    currentState.CurrentPropertyId = propIndex;
                    currentState.MaxPropertyId     = propIndex;
                    currentState.FirstWrite        = _writer.Position;
                    currentState.Properties        = new List <PropertyTag>
                    {
                        new PropertyTag
                        {
                            PropertyId = propIndex
                        }
                    };
                    currentState.State = ContinuationState.CompleteDocumentArray;
                    _continuationState.Push(currentState);
                    currentState = new BuildingState
                    {
                        State = ContinuationState.ReadArray
                    };
                    continue;

                case ContinuationState.CompleteDocumentArray:
                    currentState.Properties[0].Type     = (byte)_writeToken.WrittenToken;
                    currentState.Properties[0].Position = _writeToken.ValuePos;

                    // Register property position, name id (PropertyId) and type (object type and metadata)
                    _writeToken = _writer.WriteObjectMetadata(currentState.Properties, currentState.FirstWrite, currentState.MaxPropertyId);

                    return(true);

                case ContinuationState.ReadObject:
                    if (_state.CurrentTokenType != JsonParserToken.StartObject)
                    {
                        throw new InvalidDataException("Expected start of object, but got " + _state.CurrentTokenType);
                    }
                    currentState.State      = ContinuationState.ReadPropertyName;
                    currentState.Properties = new List <PropertyTag>();
                    currentState.FirstWrite = _writer.Position;
                    continue;

                case ContinuationState.ReadArray:
                    if (_state.CurrentTokenType != JsonParserToken.StartArray)
                    {
                        throw new InvalidDataException("Expected start of array, but got " + _state.CurrentTokenType);
                    }
                    currentState.Types     = new List <BlittableJsonToken>();
                    currentState.Positions = new List <int>();
                    currentState.State     = ContinuationState.ReadArrayValue;
                    continue;

                case ContinuationState.ReadArrayValue:
                    if (_reader.Read() == false)
                    {
                        _continuationState.Push(currentState);
                        return(false);
                    }
                    if (_state.CurrentTokenType == JsonParserToken.EndArray)
                    {
                        currentState.State = ContinuationState.CompleteArray;
                        continue;
                    }
                    currentState.State = ContinuationState.CompleteArrayValue;
                    _continuationState.Push(currentState);
                    currentState = new BuildingState
                    {
                        State = ContinuationState.ReadValue
                    };
                    continue;

                case ContinuationState.CompleteArrayValue:
                    currentState.Types.Add(_writeToken.WrittenToken);
                    currentState.Positions.Add(_writeToken.ValuePos);
                    currentState.State = ContinuationState.ReadArrayValue;
                    continue;

                case ContinuationState.CompleteArray:

                    var arrayToken     = BlittableJsonToken.StartArray;
                    var arrayInfoStart = _writer.WriteArrayMetadata(currentState.Positions, currentState.Types,
                                                                    ref arrayToken);

                    _writeToken = new WriteToken
                    {
                        ValuePos     = arrayInfoStart,
                        WrittenToken = arrayToken
                    };

                    currentState = _continuationState.Pop();
                    continue;

                case ContinuationState.ReadPropertyName:
                    if (_reader.Read() == false)
                    {
                        _continuationState.Push(currentState);
                        return(false);
                    }

                    if (_state.CurrentTokenType == JsonParserToken.EndObject)
                    {
                        _writeToken = _writer.WriteObjectMetadata(currentState.Properties, currentState.FirstWrite,
                                                                  currentState.MaxPropertyId);
                        if (_continuationState.Count == 0)
                        {
                            return(true);
                        }
                        currentState = _continuationState.Pop();
                        continue;
                    }

                    if (_state.CurrentTokenType != JsonParserToken.String)
                    {
                        throw new InvalidDataException("Expected property, but got " + _state.CurrentTokenType);
                    }


                    var property = CreateLazyStringValueFromParserState();

                    currentState.CurrentPropertyId = _context.CachedProperties.GetPropertyId(property);
                    currentState.MaxPropertyId     = Math.Max(currentState.MaxPropertyId, currentState.CurrentPropertyId);
                    currentState.State             = ContinuationState.ReadPropertyValue;
                    continue;

                case ContinuationState.ReadPropertyValue:
                    if (_reader.Read() == false)
                    {
                        _continuationState.Push(currentState);
                        return(false);
                    }
                    currentState.State = ContinuationState.CompleteReadingPropertyValue;
                    _continuationState.Push(currentState);
                    currentState = new BuildingState
                    {
                        State = ContinuationState.ReadValue
                    };
                    continue;

                case ContinuationState.CompleteReadingPropertyValue:
                    // Register property position, name id (PropertyId) and type (object type and metadata)
                    currentState.Properties.Add(new PropertyTag
                    {
                        Position   = _writeToken.ValuePos,
                        Type       = (byte)_writeToken.WrittenToken,
                        PropertyId = currentState.CurrentPropertyId
                    });
                    currentState.State = ContinuationState.ReadPropertyName;
                    continue;

                case ContinuationState.ReadValue:
                    ReadJsonValue();
                    currentState = _continuationState.Pop();
                    break;
                }
            }
        }