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); } } } }
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; }