Beispiel #1
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.
        }