blob: d1a8154532dbad535e1a759cb296be5baa9e4472 [file] [log] [blame]
khenaidooc6c7bda2020-06-17 17:20:18 -04001/*
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
20package thrift
21
22import (
23 "bufio"
24 "bytes"
khenaidood948f772021-08-11 17:49:24 -040025 "context"
khenaidooc6c7bda2020-06-17 17:20:18 -040026 "encoding/base64"
27 "encoding/json"
khenaidood948f772021-08-11 17:49:24 -040028 "errors"
khenaidooc6c7bda2020-06-17 17:20:18 -040029 "fmt"
30 "io"
31 "math"
32 "strconv"
33)
34
35type _ParseContext int
36
37const (
khenaidood948f772021-08-11 17:49:24 -040038 _CONTEXT_INVALID _ParseContext = iota
39 _CONTEXT_IN_TOPLEVEL // 1
40 _CONTEXT_IN_LIST_FIRST // 2
41 _CONTEXT_IN_LIST // 3
42 _CONTEXT_IN_OBJECT_FIRST // 4
43 _CONTEXT_IN_OBJECT_NEXT_KEY // 5
44 _CONTEXT_IN_OBJECT_NEXT_VALUE // 6
khenaidooc6c7bda2020-06-17 17:20:18 -040045)
46
47func (p _ParseContext) String() string {
48 switch p {
49 case _CONTEXT_IN_TOPLEVEL:
50 return "TOPLEVEL"
51 case _CONTEXT_IN_LIST_FIRST:
52 return "LIST-FIRST"
53 case _CONTEXT_IN_LIST:
54 return "LIST"
55 case _CONTEXT_IN_OBJECT_FIRST:
56 return "OBJECT-FIRST"
57 case _CONTEXT_IN_OBJECT_NEXT_KEY:
58 return "OBJECT-NEXT-KEY"
59 case _CONTEXT_IN_OBJECT_NEXT_VALUE:
60 return "OBJECT-NEXT-VALUE"
61 }
62 return "UNKNOWN-PARSE-CONTEXT"
63}
64
khenaidood948f772021-08-11 17:49:24 -040065type jsonContextStack []_ParseContext
66
67func (s *jsonContextStack) push(v _ParseContext) {
68 *s = append(*s, v)
69}
70
71func (s jsonContextStack) peek() (v _ParseContext, ok bool) {
72 l := len(s)
73 if l <= 0 {
74 return
75 }
76 return s[l-1], true
77}
78
79func (s *jsonContextStack) pop() (v _ParseContext, ok bool) {
80 l := len(*s)
81 if l <= 0 {
82 return
83 }
84 v = (*s)[l-1]
85 *s = (*s)[0 : l-1]
86 return v, true
87}
88
89var errEmptyJSONContextStack = NewTProtocolExceptionWithType(INVALID_DATA, errors.New("Unexpected empty json protocol context stack"))
90
91// Simple JSON protocol implementation for thrift.
khenaidooc6c7bda2020-06-17 17:20:18 -040092//
93// This protocol produces/consumes a simple output format
94// suitable for parsing by scripting languages. It should not be
95// confused with the full-featured TJSONProtocol.
96//
97type TSimpleJSONProtocol struct {
98 trans TTransport
99
khenaidood948f772021-08-11 17:49:24 -0400100 parseContextStack jsonContextStack
101 dumpContext jsonContextStack
khenaidooc6c7bda2020-06-17 17:20:18 -0400102
103 writer *bufio.Writer
104 reader *bufio.Reader
105}
106
107// Constructor
108func NewTSimpleJSONProtocol(t TTransport) *TSimpleJSONProtocol {
109 v := &TSimpleJSONProtocol{trans: t,
110 writer: bufio.NewWriter(t),
111 reader: bufio.NewReader(t),
112 }
khenaidood948f772021-08-11 17:49:24 -0400113 v.parseContextStack.push(_CONTEXT_IN_TOPLEVEL)
114 v.dumpContext.push(_CONTEXT_IN_TOPLEVEL)
khenaidooc6c7bda2020-06-17 17:20:18 -0400115 return v
116}
117
118// Factory
119type TSimpleJSONProtocolFactory struct{}
120
121func (p *TSimpleJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol {
122 return NewTSimpleJSONProtocol(trans)
123}
124
125func NewTSimpleJSONProtocolFactory() *TSimpleJSONProtocolFactory {
126 return &TSimpleJSONProtocolFactory{}
127}
128
129var (
130 JSON_COMMA []byte
131 JSON_COLON []byte
132 JSON_LBRACE []byte
133 JSON_RBRACE []byte
134 JSON_LBRACKET []byte
135 JSON_RBRACKET []byte
136 JSON_QUOTE byte
137 JSON_QUOTE_BYTES []byte
138 JSON_NULL []byte
139 JSON_TRUE []byte
140 JSON_FALSE []byte
141 JSON_INFINITY string
142 JSON_NEGATIVE_INFINITY string
143 JSON_NAN string
144 JSON_INFINITY_BYTES []byte
145 JSON_NEGATIVE_INFINITY_BYTES []byte
146 JSON_NAN_BYTES []byte
147 json_nonbase_map_elem_bytes []byte
148)
149
150func init() {
151 JSON_COMMA = []byte{','}
152 JSON_COLON = []byte{':'}
153 JSON_LBRACE = []byte{'{'}
154 JSON_RBRACE = []byte{'}'}
155 JSON_LBRACKET = []byte{'['}
156 JSON_RBRACKET = []byte{']'}
157 JSON_QUOTE = '"'
158 JSON_QUOTE_BYTES = []byte{'"'}
159 JSON_NULL = []byte{'n', 'u', 'l', 'l'}
160 JSON_TRUE = []byte{'t', 'r', 'u', 'e'}
161 JSON_FALSE = []byte{'f', 'a', 'l', 's', 'e'}
162 JSON_INFINITY = "Infinity"
163 JSON_NEGATIVE_INFINITY = "-Infinity"
164 JSON_NAN = "NaN"
165 JSON_INFINITY_BYTES = []byte{'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'}
166 JSON_NEGATIVE_INFINITY_BYTES = []byte{'-', 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'}
167 JSON_NAN_BYTES = []byte{'N', 'a', 'N'}
168 json_nonbase_map_elem_bytes = []byte{']', ',', '['}
169}
170
171func jsonQuote(s string) string {
172 b, _ := json.Marshal(s)
173 s1 := string(b)
174 return s1
175}
176
177func jsonUnquote(s string) (string, bool) {
178 s1 := new(string)
179 err := json.Unmarshal([]byte(s), s1)
180 return *s1, err == nil
181}
182
183func mismatch(expected, actual string) error {
184 return fmt.Errorf("Expected '%s' but found '%s' while parsing JSON.", expected, actual)
185}
186
khenaidood948f772021-08-11 17:49:24 -0400187func (p *TSimpleJSONProtocol) WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqId int32) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400188 p.resetContextStack() // THRIFT-3735
189 if e := p.OutputListBegin(); e != nil {
190 return e
191 }
khenaidood948f772021-08-11 17:49:24 -0400192 if e := p.WriteString(ctx, name); e != nil {
khenaidooc6c7bda2020-06-17 17:20:18 -0400193 return e
194 }
khenaidood948f772021-08-11 17:49:24 -0400195 if e := p.WriteByte(ctx, int8(typeId)); e != nil {
khenaidooc6c7bda2020-06-17 17:20:18 -0400196 return e
197 }
khenaidood948f772021-08-11 17:49:24 -0400198 if e := p.WriteI32(ctx, seqId); e != nil {
khenaidooc6c7bda2020-06-17 17:20:18 -0400199 return e
200 }
201 return nil
202}
203
khenaidood948f772021-08-11 17:49:24 -0400204func (p *TSimpleJSONProtocol) WriteMessageEnd(ctx context.Context) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400205 return p.OutputListEnd()
206}
207
khenaidood948f772021-08-11 17:49:24 -0400208func (p *TSimpleJSONProtocol) WriteStructBegin(ctx context.Context, name string) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400209 if e := p.OutputObjectBegin(); e != nil {
210 return e
211 }
212 return nil
213}
214
khenaidood948f772021-08-11 17:49:24 -0400215func (p *TSimpleJSONProtocol) WriteStructEnd(ctx context.Context) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400216 return p.OutputObjectEnd()
217}
218
khenaidood948f772021-08-11 17:49:24 -0400219func (p *TSimpleJSONProtocol) WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error {
220 if e := p.WriteString(ctx, name); e != nil {
khenaidooc6c7bda2020-06-17 17:20:18 -0400221 return e
222 }
223 return nil
224}
225
khenaidood948f772021-08-11 17:49:24 -0400226func (p *TSimpleJSONProtocol) WriteFieldEnd(ctx context.Context) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400227 return nil
228}
229
khenaidood948f772021-08-11 17:49:24 -0400230func (p *TSimpleJSONProtocol) WriteFieldStop(ctx context.Context) error { return nil }
khenaidooc6c7bda2020-06-17 17:20:18 -0400231
khenaidood948f772021-08-11 17:49:24 -0400232func (p *TSimpleJSONProtocol) WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400233 if e := p.OutputListBegin(); e != nil {
234 return e
235 }
khenaidood948f772021-08-11 17:49:24 -0400236 if e := p.WriteByte(ctx, int8(keyType)); e != nil {
khenaidooc6c7bda2020-06-17 17:20:18 -0400237 return e
238 }
khenaidood948f772021-08-11 17:49:24 -0400239 if e := p.WriteByte(ctx, int8(valueType)); e != nil {
khenaidooc6c7bda2020-06-17 17:20:18 -0400240 return e
241 }
khenaidood948f772021-08-11 17:49:24 -0400242 return p.WriteI32(ctx, int32(size))
khenaidooc6c7bda2020-06-17 17:20:18 -0400243}
244
khenaidood948f772021-08-11 17:49:24 -0400245func (p *TSimpleJSONProtocol) WriteMapEnd(ctx context.Context) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400246 return p.OutputListEnd()
247}
248
khenaidood948f772021-08-11 17:49:24 -0400249func (p *TSimpleJSONProtocol) WriteListBegin(ctx context.Context, elemType TType, size int) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400250 return p.OutputElemListBegin(elemType, size)
251}
252
khenaidood948f772021-08-11 17:49:24 -0400253func (p *TSimpleJSONProtocol) WriteListEnd(ctx context.Context) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400254 return p.OutputListEnd()
255}
256
khenaidood948f772021-08-11 17:49:24 -0400257func (p *TSimpleJSONProtocol) WriteSetBegin(ctx context.Context, elemType TType, size int) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400258 return p.OutputElemListBegin(elemType, size)
259}
260
khenaidood948f772021-08-11 17:49:24 -0400261func (p *TSimpleJSONProtocol) WriteSetEnd(ctx context.Context) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400262 return p.OutputListEnd()
263}
264
khenaidood948f772021-08-11 17:49:24 -0400265func (p *TSimpleJSONProtocol) WriteBool(ctx context.Context, b bool) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400266 return p.OutputBool(b)
267}
268
khenaidood948f772021-08-11 17:49:24 -0400269func (p *TSimpleJSONProtocol) WriteByte(ctx context.Context, b int8) error {
270 return p.WriteI32(ctx, int32(b))
khenaidooc6c7bda2020-06-17 17:20:18 -0400271}
272
khenaidood948f772021-08-11 17:49:24 -0400273func (p *TSimpleJSONProtocol) WriteI16(ctx context.Context, v int16) error {
274 return p.WriteI32(ctx, int32(v))
khenaidooc6c7bda2020-06-17 17:20:18 -0400275}
276
khenaidood948f772021-08-11 17:49:24 -0400277func (p *TSimpleJSONProtocol) WriteI32(ctx context.Context, v int32) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400278 return p.OutputI64(int64(v))
279}
280
khenaidood948f772021-08-11 17:49:24 -0400281func (p *TSimpleJSONProtocol) WriteI64(ctx context.Context, v int64) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400282 return p.OutputI64(int64(v))
283}
284
khenaidood948f772021-08-11 17:49:24 -0400285func (p *TSimpleJSONProtocol) WriteDouble(ctx context.Context, v float64) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400286 return p.OutputF64(v)
287}
288
khenaidood948f772021-08-11 17:49:24 -0400289func (p *TSimpleJSONProtocol) WriteString(ctx context.Context, v string) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400290 return p.OutputString(v)
291}
292
khenaidood948f772021-08-11 17:49:24 -0400293func (p *TSimpleJSONProtocol) WriteBinary(ctx context.Context, v []byte) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400294 // JSON library only takes in a string,
295 // not an arbitrary byte array, to ensure bytes are transmitted
296 // efficiently we must convert this into a valid JSON string
297 // therefore we use base64 encoding to avoid excessive escaping/quoting
298 if e := p.OutputPreValue(); e != nil {
299 return e
300 }
301 if _, e := p.write(JSON_QUOTE_BYTES); e != nil {
302 return NewTProtocolException(e)
303 }
304 writer := base64.NewEncoder(base64.StdEncoding, p.writer)
305 if _, e := writer.Write(v); e != nil {
306 p.writer.Reset(p.trans) // THRIFT-3735
307 return NewTProtocolException(e)
308 }
309 if e := writer.Close(); e != nil {
310 return NewTProtocolException(e)
311 }
312 if _, e := p.write(JSON_QUOTE_BYTES); e != nil {
313 return NewTProtocolException(e)
314 }
315 return p.OutputPostValue()
316}
317
318// Reading methods.
khenaidood948f772021-08-11 17:49:24 -0400319func (p *TSimpleJSONProtocol) ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqId int32, err error) {
khenaidooc6c7bda2020-06-17 17:20:18 -0400320 p.resetContextStack() // THRIFT-3735
321 if isNull, err := p.ParseListBegin(); isNull || err != nil {
322 return name, typeId, seqId, err
323 }
khenaidood948f772021-08-11 17:49:24 -0400324 if name, err = p.ReadString(ctx); err != nil {
khenaidooc6c7bda2020-06-17 17:20:18 -0400325 return name, typeId, seqId, err
326 }
khenaidood948f772021-08-11 17:49:24 -0400327 bTypeId, err := p.ReadByte(ctx)
khenaidooc6c7bda2020-06-17 17:20:18 -0400328 typeId = TMessageType(bTypeId)
329 if err != nil {
330 return name, typeId, seqId, err
331 }
khenaidood948f772021-08-11 17:49:24 -0400332 if seqId, err = p.ReadI32(ctx); err != nil {
khenaidooc6c7bda2020-06-17 17:20:18 -0400333 return name, typeId, seqId, err
334 }
335 return name, typeId, seqId, nil
336}
337
khenaidood948f772021-08-11 17:49:24 -0400338func (p *TSimpleJSONProtocol) ReadMessageEnd(ctx context.Context) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400339 return p.ParseListEnd()
340}
341
khenaidood948f772021-08-11 17:49:24 -0400342func (p *TSimpleJSONProtocol) ReadStructBegin(ctx context.Context) (name string, err error) {
khenaidooc6c7bda2020-06-17 17:20:18 -0400343 _, err = p.ParseObjectStart()
344 return "", err
345}
346
khenaidood948f772021-08-11 17:49:24 -0400347func (p *TSimpleJSONProtocol) ReadStructEnd(ctx context.Context) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400348 return p.ParseObjectEnd()
349}
350
khenaidood948f772021-08-11 17:49:24 -0400351func (p *TSimpleJSONProtocol) ReadFieldBegin(ctx context.Context) (string, TType, int16, error) {
khenaidooc6c7bda2020-06-17 17:20:18 -0400352 if err := p.ParsePreValue(); err != nil {
353 return "", STOP, 0, err
354 }
355 b, _ := p.reader.Peek(1)
356 if len(b) > 0 {
357 switch b[0] {
358 case JSON_RBRACE[0]:
359 return "", STOP, 0, nil
360 case JSON_QUOTE:
361 p.reader.ReadByte()
362 name, err := p.ParseStringBody()
363 // simplejson is not meant to be read back into thrift
364 // - see http://wiki.apache.org/thrift/ThriftUsageJava
365 // - use JSON instead
366 if err != nil {
367 return name, STOP, 0, err
368 }
369 return name, STOP, -1, p.ParsePostValue()
khenaidooc6c7bda2020-06-17 17:20:18 -0400370 }
371 e := fmt.Errorf("Expected \"}\" or '\"', but found: '%s'", string(b))
372 return "", STOP, 0, NewTProtocolExceptionWithType(INVALID_DATA, e)
373 }
374 return "", STOP, 0, NewTProtocolException(io.EOF)
375}
376
khenaidood948f772021-08-11 17:49:24 -0400377func (p *TSimpleJSONProtocol) ReadFieldEnd(ctx context.Context) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400378 return nil
khenaidooc6c7bda2020-06-17 17:20:18 -0400379}
380
khenaidood948f772021-08-11 17:49:24 -0400381func (p *TSimpleJSONProtocol) ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, e error) {
khenaidooc6c7bda2020-06-17 17:20:18 -0400382 if isNull, e := p.ParseListBegin(); isNull || e != nil {
383 return VOID, VOID, 0, e
384 }
385
386 // read keyType
khenaidood948f772021-08-11 17:49:24 -0400387 bKeyType, e := p.ReadByte(ctx)
khenaidooc6c7bda2020-06-17 17:20:18 -0400388 keyType = TType(bKeyType)
389 if e != nil {
390 return keyType, valueType, size, e
391 }
392
393 // read valueType
khenaidood948f772021-08-11 17:49:24 -0400394 bValueType, e := p.ReadByte(ctx)
khenaidooc6c7bda2020-06-17 17:20:18 -0400395 valueType = TType(bValueType)
396 if e != nil {
397 return keyType, valueType, size, e
398 }
399
400 // read size
khenaidood948f772021-08-11 17:49:24 -0400401 iSize, err := p.ReadI64(ctx)
khenaidooc6c7bda2020-06-17 17:20:18 -0400402 size = int(iSize)
403 return keyType, valueType, size, err
404}
405
khenaidood948f772021-08-11 17:49:24 -0400406func (p *TSimpleJSONProtocol) ReadMapEnd(ctx context.Context) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400407 return p.ParseListEnd()
408}
409
khenaidood948f772021-08-11 17:49:24 -0400410func (p *TSimpleJSONProtocol) ReadListBegin(ctx context.Context) (elemType TType, size int, e error) {
khenaidooc6c7bda2020-06-17 17:20:18 -0400411 return p.ParseElemListBegin()
412}
413
khenaidood948f772021-08-11 17:49:24 -0400414func (p *TSimpleJSONProtocol) ReadListEnd(ctx context.Context) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400415 return p.ParseListEnd()
416}
417
khenaidood948f772021-08-11 17:49:24 -0400418func (p *TSimpleJSONProtocol) ReadSetBegin(ctx context.Context) (elemType TType, size int, e error) {
khenaidooc6c7bda2020-06-17 17:20:18 -0400419 return p.ParseElemListBegin()
420}
421
khenaidood948f772021-08-11 17:49:24 -0400422func (p *TSimpleJSONProtocol) ReadSetEnd(ctx context.Context) error {
khenaidooc6c7bda2020-06-17 17:20:18 -0400423 return p.ParseListEnd()
424}
425
khenaidood948f772021-08-11 17:49:24 -0400426func (p *TSimpleJSONProtocol) ReadBool(ctx context.Context) (bool, error) {
khenaidooc6c7bda2020-06-17 17:20:18 -0400427 var value bool
428
429 if err := p.ParsePreValue(); err != nil {
430 return value, err
431 }
432 f, _ := p.reader.Peek(1)
433 if len(f) > 0 {
434 switch f[0] {
435 case JSON_TRUE[0]:
436 b := make([]byte, len(JSON_TRUE))
437 _, err := p.reader.Read(b)
438 if err != nil {
439 return false, NewTProtocolException(err)
440 }
441 if string(b) == string(JSON_TRUE) {
442 value = true
443 } else {
444 e := fmt.Errorf("Expected \"true\" but found: %s", string(b))
445 return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
446 }
447 break
448 case JSON_FALSE[0]:
449 b := make([]byte, len(JSON_FALSE))
450 _, err := p.reader.Read(b)
451 if err != nil {
452 return false, NewTProtocolException(err)
453 }
454 if string(b) == string(JSON_FALSE) {
455 value = false
456 } else {
457 e := fmt.Errorf("Expected \"false\" but found: %s", string(b))
458 return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
459 }
460 break
461 case JSON_NULL[0]:
462 b := make([]byte, len(JSON_NULL))
463 _, err := p.reader.Read(b)
464 if err != nil {
465 return false, NewTProtocolException(err)
466 }
467 if string(b) == string(JSON_NULL) {
468 value = false
469 } else {
470 e := fmt.Errorf("Expected \"null\" but found: %s", string(b))
471 return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
472 }
473 default:
474 e := fmt.Errorf("Expected \"true\", \"false\", or \"null\" but found: %s", string(f))
475 return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
476 }
477 }
478 return value, p.ParsePostValue()
479}
480
khenaidood948f772021-08-11 17:49:24 -0400481func (p *TSimpleJSONProtocol) ReadByte(ctx context.Context) (int8, error) {
482 v, err := p.ReadI64(ctx)
khenaidooc6c7bda2020-06-17 17:20:18 -0400483 return int8(v), err
484}
485
khenaidood948f772021-08-11 17:49:24 -0400486func (p *TSimpleJSONProtocol) ReadI16(ctx context.Context) (int16, error) {
487 v, err := p.ReadI64(ctx)
khenaidooc6c7bda2020-06-17 17:20:18 -0400488 return int16(v), err
489}
490
khenaidood948f772021-08-11 17:49:24 -0400491func (p *TSimpleJSONProtocol) ReadI32(ctx context.Context) (int32, error) {
492 v, err := p.ReadI64(ctx)
khenaidooc6c7bda2020-06-17 17:20:18 -0400493 return int32(v), err
494}
495
khenaidood948f772021-08-11 17:49:24 -0400496func (p *TSimpleJSONProtocol) ReadI64(ctx context.Context) (int64, error) {
khenaidooc6c7bda2020-06-17 17:20:18 -0400497 v, _, err := p.ParseI64()
498 return v, err
499}
500
khenaidood948f772021-08-11 17:49:24 -0400501func (p *TSimpleJSONProtocol) ReadDouble(ctx context.Context) (float64, error) {
khenaidooc6c7bda2020-06-17 17:20:18 -0400502 v, _, err := p.ParseF64()
503 return v, err
504}
505
khenaidood948f772021-08-11 17:49:24 -0400506func (p *TSimpleJSONProtocol) ReadString(ctx context.Context) (string, error) {
khenaidooc6c7bda2020-06-17 17:20:18 -0400507 var v string
508 if err := p.ParsePreValue(); err != nil {
509 return v, err
510 }
511 f, _ := p.reader.Peek(1)
512 if len(f) > 0 && f[0] == JSON_QUOTE {
513 p.reader.ReadByte()
514 value, err := p.ParseStringBody()
515 v = value
516 if err != nil {
517 return v, err
518 }
519 } else if len(f) > 0 && f[0] == JSON_NULL[0] {
520 b := make([]byte, len(JSON_NULL))
521 _, err := p.reader.Read(b)
522 if err != nil {
523 return v, NewTProtocolException(err)
524 }
525 if string(b) != string(JSON_NULL) {
526 e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b))
527 return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
528 }
529 } else {
530 e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f))
531 return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
532 }
533 return v, p.ParsePostValue()
534}
535
khenaidood948f772021-08-11 17:49:24 -0400536func (p *TSimpleJSONProtocol) ReadBinary(ctx context.Context) ([]byte, error) {
khenaidooc6c7bda2020-06-17 17:20:18 -0400537 var v []byte
538 if err := p.ParsePreValue(); err != nil {
539 return nil, err
540 }
541 f, _ := p.reader.Peek(1)
542 if len(f) > 0 && f[0] == JSON_QUOTE {
543 p.reader.ReadByte()
544 value, err := p.ParseBase64EncodedBody()
545 v = value
546 if err != nil {
547 return v, err
548 }
549 } else if len(f) > 0 && f[0] == JSON_NULL[0] {
550 b := make([]byte, len(JSON_NULL))
551 _, err := p.reader.Read(b)
552 if err != nil {
553 return v, NewTProtocolException(err)
554 }
555 if string(b) != string(JSON_NULL) {
556 e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b))
557 return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
558 }
559 } else {
560 e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f))
561 return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
562 }
563
564 return v, p.ParsePostValue()
565}
566
khenaidood948f772021-08-11 17:49:24 -0400567func (p *TSimpleJSONProtocol) Flush(ctx context.Context) (err error) {
khenaidooc6c7bda2020-06-17 17:20:18 -0400568 return NewTProtocolException(p.writer.Flush())
569}
570
khenaidood948f772021-08-11 17:49:24 -0400571func (p *TSimpleJSONProtocol) Skip(ctx context.Context, fieldType TType) (err error) {
572 return SkipDefaultDepth(ctx, p, fieldType)
khenaidooc6c7bda2020-06-17 17:20:18 -0400573}
574
575func (p *TSimpleJSONProtocol) Transport() TTransport {
576 return p.trans
577}
578
579func (p *TSimpleJSONProtocol) OutputPreValue() error {
khenaidood948f772021-08-11 17:49:24 -0400580 cxt, ok := p.dumpContext.peek()
581 if !ok {
582 return errEmptyJSONContextStack
583 }
khenaidooc6c7bda2020-06-17 17:20:18 -0400584 switch cxt {
585 case _CONTEXT_IN_LIST, _CONTEXT_IN_OBJECT_NEXT_KEY:
586 if _, e := p.write(JSON_COMMA); e != nil {
587 return NewTProtocolException(e)
588 }
khenaidooc6c7bda2020-06-17 17:20:18 -0400589 case _CONTEXT_IN_OBJECT_NEXT_VALUE:
590 if _, e := p.write(JSON_COLON); e != nil {
591 return NewTProtocolException(e)
592 }
khenaidooc6c7bda2020-06-17 17:20:18 -0400593 }
594 return nil
595}
596
597func (p *TSimpleJSONProtocol) OutputPostValue() error {
khenaidood948f772021-08-11 17:49:24 -0400598 cxt, ok := p.dumpContext.peek()
599 if !ok {
600 return errEmptyJSONContextStack
601 }
khenaidooc6c7bda2020-06-17 17:20:18 -0400602 switch cxt {
603 case _CONTEXT_IN_LIST_FIRST:
khenaidood948f772021-08-11 17:49:24 -0400604 p.dumpContext.pop()
605 p.dumpContext.push(_CONTEXT_IN_LIST)
khenaidooc6c7bda2020-06-17 17:20:18 -0400606 case _CONTEXT_IN_OBJECT_FIRST:
khenaidood948f772021-08-11 17:49:24 -0400607 p.dumpContext.pop()
608 p.dumpContext.push(_CONTEXT_IN_OBJECT_NEXT_VALUE)
khenaidooc6c7bda2020-06-17 17:20:18 -0400609 case _CONTEXT_IN_OBJECT_NEXT_KEY:
khenaidood948f772021-08-11 17:49:24 -0400610 p.dumpContext.pop()
611 p.dumpContext.push(_CONTEXT_IN_OBJECT_NEXT_VALUE)
khenaidooc6c7bda2020-06-17 17:20:18 -0400612 case _CONTEXT_IN_OBJECT_NEXT_VALUE:
khenaidood948f772021-08-11 17:49:24 -0400613 p.dumpContext.pop()
614 p.dumpContext.push(_CONTEXT_IN_OBJECT_NEXT_KEY)
khenaidooc6c7bda2020-06-17 17:20:18 -0400615 }
616 return nil
617}
618
619func (p *TSimpleJSONProtocol) OutputBool(value bool) error {
620 if e := p.OutputPreValue(); e != nil {
621 return e
622 }
623 var v string
624 if value {
625 v = string(JSON_TRUE)
626 } else {
627 v = string(JSON_FALSE)
628 }
khenaidood948f772021-08-11 17:49:24 -0400629 cxt, ok := p.dumpContext.peek()
630 if !ok {
631 return errEmptyJSONContextStack
632 }
633 switch cxt {
khenaidooc6c7bda2020-06-17 17:20:18 -0400634 case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
635 v = jsonQuote(v)
khenaidooc6c7bda2020-06-17 17:20:18 -0400636 }
637 if e := p.OutputStringData(v); e != nil {
638 return e
639 }
640 return p.OutputPostValue()
641}
642
643func (p *TSimpleJSONProtocol) OutputNull() error {
644 if e := p.OutputPreValue(); e != nil {
645 return e
646 }
647 if _, e := p.write(JSON_NULL); e != nil {
648 return NewTProtocolException(e)
649 }
650 return p.OutputPostValue()
651}
652
653func (p *TSimpleJSONProtocol) OutputF64(value float64) error {
654 if e := p.OutputPreValue(); e != nil {
655 return e
656 }
657 var v string
658 if math.IsNaN(value) {
659 v = string(JSON_QUOTE) + JSON_NAN + string(JSON_QUOTE)
660 } else if math.IsInf(value, 1) {
661 v = string(JSON_QUOTE) + JSON_INFINITY + string(JSON_QUOTE)
662 } else if math.IsInf(value, -1) {
663 v = string(JSON_QUOTE) + JSON_NEGATIVE_INFINITY + string(JSON_QUOTE)
664 } else {
khenaidood948f772021-08-11 17:49:24 -0400665 cxt, ok := p.dumpContext.peek()
666 if !ok {
667 return errEmptyJSONContextStack
668 }
khenaidooc6c7bda2020-06-17 17:20:18 -0400669 v = strconv.FormatFloat(value, 'g', -1, 64)
khenaidood948f772021-08-11 17:49:24 -0400670 switch cxt {
khenaidooc6c7bda2020-06-17 17:20:18 -0400671 case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
672 v = string(JSON_QUOTE) + v + string(JSON_QUOTE)
khenaidooc6c7bda2020-06-17 17:20:18 -0400673 }
674 }
675 if e := p.OutputStringData(v); e != nil {
676 return e
677 }
678 return p.OutputPostValue()
679}
680
681func (p *TSimpleJSONProtocol) OutputI64(value int64) error {
682 if e := p.OutputPreValue(); e != nil {
683 return e
684 }
khenaidood948f772021-08-11 17:49:24 -0400685 cxt, ok := p.dumpContext.peek()
686 if !ok {
687 return errEmptyJSONContextStack
688 }
khenaidooc6c7bda2020-06-17 17:20:18 -0400689 v := strconv.FormatInt(value, 10)
khenaidood948f772021-08-11 17:49:24 -0400690 switch cxt {
khenaidooc6c7bda2020-06-17 17:20:18 -0400691 case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
692 v = jsonQuote(v)
khenaidooc6c7bda2020-06-17 17:20:18 -0400693 }
694 if e := p.OutputStringData(v); e != nil {
695 return e
696 }
697 return p.OutputPostValue()
698}
699
700func (p *TSimpleJSONProtocol) OutputString(s string) error {
701 if e := p.OutputPreValue(); e != nil {
702 return e
703 }
704 if e := p.OutputStringData(jsonQuote(s)); e != nil {
705 return e
706 }
707 return p.OutputPostValue()
708}
709
710func (p *TSimpleJSONProtocol) OutputStringData(s string) error {
711 _, e := p.write([]byte(s))
712 return NewTProtocolException(e)
713}
714
715func (p *TSimpleJSONProtocol) OutputObjectBegin() error {
716 if e := p.OutputPreValue(); e != nil {
717 return e
718 }
719 if _, e := p.write(JSON_LBRACE); e != nil {
720 return NewTProtocolException(e)
721 }
khenaidood948f772021-08-11 17:49:24 -0400722 p.dumpContext.push(_CONTEXT_IN_OBJECT_FIRST)
khenaidooc6c7bda2020-06-17 17:20:18 -0400723 return nil
724}
725
726func (p *TSimpleJSONProtocol) OutputObjectEnd() error {
727 if _, e := p.write(JSON_RBRACE); e != nil {
728 return NewTProtocolException(e)
729 }
khenaidood948f772021-08-11 17:49:24 -0400730 _, ok := p.dumpContext.pop()
731 if !ok {
732 return errEmptyJSONContextStack
733 }
khenaidooc6c7bda2020-06-17 17:20:18 -0400734 if e := p.OutputPostValue(); e != nil {
735 return e
736 }
737 return nil
738}
739
740func (p *TSimpleJSONProtocol) OutputListBegin() error {
741 if e := p.OutputPreValue(); e != nil {
742 return e
743 }
744 if _, e := p.write(JSON_LBRACKET); e != nil {
745 return NewTProtocolException(e)
746 }
khenaidood948f772021-08-11 17:49:24 -0400747 p.dumpContext.push(_CONTEXT_IN_LIST_FIRST)
khenaidooc6c7bda2020-06-17 17:20:18 -0400748 return nil
749}
750
751func (p *TSimpleJSONProtocol) OutputListEnd() error {
752 if _, e := p.write(JSON_RBRACKET); e != nil {
753 return NewTProtocolException(e)
754 }
khenaidood948f772021-08-11 17:49:24 -0400755 _, ok := p.dumpContext.pop()
756 if !ok {
757 return errEmptyJSONContextStack
758 }
khenaidooc6c7bda2020-06-17 17:20:18 -0400759 if e := p.OutputPostValue(); e != nil {
760 return e
761 }
762 return nil
763}
764
765func (p *TSimpleJSONProtocol) OutputElemListBegin(elemType TType, size int) error {
766 if e := p.OutputListBegin(); e != nil {
767 return e
768 }
khenaidood948f772021-08-11 17:49:24 -0400769 if e := p.OutputI64(int64(elemType)); e != nil {
khenaidooc6c7bda2020-06-17 17:20:18 -0400770 return e
771 }
khenaidood948f772021-08-11 17:49:24 -0400772 if e := p.OutputI64(int64(size)); e != nil {
khenaidooc6c7bda2020-06-17 17:20:18 -0400773 return e
774 }
775 return nil
776}
777
778func (p *TSimpleJSONProtocol) ParsePreValue() error {
779 if e := p.readNonSignificantWhitespace(); e != nil {
780 return NewTProtocolException(e)
781 }
khenaidood948f772021-08-11 17:49:24 -0400782 cxt, ok := p.parseContextStack.peek()
783 if !ok {
784 return errEmptyJSONContextStack
785 }
khenaidooc6c7bda2020-06-17 17:20:18 -0400786 b, _ := p.reader.Peek(1)
787 switch cxt {
788 case _CONTEXT_IN_LIST:
789 if len(b) > 0 {
790 switch b[0] {
791 case JSON_RBRACKET[0]:
792 return nil
793 case JSON_COMMA[0]:
794 p.reader.ReadByte()
795 if e := p.readNonSignificantWhitespace(); e != nil {
796 return NewTProtocolException(e)
797 }
798 return nil
799 default:
800 e := fmt.Errorf("Expected \"]\" or \",\" in list context, but found \"%s\"", string(b))
801 return NewTProtocolExceptionWithType(INVALID_DATA, e)
802 }
803 }
khenaidooc6c7bda2020-06-17 17:20:18 -0400804 case _CONTEXT_IN_OBJECT_NEXT_KEY:
805 if len(b) > 0 {
806 switch b[0] {
807 case JSON_RBRACE[0]:
808 return nil
809 case JSON_COMMA[0]:
810 p.reader.ReadByte()
811 if e := p.readNonSignificantWhitespace(); e != nil {
812 return NewTProtocolException(e)
813 }
814 return nil
815 default:
816 e := fmt.Errorf("Expected \"}\" or \",\" in object context, but found \"%s\"", string(b))
817 return NewTProtocolExceptionWithType(INVALID_DATA, e)
818 }
819 }
khenaidooc6c7bda2020-06-17 17:20:18 -0400820 case _CONTEXT_IN_OBJECT_NEXT_VALUE:
821 if len(b) > 0 {
822 switch b[0] {
823 case JSON_COLON[0]:
824 p.reader.ReadByte()
825 if e := p.readNonSignificantWhitespace(); e != nil {
826 return NewTProtocolException(e)
827 }
828 return nil
829 default:
830 e := fmt.Errorf("Expected \":\" in object context, but found \"%s\"", string(b))
831 return NewTProtocolExceptionWithType(INVALID_DATA, e)
832 }
833 }
khenaidooc6c7bda2020-06-17 17:20:18 -0400834 }
835 return nil
836}
837
838func (p *TSimpleJSONProtocol) ParsePostValue() error {
839 if e := p.readNonSignificantWhitespace(); e != nil {
840 return NewTProtocolException(e)
841 }
khenaidood948f772021-08-11 17:49:24 -0400842 cxt, ok := p.parseContextStack.peek()
843 if !ok {
844 return errEmptyJSONContextStack
845 }
khenaidooc6c7bda2020-06-17 17:20:18 -0400846 switch cxt {
847 case _CONTEXT_IN_LIST_FIRST:
khenaidood948f772021-08-11 17:49:24 -0400848 p.parseContextStack.pop()
849 p.parseContextStack.push(_CONTEXT_IN_LIST)
khenaidooc6c7bda2020-06-17 17:20:18 -0400850 case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
khenaidood948f772021-08-11 17:49:24 -0400851 p.parseContextStack.pop()
852 p.parseContextStack.push(_CONTEXT_IN_OBJECT_NEXT_VALUE)
khenaidooc6c7bda2020-06-17 17:20:18 -0400853 case _CONTEXT_IN_OBJECT_NEXT_VALUE:
khenaidood948f772021-08-11 17:49:24 -0400854 p.parseContextStack.pop()
855 p.parseContextStack.push(_CONTEXT_IN_OBJECT_NEXT_KEY)
khenaidooc6c7bda2020-06-17 17:20:18 -0400856 }
857 return nil
858}
859
860func (p *TSimpleJSONProtocol) readNonSignificantWhitespace() error {
861 for {
862 b, _ := p.reader.Peek(1)
863 if len(b) < 1 {
864 return nil
865 }
866 switch b[0] {
867 case ' ', '\r', '\n', '\t':
868 p.reader.ReadByte()
869 continue
870 default:
871 break
872 }
873 break
874 }
875 return nil
876}
877
878func (p *TSimpleJSONProtocol) ParseStringBody() (string, error) {
879 line, err := p.reader.ReadString(JSON_QUOTE)
880 if err != nil {
881 return "", NewTProtocolException(err)
882 }
883 l := len(line)
884 // count number of escapes to see if we need to keep going
885 i := 1
886 for ; i < l; i++ {
887 if line[l-i-1] != '\\' {
888 break
889 }
890 }
891 if i&0x01 == 1 {
892 v, ok := jsonUnquote(string(JSON_QUOTE) + line)
893 if !ok {
894 return "", NewTProtocolException(err)
895 }
896 return v, nil
897 }
898 s, err := p.ParseQuotedStringBody()
899 if err != nil {
900 return "", NewTProtocolException(err)
901 }
902 str := string(JSON_QUOTE) + line + s
903 v, ok := jsonUnquote(str)
904 if !ok {
905 e := fmt.Errorf("Unable to parse as JSON string %s", str)
906 return "", NewTProtocolExceptionWithType(INVALID_DATA, e)
907 }
908 return v, nil
909}
910
911func (p *TSimpleJSONProtocol) ParseQuotedStringBody() (string, error) {
912 line, err := p.reader.ReadString(JSON_QUOTE)
913 if err != nil {
914 return "", NewTProtocolException(err)
915 }
916 l := len(line)
917 // count number of escapes to see if we need to keep going
918 i := 1
919 for ; i < l; i++ {
920 if line[l-i-1] != '\\' {
921 break
922 }
923 }
924 if i&0x01 == 1 {
925 return line, nil
926 }
927 s, err := p.ParseQuotedStringBody()
928 if err != nil {
929 return "", NewTProtocolException(err)
930 }
931 v := line + s
932 return v, nil
933}
934
935func (p *TSimpleJSONProtocol) ParseBase64EncodedBody() ([]byte, error) {
936 line, err := p.reader.ReadBytes(JSON_QUOTE)
937 if err != nil {
938 return line, NewTProtocolException(err)
939 }
940 line2 := line[0 : len(line)-1]
941 l := len(line2)
942 if (l % 4) != 0 {
943 pad := 4 - (l % 4)
944 fill := [...]byte{'=', '=', '='}
945 line2 = append(line2, fill[:pad]...)
946 l = len(line2)
947 }
948 output := make([]byte, base64.StdEncoding.DecodedLen(l))
949 n, err := base64.StdEncoding.Decode(output, line2)
950 return output[0:n], NewTProtocolException(err)
951}
952
953func (p *TSimpleJSONProtocol) ParseI64() (int64, bool, error) {
954 if err := p.ParsePreValue(); err != nil {
955 return 0, false, err
956 }
957 var value int64
958 var isnull bool
959 if p.safePeekContains(JSON_NULL) {
960 p.reader.Read(make([]byte, len(JSON_NULL)))
961 isnull = true
962 } else {
963 num, err := p.readNumeric()
964 isnull = (num == nil)
965 if !isnull {
966 value = num.Int64()
967 }
968 if err != nil {
969 return value, isnull, err
970 }
971 }
972 return value, isnull, p.ParsePostValue()
973}
974
975func (p *TSimpleJSONProtocol) ParseF64() (float64, bool, error) {
976 if err := p.ParsePreValue(); err != nil {
977 return 0, false, err
978 }
979 var value float64
980 var isnull bool
981 if p.safePeekContains(JSON_NULL) {
982 p.reader.Read(make([]byte, len(JSON_NULL)))
983 isnull = true
984 } else {
985 num, err := p.readNumeric()
986 isnull = (num == nil)
987 if !isnull {
988 value = num.Float64()
989 }
990 if err != nil {
991 return value, isnull, err
992 }
993 }
994 return value, isnull, p.ParsePostValue()
995}
996
997func (p *TSimpleJSONProtocol) ParseObjectStart() (bool, error) {
998 if err := p.ParsePreValue(); err != nil {
999 return false, err
1000 }
1001 var b []byte
1002 b, err := p.reader.Peek(1)
1003 if err != nil {
1004 return false, err
1005 }
1006 if len(b) > 0 && b[0] == JSON_LBRACE[0] {
1007 p.reader.ReadByte()
khenaidood948f772021-08-11 17:49:24 -04001008 p.parseContextStack.push(_CONTEXT_IN_OBJECT_FIRST)
khenaidooc6c7bda2020-06-17 17:20:18 -04001009 return false, nil
1010 } else if p.safePeekContains(JSON_NULL) {
1011 return true, nil
1012 }
1013 e := fmt.Errorf("Expected '{' or null, but found '%s'", string(b))
1014 return false, NewTProtocolExceptionWithType(INVALID_DATA, e)
1015}
1016
1017func (p *TSimpleJSONProtocol) ParseObjectEnd() error {
1018 if isNull, err := p.readIfNull(); isNull || err != nil {
1019 return err
1020 }
khenaidood948f772021-08-11 17:49:24 -04001021 cxt, _ := p.parseContextStack.peek()
khenaidooc6c7bda2020-06-17 17:20:18 -04001022 if (cxt != _CONTEXT_IN_OBJECT_FIRST) && (cxt != _CONTEXT_IN_OBJECT_NEXT_KEY) {
1023 e := fmt.Errorf("Expected to be in the Object Context, but not in Object Context (%d)", cxt)
1024 return NewTProtocolExceptionWithType(INVALID_DATA, e)
1025 }
1026 line, err := p.reader.ReadString(JSON_RBRACE[0])
1027 if err != nil {
1028 return NewTProtocolException(err)
1029 }
1030 for _, char := range line {
1031 switch char {
1032 default:
1033 e := fmt.Errorf("Expecting end of object \"}\", but found: \"%s\"", line)
1034 return NewTProtocolExceptionWithType(INVALID_DATA, e)
1035 case ' ', '\n', '\r', '\t', '}':
1036 break
1037 }
1038 }
khenaidood948f772021-08-11 17:49:24 -04001039 p.parseContextStack.pop()
khenaidooc6c7bda2020-06-17 17:20:18 -04001040 return p.ParsePostValue()
1041}
1042
1043func (p *TSimpleJSONProtocol) ParseListBegin() (isNull bool, err error) {
1044 if e := p.ParsePreValue(); e != nil {
1045 return false, e
1046 }
1047 var b []byte
1048 b, err = p.reader.Peek(1)
1049 if err != nil {
1050 return false, err
1051 }
1052 if len(b) >= 1 && b[0] == JSON_LBRACKET[0] {
khenaidood948f772021-08-11 17:49:24 -04001053 p.parseContextStack.push(_CONTEXT_IN_LIST_FIRST)
khenaidooc6c7bda2020-06-17 17:20:18 -04001054 p.reader.ReadByte()
1055 isNull = false
1056 } else if p.safePeekContains(JSON_NULL) {
1057 isNull = true
1058 } else {
1059 err = fmt.Errorf("Expected \"null\" or \"[\", received %q", b)
1060 }
1061 return isNull, NewTProtocolExceptionWithType(INVALID_DATA, err)
1062}
1063
1064func (p *TSimpleJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) {
1065 if isNull, e := p.ParseListBegin(); isNull || e != nil {
1066 return VOID, 0, e
1067 }
khenaidood948f772021-08-11 17:49:24 -04001068 bElemType, _, err := p.ParseI64()
khenaidooc6c7bda2020-06-17 17:20:18 -04001069 elemType = TType(bElemType)
1070 if err != nil {
1071 return elemType, size, err
1072 }
khenaidood948f772021-08-11 17:49:24 -04001073 nSize, _, err2 := p.ParseI64()
khenaidooc6c7bda2020-06-17 17:20:18 -04001074 size = int(nSize)
1075 return elemType, size, err2
1076}
1077
1078func (p *TSimpleJSONProtocol) ParseListEnd() error {
1079 if isNull, err := p.readIfNull(); isNull || err != nil {
1080 return err
1081 }
khenaidood948f772021-08-11 17:49:24 -04001082 cxt, _ := p.parseContextStack.peek()
khenaidooc6c7bda2020-06-17 17:20:18 -04001083 if cxt != _CONTEXT_IN_LIST {
1084 e := fmt.Errorf("Expected to be in the List Context, but not in List Context (%d)", cxt)
1085 return NewTProtocolExceptionWithType(INVALID_DATA, e)
1086 }
1087 line, err := p.reader.ReadString(JSON_RBRACKET[0])
1088 if err != nil {
1089 return NewTProtocolException(err)
1090 }
1091 for _, char := range line {
1092 switch char {
1093 default:
khenaidood948f772021-08-11 17:49:24 -04001094 e := fmt.Errorf("Expecting end of list \"]\", but found: \"%v\"", line)
khenaidooc6c7bda2020-06-17 17:20:18 -04001095 return NewTProtocolExceptionWithType(INVALID_DATA, e)
1096 case ' ', '\n', '\r', '\t', rune(JSON_RBRACKET[0]):
1097 break
1098 }
1099 }
khenaidood948f772021-08-11 17:49:24 -04001100 p.parseContextStack.pop()
1101 if cxt, ok := p.parseContextStack.peek(); !ok {
1102 return errEmptyJSONContextStack
1103 } else if cxt == _CONTEXT_IN_TOPLEVEL {
khenaidooc6c7bda2020-06-17 17:20:18 -04001104 return nil
1105 }
1106 return p.ParsePostValue()
1107}
1108
1109func (p *TSimpleJSONProtocol) readSingleValue() (interface{}, TType, error) {
1110 e := p.readNonSignificantWhitespace()
1111 if e != nil {
1112 return nil, VOID, NewTProtocolException(e)
1113 }
1114 b, e := p.reader.Peek(1)
1115 if len(b) > 0 {
1116 c := b[0]
1117 switch c {
1118 case JSON_NULL[0]:
1119 buf := make([]byte, len(JSON_NULL))
1120 _, e := p.reader.Read(buf)
1121 if e != nil {
1122 return nil, VOID, NewTProtocolException(e)
1123 }
1124 if string(JSON_NULL) != string(buf) {
1125 e = mismatch(string(JSON_NULL), string(buf))
1126 return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e)
1127 }
1128 return nil, VOID, nil
1129 case JSON_QUOTE:
1130 p.reader.ReadByte()
1131 v, e := p.ParseStringBody()
1132 if e != nil {
1133 return v, UTF8, NewTProtocolException(e)
1134 }
1135 if v == JSON_INFINITY {
1136 return INFINITY, DOUBLE, nil
1137 } else if v == JSON_NEGATIVE_INFINITY {
1138 return NEGATIVE_INFINITY, DOUBLE, nil
1139 } else if v == JSON_NAN {
1140 return NAN, DOUBLE, nil
1141 }
1142 return v, UTF8, nil
1143 case JSON_TRUE[0]:
1144 buf := make([]byte, len(JSON_TRUE))
1145 _, e := p.reader.Read(buf)
1146 if e != nil {
1147 return true, BOOL, NewTProtocolException(e)
1148 }
1149 if string(JSON_TRUE) != string(buf) {
1150 e := mismatch(string(JSON_TRUE), string(buf))
1151 return true, BOOL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1152 }
1153 return true, BOOL, nil
1154 case JSON_FALSE[0]:
1155 buf := make([]byte, len(JSON_FALSE))
1156 _, e := p.reader.Read(buf)
1157 if e != nil {
1158 return false, BOOL, NewTProtocolException(e)
1159 }
1160 if string(JSON_FALSE) != string(buf) {
1161 e := mismatch(string(JSON_FALSE), string(buf))
1162 return false, BOOL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1163 }
1164 return false, BOOL, nil
1165 case JSON_LBRACKET[0]:
1166 _, e := p.reader.ReadByte()
1167 return make([]interface{}, 0), LIST, NewTProtocolException(e)
1168 case JSON_LBRACE[0]:
1169 _, e := p.reader.ReadByte()
1170 return make(map[string]interface{}), STRUCT, NewTProtocolException(e)
1171 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'e', 'E', '.', '+', '-', JSON_INFINITY[0], JSON_NAN[0]:
1172 // assume numeric
1173 v, e := p.readNumeric()
1174 return v, DOUBLE, e
1175 default:
1176 e := fmt.Errorf("Expected element in list but found '%s' while parsing JSON.", string(c))
1177 return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e)
1178 }
1179 }
1180 e = fmt.Errorf("Cannot read a single element while parsing JSON.")
1181 return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e)
1182
1183}
1184
1185func (p *TSimpleJSONProtocol) readIfNull() (bool, error) {
1186 cont := true
1187 for cont {
1188 b, _ := p.reader.Peek(1)
1189 if len(b) < 1 {
1190 return false, nil
1191 }
1192 switch b[0] {
1193 default:
1194 return false, nil
1195 case JSON_NULL[0]:
1196 cont = false
1197 break
1198 case ' ', '\n', '\r', '\t':
1199 p.reader.ReadByte()
1200 break
1201 }
1202 }
1203 if p.safePeekContains(JSON_NULL) {
1204 p.reader.Read(make([]byte, len(JSON_NULL)))
1205 return true, nil
1206 }
1207 return false, nil
1208}
1209
1210func (p *TSimpleJSONProtocol) readQuoteIfNext() {
1211 b, _ := p.reader.Peek(1)
1212 if len(b) > 0 && b[0] == JSON_QUOTE {
1213 p.reader.ReadByte()
1214 }
1215}
1216
1217func (p *TSimpleJSONProtocol) readNumeric() (Numeric, error) {
1218 isNull, err := p.readIfNull()
1219 if isNull || err != nil {
1220 return NUMERIC_NULL, err
1221 }
1222 hasDecimalPoint := false
1223 nextCanBeSign := true
1224 hasE := false
1225 MAX_LEN := 40
1226 buf := bytes.NewBuffer(make([]byte, 0, MAX_LEN))
1227 continueFor := true
1228 inQuotes := false
1229 for continueFor {
1230 c, err := p.reader.ReadByte()
1231 if err != nil {
1232 if err == io.EOF {
1233 break
1234 }
1235 return NUMERIC_NULL, NewTProtocolException(err)
1236 }
1237 switch c {
1238 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
1239 buf.WriteByte(c)
1240 nextCanBeSign = false
1241 case '.':
1242 if hasDecimalPoint {
1243 e := fmt.Errorf("Unable to parse number with multiple decimal points '%s.'", buf.String())
1244 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1245 }
1246 if hasE {
1247 e := fmt.Errorf("Unable to parse number with decimal points in the exponent '%s.'", buf.String())
1248 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1249 }
1250 buf.WriteByte(c)
1251 hasDecimalPoint, nextCanBeSign = true, false
1252 case 'e', 'E':
1253 if hasE {
1254 e := fmt.Errorf("Unable to parse number with multiple exponents '%s%c'", buf.String(), c)
1255 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1256 }
1257 buf.WriteByte(c)
1258 hasE, nextCanBeSign = true, true
1259 case '-', '+':
1260 if !nextCanBeSign {
1261 e := fmt.Errorf("Negative sign within number")
1262 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1263 }
1264 buf.WriteByte(c)
1265 nextCanBeSign = false
1266 case ' ', 0, '\t', '\n', '\r', JSON_RBRACE[0], JSON_RBRACKET[0], JSON_COMMA[0], JSON_COLON[0]:
1267 p.reader.UnreadByte()
1268 continueFor = false
1269 case JSON_NAN[0]:
1270 if buf.Len() == 0 {
1271 buffer := make([]byte, len(JSON_NAN))
1272 buffer[0] = c
1273 _, e := p.reader.Read(buffer[1:])
1274 if e != nil {
1275 return NUMERIC_NULL, NewTProtocolException(e)
1276 }
1277 if JSON_NAN != string(buffer) {
1278 e := mismatch(JSON_NAN, string(buffer))
1279 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1280 }
1281 if inQuotes {
1282 p.readQuoteIfNext()
1283 }
1284 return NAN, nil
1285 } else {
1286 e := fmt.Errorf("Unable to parse number starting with character '%c'", c)
1287 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1288 }
1289 case JSON_INFINITY[0]:
1290 if buf.Len() == 0 || (buf.Len() == 1 && buf.Bytes()[0] == '+') {
1291 buffer := make([]byte, len(JSON_INFINITY))
1292 buffer[0] = c
1293 _, e := p.reader.Read(buffer[1:])
1294 if e != nil {
1295 return NUMERIC_NULL, NewTProtocolException(e)
1296 }
1297 if JSON_INFINITY != string(buffer) {
1298 e := mismatch(JSON_INFINITY, string(buffer))
1299 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1300 }
1301 if inQuotes {
1302 p.readQuoteIfNext()
1303 }
1304 return INFINITY, nil
1305 } else if buf.Len() == 1 && buf.Bytes()[0] == JSON_NEGATIVE_INFINITY[0] {
1306 buffer := make([]byte, len(JSON_NEGATIVE_INFINITY))
1307 buffer[0] = JSON_NEGATIVE_INFINITY[0]
1308 buffer[1] = c
1309 _, e := p.reader.Read(buffer[2:])
1310 if e != nil {
1311 return NUMERIC_NULL, NewTProtocolException(e)
1312 }
1313 if JSON_NEGATIVE_INFINITY != string(buffer) {
1314 e := mismatch(JSON_NEGATIVE_INFINITY, string(buffer))
1315 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1316 }
1317 if inQuotes {
1318 p.readQuoteIfNext()
1319 }
1320 return NEGATIVE_INFINITY, nil
1321 } else {
1322 e := fmt.Errorf("Unable to parse number starting with character '%c' due to existing buffer %s", c, buf.String())
1323 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1324 }
1325 case JSON_QUOTE:
1326 if !inQuotes {
1327 inQuotes = true
1328 } else {
1329 break
1330 }
1331 default:
1332 e := fmt.Errorf("Unable to parse number starting with character '%c'", c)
1333 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1334 }
1335 }
1336 if buf.Len() == 0 {
1337 e := fmt.Errorf("Unable to parse number from empty string ''")
1338 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1339 }
1340 return NewNumericFromJSONString(buf.String(), false), nil
1341}
1342
1343// Safely peeks into the buffer, reading only what is necessary
1344func (p *TSimpleJSONProtocol) safePeekContains(b []byte) bool {
1345 for i := 0; i < len(b); i++ {
1346 a, _ := p.reader.Peek(i + 1)
khenaidood948f772021-08-11 17:49:24 -04001347 if len(a) < (i+1) || a[i] != b[i] {
khenaidooc6c7bda2020-06-17 17:20:18 -04001348 return false
1349 }
1350 }
1351 return true
1352}
1353
1354// Reset the context stack to its initial state.
1355func (p *TSimpleJSONProtocol) resetContextStack() {
khenaidood948f772021-08-11 17:49:24 -04001356 p.parseContextStack = jsonContextStack{_CONTEXT_IN_TOPLEVEL}
1357 p.dumpContext = jsonContextStack{_CONTEXT_IN_TOPLEVEL}
khenaidooc6c7bda2020-06-17 17:20:18 -04001358}
1359
1360func (p *TSimpleJSONProtocol) write(b []byte) (int, error) {
1361 n, err := p.writer.Write(b)
1362 if err != nil {
1363 p.writer.Reset(p.trans) // THRIFT-3735
1364 }
1365 return n, err
1366}
khenaidood948f772021-08-11 17:49:24 -04001367
1368// SetTConfiguration implements TConfigurationSetter for propagation.
1369func (p *TSimpleJSONProtocol) SetTConfiguration(conf *TConfiguration) {
1370 PropagateTConfiguration(p.trans, conf)
1371}
1372
1373var _ TConfigurationSetter = (*TSimpleJSONProtocol)(nil)