(*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *)

{$SCOPEDENUMS ON}

unit Thrift.Protocol.JSON;

interface

uses
  Character,
  Classes,
  SysUtils,
  Math,
  Generics.Collections,
  Thrift.Configuration,
  Thrift.Transport,
  Thrift.Protocol,
  Thrift.Stream,
  Thrift.Utils;

type
  IJSONProtocol = interface( IProtocol)
    ['{F0DAFDBD-692A-4B71-9736-F5D485A2178F}']
    // Read a byte that must match b; otherwise an exception is thrown.
    procedure ReadJSONSyntaxChar( b : Byte);
  end;

  // JSON protocol implementation for thrift.
  // This is a full-featured protocol supporting Write and Read.
  // Please see the C++ class header for a detailed description of the protocol's wire format.
  // Adapted from the C# version.
  TJSONProtocolImpl = class( TProtocolImpl, IJSONProtocol)
  public
    type
      TFactory = class( TInterfacedObject, IProtocolFactory)
      public
        function GetProtocol( const trans: ITransport): IProtocol;
      end;

  strict private
    class function GetTypeNameForTypeID(typeID : TType) : string;
    class function GetTypeIDForTypeName( const name : string) : TType;

  strict protected
    type
      // Base class for tracking JSON contexts that may require
      // inserting/Reading additional JSON syntax characters.
      // This base context does nothing.
      TJSONBaseContext = class
      strict protected
        FProto : Pointer;  // weak IJSONProtocol;
      public
        constructor Create( const aProto : IJSONProtocol);
        procedure Write;  virtual;
        procedure Read;  virtual;
        function EscapeNumbers : Boolean;  virtual;
      end;

      // Context for JSON lists.
      // Will insert/Read commas before each item except for the first one.
      TJSONListContext = class( TJSONBaseContext)
      strict private
        FFirst : Boolean;
      public
        constructor Create( const aProto : IJSONProtocol);
        procedure Write;  override;
        procedure Read;  override;
      end;

      // Context for JSON records. Will insert/Read colons before the value portion of each record
      // pair, and commas before each key except the first. In addition, will indicate that numbers
      // in the key position need to be escaped in quotes (since JSON keys must be strings).
      TJSONPairContext = class( TJSONBaseContext)
      strict private
        FFirst, FColon : Boolean;
      public
        constructor Create( const aProto : IJSONProtocol);
        procedure Write;  override;
        procedure Read;  override;
        function EscapeNumbers : Boolean;  override;
      end;

      // Holds up to one byte from the transport
      TLookaheadReader = class
      strict protected
        FProto : Pointer;  // weak IJSONProtocol;

      protected
        constructor Create( const aProto : IJSONProtocol);

      strict private
        FHasData : Boolean;
        FData    : Byte;

      public
        // Return and consume the next byte to be Read, either taking it from the
        // data buffer if present or getting it from the transport otherwise.
        function Read : Byte;

        // Return the next byte to be Read without consuming, filling the data
        // buffer if it has not been filled alReady.
        function Peek : Byte;
      end;

  strict protected
    // Stack of nested contexts that we may be in
    FContextStack : TStack<TJSONBaseContext>;

    // Current context that we are in
    FContext : TJSONBaseContext;

    // Reader that manages a 1-byte buffer
    FReader : TLookaheadReader;

    // Push/pop a new JSON context onto/from the stack.
    procedure ResetContextStack;
    procedure PushContext( const aCtx : TJSONBaseContext);
    procedure PopContext;

  strict protected
    function  GetMinSerializedSize( const aType : TType) : Integer;  override;
    procedure Reset;  override;

  public
    // TJSONProtocolImpl Constructor
    constructor Create( const aTrans : ITransport);  override;
    destructor Destroy;   override;

  strict protected
    // IJSONProtocol
    // Read a byte that must match b; otherwise an exception is thrown.
    procedure ReadJSONSyntaxChar( b : Byte);

  strict private
    // Convert a byte containing a hex char ('0'-'9' or 'a'-'f') into its corresponding hex value
    class function HexVal( ch : Byte) : Byte;

    // Convert a byte containing a hex value to its corresponding hex character
    class function HexChar( val : Byte) : Byte;

    // Write the bytes in array buf as a JSON characters, escaping as needed
    procedure WriteJSONString( const b : TBytes);  overload;
    procedure WriteJSONString( const str : string);  overload;

    // Write out number as a JSON value. If the context dictates so, it will be
    // wrapped in quotes to output as a JSON string.
    procedure WriteJSONInteger( const num : Int64);

    // Write out a double as a JSON value. If it is NaN or infinity or if the
    // context dictates escaping, Write out as JSON string.
    procedure WriteJSONDouble( const num : Double);

    // Write out contents of byte array b as a JSON string with base-64 encoded data
    procedure WriteJSONBase64( const b : TBytes);

    procedure WriteJSONObjectStart;
    procedure WriteJSONObjectEnd;
    procedure WriteJSONArrayStart;
    procedure WriteJSONArrayEnd;

  public
    // IProtocol
    procedure WriteMessageBegin( const aMsg : TThriftMessage); override;
    procedure WriteMessageEnd; override;
    procedure WriteStructBegin( const struc: TThriftStruct); override;
    procedure WriteStructEnd; override;
    procedure WriteFieldBegin( const field: TThriftField); override;
    procedure WriteFieldEnd; override;
    procedure WriteFieldStop; override;
    procedure WriteMapBegin( const map: TThriftMap); override;
    procedure WriteMapEnd; override;
    procedure WriteListBegin( const list: TThriftList); override;
    procedure WriteListEnd(); override;
    procedure WriteSetBegin( const set_: TThriftSet ); override;
    procedure WriteSetEnd(); override;
    procedure WriteBool( b: Boolean); override;
    procedure WriteByte( b: ShortInt); override;
    procedure WriteI16( i16: SmallInt); override;
    procedure WriteI32( i32: Integer); override;
    procedure WriteI64( const i64: Int64); override;
    procedure WriteDouble( const d: Double); override;
    procedure WriteString( const s: string );   override;
    procedure WriteBinary( const b: TBytes); override;
    //
    function ReadMessageBegin: TThriftMessage; override;
    procedure ReadMessageEnd(); override;
    function ReadStructBegin: TThriftStruct; override;
    procedure ReadStructEnd; override;
    function ReadFieldBegin: TThriftField; override;
    procedure ReadFieldEnd(); override;
    function ReadMapBegin: TThriftMap; override;
    procedure ReadMapEnd(); override;
    function ReadListBegin: TThriftList; override;
    procedure ReadListEnd(); override;
    function ReadSetBegin: TThriftSet; override;
    procedure ReadSetEnd(); override;
    function ReadBool: Boolean; override;
    function ReadByte: ShortInt; override;
    function ReadI16: SmallInt; override;
    function ReadI32: Integer; override;
    function ReadI64: Int64; override;
    function ReadDouble:Double; override;
    function ReadString : string;  override;
    function ReadBinary: TBytes; override;


  strict private
    // Reading methods.

    // Read in a JSON string, unescaping as appropriate.
    // Skip Reading from the context if skipContext is true.
    function ReadJSONString( skipContext : Boolean) : TBytes;

    // Return true if the given byte could be a valid part of a JSON number.
    function IsJSONNumeric( b : Byte) : Boolean;

    // Read in a sequence of characters that are all valid in JSON numbers. Does
    // not do a complete regex check to validate that this is actually a number.
    function ReadJSONNumericChars : String;

    // Read in a JSON number. If the context dictates, Read in enclosing quotes.
    function ReadJSONInteger : Int64;

    // Read in a JSON double value. Throw if the value is not wrapped in quotes
    // when expected or if wrapped in quotes when not expected.
    function ReadJSONDouble : Double;

    // Read in a JSON string containing base-64 encoded data and decode it.
    function ReadJSONBase64 : TBytes;

    procedure ReadJSONObjectStart;
    procedure ReadJSONObjectEnd;
    procedure ReadJSONArrayStart;
    procedure ReadJSONArrayEnd;
  end;


