public void WriteObjectEnd()
        {
            var  currentState = _continuationState.Pop();
            long start        = 0;

            start = _writer.Position;
            switch (currentState.State)
            {
            case ContinuationState.ReadPropertyName:
            case ContinuationState.ReadPropertyValue:
            {
                _writeToken = _writer.WriteObjectMetadata(currentState.Properties, currentState.FirstWrite,
                                                          currentState.MaxPropertyId);

                // here we know that the last itme in the stack is the keep the last ReadObjectDocument
                if (_continuationState.Count > 1)
                {
                    var outerState = _continuationState.Pop();
                    if (outerState.State == ContinuationState.ReadArray)
                    {
                        outerState.Types.Add(_writeToken.WrittenToken);
                        outerState.Positions.Add(_writeToken.ValuePos);
                    }
                    else
                    {
                        outerState.Properties.Add(new PropertyTag(
                                                      type: (byte)_writeToken.WrittenToken,
                                                      property: outerState.CurrentProperty,
                                                      position: _writeToken.ValuePos
                                                      ));
                    }

                    if (outerState.FirstWrite == -1)
                    {
                        outerState.FirstWrite = start;
                    }
                    _continuationState.Push(outerState);
                }
            }
            break;

            case ContinuationState.ReadArray:
            {
                _writeToken = _writer.WriteObjectMetadata(currentState.Properties, currentState.FirstWrite,
                                                          currentState.MaxPropertyId);

                if (_continuationState.Count > 1)
                {
                    var outerState = _continuationState.Count > 0 ? _continuationState.Pop() : currentState;
                    if (outerState.FirstWrite == -1)
                    {
                        outerState.FirstWrite = start;
                    }
                    _continuationState.Push(outerState);
                }

                currentState.Types.Add(_writeToken.WrittenToken);
                currentState.Positions.Add(_writeToken.ValuePos);
                _continuationState.Push(currentState);
            }
            break;

            case ContinuationState.ReadObjectDocument:
            {
                currentState.Properties.Add(new PropertyTag
                    {
                        Position = _writeToken.ValuePos,
                        Type     = (byte)_writeToken.WrittenToken,
                        Property = currentState.CurrentProperty
                    });
                if (currentState.FirstWrite == -1)
                {
                    currentState.FirstWrite = start;
                }

                _writeToken = _writer.WriteObjectMetadata(currentState.Properties, currentState.FirstWrite,
                                                          currentState.MaxPropertyId);
            }
            break;

            default:
                ThrowIllegalStateException(currentState.State, "ReadEndObject");
                break;
            }
        }
Пример #2
0
        private bool ReadInternal <TWriteStrategy>() where TWriteStrategy : IWriteStrategy
        {
            var continuationState = _continuationState;
            var currentState      = continuationState.Pop();
            var reader            = _reader;
            var state             = _state;

            while (true)
            {
                switch (currentState.State)
                {
                case ContinuationState.ReadObjectDocument:
                    if (reader.Read() == false)
                    {
                        continuationState.Push(currentState);
                        goto ReturnFalse;
                    }
                    currentState.State = ContinuationState.ReadObject;
                    continue;

                case ContinuationState.ReadArrayDocument:
                    if (reader.Read() == false)
                    {
                        continuationState.Push(currentState);
                        goto ReturnFalse;
                    }

                    var fakeProperty = _context.CachedProperties.GetProperty(_fakeFieldName);
                    currentState.CurrentProperty = fakeProperty;
                    currentState.MaxPropertyId   = fakeProperty.PropertyId;
                    currentState.FirstWrite      = _writer.Position;
                    currentState.Properties      = _propertiesCache.Allocate();
                    currentState.Properties.Add(new PropertyTag {
                        Property = fakeProperty
                    });
                    currentState.State = ContinuationState.CompleteDocumentArray;
                    continuationState.Push(currentState);
                    currentState = new BuildingState(ContinuationState.ReadArray);
                    continue;

                case ContinuationState.CompleteDocumentArray:
                    currentState.Properties[0] = new PropertyTag(
                        type: (byte)_writeToken.WrittenToken,
                        property: currentState.Properties[0].Property,
                        position: _writeToken.ValuePos
                        );

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

                case ContinuationState.ReadObject:
                    if (state.CurrentTokenType == JsonParserToken.StartObject)
                    {
                        currentState.State      = ContinuationState.ReadPropertyName;
                        currentState.Properties = _propertiesCache.Allocate();
                        currentState.FirstWrite = _writer.Position;
                        continue;
                    }

                    goto ErrorExpectedStartOfObject;

                case ContinuationState.ReadArray:
                    if (state.CurrentTokenType == JsonParserToken.StartArray)
                    {
                        currentState.Types     = _tokensCache.Allocate();
                        currentState.Positions = _positionsCache.Allocate();
                        currentState.State     = ContinuationState.ReadArrayValue;
                        continue;
                    }

                    goto ErrorExpectedStartOfArray;

                case ContinuationState.ReadArrayValue:
                    if (reader.Read() == false)
                    {
                        continuationState.Push(currentState);
                        goto ReturnFalse;
                    }

                    if (state.CurrentTokenType == JsonParserToken.EndArray)
                    {
                        currentState.State = ContinuationState.CompleteArray;
                        continue;
                    }

                    currentState.State = ContinuationState.CompleteArrayValue;
                    continuationState.Push(currentState);
                    currentState = new BuildingState(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(arrayInfoStart, arrayToken);
                    currentState = continuationState.Pop();
                    continue;

                case ContinuationState.ReadPropertyName:
                    if (ReadMaybeModifiedPropertyName() == false)
                    {
                        continuationState.Push(currentState);
                        goto ReturnFalse;
                    }

                    if (state.CurrentTokenType == JsonParserToken.EndObject)
                    {
                        _modifier?.EndObject();
                        _writeToken = _writer.WriteObjectMetadata(currentState.Properties, currentState.FirstWrite, currentState.MaxPropertyId);
                        if (continuationState.Count == 0)
                        {
                            goto ReturnTrue;
                        }

                        currentState = continuationState.Pop();
                        continue;
                    }

                    if (state.CurrentTokenType != JsonParserToken.String)
                    {
                        goto ErrorExpectedProperty;
                    }

                    var property = CreateLazyStringValueFromParserState();
                    currentState.CurrentProperty = _context.CachedProperties.GetProperty(property);
                    currentState.MaxPropertyId   = Math.Max(currentState.MaxPropertyId, currentState.CurrentProperty.PropertyId);
                    currentState.State           = ContinuationState.ReadPropertyValue;
                    continue;

                case ContinuationState.ReadPropertyValue:
                    if (reader.Read() == false)
                    {
                        continuationState.Push(currentState);
                        goto ReturnFalse;
                    }
                    currentState.State = ContinuationState.CompleteReadingPropertyValue;
                    continuationState.Push(currentState);
                    currentState = new BuildingState(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,
                                                    property: currentState.CurrentProperty));

                    currentState.State = ContinuationState.ReadPropertyName;
                    continue;

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

            ReturnTrue : return(true);

            ReturnFalse : return(false);

            ErrorExpectedProperty      : ThrowExpectedProperty();
            ErrorExpectedStartOfObject : ThrowExpectedStartOfObject();
            ErrorExpectedStartOfArray  : ThrowExpectedStartOfArray();
            return(false); // Will never execute.
        }
Пример #3
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;
                }
            }
        }