(*
 * 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.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);
    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 : TMemoryStream;
    ch  : Byte;
    wch : Word;
    highSurogate: Char;
    surrogatePairs: Array[0..1] of Char;
    off : Integer;
    tmp : TBytes;
begin
  highSurogate := #0;
  buffer := TMemoryStream.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.