implementation

var
  COMMA     : TBytes;
  COLON     : TBytes;
  LBRACE    : TBytes;
  RBRACE    : TBytes;
  LBRACKET  : TBytes;
  RBRACKET  : TBytes;
  QUOTE     : TBytes;
  BACKSLASH : TBytes;
  ESCSEQ    : TBytes;

const
  VERSION = 1;
  JSON_CHAR_TABLE : array[0..$2F] of Byte
                  = (0,0,0,0, 0,0,0,0, Byte('b'),Byte('t'),Byte('n'),0, Byte('f'),Byte('r'),0,0,
                     0,0,0,0, 0,0,0,0, 0,0,0,0,  0,0,0,0,
                     1,1,Byte('"'),1,  1,1,1,1, 1,1,1,1, 1,1,1,1);

  ESCAPE_CHARS     = '"\/btnfr';
  ESCAPE_CHAR_VALS = '"\/'#8#9#10#12#13;

  DEF_STRING_SIZE = 16;

  NAME_BOOL   = 'tf';
  NAME_BYTE   = 'i8';
  NAME_I16    = 'i16';
  NAME_I32    = 'i32';
  NAME_I64    = 'i64';
  NAME_DOUBLE = 'dbl';
  NAME_STRUCT = 'rec';
  NAME_STRING = 'str';
  NAME_MAP    = 'map';
  NAME_LIST   = 'lst';
  NAME_SET    = 'set';

  INVARIANT_CULTURE : TFormatSettings
                    = ( ThousandSeparator: ',';
                        DecimalSeparator: '.');



