blob: 71598acbbb6cf33dc2ab75d85d8bc0b36be59775 [file] [log] [blame]
Jens Geyer0e87c462013-06-18 22:25:07 +02001/*
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"
25 "encoding/base64"
26 "encoding/json"
27 "fmt"
28 "io"
29 "math"
30 "strconv"
31)
32
33type _ParseContext int
34
35const (
36 _CONTEXT_IN_TOPLEVEL _ParseContext = 1
37 _CONTEXT_IN_LIST_FIRST _ParseContext = 2
38 _CONTEXT_IN_LIST _ParseContext = 3
39 _CONTEXT_IN_OBJECT_FIRST _ParseContext = 4
40 _CONTEXT_IN_OBJECT_NEXT_KEY _ParseContext = 5
41 _CONTEXT_IN_OBJECT_NEXT_VALUE _ParseContext = 6
42)
43
44func (p _ParseContext) String() string {
45 switch p {
46 case _CONTEXT_IN_TOPLEVEL:
47 return "TOPLEVEL"
48 case _CONTEXT_IN_LIST_FIRST:
49 return "LIST-FIRST"
50 case _CONTEXT_IN_LIST:
51 return "LIST"
52 case _CONTEXT_IN_OBJECT_FIRST:
53 return "OBJECT-FIRST"
54 case _CONTEXT_IN_OBJECT_NEXT_KEY:
55 return "OBJECT-NEXT-KEY"
56 case _CONTEXT_IN_OBJECT_NEXT_VALUE:
57 return "OBJECT-NEXT-VALUE"
58 }
59 return "UNKNOWN-PARSE-CONTEXT"
60}
61
62// JSON protocol implementation for thrift.
63//
64// This protocol produces/consumes a simple output format
65// suitable for parsing by scripting languages. It should not be
66// confused with the full-featured TJSONProtocol.
67//
68type TSimpleJSONProtocol struct {
69 trans TTransport
70
71 parseContextStack []int
72 dumpContext []int
73
74 writer *bufio.Writer
75 reader *bufio.Reader
76}
77
78// Constructor
79func NewTSimpleJSONProtocol(t TTransport) *TSimpleJSONProtocol {
80 v := &TSimpleJSONProtocol{trans: t,
81 writer: bufio.NewWriter(t),
82 reader: bufio.NewReader(t),
83 }
84 v.parseContextStack = append(v.parseContextStack, int(_CONTEXT_IN_TOPLEVEL))
85 v.dumpContext = append(v.dumpContext, int(_CONTEXT_IN_TOPLEVEL))
86 return v
87}
88
89// Factory
90type TSimpleJSONProtocolFactory struct{}
91
92func (p *TSimpleJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol {
93 return NewTSimpleJSONProtocol(trans)
94}
95
96func NewTSimpleJSONProtocolFactory() *TSimpleJSONProtocolFactory {
97 return &TSimpleJSONProtocolFactory{}
98}
99
100var (
101 JSON_COMMA []byte
102 JSON_COLON []byte
103 JSON_LBRACE []byte
104 JSON_RBRACE []byte
105 JSON_LBRACKET []byte
106 JSON_RBRACKET []byte
107 JSON_QUOTE byte
108 JSON_QUOTE_BYTES []byte
109 JSON_NULL []byte
110 JSON_TRUE []byte
111 JSON_FALSE []byte
112 JSON_INFINITY string
113 JSON_NEGATIVE_INFINITY string
114 JSON_NAN string
115 JSON_INFINITY_BYTES []byte
116 JSON_NEGATIVE_INFINITY_BYTES []byte
117 JSON_NAN_BYTES []byte
118 json_nonbase_map_elem_bytes []byte
119)
120
121func init() {
122 JSON_COMMA = []byte{','}
123 JSON_COLON = []byte{':'}
124 JSON_LBRACE = []byte{'{'}
125 JSON_RBRACE = []byte{'}'}
126 JSON_LBRACKET = []byte{'['}
127 JSON_RBRACKET = []byte{']'}
128 JSON_QUOTE = '"'
129 JSON_QUOTE_BYTES = []byte{'"'}
130 JSON_NULL = []byte{'n', 'u', 'l', 'l'}
131 JSON_TRUE = []byte{'t', 'r', 'u', 'e'}
132 JSON_FALSE = []byte{'f', 'a', 'l', 's', 'e'}
133 JSON_INFINITY = "Infinity"
134 JSON_NEGATIVE_INFINITY = "-Infinity"
135 JSON_NAN = "NaN"
136 JSON_INFINITY_BYTES = []byte{'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'}
137 JSON_NEGATIVE_INFINITY_BYTES = []byte{'-', 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'}
138 JSON_NAN_BYTES = []byte{'N', 'a', 'N'}
139 json_nonbase_map_elem_bytes = []byte{']', ',', '['}
140}
141
142func jsonQuote(s string) string {
143 b, _ := json.Marshal(s)
144 s1 := string(b)
145 return s1
146}
147
148func jsonUnquote(s string) (string, bool) {
149 s1 := new(string)
150 err := json.Unmarshal([]byte(s), s1)
151 return *s1, err == nil
152}
153
154func mismatch(expected, actual string) error {
155 return fmt.Errorf("Expected '%s' but found '%s' while parsing JSON.", expected, actual)
156}
157
158func (p *TSimpleJSONProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) error {
159 if e := p.OutputListBegin(); e != nil {
160 return e
161 }
162 if e := p.WriteString(name); e != nil {
163 return e
164 }
165 if e := p.WriteByte(byte(typeId)); e != nil {
166 return e
167 }
168 if e := p.WriteI32(seqId); e != nil {
169 return e
170 }
171 return nil
172}
173
174func (p *TSimpleJSONProtocol) WriteMessageEnd() error {
175 return p.OutputListEnd()
176}
177
178func (p *TSimpleJSONProtocol) WriteStructBegin(name string) error {
179 if e := p.OutputObjectBegin(); e != nil {
180 return e
181 }
182 return nil
183}
184
185func (p *TSimpleJSONProtocol) WriteStructEnd() error {
186 return p.OutputObjectEnd()
187}
188
189func (p *TSimpleJSONProtocol) WriteFieldBegin(name string, typeId TType, id int16) error {
190 if e := p.WriteString(name); e != nil {
191 return e
192 }
193 return nil
194}
195
196func (p *TSimpleJSONProtocol) WriteFieldEnd() error {
197 //return p.OutputListEnd()
198 return nil
199}
200
201func (p *TSimpleJSONProtocol) WriteFieldStop() error { return nil }
202
203func (p *TSimpleJSONProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error {
204 if e := p.OutputListBegin(); e != nil {
205 return e
206 }
207 if e := p.WriteByte(byte(keyType)); e != nil {
208 return e
209 }
210 if e := p.WriteByte(byte(valueType)); e != nil {
211 return e
212 }
213 return p.WriteI32(int32(size))
214}
215
216func (p *TSimpleJSONProtocol) WriteMapEnd() error {
217 return p.OutputListEnd()
218}
219
220func (p *TSimpleJSONProtocol) WriteListBegin(elemType TType, size int) error {
221 return p.OutputElemListBegin(elemType, size)
222}
223
224func (p *TSimpleJSONProtocol) WriteListEnd() error {
225 return p.OutputListEnd()
226}
227
228func (p *TSimpleJSONProtocol) WriteSetBegin(elemType TType, size int) error {
229 return p.OutputElemListBegin(elemType, size)
230}
231
232func (p *TSimpleJSONProtocol) WriteSetEnd() error {
233 return p.OutputListEnd()
234}
235
236func (p *TSimpleJSONProtocol) WriteBool(b bool) error {
237 return p.OutputBool(b)
238}
239
240func (p *TSimpleJSONProtocol) WriteByte(b byte) error {
241 return p.WriteI32(int32(b))
242}
243
244func (p *TSimpleJSONProtocol) WriteI16(v int16) error {
245 return p.WriteI32(int32(v))
246}
247
248func (p *TSimpleJSONProtocol) WriteI32(v int32) error {
249 return p.OutputI64(int64(v))
250}
251
252func (p *TSimpleJSONProtocol) WriteI64(v int64) error {
253 return p.OutputI64(int64(v))
254}
255
256func (p *TSimpleJSONProtocol) WriteDouble(v float64) error {
257 return p.OutputF64(v)
258}
259
260func (p *TSimpleJSONProtocol) WriteString(v string) error {
261 return p.OutputString(v)
262}
263
264func (p *TSimpleJSONProtocol) WriteBinary(v []byte) error {
265 // JSON library only takes in a string,
266 // not an arbitrary byte array, to ensure bytes are transmitted
267 // efficiently we must convert this into a valid JSON string
268 // therefore we use base64 encoding to avoid excessive escaping/quoting
269 if e := p.OutputPreValue(); e != nil {
270 return e
271 }
272 if _, e := p.writer.Write(JSON_QUOTE_BYTES); e != nil {
273 return NewTProtocolException(e)
274 }
275 writer := base64.NewEncoder(base64.StdEncoding, p.writer)
276 if _, e := writer.Write(v); e != nil {
277 return NewTProtocolException(e)
278 }
279 if e := writer.Close(); e != nil {
280 return NewTProtocolException(e)
281 }
282 if _, e := p.writer.Write(JSON_QUOTE_BYTES); e != nil {
283 return NewTProtocolException(e)
284 }
285 return p.OutputPostValue()
286}
287
288// Reading methods.
289
290func (p *TSimpleJSONProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) {
291 if isNull, err := p.ParseListBegin(); isNull || err != nil {
292 return name, typeId, seqId, err
293 }
294 if name, err = p.ReadString(); err != nil {
295 return name, typeId, seqId, err
296 }
297 bTypeId, err := p.ReadByte()
298 typeId = TMessageType(bTypeId)
299 if err != nil {
300 return name, typeId, seqId, err
301 }
302 if seqId, err = p.ReadI32(); err != nil {
303 return name, typeId, seqId, err
304 }
305 return name, typeId, seqId, nil
306}
307
308func (p *TSimpleJSONProtocol) ReadMessageEnd() error {
309 return p.ParseListEnd()
310}
311
312func (p *TSimpleJSONProtocol) ReadStructBegin() (name string, err error) {
313 _, err = p.ParseObjectStart()
314 return "", err
315}
316
317func (p *TSimpleJSONProtocol) ReadStructEnd() error {
318 return p.ParseObjectEnd()
319}
320
321func (p *TSimpleJSONProtocol) ReadFieldBegin() (string, TType, int16, error) {
322 if err := p.ParsePreValue(); err != nil {
323 return "", STOP, 0, err
324 }
Jens Geyer0e87c462013-06-18 22:25:07 +0200325 b, _ := p.reader.Peek(1)
326 if len(b) > 0 {
327 switch b[0] {
328 case JSON_RBRACE[0]:
329 return "", STOP, 0, nil
330 case JSON_QUOTE:
331 p.reader.ReadByte()
332 name, err := p.ParseStringBody()
Jens Geyer4ba11602013-09-10 21:33:55 +0200333 // simplejson is not meant to be read back into thrift
334 // - see http://wiki.apache.org/thrift/ThriftUsageJava
335 // - use JSON instead
Jens Geyer0e87c462013-06-18 22:25:07 +0200336 if err != nil {
337 return name, STOP, 0, err
338 }
339 return name, STOP, -1, p.ParsePostValue()
340 /*
341 if err = p.ParsePostValue(); err != nil {
342 return name, STOP, 0, err
343 }
344 if isNull, err := p.ParseListBegin(); isNull || err != nil {
345 return name, STOP, 0, err
346 }
347 bType, err := p.ReadByte()
348 thetype := TType(bType)
349 if err != nil {
350 return name, thetype, 0, err
351 }
352 id, err := p.ReadI16()
353 return name, thetype, id, err
354 */
355 }
356 e := fmt.Errorf("Expected \"}\" or '\"', but found: '%s'", string(b))
357 return "", STOP, 0, NewTProtocolExceptionWithType(INVALID_DATA, e)
358 }
359 return "", STOP, 0, NewTProtocolException(io.EOF)
360}
361
362func (p *TSimpleJSONProtocol) ReadFieldEnd() error {
363 return nil
364 //return p.ParseListEnd()
365}
366
367func (p *TSimpleJSONProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, e error) {
368 if isNull, e := p.ParseListBegin(); isNull || e != nil {
369 return VOID, VOID, 0, e
370 }
371
372 // read keyType
373 bKeyType, e := p.ReadByte()
374 keyType = TType(bKeyType)
375 if e != nil {
376 return keyType, valueType, size, e
377 }
378
379 // read valueType
380 bValueType, e := p.ReadByte()
381 valueType = TType(bValueType)
382 if e != nil {
383 return keyType, valueType, size, e
384 }
385
386 // read size
387 iSize, err := p.ReadI64()
388 size = int(iSize)
389 return keyType, valueType, size, err
390}
391
392func (p *TSimpleJSONProtocol) ReadMapEnd() error {
393 return p.ParseListEnd()
394}
395
396func (p *TSimpleJSONProtocol) ReadListBegin() (elemType TType, size int, e error) {
397 return p.ParseElemListBegin()
398}
399
400func (p *TSimpleJSONProtocol) ReadListEnd() error {
401 return p.ParseListEnd()
402}
403
404func (p *TSimpleJSONProtocol) ReadSetBegin() (elemType TType, size int, e error) {
405 return p.ParseElemListBegin()
406}
407
408func (p *TSimpleJSONProtocol) ReadSetEnd() error {
409 return p.ParseListEnd()
410}
411
412func (p *TSimpleJSONProtocol) ReadBool() (bool, error) {
413 var value bool
414 if err := p.ParsePreValue(); err != nil {
415 return value, err
416 }
417 b, _ := p.reader.Peek(len(JSON_TRUE))
418 if len(b) > 0 {
419 switch b[0] {
420 case JSON_TRUE[0]:
421 if string(b) == string(JSON_TRUE) {
422 p.reader.Read(b[0:len(JSON_TRUE)])
423 value = true
424 } else {
425 e := fmt.Errorf("Expected \"true\" but found: %s", string(b))
426 return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
427 }
428 break
429 case JSON_FALSE[0]:
430 if string(b) == string(JSON_FALSE[:len(b)]) {
431 p.reader.Read(b[0:len(JSON_FALSE)])
432 value = false
433 } else {
434 e := fmt.Errorf("Expected \"false\" but found: %s", string(b))
435 return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
436 }
437 break
438 case JSON_NULL[0]:
439 if string(b) == string(JSON_NULL) {
440 p.reader.Read(b[0:len(JSON_NULL)])
441 value = false
442 } else {
443 e := fmt.Errorf("Expected \"null\" but found: %s", string(b))
444 return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
445 }
446 default:
447 e := fmt.Errorf("Expected \"true\", \"false\", or \"null\" but found: %s", string(b))
448 return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
449 }
450 }
451 return value, p.ParsePostValue()
452}
453
454func (p *TSimpleJSONProtocol) ReadByte() (byte, error) {
455 v, err := p.ReadI64()
456 return byte(v), err
457}
458
459func (p *TSimpleJSONProtocol) ReadI16() (int16, error) {
460 v, err := p.ReadI64()
461 return int16(v), err
462}
463
464func (p *TSimpleJSONProtocol) ReadI32() (int32, error) {
465 v, err := p.ReadI64()
466 return int32(v), err
467}
468
469func (p *TSimpleJSONProtocol) ReadI64() (int64, error) {
470 v, _, err := p.ParseI64()
471 return v, err
472}
473
474func (p *TSimpleJSONProtocol) ReadDouble() (float64, error) {
475 v, _, err := p.ParseF64()
476 return v, err
477}
478
479func (p *TSimpleJSONProtocol) ReadString() (string, error) {
480 var v string
481 if err := p.ParsePreValue(); err != nil {
482 return v, err
483 }
484 var b []byte
Jens Geyer8a0f8d12013-09-10 21:30:41 +0200485 b, _ = p.reader.Peek(len(JSON_NULL))
Jens Geyer0e87c462013-06-18 22:25:07 +0200486 if len(b) > 0 && b[0] == JSON_QUOTE {
487 p.reader.ReadByte()
488 value, err := p.ParseStringBody()
489 v = value
490 if err != nil {
491 return v, err
492 }
493 } else if len(b) >= len(JSON_NULL) && string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
494 _, err := p.reader.Read(b[0:len(JSON_NULL)])
495 if err != nil {
496 return v, NewTProtocolException(err)
497 }
498 } else {
499 e := fmt.Errorf("Expected a JSON string, found %s", string(b))
500 return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
501 }
502 return v, p.ParsePostValue()
503}
504
505func (p *TSimpleJSONProtocol) ReadBinary() ([]byte, error) {
506 var v []byte
507 if err := p.ParsePreValue(); err != nil {
508 return nil, err
509 }
510 b, _ := p.reader.Peek(len(JSON_NULL))
511 if len(b) > 0 && b[0] == JSON_QUOTE {
512 p.reader.ReadByte()
513 value, err := p.ParseBase64EncodedBody()
514 v = value
515 if err != nil {
516 return v, err
517 }
518 } else if len(b) >= len(JSON_NULL) && string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
519 _, err := p.reader.Read(b[0:len(JSON_NULL)])
520 if err != nil {
521 return v, NewTProtocolException(err)
522 }
523 } else {
524 e := fmt.Errorf("Expected a JSON string, found %s", string(b))
525 return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
526 }
527 return v, p.ParsePostValue()
528}
529
530func (p *TSimpleJSONProtocol) Flush() (err error) {
531 return NewTProtocolException(p.writer.Flush())
532}
533
534func (p *TSimpleJSONProtocol) Skip(fieldType TType) (err error) {
535 return SkipDefaultDepth(p, fieldType)
536}
537
538func (p *TSimpleJSONProtocol) Transport() TTransport {
539 return p.trans
540}
541
542func (p *TSimpleJSONProtocol) OutputPreValue() error {
543 cxt := _ParseContext(p.dumpContext[len(p.dumpContext)-1])
544 switch cxt {
545 case _CONTEXT_IN_LIST, _CONTEXT_IN_OBJECT_NEXT_KEY:
546 if _, e := p.writer.Write(JSON_COMMA); e != nil {
547 return NewTProtocolException(e)
548 }
549 break
550 case _CONTEXT_IN_OBJECT_NEXT_VALUE:
551 if _, e := p.writer.Write(JSON_COLON); e != nil {
552 return NewTProtocolException(e)
553 }
554 break
555 }
556 return nil
557}
558
559func (p *TSimpleJSONProtocol) OutputPostValue() error {
560 cxt := _ParseContext(p.dumpContext[len(p.dumpContext)-1])
561 switch cxt {
562 case _CONTEXT_IN_LIST_FIRST:
563 p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
564 p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_LIST))
565 break
566 case _CONTEXT_IN_OBJECT_FIRST:
567 p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
568 p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_VALUE))
569 break
570 case _CONTEXT_IN_OBJECT_NEXT_KEY:
571 p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
572 p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_VALUE))
573 break
574 case _CONTEXT_IN_OBJECT_NEXT_VALUE:
575 p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
576 p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_KEY))
577 break
578 }
579 return nil
580}
581
582func (p *TSimpleJSONProtocol) OutputBool(value bool) error {
583 if e := p.OutputPreValue(); e != nil {
584 return e
585 }
586 var v string
587 if value {
588 v = string(JSON_TRUE)
589 } else {
590 v = string(JSON_FALSE)
591 }
592 switch _ParseContext(p.dumpContext[len(p.dumpContext)-1]) {
593 case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
594 v = jsonQuote(v)
595 default:
596 }
597 if e := p.OutputStringData(v); e != nil {
598 return e
599 }
600 return p.OutputPostValue()
601}
602
603func (p *TSimpleJSONProtocol) OutputNull() error {
604 if e := p.OutputPreValue(); e != nil {
605 return e
606 }
607 if _, e := p.writer.Write(JSON_NULL); e != nil {
608 return NewTProtocolException(e)
609 }
610 return p.OutputPostValue()
611}
612
613func (p *TSimpleJSONProtocol) OutputF64(value float64) error {
614 if e := p.OutputPreValue(); e != nil {
615 return e
616 }
617 var v string
618 if math.IsNaN(value) {
619 v = string(JSON_QUOTE) + JSON_NAN + string(JSON_QUOTE)
620 } else if math.IsInf(value, 1) {
621 v = string(JSON_QUOTE) + JSON_INFINITY + string(JSON_QUOTE)
622 } else if math.IsInf(value, -1) {
623 v = string(JSON_QUOTE) + JSON_NEGATIVE_INFINITY + string(JSON_QUOTE)
624 } else {
625 v = strconv.FormatFloat(value, 'g', -1, 64)
626 switch _ParseContext(p.dumpContext[len(p.dumpContext)-1]) {
627 case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
628 v = string(JSON_QUOTE) + v + string(JSON_QUOTE)
629 default:
630 }
631 }
632 if e := p.OutputStringData(v); e != nil {
633 return e
634 }
635 return p.OutputPostValue()
636}
637
638func (p *TSimpleJSONProtocol) OutputI64(value int64) error {
639 if e := p.OutputPreValue(); e != nil {
640 return e
641 }
642 v := strconv.FormatInt(value, 10)
643 switch _ParseContext(p.dumpContext[len(p.dumpContext)-1]) {
644 case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
645 v = jsonQuote(v)
646 default:
647 }
648 if e := p.OutputStringData(v); e != nil {
649 return e
650 }
651 return p.OutputPostValue()
652}
653
654func (p *TSimpleJSONProtocol) OutputString(s string) error {
655 if e := p.OutputPreValue(); e != nil {
656 return e
657 }
658 if e := p.OutputStringData(jsonQuote(s)); e != nil {
659 return e
660 }
661 return p.OutputPostValue()
662}
663
664func (p *TSimpleJSONProtocol) OutputStringData(s string) error {
665 _, e := p.writer.Write([]byte(s))
666 return NewTProtocolException(e)
667}
668
669func (p *TSimpleJSONProtocol) OutputObjectBegin() error {
670 if e := p.OutputPreValue(); e != nil {
671 return e
672 }
673 if _, e := p.writer.Write(JSON_LBRACE); e != nil {
674 return NewTProtocolException(e)
675 }
676 p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_FIRST))
677 return nil
678}
679
680func (p *TSimpleJSONProtocol) OutputObjectEnd() error {
681 if _, e := p.writer.Write(JSON_RBRACE); e != nil {
682 return NewTProtocolException(e)
683 }
684 p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
685 if e := p.OutputPostValue(); e != nil {
686 return e
687 }
688 return nil
689}
690
691func (p *TSimpleJSONProtocol) OutputListBegin() error {
692 if e := p.OutputPreValue(); e != nil {
693 return e
694 }
695 if _, e := p.writer.Write(JSON_LBRACKET); e != nil {
696 return NewTProtocolException(e)
697 }
698 p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_LIST_FIRST))
699 return nil
700}
701
702func (p *TSimpleJSONProtocol) OutputListEnd() error {
703 if _, e := p.writer.Write(JSON_RBRACKET); e != nil {
704 return NewTProtocolException(e)
705 }
706 p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
707 if e := p.OutputPostValue(); e != nil {
708 return e
709 }
710 return nil
711}
712
713func (p *TSimpleJSONProtocol) OutputElemListBegin(elemType TType, size int) error {
714 if e := p.OutputListBegin(); e != nil {
715 return e
716 }
717 if e := p.WriteByte(byte(elemType)); e != nil {
718 return e
719 }
720 if e := p.WriteI64(int64(size)); e != nil {
721 return e
722 }
723 return nil
724}
725
726func (p *TSimpleJSONProtocol) ParsePreValue() error {
727 if e := p.readNonSignificantWhitespace(); e != nil {
728 return NewTProtocolException(e)
729 }
730 cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1])
Jens Geyer0e87c462013-06-18 22:25:07 +0200731 b, _ := p.reader.Peek(1)
732 switch cxt {
733 case _CONTEXT_IN_LIST:
734 if len(b) > 0 {
735 switch b[0] {
736 case JSON_RBRACKET[0]:
737 return nil
738 case JSON_COMMA[0]:
739 p.reader.ReadByte()
740 if e := p.readNonSignificantWhitespace(); e != nil {
741 return NewTProtocolException(e)
742 }
743 return nil
744 default:
745 e := fmt.Errorf("Expected \"]\" or \",\" in list context, but found \"%s\"", string(b))
746 return NewTProtocolExceptionWithType(INVALID_DATA, e)
747 }
748 }
749 break
750 case _CONTEXT_IN_OBJECT_NEXT_KEY:
751 if len(b) > 0 {
752 switch b[0] {
753 case JSON_RBRACE[0]:
754 return nil
755 case JSON_COMMA[0]:
756 p.reader.ReadByte()
757 if e := p.readNonSignificantWhitespace(); e != nil {
758 return NewTProtocolException(e)
759 }
760 return nil
761 default:
762 e := fmt.Errorf("Expected \"}\" or \",\" in object context, but found \"%s\"", string(b))
763 return NewTProtocolExceptionWithType(INVALID_DATA, e)
764 }
765 }
766 break
767 case _CONTEXT_IN_OBJECT_NEXT_VALUE:
768 if len(b) > 0 {
769 switch b[0] {
770 case JSON_COLON[0]:
771 p.reader.ReadByte()
772 if e := p.readNonSignificantWhitespace(); e != nil {
773 return NewTProtocolException(e)
774 }
775 return nil
776 default:
777 e := fmt.Errorf("Expected \":\" in object context, but found \"%s\"", string(b))
778 return NewTProtocolExceptionWithType(INVALID_DATA, e)
779 }
780 }
781 break
782 }
783 return nil
784}
785
786func (p *TSimpleJSONProtocol) ParsePostValue() error {
787 if e := p.readNonSignificantWhitespace(); e != nil {
788 return NewTProtocolException(e)
789 }
790 cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1])
791 switch cxt {
792 case _CONTEXT_IN_LIST_FIRST:
793 p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1]
794 p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_LIST))
795 break
796 case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
797 p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1]
798 p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_OBJECT_NEXT_VALUE))
799 break
800 case _CONTEXT_IN_OBJECT_NEXT_VALUE:
801 p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1]
802 p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_OBJECT_NEXT_KEY))
803 break
804 }
805 return nil
806}
807
808func (p *TSimpleJSONProtocol) readNonSignificantWhitespace() error {
Jens Geyer8a0f8d12013-09-10 21:30:41 +0200809 for {
Jens Geyer0e87c462013-06-18 22:25:07 +0200810 b, _ := p.reader.Peek(1)
811 if len(b) < 1 {
812 return nil
813 }
814 switch b[0] {
815 case ' ', '\r', '\n', '\t':
816 p.reader.ReadByte()
817 continue
818 default:
819 break
820 }
821 break
822 }
823 return nil
824}
825
826func (p *TSimpleJSONProtocol) ParseStringBody() (string, error) {
827 line, err := p.reader.ReadString(JSON_QUOTE)
828 if err != nil {
829 return "", NewTProtocolException(err)
830 }
831 l := len(line)
832 // count number of escapes to see if we need to keep going
833 i := 1
834 for ; i < l; i++ {
835 if line[l-i-1] != '\\' {
836 break
837 }
838 }
839 if i&0x01 == 1 {
840 v, ok := jsonUnquote(string(JSON_QUOTE) + line)
841 if !ok {
842 return "", NewTProtocolException(err)
843 }
844 return v, nil
845 }
846 s, err := p.ParseQuotedStringBody()
847 if err != nil {
848 return "", NewTProtocolException(err)
849 }
850 str := string(JSON_QUOTE) + line + s
851 v, ok := jsonUnquote(str)
852 if !ok {
853 e := fmt.Errorf("Unable to parse as JSON string %s", str)
854 return "", NewTProtocolExceptionWithType(INVALID_DATA, e)
855 }
856 return v, nil
857}
858
859func (p *TSimpleJSONProtocol) ParseQuotedStringBody() (string, error) {
860 line, err := p.reader.ReadString(JSON_QUOTE)
861 if err != nil {
862 return "", NewTProtocolException(err)
863 }
864 l := len(line)
865 // count number of escapes to see if we need to keep going
866 i := 1
867 for ; i < l; i++ {
868 if line[l-i-1] != '\\' {
869 break
870 }
871 }
872 if i&0x01 == 1 {
873 return line, nil
874 }
875 s, err := p.ParseQuotedStringBody()
876 if err != nil {
877 return "", NewTProtocolException(err)
878 }
879 v := line + s
880 return v, nil
881}
882
883func (p *TSimpleJSONProtocol) ParseBase64EncodedBody() ([]byte, error) {
884 line, err := p.reader.ReadBytes(JSON_QUOTE)
885 if err != nil {
886 return line, NewTProtocolException(err)
887 }
888 line2 := line[0 : len(line)-1]
889 l := len(line2)
890 output := make([]byte, base64.StdEncoding.DecodedLen(l))
891 n, err := base64.StdEncoding.Decode(output, line2)
892 return output[0:n], NewTProtocolException(err)
893}
894
895func (p *TSimpleJSONProtocol) ParseI64() (int64, bool, error) {
896 if err := p.ParsePreValue(); err != nil {
897 return 0, false, err
898 }
899 var value int64
900 var isnull bool
901 b, _ := p.reader.Peek(len(JSON_NULL))
902 if len(b) >= len(JSON_NULL) && string(b) == string(JSON_NULL) {
903 p.reader.Read(b[0:len(JSON_NULL)])
904 isnull = true
905 } else {
906 num, err := p.readNumeric()
907 isnull = (num == nil)
908 if !isnull {
909 value = num.Int64()
910 }
911 if err != nil {
912 return value, isnull, err
913 }
914 }
915 return value, isnull, p.ParsePostValue()
916}
917
918func (p *TSimpleJSONProtocol) ParseF64() (float64, bool, error) {
919 if err := p.ParsePreValue(); err != nil {
920 return 0, false, err
921 }
922 var value float64
923 var isnull bool
924 b, _ := p.reader.Peek(len(JSON_NULL))
925 if len(b) >= len(JSON_NULL) && string(b) == string(JSON_NULL) {
926 p.reader.Read(b[0:len(JSON_NULL)])
927 isnull = true
928 } else {
929 num, err := p.readNumeric()
930 isnull = (num == nil)
931 if !isnull {
932 value = num.Float64()
933 }
934 if err != nil {
935 return value, isnull, err
936 }
937 }
938 return value, isnull, p.ParsePostValue()
939}
940
941func (p *TSimpleJSONProtocol) ParseObjectStart() (bool, error) {
942 if err := p.ParsePreValue(); err != nil {
943 return false, err
944 }
945 var b []byte
Jens Geyer8a0f8d12013-09-10 21:30:41 +0200946 b, _ = p.reader.Peek(len(JSON_NULL))
Jens Geyer0e87c462013-06-18 22:25:07 +0200947 if len(b) > 0 && b[0] == JSON_LBRACE[0] {
948 p.reader.ReadByte()
949 p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_OBJECT_FIRST))
950 return false, nil
951 } else if len(b) >= len(JSON_NULL) && string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
952 return true, nil
953 }
954 e := fmt.Errorf("Expected '{' or null, but found '%s'", string(b))
955 return false, NewTProtocolExceptionWithType(INVALID_DATA, e)
956}
957
958func (p *TSimpleJSONProtocol) ParseObjectEnd() error {
959 if isNull, err := p.readIfNull(); isNull || err != nil {
960 return err
961 }
962 cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1])
963 if cxt != _CONTEXT_IN_OBJECT_FIRST && cxt != _CONTEXT_IN_OBJECT_NEXT_KEY {
964 e := fmt.Errorf("Expected to be in the Object Context, but not in Object Context")
965 return NewTProtocolExceptionWithType(INVALID_DATA, e)
966 }
967 line, err := p.reader.ReadString(JSON_RBRACE[0])
968 if err != nil {
969 return NewTProtocolException(err)
970 }
971 for _, char := range line {
972 switch char {
973 default:
974 e := fmt.Errorf("Expecting end of object \"}\", but found: \"%s\"", line)
975 return NewTProtocolExceptionWithType(INVALID_DATA, e)
976 case ' ', '\n', '\r', '\t', '}':
977 break
978 }
979 }
980 p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1]
981 return p.ParsePostValue()
982}
983
984func (p *TSimpleJSONProtocol) ParseListBegin() (isNull bool, err error) {
985 if e := p.ParsePreValue(); e != nil {
986 return false, e
987 }
988 var b []byte
Jens Geyer8a0f8d12013-09-10 21:30:41 +0200989 b, err = p.reader.Peek(len(JSON_NULL))
Jens Geyer0e87c462013-06-18 22:25:07 +0200990 if err != nil {
991 return false, err
992 }
993 if len(b) >= 1 && b[0] == JSON_LBRACKET[0] {
994 p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_LIST_FIRST))
995 p.reader.ReadByte()
996 isNull = false
997 } else if len(b) >= len(JSON_NULL) && string(b) == string(JSON_NULL) {
998 isNull = true
999 } else {
1000 err = fmt.Errorf("Expected \"null\" or \"[\", received %q", b)
1001 }
1002 return isNull, NewTProtocolExceptionWithType(INVALID_DATA, err)
1003}
1004
1005func (p *TSimpleJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) {
1006 if isNull, e := p.ParseListBegin(); isNull || e != nil {
1007 return VOID, 0, e
1008 }
1009 bElemType, err := p.ReadByte()
1010 elemType = TType(bElemType)
1011 if err != nil {
1012 return elemType, size, err
1013 }
1014 nSize, err2 := p.ReadI64()
1015 size = int(nSize)
1016 return elemType, size, err2
1017}
1018
1019func (p *TSimpleJSONProtocol) ParseListEnd() error {
1020 if isNull, err := p.readIfNull(); isNull || err != nil {
1021 return err
1022 }
1023 if _ParseContext(p.parseContextStack[len(p.parseContextStack)-1]) != _CONTEXT_IN_LIST {
1024 e := fmt.Errorf("Expected to be in the List Context, but not in List Context")
1025 return NewTProtocolExceptionWithType(INVALID_DATA, e)
1026 }
1027 line, err := p.reader.ReadString(JSON_RBRACKET[0])
1028 if err != nil {
1029 return NewTProtocolException(err)
1030 }
1031 for _, char := range line {
1032 switch char {
1033 default:
1034 e := fmt.Errorf("Expecting end of list \"]\", but found: \"", line, "\"")
1035 return NewTProtocolExceptionWithType(INVALID_DATA, e)
1036 case ' ', '\n', '\r', '\t', rune(JSON_RBRACKET[0]):
1037 break
1038 }
1039 }
1040 p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1]
1041 return p.ParsePostValue()
1042}
1043
1044func (p *TSimpleJSONProtocol) readSingleValue() (interface{}, TType, error) {
1045 e := p.readNonSignificantWhitespace()
1046 if e != nil {
1047 return nil, VOID, NewTProtocolException(e)
1048 }
1049 b, e := p.reader.Peek(10)
1050 if len(b) > 0 {
1051 c := b[0]
1052 switch c {
1053 case JSON_NULL[0]:
1054 buf := make([]byte, len(JSON_NULL))
1055 _, e := p.reader.Read(buf)
1056 if e != nil {
1057 return nil, VOID, NewTProtocolException(e)
1058 }
1059 if string(JSON_NULL) != string(buf) {
1060 e = mismatch(string(JSON_NULL), string(buf))
1061 return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e)
1062 }
1063 return nil, VOID, nil
1064 case JSON_QUOTE:
1065 p.reader.ReadByte()
1066 v, e := p.ParseStringBody()
1067 if e != nil {
1068 return v, UTF8, NewTProtocolException(e)
1069 }
1070 if v == JSON_INFINITY {
1071 return INFINITY, DOUBLE, nil
1072 } else if v == JSON_NEGATIVE_INFINITY {
1073 return NEGATIVE_INFINITY, DOUBLE, nil
1074 } else if v == JSON_NAN {
1075 return NAN, DOUBLE, nil
1076 }
1077 return v, UTF8, nil
1078 case JSON_TRUE[0]:
1079 buf := make([]byte, len(JSON_TRUE))
1080 _, e := p.reader.Read(buf)
1081 if e != nil {
1082 return true, BOOL, NewTProtocolException(e)
1083 }
1084 if string(JSON_TRUE) != string(buf) {
1085 e := mismatch(string(JSON_TRUE), string(buf))
1086 return true, BOOL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1087 }
1088 return true, BOOL, nil
1089 case JSON_FALSE[0]:
1090 buf := make([]byte, len(JSON_FALSE))
1091 _, e := p.reader.Read(buf)
1092 if e != nil {
1093 return false, BOOL, NewTProtocolException(e)
1094 }
1095 if string(JSON_FALSE) != string(buf) {
1096 e := mismatch(string(JSON_FALSE), string(buf))
1097 return false, BOOL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1098 }
1099 return false, BOOL, nil
1100 case JSON_LBRACKET[0]:
1101 _, e := p.reader.ReadByte()
1102 return make([]interface{}, 0), LIST, NewTProtocolException(e)
1103 case JSON_LBRACE[0]:
1104 _, e := p.reader.ReadByte()
1105 return make(map[string]interface{}), STRUCT, NewTProtocolException(e)
1106 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'e', 'E', '.', '+', '-', JSON_INFINITY[0], JSON_NAN[0]:
1107 // assume numeric
1108 v, e := p.readNumeric()
1109 return v, DOUBLE, e
1110 default:
1111 e := fmt.Errorf("Expected element in list but found '%s' while parsing JSON.", string(c))
1112 return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e)
1113 }
1114 }
1115 e = fmt.Errorf("Cannot read a single element while parsing JSON.")
1116 return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e)
1117
1118}
1119
1120func (p *TSimpleJSONProtocol) readIfNull() (bool, error) {
1121 cont := true
Jens Geyer8a0f8d12013-09-10 21:30:41 +02001122 for cont {
Jens Geyer0e87c462013-06-18 22:25:07 +02001123 b, _ := p.reader.Peek(1)
1124 if len(b) < 1 {
1125 return false, nil
1126 }
1127 switch b[0] {
1128 default:
1129 return false, nil
1130 case JSON_NULL[0]:
1131 cont = false
1132 break
1133 case ' ', '\n', '\r', '\t':
1134 p.reader.ReadByte()
1135 break
1136 }
1137 }
Jens Geyer0e87c462013-06-18 22:25:07 +02001138 b, _ := p.reader.Peek(len(JSON_NULL))
1139 if string(b) == string(JSON_NULL) {
1140 p.reader.Read(b[0:len(JSON_NULL)])
1141 return true, nil
1142 }
1143 return false, nil
1144}
1145
1146func (p *TSimpleJSONProtocol) readQuoteIfNext() {
Jens Geyer0e87c462013-06-18 22:25:07 +02001147 b, _ := p.reader.Peek(1)
1148 if len(b) > 0 && b[0] == JSON_QUOTE {
1149 p.reader.ReadByte()
1150 }
1151}
1152
1153func (p *TSimpleJSONProtocol) readNumeric() (Numeric, error) {
1154 isNull, err := p.readIfNull()
1155 if isNull || err != nil {
1156 return NUMERIC_NULL, err
1157 }
1158 hasDecimalPoint := false
1159 nextCanBeSign := true
1160 hasE := false
1161 MAX_LEN := 40
1162 buf := bytes.NewBuffer(make([]byte, 0, MAX_LEN))
1163 continueFor := true
1164 inQuotes := false
1165 for continueFor {
1166 c, err := p.reader.ReadByte()
1167 if err != nil {
1168 if err == io.EOF {
1169 break
1170 }
1171 return NUMERIC_NULL, NewTProtocolException(err)
1172 }
1173 switch c {
1174 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
1175 buf.WriteByte(c)
1176 nextCanBeSign = false
1177 case '.':
1178 if hasDecimalPoint {
1179 e := fmt.Errorf("Unable to parse number with multiple decimal points '%s.'", buf.String())
1180 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1181 }
1182 if hasE {
1183 e := fmt.Errorf("Unable to parse number with decimal points in the exponent '%s.'", buf.String())
1184 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1185 }
1186 buf.WriteByte(c)
1187 hasDecimalPoint, nextCanBeSign = true, false
1188 case 'e', 'E':
1189 if hasE {
1190 e := fmt.Errorf("Unable to parse number with multiple exponents '%s%c'", buf.String(), c)
1191 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1192 }
1193 buf.WriteByte(c)
1194 hasE, nextCanBeSign = true, true
1195 case '-', '+':
1196 if !nextCanBeSign {
1197 e := fmt.Errorf("Negative sign within number")
1198 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1199 }
1200 buf.WriteByte(c)
1201 nextCanBeSign = false
1202 case ' ', 0, '\t', '\n', '\r', JSON_RBRACE[0], JSON_RBRACKET[0], JSON_COMMA[0], JSON_COLON[0]:
1203 p.reader.UnreadByte()
1204 continueFor = false
1205 case JSON_NAN[0]:
1206 if buf.Len() == 0 {
1207 buffer := make([]byte, len(JSON_NAN))
1208 buffer[0] = c
1209 _, e := p.reader.Read(buffer[1:])
1210 if e != nil {
1211 return NUMERIC_NULL, NewTProtocolException(e)
1212 }
1213 if JSON_NAN != string(buffer) {
1214 e := mismatch(JSON_NAN, string(buffer))
1215 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1216 }
1217 if inQuotes {
1218 p.readQuoteIfNext()
1219 }
1220 return NAN, nil
1221 } else {
1222 e := fmt.Errorf("Unable to parse number starting with character '%c'", c)
1223 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1224 }
1225 case JSON_INFINITY[0]:
1226 if buf.Len() == 0 || (buf.Len() == 1 && buf.Bytes()[0] == '+') {
1227 buffer := make([]byte, len(JSON_INFINITY))
1228 buffer[0] = c
1229 _, e := p.reader.Read(buffer[1:])
1230 if e != nil {
1231 return NUMERIC_NULL, NewTProtocolException(e)
1232 }
1233 if JSON_INFINITY != string(buffer) {
1234 e := mismatch(JSON_INFINITY, string(buffer))
1235 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1236 }
1237 if inQuotes {
1238 p.readQuoteIfNext()
1239 }
1240 return INFINITY, nil
1241 } else if buf.Len() == 1 && buf.Bytes()[0] == JSON_NEGATIVE_INFINITY[0] {
1242 buffer := make([]byte, len(JSON_NEGATIVE_INFINITY))
1243 buffer[0] = JSON_NEGATIVE_INFINITY[0]
1244 buffer[1] = c
1245 _, e := p.reader.Read(buffer[2:])
1246 if e != nil {
1247 return NUMERIC_NULL, NewTProtocolException(e)
1248 }
1249 if JSON_NEGATIVE_INFINITY != string(buffer) {
1250 e := mismatch(JSON_NEGATIVE_INFINITY, string(buffer))
1251 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1252 }
1253 if inQuotes {
1254 p.readQuoteIfNext()
1255 }
1256 return NEGATIVE_INFINITY, nil
1257 } else {
1258 e := fmt.Errorf("Unable to parse number starting with character '%c' due to existing buffer %s", c, buf.String())
1259 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1260 }
1261 case JSON_QUOTE:
1262 if !inQuotes {
1263 inQuotes = true
1264 } else {
1265 break
1266 }
1267 default:
1268 e := fmt.Errorf("Unable to parse number starting with character '%c'", c)
1269 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1270 }
1271 }
1272 if buf.Len() == 0 {
1273 e := fmt.Errorf("Unable to parse number from empty string ''")
1274 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1275 }
1276 return NewNumericFromJSONString(buf.String(), false), nil
1277}