github.com/artyom/thrift@v0.0.0-20130902103359-388840a05deb/json_protocol.go (about)

     1  /*
     2   * Licensed to the Apache Software Foundation (ASF) under one
     3   * or more contributor license agreements. See the NOTICE file
     4   * distributed with this work for additional information
     5   * regarding copyright ownership. The ASF licenses this file
     6   * to you under the Apache License, Version 2.0 (the
     7   * "License"); you may not use this file except in compliance
     8   * with the License. You may obtain a copy of the License at
     9   *
    10   *   http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing,
    13   * software distributed under the License is distributed on an
    14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   * KIND, either express or implied. See the License for the
    16   * specific language governing permissions and limitations
    17   * under the License.
    18   */
    19  
    20  package thrift
    21  
    22  import (
    23  	"encoding/base64"
    24  	"fmt"
    25  )
    26  
    27  const (
    28  	THRIFT_JSON_PROTOCOL_VERSION = 1
    29  )
    30  
    31  // for references to _ParseContext see tsimplejson_protocol.go
    32  
    33  // JSON protocol implementation for thrift.
    34  //
    35  // This protocol produces/consumes a simple output format
    36  // suitable for parsing by scripting languages.  It should not be
    37  // confused with the full-featured TJSONProtocol.
    38  //
    39  type TJSONProtocol struct {
    40  	*TSimpleJSONProtocol
    41  }
    42  
    43  // Constructor
    44  func NewTJSONProtocol(t TTransport) *TJSONProtocol {
    45  	v := &TJSONProtocol{TSimpleJSONProtocol: NewTSimpleJSONProtocol(t)}
    46  	v.parseContextStack = append(v.parseContextStack, int(_CONTEXT_IN_TOPLEVEL))
    47  	v.dumpContext = append(v.dumpContext, int(_CONTEXT_IN_TOPLEVEL))
    48  	return v
    49  }
    50  
    51  // Factory
    52  type TJSONProtocolFactory struct{}
    53  
    54  func (p *TJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol {
    55  	return NewTJSONProtocol(trans)
    56  }
    57  
    58  func NewTJSONProtocolFactory() *TJSONProtocolFactory {
    59  	return &TJSONProtocolFactory{}
    60  }
    61  
    62  func (p *TJSONProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) error {
    63  	if e := p.OutputListBegin(); e != nil {
    64  		return e
    65  	}
    66  	if e := p.WriteI32(THRIFT_JSON_PROTOCOL_VERSION); e != nil {
    67  		return e
    68  	}
    69  	if e := p.WriteString(name); e != nil {
    70  		return e
    71  	}
    72  	if e := p.WriteByte(byte(typeId)); e != nil {
    73  		return e
    74  	}
    75  	if e := p.WriteI32(seqId); e != nil {
    76  		return e
    77  	}
    78  	return nil
    79  }
    80  
    81  func (p *TJSONProtocol) WriteMessageEnd() error {
    82  	return p.OutputListEnd()
    83  }
    84  
    85  func (p *TJSONProtocol) WriteStructBegin(name string) error {
    86  	if e := p.OutputObjectBegin(); e != nil {
    87  		return e
    88  	}
    89  	return nil
    90  }
    91  
    92  func (p *TJSONProtocol) WriteStructEnd() error {
    93  	return p.OutputObjectEnd()
    94  }
    95  
    96  func (p *TJSONProtocol) WriteFieldBegin(name string, typeId TType, id int16) error {
    97  	if e := p.WriteI16(id); e != nil {
    98  		return e
    99  	}
   100  	if e := p.OutputObjectBegin(); e != nil {
   101  		return e
   102  	}
   103  	if e := p.WriteString(p.TypeIdToString(typeId)); e != nil {
   104  		return e
   105  	}
   106  	return nil
   107  }
   108  
   109  func (p *TJSONProtocol) WriteFieldEnd() error {
   110  	return p.OutputObjectEnd()
   111  }
   112  
   113  func (p *TJSONProtocol) WriteFieldStop() error { return nil }
   114  
   115  func (p *TJSONProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error {
   116  	if e := p.OutputListBegin(); e != nil {
   117  		return e
   118  	}
   119  	if e := p.WriteString(p.TypeIdToString(keyType)); e != nil {
   120  		return e
   121  	}
   122  	if e := p.WriteString(p.TypeIdToString(valueType)); e != nil {
   123  		return e
   124  	}
   125  	return p.WriteI64(int64(size))
   126  }
   127  
   128  func (p *TJSONProtocol) WriteMapEnd() error {
   129  	return p.OutputListEnd()
   130  }
   131  
   132  func (p *TJSONProtocol) WriteListBegin(elemType TType, size int) error {
   133  	return p.OutputElemListBegin(elemType, size)
   134  }
   135  
   136  func (p *TJSONProtocol) WriteListEnd() error {
   137  	return p.OutputListEnd()
   138  }
   139  
   140  func (p *TJSONProtocol) WriteSetBegin(elemType TType, size int) error {
   141  	return p.OutputElemListBegin(elemType, size)
   142  }
   143  
   144  func (p *TJSONProtocol) WriteSetEnd() error {
   145  	return p.OutputListEnd()
   146  }
   147  
   148  func (p *TJSONProtocol) WriteBool(b bool) error {
   149  	return p.OutputBool(b)
   150  }
   151  
   152  func (p *TJSONProtocol) WriteByte(b byte) error {
   153  	return p.WriteI32(int32(b))
   154  }
   155  
   156  func (p *TJSONProtocol) WriteI16(v int16) error {
   157  	return p.WriteI32(int32(v))
   158  }
   159  
   160  func (p *TJSONProtocol) WriteI32(v int32) error {
   161  	return p.OutputI64(int64(v))
   162  }
   163  
   164  func (p *TJSONProtocol) WriteI64(v int64) error {
   165  	return p.OutputI64(int64(v))
   166  }
   167  
   168  func (p *TJSONProtocol) WriteDouble(v float64) error {
   169  	return p.OutputF64(v)
   170  }
   171  
   172  func (p *TJSONProtocol) WriteString(v string) error {
   173  	return p.OutputString(v)
   174  }
   175  
   176  func (p *TJSONProtocol) WriteBinary(v []byte) error {
   177  	// JSON library only takes in a string,
   178  	// not an arbitrary byte array, to ensure bytes are transmitted
   179  	// efficiently we must convert this into a valid JSON string
   180  	// therefore we use base64 encoding to avoid excessive escaping/quoting
   181  	if e := p.OutputPreValue(); e != nil {
   182  		return e
   183  	}
   184  	p.writer.Write(JSON_QUOTE_BYTES)
   185  	writer := base64.NewEncoder(base64.StdEncoding, p.writer)
   186  	if _, e := writer.Write(v); e != nil {
   187  		return NewTProtocolException(e)
   188  	}
   189  	writer.Close()
   190  	p.writer.Write(JSON_QUOTE_BYTES)
   191  	return p.OutputPostValue()
   192  }
   193  
   194  // Reading methods.
   195  
   196  func (p *TJSONProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) {
   197  	if isNull, err := p.ParseListBegin(); isNull || err != nil {
   198  		return name, typeId, seqId, err
   199  	}
   200  	version, err := p.ReadI32()
   201  	if err != nil {
   202  		return name, typeId, seqId, err
   203  	}
   204  	if version != THRIFT_JSON_PROTOCOL_VERSION {
   205  		e := fmt.Errorf("Unknown Protocol version %d, expected version %d", version, THRIFT_JSON_PROTOCOL_VERSION)
   206  		return name, typeId, seqId, NewTProtocolExceptionWithType(INVALID_DATA, e)
   207  
   208  	}
   209  	if name, err = p.ReadString(); err != nil {
   210  		return name, typeId, seqId, err
   211  	}
   212  	bTypeId, err := p.ReadByte()
   213  	typeId = TMessageType(bTypeId)
   214  	if err != nil {
   215  		return name, typeId, seqId, err
   216  	}
   217  	if seqId, err = p.ReadI32(); err != nil {
   218  		return name, typeId, seqId, err
   219  	}
   220  	return name, typeId, seqId, nil
   221  }
   222  
   223  func (p *TJSONProtocol) ReadMessageEnd() error {
   224  	err := p.ParseListEnd()
   225  	return err
   226  }
   227  
   228  func (p *TJSONProtocol) ReadStructBegin() (name string, err error) {
   229  	_, err = p.ParseObjectStart()
   230  	return "", err
   231  }
   232  
   233  func (p *TJSONProtocol) ReadStructEnd() error {
   234  	return p.ParseObjectEnd()
   235  }
   236  
   237  func (p *TJSONProtocol) ReadFieldBegin() (string, TType, int16, error) {
   238  	if p.reader.Buffered() < 1 {
   239  		return "", STOP, -1, nil
   240  	}
   241  	b, _ := p.reader.Peek(1)
   242  	if len(b) < 1 || b[0] == JSON_RBRACE[0] || b[0] == JSON_RBRACKET[0] {
   243  		return "", STOP, -1, nil
   244  	}
   245  	fieldId, err := p.ReadI16()
   246  	if err != nil {
   247  		return "", STOP, fieldId, err
   248  	}
   249  	if _, err = p.ParseObjectStart(); err != nil {
   250  		return "", STOP, fieldId, err
   251  	}
   252  	sType, err := p.ReadString()
   253  	fType := p.StringToTypeId(sType)
   254  	return "", fType, fieldId, err
   255  }
   256  
   257  func (p *TJSONProtocol) ReadFieldEnd() error {
   258  	return p.ParseObjectEnd()
   259  }
   260  
   261  func (p *TJSONProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, e error) {
   262  	if isNull, e := p.ParseListBegin(); isNull || e != nil {
   263  		return VOID, VOID, 0, e
   264  	}
   265  
   266  	// read keyType
   267  	sKeyType, e := p.ReadString()
   268  	keyType = p.StringToTypeId(sKeyType)
   269  	if e != nil {
   270  		return keyType, valueType, size, e
   271  	}
   272  
   273  	// read valueType
   274  	sValueType, e := p.ReadString()
   275  	valueType = p.StringToTypeId(sValueType)
   276  	if e != nil {
   277  		return keyType, valueType, size, e
   278  	}
   279  
   280  	// read size
   281  	iSize, err := p.ReadI64()
   282  	size = int(iSize)
   283  	return keyType, valueType, size, err
   284  }
   285  
   286  func (p *TJSONProtocol) ReadMapEnd() error {
   287  	return p.ParseListEnd()
   288  }
   289  
   290  func (p *TJSONProtocol) ReadListBegin() (elemType TType, size int, e error) {
   291  	return p.ParseElemListBegin()
   292  }
   293  
   294  func (p *TJSONProtocol) ReadListEnd() error {
   295  	return p.ParseListEnd()
   296  }
   297  
   298  func (p *TJSONProtocol) ReadSetBegin() (elemType TType, size int, e error) {
   299  	return p.ParseElemListBegin()
   300  }
   301  
   302  func (p *TJSONProtocol) ReadSetEnd() error {
   303  	return p.ParseListEnd()
   304  }
   305  
   306  func (p *TJSONProtocol) ReadBool() (bool, error) {
   307  	var value bool
   308  	if err := p.ParsePreValue(); err != nil {
   309  		return value, err
   310  	}
   311  	b, _ := p.reader.Peek(len(JSON_FALSE))
   312  	if len(b) > 0 {
   313  		switch b[0] {
   314  		case JSON_TRUE[0]:
   315  			if string(b[0:len(JSON_TRUE)]) == string(JSON_TRUE) {
   316  				p.reader.Read(b[0:len(JSON_TRUE)])
   317  				value = true
   318  			} else {
   319  				e := fmt.Errorf("Expected \"true\" but found: %s", string(b))
   320  				return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
   321  			}
   322  			break
   323  		case JSON_FALSE[0]:
   324  			if string(b[0:len(JSON_FALSE)]) == string(JSON_FALSE) {
   325  				p.reader.Read(b[0:len(JSON_FALSE)])
   326  				value = false
   327  			} else {
   328  				e := fmt.Errorf("Expected \"false\" but found: %s", string(b))
   329  				return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
   330  			}
   331  			break
   332  		case JSON_NULL[0]:
   333  			if string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
   334  				p.reader.Read(b[0:len(JSON_NULL)])
   335  				value = false
   336  			} else {
   337  				e := fmt.Errorf("Expected \"null\" but found: %s", string(b))
   338  				return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
   339  			}
   340  		default:
   341  			e := fmt.Errorf("Expected \"true\", \"false\", or \"null\" but found: %s", string(b))
   342  			return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
   343  		}
   344  	}
   345  	return value, p.ParsePostValue()
   346  }
   347  
   348  func (p *TJSONProtocol) ReadByte() (byte, error) {
   349  	v, err := p.ReadI64()
   350  	return byte(v), err
   351  }
   352  
   353  func (p *TJSONProtocol) ReadI16() (int16, error) {
   354  	v, err := p.ReadI64()
   355  	return int16(v), err
   356  }
   357  
   358  func (p *TJSONProtocol) ReadI32() (int32, error) {
   359  	v, err := p.ReadI64()
   360  	return int32(v), err
   361  }
   362  
   363  func (p *TJSONProtocol) ReadI64() (int64, error) {
   364  	v, _, err := p.ParseI64()
   365  	return v, err
   366  }
   367  
   368  func (p *TJSONProtocol) ReadDouble() (float64, error) {
   369  	v, _, err := p.ParseF64()
   370  	return v, err
   371  }
   372  
   373  func (p *TJSONProtocol) ReadString() (string, error) {
   374  	var v string
   375  	if err := p.ParsePreValue(); err != nil {
   376  		return v, err
   377  	}
   378  	b, _ := p.reader.Peek(len(JSON_NULL))
   379  	if len(b) > 0 && b[0] == JSON_QUOTE {
   380  		p.reader.ReadByte()
   381  		value, err := p.ParseStringBody()
   382  		v = value
   383  		if err != nil {
   384  			return v, err
   385  		}
   386  	} else if len(b) >= len(JSON_NULL) && string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
   387  		_, err := p.reader.Read(b[0:len(JSON_NULL)])
   388  		if err != nil {
   389  			return v, NewTProtocolException(err)
   390  		}
   391  	} else {
   392  		e := fmt.Errorf("Expected a JSON string, found %s", string(b))
   393  		return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
   394  	}
   395  	return v, p.ParsePostValue()
   396  }
   397  
   398  func (p *TJSONProtocol) ReadBinary() ([]byte, error) {
   399  	var v []byte
   400  	if err := p.ParsePreValue(); err != nil {
   401  		return nil, err
   402  	}
   403  	b, _ := p.reader.Peek(len(JSON_NULL))
   404  	if len(b) > 0 && b[0] == JSON_QUOTE {
   405  		p.reader.ReadByte()
   406  		value, err := p.ParseBase64EncodedBody()
   407  		v = value
   408  		if err != nil {
   409  			return v, err
   410  		}
   411  	} else if len(b) >= len(JSON_NULL) && string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
   412  		_, err := p.reader.Read(b[0:len(JSON_NULL)])
   413  		if err != nil {
   414  			return v, NewTProtocolException(err)
   415  		}
   416  	} else {
   417  		e := fmt.Errorf("Expected a JSON string, found %s", string(b))
   418  		return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
   419  	}
   420  	return v, p.ParsePostValue()
   421  }
   422  
   423  func (p *TJSONProtocol) Flush() (err error) {
   424  	return NewTProtocolException(p.writer.Flush())
   425  }
   426  
   427  func (p *TJSONProtocol) Skip(fieldType TType) (err error) {
   428  	return SkipDefaultDepth(p, fieldType)
   429  }
   430  
   431  func (p *TJSONProtocol) Transport() TTransport {
   432  	return p.trans
   433  }
   434  
   435  func (p *TJSONProtocol) OutputElemListBegin(elemType TType, size int) error {
   436  	if e := p.OutputListBegin(); e != nil {
   437  		return e
   438  	}
   439  	if e := p.WriteString(p.TypeIdToString(elemType)); e != nil {
   440  		return e
   441  	}
   442  	if e := p.WriteI64(int64(size)); e != nil {
   443  		return e
   444  	}
   445  	return nil
   446  }
   447  
   448  
   449  func (p *TJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) {
   450  	if isNull, e := p.ParseListBegin(); isNull || e != nil {
   451  		return VOID, 0, e
   452  	}
   453  	sElemType, err := p.ReadString()
   454  	elemType = p.StringToTypeId(sElemType)
   455  	if err != nil {
   456  		return elemType, size, err
   457  	}
   458  	nSize, err2 := p.ReadI64()
   459  	size = int(nSize)
   460  	return elemType, size, err2
   461  }
   462  
   463  func (p *TJSONProtocol) readElemListBegin() (elemType TType, size int, e error) {
   464  	if isNull, e := p.ParseListBegin(); isNull || e != nil {
   465  		return VOID, 0, e
   466  	}
   467  	sElemType, err := p.ReadString()
   468  	elemType = p.StringToTypeId(sElemType)
   469  	if err != nil {
   470  		return elemType, size, err
   471  	}
   472  	nSize, err2 := p.ReadI64()
   473  	size = int(nSize)
   474  	return elemType, size, err2
   475  }
   476  
   477  func (p *TJSONProtocol) writeElemListBegin(elemType TType, size int) error {
   478  	if e := p.OutputListBegin(); e != nil {
   479  		return e
   480  	}
   481  	if e := p.OutputString(p.TypeIdToString(elemType)); e != nil {
   482  		return e
   483  	}
   484  	if e := p.OutputI64(int64(size)); e != nil {
   485  		return e
   486  	}
   487  	return nil
   488  }
   489  
   490  func (p *TJSONProtocol) TypeIdToString(fieldType TType) string {
   491  	switch byte(fieldType) {
   492  	case STOP:
   493  		return "stp"
   494  	case VOID:
   495  		return "v"
   496  	case BOOL:
   497  		return "tf"
   498  	case BYTE:
   499  		return "i8"
   500  	case DOUBLE:
   501  		return "dbl"
   502  	case I16:
   503  		return "i16"
   504  	case I32:
   505  		return "i32"
   506  	case I64:
   507  		return "i64"
   508  	case STRING:
   509  		return "str"
   510  	case STRUCT:
   511  		return "rec"
   512  	case MAP:
   513  		return "map"
   514  	case SET:
   515  		return "set"
   516  	case LIST:
   517  		return "lst"
   518  	case UTF16:
   519  		return "str"
   520  	}
   521  	return ""
   522  }
   523  
   524  func (p *TJSONProtocol) StringToTypeId(fieldType string) TType {
   525  	switch fieldType {
   526  	case "stp":
   527  		return TType(STOP)
   528  	case "v":
   529  		return TType(VOID)
   530  	case "tf":
   531  		return TType(BOOL)
   532  	case "i8":
   533  		return TType(BYTE)
   534  	case "dbl":
   535  		return TType(DOUBLE)
   536  	case "16":
   537  		return TType(I16)
   538  	case "i32":
   539  		return TType(I32)
   540  	case "i64":
   541  		return TType(I64)
   542  	case "str":
   543  		return TType(STRING)
   544  	case "rec":
   545  		return TType(STRUCT)
   546  	case "map":
   547  		return TType(MAP)
   548  	case "set":
   549  		return TType(SET)
   550  	case "lst":
   551  		return TType(LIST)
   552  	case "u16":
   553  		return TType(UTF16)
   554  	}
   555  	return TType(STOP)
   556  }