//--- TJSONProtocolImpl ----------------------


function TJSONProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol;
begin
  result := TJSONProtocolImpl.Create( trans);
end;

class function TJSONProtocolImpl.GetTypeNameForTypeID(typeID : TType) : string;
begin
  case typeID of
    TType.Bool_:    result := NAME_BOOL;
    TType.Byte_:    result := NAME_BYTE;
    TType.I16:      result := NAME_I16;
    TType.I32:      result := NAME_I32;
    TType.I64:      result := NAME_I64;
    TType.Double_:  result := NAME_DOUBLE;
    TType.String_:  result := NAME_STRING;
    TType.Struct:   result := NAME_STRUCT;
    TType.Map:      result := NAME_MAP;
    TType.Set_:     result := NAME_SET;
    TType.List:     result := NAME_LIST;
  else
    raise TProtocolExceptionNotImplemented.Create('Unrecognized type ('+IntToStr(Ord(typeID))+')');
  end;
end;


class function TJSONProtocolImpl.GetTypeIDForTypeName( const name : string) : TType;
begin
  if      name = NAME_BOOL   then result := TType.Bool_
  else if name = NAME_BYTE   then result := TType.Byte_
  else if name = NAME_I16    then result := TType.I16
  else if name = NAME_I32    then result := TType.I32
  else if name = NAME_I64    then result := TType.I64
  else if name = NAME_DOUBLE then result := TType.Double_
  else if name = NAME_STRUCT then result := TType.Struct
  else if name = NAME_STRING then result := TType.String_
  else if name = NAME_MAP    then result := TType.Map
  else if name = NAME_LIST   then result := TType.List
  else if name = NAME_SET    then result := TType.Set_
  else raise TProtocolExceptionNotImplemented.Create('Unrecognized type ('+name+')');
end;


constructor TJSONProtocolImpl.TJSONBaseContext.Create( const aProto : IJSONProtocol);
begin
  inherited Create;
  FProto := Pointer(aProto);
end;


procedure TJSONProtocolImpl.TJSONBaseContext.Write;
begin
  // nothing
end;


procedure TJSONProtocolImpl.TJSONBaseContext.Read;
begin
  // nothing
end;


function TJSONProtocolImpl.TJSONBaseContext.EscapeNumbers : Boolean;
begin
  result := FALSE;
end;


constructor TJSONProtocolImpl.TJSONListContext.Create( const aProto : IJSONProtocol);
begin
  inherited Create( aProto);
  FFirst := TRUE;
end;


procedure TJSONProtocolImpl.TJSONListContext.Write;
begin
  if FFirst
  then FFirst := FALSE
  else IJSONProtocol(FProto).Transport.Write( COMMA);
end;


procedure TJSONProtocolImpl.TJSONListContext.Read;
begin
  if FFirst
  then FFirst := FALSE
  else IJSONProtocol(FProto).ReadJSONSyntaxChar( COMMA[0]);
end;


constructor TJSONProtocolImpl.TJSONPairContext.Create( const aProto : IJSONProtocol);
begin
  inherited Create( aProto);
  FFirst := TRUE;
  FColon := TRUE;
end;


procedure TJSONProtocolImpl.TJSONPairContext.Write;
begin
  if FFirst then begin
    FFirst := FALSE;
    FColon := TRUE;
  end
  else begin
    if FColon
    then IJSONProtocol(FProto).Transport.Write( COLON)
    else IJSONProtocol(FProto).Transport.Write( COMMA);
    FColon := not FColon;
  end;
end;


procedure TJSONProtocolImpl.TJSONPairContext.Read;
begin
  if FFirst then begin
    FFirst := FALSE;
    FColon := TRUE;
  end
  else begin
    if FColon
    then IJSONProtocol(FProto).ReadJSONSyntaxChar( COLON[0])
    else IJSONProtocol(FProto).ReadJSONSyntaxChar( COMMA[0]);
    FColon := not FColon;
  end;
end;


function TJSONProtocolImpl.TJSONPairContext.EscapeNumbers : Boolean;
begin
  result := FColon;
end;


constructor TJSONProtocolImpl.TLookaheadReader.Create( const aProto : IJSONProtocol);
begin
  inherited Create;
  FProto   := Pointer(aProto);
  FHasData := FALSE;
end;


