public void ClearResetsSizeAndEffectivellyClears()
        {
            using (var context = JsonOperationContext.ShortTermSingleUse())
            {
                var allocation = context.GetMemory(DefaultBufferSize);

                using (var buffer = new UnmanagedWriteBuffer(context, allocation))
                {
                    Assert.Equal(buffer.SizeInBytes, 0);
                    buffer.Write(AllocationsBatch, 0, AllocationsBatch.Length);
                    Assert.Equal(buffer.SizeInBytes, AllocationsBatch.Length);
                    buffer.Clear();
                    Assert.Equal(buffer.SizeInBytes, 0);

                    byte[] outputBuffer = new byte[AllocationsBatch.Length];
                    for (var i = 0; i < outputBuffer.Length; i++)
                    {
                        outputBuffer[i] = 124;
                        fixed(byte *outputBufferPtr = outputBuffer)
                        buffer.CopyTo(outputBufferPtr);

                        foreach (var b in outputBuffer)
                        {
                            Assert.Equal(b, 124);
                        }
                }
            }
        }
Exemple #2
0
        public bool Read()
        {
            var state = _state;

            if (state.Continuation != JsonParserTokenContinuation.None || _maybeBeforePreamble)
            {
                goto ReadContinuation;
            }

MainLoop:

            byte b;
            byte *currentBuffer = _inputBuffer;
            uint  bufferSize    = _bufSize;
            uint  pos           = _pos;

            while (true)
            {
                if (pos >= bufferSize)
                {
                    goto ReturnFalse;
                }

                b = currentBuffer[pos];
                pos++;
                _charPos++;

                if (b == ':' || b == ',')
                {
                    if (state.CurrentTokenType == JsonParserToken.Separator || state.CurrentTokenType == JsonParserToken.StartObject || state.CurrentTokenType == JsonParserToken.StartArray)
                    {
                        goto Error;
                    }

                    state.CurrentTokenType = JsonParserToken.Separator;
                    continue;
                }

                if (b == '\'' || b == '"')
                {
                    goto ParseString; // PERF: Avoid very lengthy method here; as we are going to return anyways.
                }
                if ((b >= '0' && b <= '9') || IsPossibleNegativeNumber(b, bufferSize, pos, currentBuffer))
                {
                    goto ParseNumber; // PERF: Avoid very lengthy method here; as we are going to return anyways.
                }
                if (b == '{')
                {
                    state.CurrentTokenType = JsonParserToken.StartObject;
                    goto ReturnTrue;
                }

                if (b == '}')
                {
                    state.CurrentTokenType = JsonParserToken.EndObject;
                    goto ReturnTrue;
                }
                if (b == '[')
                {
                    state.CurrentTokenType = JsonParserToken.StartArray;
                    goto ReturnTrue;
                }
                if (b == ']')
                {
                    state.CurrentTokenType = JsonParserToken.EndArray;
                    goto ReturnTrue;
                }

                bool couldRead;
                if (!ReadUnlikely(b, ref pos, out couldRead))
                {
                    continue; // We can only continue here, if there is a failure to parse, we will throw inside ReadUnlikely.
                }
                if (couldRead)
                {
                    goto ReturnTrue;
                }
                goto ReturnFalse;
            }

ParseString:
            {
                state.EscapePositions.Clear();
                _unmanagedWriteBuffer.Clear();
                _prevEscapePosition    = 0;
                _currentQuote          = b;
                state.CurrentTokenType = JsonParserToken.String;
                if (ParseString(ref pos) == false)
                {
                    state.Continuation = JsonParserTokenContinuation.PartialString;
                    goto ReturnFalse;
                }
                _unmanagedWriteBuffer.EnsureSingleChunk(state);
                goto ReturnTrue;
            }

ParseNumber:
            {
                _unmanagedWriteBuffer.Clear();
                state.EscapePositions.Clear();
                state.Long          = 0;
                _zeroPrefix         = b == '0';
                _isNegative         = false;
                _isFractionedDouble = false;
                _isExponent         = false;
                _isOverflow         = false;

                // ParseNumber need to call _charPos++ & _pos++, so we'll reset them for the first char
                pos--;
                _charPos--;

                if (ParseNumber(ref state.Long, ref pos) == false)
                {
                    state.Continuation = JsonParserTokenContinuation.PartialNumber;
                    goto ReturnFalse;
                }

                if (state.CurrentTokenType == JsonParserToken.Float)
                {
                    _unmanagedWriteBuffer.EnsureSingleChunk(state);
                }
                goto ReturnTrue;
            }

Error:
            ThrowCannotHaveCharInThisPosition(b);

ReturnTrue:
            _pos = pos;
            return(true);

ReturnFalse:
            _pos = pos;
            return(false);


ReadContinuation:                                                       // PERF: This is a "manual procedure"
            if (state.Continuation != JsonParserTokenContinuation.None) // parse normally
            {
                return(ContinueParsingValue());
            }

            state.Continuation = JsonParserTokenContinuation.None;
            if (_maybeBeforePreamble)
            {
                if (ReadMaybeBeforePreamble() == false)
                {
                    return(false);
                }
            }

            goto MainLoop;
        }