function TJSONProtocolImpl.TLookaheadReader.Read : Byte;
begin
  if FHasData
  then FHasData := FALSE
  else begin
    IJSONProtocol(FProto).Transport.ReadAll( @FData, SizeOf(FData), 0, 1);
  end;
  result := FData;
end;


function TJSONProtocolImpl.TLookaheadReader.Peek : Byte;
begin
  if not FHasData then begin
    IJSONProtocol(FProto).Transport.ReadAll( @FData, SizeOf(FData), 0, 1);
    FHasData := TRUE;
  end;
  result := FData;
end;


constructor TJSONProtocolImpl.Create( const aTrans : ITransport);
begin
  inherited Create( aTrans);

  // Stack of nested contexts that we may be in
  FContextStack := TStack<TJSONBaseContext>.Create;

  FContext := TJSONBaseContext.Create( Self);
  FReader  := TLookaheadReader.Create( Self);
end;


destructor TJSONProtocolImpl.Destroy;
begin
  try
    ResetContextStack;  // free any contents
    FreeAndNil( FReader);
    FreeAndNil( FContext);
    FreeAndNil( FContextStack);
  finally
    inherited Destroy;
  end;
end;


procedure TJSONProtocolImpl.Reset;
begin
  inherited Reset;
  ResetContextStack;
end;


procedure TJSONProtocolImpl.ResetContextStack;
begin
  while FContextStack.Count > 0
  do PopContext;
end;


procedure TJSONProtocolImpl.PushContext( const aCtx : TJSONBaseContext);
begin
  FContextStack.Push( FContext);
  FContext := aCtx;
end;


procedure TJSONProtocolImpl.PopContext;
begin
  FreeAndNil(FContext);
  FContext := FContextStack.Pop;
end;


procedure TJSONProtocolImpl.ReadJSONSyntaxChar( b : Byte);
var ch : Byte;
begin
  ch := FReader.Read;
  if (ch <> b)
  then raise TProtocolExceptionInvalidData.Create('Unexpected character ('+Char(ch)+')');
end;


class function TJSONProtocolImpl.HexVal( ch : Byte) : Byte;
var i : Integer;
begin
  i := StrToIntDef( '$0'+Char(ch), -1);
  if (0 <= i) and (i < $10)
  then result := i
  else raise TProtocolExceptionInvalidData.Create('Expected hex character ('+Char(ch)+')');
end;


class function TJSONProtocolImpl.HexChar( val : Byte) : Byte;
const HEXCHARS = '0123456789ABCDEF';
begin
  result := Byte( PChar(HEXCHARS)[val and $0F]);
  ASSERT( Pos( Char(result), HEXCHARS) > 0);
end;


procedure TJSONProtocolImpl.WriteJSONString( const str : string);
begin
  WriteJSONString( SysUtils.TEncoding.UTF8.GetBytes( str));
end;


procedure TJSONProtocolImpl.WriteJSONString( const b : TBytes);
var i : Integer;
    tmp : TBytes;
begin
  FContext.Write;
  Transport.Write( QUOTE);
  for i := 0 to Length(b)-1 do begin

    if (b[i] and $00FF) >= $30 then begin

      if (b[i] = BACKSLASH[0]) then begin
        Transport.Write( BACKSLASH);
        Transport.Write( BACKSLASH);
      end
      else begin
        Transport.Write( b, i, 1);
      end;

    end
    else begin
      SetLength( tmp, 2);
      tmp[0] := JSON_CHAR_TABLE[b[i]];
      if (tmp[0] = 1) then begin
        Transport.Write( b, i, 1)
      end
      else if (tmp[0] > 1) then begin
        Transport.Write( BACKSLASH);
        Transport.Write( tmp, 0, 1);
      end
      else begin
        Transport.Write( ESCSEQ);
        tmp[0] := HexChar( b[i] div $10);
        tmp[1] := HexChar( b[i]);
        Transport.Write( tmp, 0, 2);
      end;
    end;
  end;
  Transport.Write( QUOTE);
end;


procedure TJSONProtocolImpl.WriteJSONInteger( const num : Int64);
var str : String;
    escapeNum : Boolean;
begin
  FContext.Write;
  str := IntToStr(num);

  escapeNum := FContext.EscapeNumbers;
  if escapeNum
  then Transport.Write( QUOTE);

  Transport.Write( SysUtils.TEncoding.UTF8.GetBytes( str));

  if escapeNum
  then Transport.Write( QUOTE);
end;


procedure TJSONProtocolImpl.WriteJSONDouble( const num : Double);
var str : string;
    special : Boolean;
    escapeNum : Boolean;
begin
  FContext.Write;

  str := FloatToStr( num, INVARIANT_CULTURE);
  special := FALSE;

  case UpCase(str[1]) of
    'N' : special := TRUE;  // NaN
    'I' : special := TRUE;  // Infinity
    '-' : special := (UpCase(str[2]) = 'I'); // -Infinity
  end;

  escapeNum := special or FContext.EscapeNumbers;


  if escapeNum
  then Transport.Write( QUOTE);

  Transport.Write( SysUtils.TEncoding.UTF8.GetBytes( str));

  if escapeNum
  then Transport.Write( QUOTE);
end;


procedure TJSONProtocolImpl.WriteJSONBase64( const b : TBytes);
var len, off, cnt : Integer;
    tmpBuf : TBytes;
begin
  FContext.Write;
  Transport.Write( QUOTE);

  len := Length(b);
  off := 0;
  SetLength( tmpBuf, 4);

  while len >= 3 do begin
    // Encode 3 bytes at a time
    Base64Utils.Encode( b, off, 3, tmpBuf, 0);
    Transport.Write( tmpBuf, 0, 4);
    Inc( off, 3);
    Dec( len, 3);
  end;

  // Encode remainder, if any
  if len > 0 then begin
    cnt := Base64Utils.Encode( b, off, len, tmpBuf, 0);
    Transport.Write( tmpBuf, 0, cnt);
  end;

  Transport.Write( QUOTE);
end;


procedure TJSONProtocolImpl.WriteJSONObjectStart;
begin
  FContext.Write;
  Transport.Write( LBRACE);
  PushContext( TJSONPairContext.Create( Self));
end;


procedure TJSONProtocolImpl.WriteJSONObjectEnd;
begin
  PopContext;
  Transport.Write( RBRACE);
end;


procedure TJSONProtocolImpl.WriteJSONArrayStart;
begin
  FContext.Write;
  Transport.Write( LBRACKET);
  PushContext( TJSONListContext.Create( Self));
end;


procedure TJSONProtocolImpl.WriteJSONArrayEnd;
begin
  PopContext;
  Transport.Write( RBRACKET);
end;


procedure TJSONProtocolImpl.WriteMessageBegin( const aMsg : TThriftMessage);
begin
  Reset;
  ResetContextStack;  // THRIFT-1473

  WriteJSONArrayStart;
  WriteJSONInteger(VERSION);

  WriteJSONString( SysUtils.TEncoding.UTF8.GetBytes( aMsg.Name));

  WriteJSONInteger( LongInt( aMsg.Type_));
  WriteJSONInteger( aMsg.SeqID);
end;

procedure TJSONProtocolImpl.WriteMessageEnd;
begin
  WriteJSONArrayEnd;
end;


procedure TJSONProtocolImpl.WriteStructBegin( const struc: TThriftStruct);
begin
  WriteJSONObjectStart;
end;


procedure TJSONProtocolImpl.WriteStructEnd;
begin
  WriteJSONObjectEnd;
end;


procedure TJSONProtocolImpl.WriteFieldBegin( const field : TThriftField);
begin
  WriteJSONInteger(field.ID);
  WriteJSONObjectStart;
  WriteJSONString( GetTypeNameForTypeID(field.Type_));
end;


procedure TJSONProtocolImpl.WriteFieldEnd;
begin
  WriteJSONObjectEnd;
end;


procedure TJSONProtocolImpl.WriteFieldStop;
begin
  // nothing to do
end;

procedure TJSONProtocolImpl.WriteMapBegin( const map: TThriftMap);
begin
  WriteJSONArrayStart;
  WriteJSONString( GetTypeNameForTypeID( map.KeyType));
  WriteJSONString( GetTypeNameForTypeID( map.ValueType));
  WriteJSONInteger( map.Count);
  WriteJSONObjectStart;
end;


procedure TJSONProtocolImpl.WriteMapEnd;
begin
  WriteJSONObjectEnd;
  WriteJSONArrayEnd;
end;


procedure TJSONProtocolImpl.WriteListBegin( const list: TThriftList);
begin
  WriteJSONArrayStart;
  WriteJSONString( GetTypeNameForTypeID( list.ElementType));
  WriteJSONInteger(list.Count);
end;


procedure TJSONProtocolImpl.WriteListEnd;
begin
  WriteJSONArrayEnd;
end;


procedure TJSONProtocolImpl.WriteSetBegin( const set_: TThriftSet);
begin
  WriteJSONArrayStart;
  WriteJSONString( GetTypeNameForTypeID( set_.ElementType));
  WriteJSONInteger( set_.Count);
end;


procedure TJSONProtocolImpl.WriteSetEnd;
begin
  WriteJSONArrayEnd;
end;

procedure TJSONProtocolImpl.WriteBool( b: Boolean);
begin
  if b
  then WriteJSONInteger( 1)
  else WriteJSONInteger( 0);
end;

procedure TJSONProtocolImpl.WriteByte( b: ShortInt);
begin
  WriteJSONInteger( b);
end;

procedure TJSONProtocolImpl.WriteI16( i16: SmallInt);
begin
  WriteJSONInteger( i16);
end;

procedure TJSONProtocolImpl.WriteI32( i32: Integer);
begin
  WriteJSONInteger( i32);
end;

procedure TJSONProtocolImpl.WriteI64( const i64: Int64);
begin
  WriteJSONInteger(i64);
end;

procedure TJSONProtocolImpl.WriteDouble( const d: Double);
begin
  WriteJSONDouble( d);
end;

procedure TJSONProtocolImpl.WriteString( const s: string );
begin
  WriteJSONString( SysUtils.TEncoding.UTF8.GetBytes( s));
end;

procedure TJSONProtocolImpl.WriteBinary( const b: TBytes);
begin
  WriteJSONBase64( b);
end;


function TJSONProtocolImpl.ReadJSONString( skipContext : Boolean) : TBytes;
var buffer : TThriftMemoryStream;
    ch  : Byte;
    wch : Word;
    highSurogate: Char;
    surrogatePairs: Array[0..1] of Char;
    off : Integer;
    tmp : TBytes;
begin
  highSurogate := #0;
  buffer := TThriftMemoryStream.Create;
  try
    if not skipContext
    then FContext.Read;

    ReadJSONSyntaxChar( QUOTE[0]);

    while TRUE do begin
      ch := FReader.Read;

      if (ch = QUOTE[0])
      then Break;

      // check for escapes
      if (ch <> ESCSEQ[0]) then begin
        buffer.Write( ch, 1);
        Continue;
      end;

      // distuinguish between \uNNNN and \?
      ch := FReader.Read;
      if (ch <> ESCSEQ[1])
      then begin
        off := Pos( Char(ch), ESCAPE_CHARS);
        if off < 1
        then raise TProtocolExceptionInvalidData.Create('Expected control char');
        ch := Byte( ESCAPE_CHAR_VALS[off]);
        buffer.Write( ch, 1);
        Continue;
      end;

      // it is \uXXXX
      SetLength( tmp, 4);
      Transport.ReadAll( tmp, 0, 4);
      wch := (HexVal(tmp[0]) shl 12)
           + (HexVal(tmp[1]) shl 8)
           + (HexVal(tmp[2]) shl 4)
           +  HexVal(tmp[3]);

      // we need to make UTF8 bytes from it, to be decoded later
      if CharUtils.IsHighSurrogate(char(wch)) then begin
        if highSurogate <> #0
        then raise TProtocolExceptionInvalidData.Create('Expected low surrogate char');
        highSurogate := char(wch);
      end
      else if CharUtils.IsLowSurrogate(char(wch)) then begin
        if highSurogate = #0
        then TProtocolExceptionInvalidData.Create('Expected high surrogate char');
        surrogatePairs[0] := highSurogate;
        surrogatePairs[1] := char(wch);
        tmp := TEncoding.UTF8.GetBytes(surrogatePairs);
        buffer.Write( tmp[0], Length(tmp));
        highSurogate := #0;
      end
      else begin
        tmp := SysUtils.TEncoding.UTF8.GetBytes(Char(wch));
        buffer.Write( tmp[0], Length(tmp));
      end;
    end;

    if highSurogate <> #0
    then raise TProtocolExceptionInvalidData.Create('Expected low surrogate char');

    SetLength( result, buffer.Size);
    if buffer.Size > 0 then Move( buffer.Memory^, result[0], Length(result));

  finally
    buffer.Free;
  end;
end;


function TJSONProtocolImpl.IsJSONNumeric( b : Byte) : Boolean;
const NUMCHARS = ['+','-','.','0','1','2','3','4','5','6','7','8','9','E','e'];
begin
  result := CharInSet( Char(b), NUMCHARS);
end;


function TJSONProtocolImpl.ReadJSONNumericChars : string;
var strbld : TThriftStringBuilder;
    ch : Byte;
begin
  strbld := TThriftStringBuilder.Create;
  try
    while TRUE do begin
      ch := FReader.Peek;
      if IsJSONNumeric(ch)
      then strbld.Append( Char(FReader.Read))
      else Break;
    end;
    result := strbld.ToString;

  finally
    strbld.Free;
  end;
end;


function TJSONProtocolImpl.ReadJSONInteger : Int64;
var str : string;
begin
  FContext.Read;
  if FContext.EscapeNumbers
  then ReadJSONSyntaxChar( QUOTE[0]);

  str := ReadJSONNumericChars;

  if FContext.EscapeNumbers
  then ReadJSONSyntaxChar( QUOTE[0]);

  try
    result := StrToInt64(str);
  except
    on e:Exception do begin
      raise TProtocolExceptionInvalidData.Create('Bad data encounted in numeric data ('+str+') ('+e.Message+')');
    end;
  end;
end;


function TJSONProtocolImpl.ReadJSONDouble : Double;
var dub : Double;
    str : string;
begin
  FContext.Read;

  if FReader.Peek = QUOTE[0]
  then begin
    str := SysUtils.TEncoding.UTF8.GetString( ReadJSONString( TRUE));
    dub := StrToFloat( str, INVARIANT_CULTURE);

    if not FContext.EscapeNumbers()
    and not Math.IsNaN(dub)
    and not Math.IsInfinite(dub)
    then begin
      // Throw exception -- we should not be in a string in  Self case
      raise TProtocolExceptionInvalidData.Create('Numeric data unexpectedly quoted');
    end;
    result := dub;
    Exit;
  end;

  // will throw - we should have had a quote if escapeNum == true
  if FContext.EscapeNumbers
  then ReadJSONSyntaxChar( QUOTE[0]);

  try
    str := ReadJSONNumericChars;
    result := StrToFloat( str, INVARIANT_CULTURE);
  except
    on e:Exception
    do raise TProtocolExceptionInvalidData.Create('Bad data encounted in numeric data ('+str+') ('+e.Message+')');
  end;
end;


function TJSONProtocolImpl.ReadJSONBase64 : TBytes;
var b : TBytes;
    len, off, size : Integer;
begin
  b := ReadJSONString(false);

  len := Length(b);
  off := 0;
  size := 0;

  // reduce len to ignore fill bytes
  Dec(len);
  while (len >= 0) and (b[len] = Byte('=')) do Dec(len);
  Inc(len);

  // read & decode full byte triplets = 4 source bytes
  while (len >= 4) do begin
    // Decode 4 bytes at a time
    Inc( size, Base64Utils.Decode( b, off, 4, b, size)); // decoded in place
    Inc( off, 4);
    Dec( len, 4);
  end;

  // Don't decode if we hit the end or got a single leftover byte (invalid
  // base64 but legal for skip of regular string type)
  if len > 1 then begin
    // Decode remainder
    Inc( size, Base64Utils.Decode( b, off, len, b, size)); // decoded in place
  end;

  // resize to final size and return the data
  SetLength( b, size);
  result := b;
end;


procedure TJSONProtocolImpl.ReadJSONObjectStart;
begin
  FContext.Read;
  ReadJSONSyntaxChar( LBRACE[0]);
  PushContext( TJSONPairContext.Create( Self));
end;


procedure TJSONProtocolImpl.ReadJSONObjectEnd;
begin
  ReadJSONSyntaxChar( RBRACE[0]);
  PopContext;
end;


procedure TJSONProtocolImpl.ReadJSONArrayStart;
begin
  FContext.Read;
  ReadJSONSyntaxChar( LBRACKET[0]);
  PushContext( TJSONListContext.Create( Self));
end;


procedure TJSONProtocolImpl.ReadJSONArrayEnd;
begin
  ReadJSONSyntaxChar( RBRACKET[0]);
  PopContext;
end;


function TJSONProtocolImpl.ReadMessageBegin: TThriftMessage;
begin
  Reset;
  ResetContextStack;  // THRIFT-1473

  Init( result);
  ReadJSONArrayStart;

  if ReadJSONInteger <> VERSION
  then raise TProtocolExceptionBadVersion.Create('Message contained bad version.');

  result.Name  := SysUtils.TEncoding.UTF8.GetString( ReadJSONString( FALSE));
  result.Type_ := TMessageType( ReadJSONInteger);
  result.SeqID := ReadJSONInteger;
end;


procedure TJSONProtocolImpl.ReadMessageEnd;
begin
  ReadJSONArrayEnd;
end;


function TJSONProtocolImpl.ReadStructBegin : TThriftStruct ;
begin
  ReadJSONObjectStart;
  Init( result);
end;


procedure TJSONProtocolImpl.ReadStructEnd;
begin
  ReadJSONObjectEnd;
end;


function TJSONProtocolImpl.ReadFieldBegin : TThriftField;
var ch : Byte;
    str : string;
begin
  Init( result);
  ch := FReader.Peek;
  if ch = RBRACE[0]
  then result.Type_ := TType.Stop
  else begin
    result.ID := ReadJSONInteger;
    ReadJSONObjectStart;

    str := SysUtils.TEncoding.UTF8.GetString( ReadJSONString( FALSE));
    result.Type_ := GetTypeIDForTypeName( str);
  end;
end;


procedure TJSONProtocolImpl.ReadFieldEnd;
begin
  ReadJSONObjectEnd;
end;


function TJSONProtocolImpl.ReadMapBegin : TThriftMap;
var str : string;
begin
  Init( result);
  ReadJSONArrayStart;

  str := SysUtils.TEncoding.UTF8.GetString( ReadJSONString(FALSE));
  result.KeyType := GetTypeIDForTypeName( str);

  str := SysUtils.TEncoding.UTF8.GetString( ReadJSONString(FALSE));
  result.ValueType := GetTypeIDForTypeName( str);

  result.Count := ReadJSONInteger;
  CheckReadBytesAvailable(result);

  ReadJSONObjectStart;
end;


procedure TJSONProtocolImpl.ReadMapEnd;
begin
  ReadJSONObjectEnd;
  ReadJSONArrayEnd;
end;


function TJSONProtocolImpl.ReadListBegin : TThriftList;
var str : string;
begin
  Init( result);
  ReadJSONArrayStart;

  str := SysUtils.TEncoding.UTF8.GetString( ReadJSONString(FALSE));
  result.ElementType := GetTypeIDForTypeName( str);
  result.Count := ReadJSONInteger;
  CheckReadBytesAvailable(result);
end;


procedure TJSONProtocolImpl.ReadListEnd;
begin
  ReadJSONArrayEnd;
end;


function TJSONProtocolImpl.ReadSetBegin : TThriftSet;
var str : string;
begin
  Init( result);
  ReadJSONArrayStart;

  str := SysUtils.TEncoding.UTF8.GetString( ReadJSONString(FALSE));
  result.ElementType := GetTypeIDForTypeName( str);
  result.Count := ReadJSONInteger;
  CheckReadBytesAvailable(result);
end;


procedure TJSONProtocolImpl.ReadSetEnd;
begin
  ReadJSONArrayEnd;
end;


function TJSONProtocolImpl.ReadBool : Boolean;
begin
  result := (ReadJSONInteger <> 0);
end;


function TJSONProtocolImpl.ReadByte : ShortInt;
begin
  result := ReadJSONInteger;
end;


function TJSONProtocolImpl.ReadI16 : SmallInt;
begin
  result := ReadJSONInteger;
end;


function TJSONProtocolImpl.ReadI32 : LongInt;
begin
  result := ReadJSONInteger;
end;


function TJSONProtocolImpl.ReadI64 : Int64;
begin
  result := ReadJSONInteger;
end;


function TJSONProtocolImpl.ReadDouble : Double;
begin
  result := ReadJSONDouble;
end;


function TJSONProtocolImpl.ReadString : string;
begin
  result := SysUtils.TEncoding.UTF8.GetString( ReadJSONString( FALSE));
end;


function TJSONProtocolImpl.ReadBinary : TBytes;
begin
  result := ReadJSONBase64;
end;


function TJSONProtocolImpl.GetMinSerializedSize( const aType : TType) : Integer;
// Return the minimum number of bytes a type will consume on the wire
begin
  case aType of
    TType.Stop:    result := 0;
    TType.Void:    result := 0;
    TType.Bool_:   result := 1;
    TType.Byte_:   result := 1;
    TType.Double_: result := 1;
    TType.I16:     result := 1;
    TType.I32:     result := 1;
    TType.I64:     result := 1;
    TType.String_: result := 2;  // empty string
    TType.Struct:  result := 2;  // empty struct
    TType.Map:     result := 2;  // empty map
    TType.Set_:    result := 2;  // empty set
    TType.List:    result := 2;  // empty list
  else
    raise TTransportExceptionBadArgs.Create('Unhandled type code');
  end;
end;



//--- init code ---

procedure InitBytes( var b : TBytes; aData : array of Byte);
begin
  SetLength( b, Length(aData));
  Move( aData, b[0], Length(b));
end;

initialization
  InitBytes( COMMA,     [Byte(',')]);
  InitBytes( COLON,     [Byte(':')]);
  InitBytes( LBRACE,    [Byte('{')]);
  InitBytes( RBRACE,    [Byte('}')]);
  InitBytes( LBRACKET,  [Byte('[')]);
  InitBytes( RBRACKET,  [Byte(']')]);
  InitBytes( QUOTE,     [Byte('"')]);
  InitBytes( BACKSLASH, [Byte('\')]);
  InitBytes( ESCSEQ,    [Byte('\'),Byte('u'),Byte('0'),Byte('0')]);
end.
