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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
34 type _ParseContext int
37 _CONTEXT_IN_TOPLEVEL _ParseContext = 1
38 _CONTEXT_IN_LIST_FIRST _ParseContext = 2
39 _CONTEXT_IN_LIST _ParseContext = 3
40 _CONTEXT_IN_OBJECT_FIRST _ParseContext = 4
41 _CONTEXT_IN_OBJECT_NEXT_KEY _ParseContext = 5
42 _CONTEXT_IN_OBJECT_NEXT_VALUE _ParseContext = 6
45 func (p _ParseContext) String() string {
47 case _CONTEXT_IN_TOPLEVEL:
49 case _CONTEXT_IN_LIST_FIRST:
51 case _CONTEXT_IN_LIST:
53 case _CONTEXT_IN_OBJECT_FIRST:
55 case _CONTEXT_IN_OBJECT_NEXT_KEY:
56 return "OBJECT-NEXT-KEY"
57 case _CONTEXT_IN_OBJECT_NEXT_VALUE:
58 return "OBJECT-NEXT-VALUE"
60 return "UNKNOWN-PARSE-CONTEXT"
63 // Simple JSON protocol implementation for thrift.
65 // This protocol produces/consumes a simple output format
66 // suitable for parsing by scripting languages. It should not be
67 // confused with the full-featured TJSONProtocol.
69 type TSimpleJSONProtocol struct {
72 parseContextStack []int
80 func NewTSimpleJSONProtocol(t TTransport) *TSimpleJSONProtocol {
81 v := &TSimpleJSONProtocol{trans: t,
82 writer: bufio.NewWriter(t),
83 reader: bufio.NewReader(t),
85 v.parseContextStack = append(v.parseContextStack, int(_CONTEXT_IN_TOPLEVEL))
86 v.dumpContext = append(v.dumpContext, int(_CONTEXT_IN_TOPLEVEL))
91 type TSimpleJSONProtocolFactory struct{}
93 func (p *TSimpleJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol {
94 return NewTSimpleJSONProtocol(trans)
97 func NewTSimpleJSONProtocolFactory() *TSimpleJSONProtocolFactory {
98 return &TSimpleJSONProtocolFactory{}
109 JSON_QUOTE_BYTES []byte
114 JSON_NEGATIVE_INFINITY string
116 JSON_INFINITY_BYTES []byte
117 JSON_NEGATIVE_INFINITY_BYTES []byte
118 JSON_NAN_BYTES []byte
119 json_nonbase_map_elem_bytes []byte
123 JSON_COMMA = []byte{','}
124 JSON_COLON = []byte{':'}
125 JSON_LBRACE = []byte{'{'}
126 JSON_RBRACE = []byte{'}'}
127 JSON_LBRACKET = []byte{'['}
128 JSON_RBRACKET = []byte{']'}
130 JSON_QUOTE_BYTES = []byte{'"'}
131 JSON_NULL = []byte{'n', 'u', 'l', 'l'}
132 JSON_TRUE = []byte{'t', 'r', 'u', 'e'}
133 JSON_FALSE = []byte{'f', 'a', 'l', 's', 'e'}
134 JSON_INFINITY = "Infinity"
135 JSON_NEGATIVE_INFINITY = "-Infinity"
137 JSON_INFINITY_BYTES = []byte{'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'}
138 JSON_NEGATIVE_INFINITY_BYTES = []byte{'-', 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'}
139 JSON_NAN_BYTES = []byte{'N', 'a', 'N'}
140 json_nonbase_map_elem_bytes = []byte{']', ',', '['}
143 func jsonQuote(s string) string {
144 b, _ := json.Marshal(s)
149 func jsonUnquote(s string) (string, bool) {
151 err := json.Unmarshal([]byte(s), s1)
152 return *s1, err == nil
155 func mismatch(expected, actual string) error {
156 return fmt.Errorf("Expected '%s' but found '%s' while parsing JSON.", expected, actual)
159 func (p *TSimpleJSONProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) error {
160 p.resetContextStack() // THRIFT-3735
161 if e := p.OutputListBegin(); e != nil {
164 if e := p.WriteString(name); e != nil {
167 if e := p.WriteByte(int8(typeId)); e != nil {
170 if e := p.WriteI32(seqId); e != nil {
176 func (p *TSimpleJSONProtocol) WriteMessageEnd() error {
177 return p.OutputListEnd()
180 func (p *TSimpleJSONProtocol) WriteStructBegin(name string) error {
181 if e := p.OutputObjectBegin(); e != nil {
187 func (p *TSimpleJSONProtocol) WriteStructEnd() error {
188 return p.OutputObjectEnd()
191 func (p *TSimpleJSONProtocol) WriteFieldBegin(name string, typeId TType, id int16) error {
192 if e := p.WriteString(name); e != nil {
198 func (p *TSimpleJSONProtocol) WriteFieldEnd() error {
199 //return p.OutputListEnd()
203 func (p *TSimpleJSONProtocol) WriteFieldStop() error { return nil }
205 func (p *TSimpleJSONProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error {
206 if e := p.OutputListBegin(); e != nil {
209 if e := p.WriteByte(int8(keyType)); e != nil {
212 if e := p.WriteByte(int8(valueType)); e != nil {
215 return p.WriteI32(int32(size))
218 func (p *TSimpleJSONProtocol) WriteMapEnd() error {
219 return p.OutputListEnd()
222 func (p *TSimpleJSONProtocol) WriteListBegin(elemType TType, size int) error {
223 return p.OutputElemListBegin(elemType, size)
226 func (p *TSimpleJSONProtocol) WriteListEnd() error {
227 return p.OutputListEnd()
230 func (p *TSimpleJSONProtocol) WriteSetBegin(elemType TType, size int) error {
231 return p.OutputElemListBegin(elemType, size)
234 func (p *TSimpleJSONProtocol) WriteSetEnd() error {
235 return p.OutputListEnd()
238 func (p *TSimpleJSONProtocol) WriteBool(b bool) error {
239 return p.OutputBool(b)
242 func (p *TSimpleJSONProtocol) WriteByte(b int8) error {
243 return p.WriteI32(int32(b))
246 func (p *TSimpleJSONProtocol) WriteI16(v int16) error {
247 return p.WriteI32(int32(v))
250 func (p *TSimpleJSONProtocol) WriteI32(v int32) error {
251 return p.OutputI64(int64(v))
254 func (p *TSimpleJSONProtocol) WriteI64(v int64) error {
255 return p.OutputI64(int64(v))
258 func (p *TSimpleJSONProtocol) WriteDouble(v float64) error {
259 return p.OutputF64(v)
262 func (p *TSimpleJSONProtocol) WriteString(v string) error {
263 return p.OutputString(v)
266 func (p *TSimpleJSONProtocol) WriteBinary(v []byte) error {
267 // JSON library only takes in a string,
268 // not an arbitrary byte array, to ensure bytes are transmitted
269 // efficiently we must convert this into a valid JSON string
270 // therefore we use base64 encoding to avoid excessive escaping/quoting
271 if e := p.OutputPreValue(); e != nil {
274 if _, e := p.write(JSON_QUOTE_BYTES); e != nil {
275 return NewTProtocolException(e)
277 writer := base64.NewEncoder(base64.StdEncoding, p.writer)
278 if _, e := writer.Write(v); e != nil {
279 p.writer.Reset(p.trans) // THRIFT-3735
280 return NewTProtocolException(e)
282 if e := writer.Close(); e != nil {
283 return NewTProtocolException(e)
285 if _, e := p.write(JSON_QUOTE_BYTES); e != nil {
286 return NewTProtocolException(e)
288 return p.OutputPostValue()
292 func (p *TSimpleJSONProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) {
293 p.resetContextStack() // THRIFT-3735
294 if isNull, err := p.ParseListBegin(); isNull || err != nil {
295 return name, typeId, seqId, err
297 if name, err = p.ReadString(); err != nil {
298 return name, typeId, seqId, err
300 bTypeId, err := p.ReadByte()
301 typeId = TMessageType(bTypeId)
303 return name, typeId, seqId, err
305 if seqId, err = p.ReadI32(); err != nil {
306 return name, typeId, seqId, err
308 return name, typeId, seqId, nil
311 func (p *TSimpleJSONProtocol) ReadMessageEnd() error {
312 return p.ParseListEnd()
315 func (p *TSimpleJSONProtocol) ReadStructBegin() (name string, err error) {
316 _, err = p.ParseObjectStart()
320 func (p *TSimpleJSONProtocol) ReadStructEnd() error {
321 return p.ParseObjectEnd()
324 func (p *TSimpleJSONProtocol) ReadFieldBegin() (string, TType, int16, error) {
325 if err := p.ParsePreValue(); err != nil {
326 return "", STOP, 0, err
328 b, _ := p.reader.Peek(1)
332 return "", STOP, 0, nil
335 name, err := p.ParseStringBody()
336 // simplejson is not meant to be read back into thrift
337 // - see http://wiki.apache.org/thrift/ThriftUsageJava
338 // - use JSON instead
340 return name, STOP, 0, err
342 return name, STOP, -1, p.ParsePostValue()
344 if err = p.ParsePostValue(); err != nil {
345 return name, STOP, 0, err
347 if isNull, err := p.ParseListBegin(); isNull || err != nil {
348 return name, STOP, 0, err
350 bType, err := p.ReadByte()
351 thetype := TType(bType)
353 return name, thetype, 0, err
355 id, err := p.ReadI16()
356 return name, thetype, id, err
359 e := fmt.Errorf("Expected \"}\" or '\"', but found: '%s'", string(b))
360 return "", STOP, 0, NewTProtocolExceptionWithType(INVALID_DATA, e)
362 return "", STOP, 0, NewTProtocolException(io.EOF)
365 func (p *TSimpleJSONProtocol) ReadFieldEnd() error {
367 //return p.ParseListEnd()
370 func (p *TSimpleJSONProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, e error) {
371 if isNull, e := p.ParseListBegin(); isNull || e != nil {
372 return VOID, VOID, 0, e
376 bKeyType, e := p.ReadByte()
377 keyType = TType(bKeyType)
379 return keyType, valueType, size, e
383 bValueType, e := p.ReadByte()
384 valueType = TType(bValueType)
386 return keyType, valueType, size, e
390 iSize, err := p.ReadI64()
392 return keyType, valueType, size, err
395 func (p *TSimpleJSONProtocol) ReadMapEnd() error {
396 return p.ParseListEnd()
399 func (p *TSimpleJSONProtocol) ReadListBegin() (elemType TType, size int, e error) {
400 return p.ParseElemListBegin()
403 func (p *TSimpleJSONProtocol) ReadListEnd() error {
404 return p.ParseListEnd()
407 func (p *TSimpleJSONProtocol) ReadSetBegin() (elemType TType, size int, e error) {
408 return p.ParseElemListBegin()
411 func (p *TSimpleJSONProtocol) ReadSetEnd() error {
412 return p.ParseListEnd()
415 func (p *TSimpleJSONProtocol) ReadBool() (bool, error) {
418 if err := p.ParsePreValue(); err != nil {
421 f, _ := p.reader.Peek(1)
425 b := make([]byte, len(JSON_TRUE))
426 _, err := p.reader.Read(b)
428 return false, NewTProtocolException(err)
430 if string(b) == string(JSON_TRUE) {
433 e := fmt.Errorf("Expected \"true\" but found: %s", string(b))
434 return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
438 b := make([]byte, len(JSON_FALSE))
439 _, err := p.reader.Read(b)
441 return false, NewTProtocolException(err)
443 if string(b) == string(JSON_FALSE) {
446 e := fmt.Errorf("Expected \"false\" but found: %s", string(b))
447 return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
451 b := make([]byte, len(JSON_NULL))
452 _, err := p.reader.Read(b)
454 return false, NewTProtocolException(err)
456 if string(b) == string(JSON_NULL) {
459 e := fmt.Errorf("Expected \"null\" but found: %s", string(b))
460 return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
463 e := fmt.Errorf("Expected \"true\", \"false\", or \"null\" but found: %s", string(f))
464 return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
467 return value, p.ParsePostValue()
470 func (p *TSimpleJSONProtocol) ReadByte() (int8, error) {
471 v, err := p.ReadI64()
475 func (p *TSimpleJSONProtocol) ReadI16() (int16, error) {
476 v, err := p.ReadI64()
480 func (p *TSimpleJSONProtocol) ReadI32() (int32, error) {
481 v, err := p.ReadI64()
485 func (p *TSimpleJSONProtocol) ReadI64() (int64, error) {
486 v, _, err := p.ParseI64()
490 func (p *TSimpleJSONProtocol) ReadDouble() (float64, error) {
491 v, _, err := p.ParseF64()
495 func (p *TSimpleJSONProtocol) ReadString() (string, error) {
497 if err := p.ParsePreValue(); err != nil {
500 f, _ := p.reader.Peek(1)
501 if len(f) > 0 && f[0] == JSON_QUOTE {
503 value, err := p.ParseStringBody()
508 } else if len(f) > 0 && f[0] == JSON_NULL[0] {
509 b := make([]byte, len(JSON_NULL))
510 _, err := p.reader.Read(b)
512 return v, NewTProtocolException(err)
514 if string(b) != string(JSON_NULL) {
515 e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b))
516 return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
519 e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f))
520 return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
522 return v, p.ParsePostValue()
525 func (p *TSimpleJSONProtocol) ReadBinary() ([]byte, error) {
527 if err := p.ParsePreValue(); err != nil {
530 f, _ := p.reader.Peek(1)
531 if len(f) > 0 && f[0] == JSON_QUOTE {
533 value, err := p.ParseBase64EncodedBody()
538 } else if len(f) > 0 && f[0] == JSON_NULL[0] {
539 b := make([]byte, len(JSON_NULL))
540 _, err := p.reader.Read(b)
542 return v, NewTProtocolException(err)
544 if string(b) != string(JSON_NULL) {
545 e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b))
546 return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
549 e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f))
550 return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
553 return v, p.ParsePostValue()
556 func (p *TSimpleJSONProtocol) Flush(ctx context.Context) (err error) {
557 return NewTProtocolException(p.writer.Flush())
560 func (p *TSimpleJSONProtocol) Skip(fieldType TType) (err error) {
561 return SkipDefaultDepth(p, fieldType)
564 func (p *TSimpleJSONProtocol) Transport() TTransport {
568 func (p *TSimpleJSONProtocol) OutputPreValue() error {
569 cxt := _ParseContext(p.dumpContext[len(p.dumpContext)-1])
571 case _CONTEXT_IN_LIST, _CONTEXT_IN_OBJECT_NEXT_KEY:
572 if _, e := p.write(JSON_COMMA); e != nil {
573 return NewTProtocolException(e)
576 case _CONTEXT_IN_OBJECT_NEXT_VALUE:
577 if _, e := p.write(JSON_COLON); e != nil {
578 return NewTProtocolException(e)
585 func (p *TSimpleJSONProtocol) OutputPostValue() error {
586 cxt := _ParseContext(p.dumpContext[len(p.dumpContext)-1])
588 case _CONTEXT_IN_LIST_FIRST:
589 p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
590 p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_LIST))
592 case _CONTEXT_IN_OBJECT_FIRST:
593 p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
594 p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_VALUE))
596 case _CONTEXT_IN_OBJECT_NEXT_KEY:
597 p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
598 p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_VALUE))
600 case _CONTEXT_IN_OBJECT_NEXT_VALUE:
601 p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
602 p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_KEY))
608 func (p *TSimpleJSONProtocol) OutputBool(value bool) error {
609 if e := p.OutputPreValue(); e != nil {
614 v = string(JSON_TRUE)
616 v = string(JSON_FALSE)
618 switch _ParseContext(p.dumpContext[len(p.dumpContext)-1]) {
619 case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
623 if e := p.OutputStringData(v); e != nil {
626 return p.OutputPostValue()
629 func (p *TSimpleJSONProtocol) OutputNull() error {
630 if e := p.OutputPreValue(); e != nil {
633 if _, e := p.write(JSON_NULL); e != nil {
634 return NewTProtocolException(e)
636 return p.OutputPostValue()
639 func (p *TSimpleJSONProtocol) OutputF64(value float64) error {
640 if e := p.OutputPreValue(); e != nil {
644 if math.IsNaN(value) {
645 v = string(JSON_QUOTE) + JSON_NAN + string(JSON_QUOTE)
646 } else if math.IsInf(value, 1) {
647 v = string(JSON_QUOTE) + JSON_INFINITY + string(JSON_QUOTE)
648 } else if math.IsInf(value, -1) {
649 v = string(JSON_QUOTE) + JSON_NEGATIVE_INFINITY + string(JSON_QUOTE)
651 v = strconv.FormatFloat(value, 'g', -1, 64)
652 switch _ParseContext(p.dumpContext[len(p.dumpContext)-1]) {
653 case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
654 v = string(JSON_QUOTE) + v + string(JSON_QUOTE)
658 if e := p.OutputStringData(v); e != nil {
661 return p.OutputPostValue()
664 func (p *TSimpleJSONProtocol) OutputI64(value int64) error {
665 if e := p.OutputPreValue(); e != nil {
668 v := strconv.FormatInt(value, 10)
669 switch _ParseContext(p.dumpContext[len(p.dumpContext)-1]) {
670 case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
674 if e := p.OutputStringData(v); e != nil {
677 return p.OutputPostValue()
680 func (p *TSimpleJSONProtocol) OutputString(s string) error {
681 if e := p.OutputPreValue(); e != nil {
684 if e := p.OutputStringData(jsonQuote(s)); e != nil {
687 return p.OutputPostValue()
690 func (p *TSimpleJSONProtocol) OutputStringData(s string) error {
691 _, e := p.write([]byte(s))
692 return NewTProtocolException(e)
695 func (p *TSimpleJSONProtocol) OutputObjectBegin() error {
696 if e := p.OutputPreValue(); e != nil {
699 if _, e := p.write(JSON_LBRACE); e != nil {
700 return NewTProtocolException(e)
702 p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_FIRST))
706 func (p *TSimpleJSONProtocol) OutputObjectEnd() error {
707 if _, e := p.write(JSON_RBRACE); e != nil {
708 return NewTProtocolException(e)
710 p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
711 if e := p.OutputPostValue(); e != nil {
717 func (p *TSimpleJSONProtocol) OutputListBegin() error {
718 if e := p.OutputPreValue(); e != nil {
721 if _, e := p.write(JSON_LBRACKET); e != nil {
722 return NewTProtocolException(e)
724 p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_LIST_FIRST))
728 func (p *TSimpleJSONProtocol) OutputListEnd() error {
729 if _, e := p.write(JSON_RBRACKET); e != nil {
730 return NewTProtocolException(e)
732 p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
733 if e := p.OutputPostValue(); e != nil {
739 func (p *TSimpleJSONProtocol) OutputElemListBegin(elemType TType, size int) error {
740 if e := p.OutputListBegin(); e != nil {
743 if e := p.WriteByte(int8(elemType)); e != nil {
746 if e := p.WriteI64(int64(size)); e != nil {
752 func (p *TSimpleJSONProtocol) ParsePreValue() error {
753 if e := p.readNonSignificantWhitespace(); e != nil {
754 return NewTProtocolException(e)
756 cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1])
757 b, _ := p.reader.Peek(1)
759 case _CONTEXT_IN_LIST:
762 case JSON_RBRACKET[0]:
766 if e := p.readNonSignificantWhitespace(); e != nil {
767 return NewTProtocolException(e)
771 e := fmt.Errorf("Expected \"]\" or \",\" in list context, but found \"%s\"", string(b))
772 return NewTProtocolExceptionWithType(INVALID_DATA, e)
776 case _CONTEXT_IN_OBJECT_NEXT_KEY:
783 if e := p.readNonSignificantWhitespace(); e != nil {
784 return NewTProtocolException(e)
788 e := fmt.Errorf("Expected \"}\" or \",\" in object context, but found \"%s\"", string(b))
789 return NewTProtocolExceptionWithType(INVALID_DATA, e)
793 case _CONTEXT_IN_OBJECT_NEXT_VALUE:
798 if e := p.readNonSignificantWhitespace(); e != nil {
799 return NewTProtocolException(e)
803 e := fmt.Errorf("Expected \":\" in object context, but found \"%s\"", string(b))
804 return NewTProtocolExceptionWithType(INVALID_DATA, e)
812 func (p *TSimpleJSONProtocol) ParsePostValue() error {
813 if e := p.readNonSignificantWhitespace(); e != nil {
814 return NewTProtocolException(e)
816 cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1])
818 case _CONTEXT_IN_LIST_FIRST:
819 p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1]
820 p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_LIST))
822 case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
823 p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1]
824 p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_OBJECT_NEXT_VALUE))
826 case _CONTEXT_IN_OBJECT_NEXT_VALUE:
827 p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1]
828 p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_OBJECT_NEXT_KEY))
834 func (p *TSimpleJSONProtocol) readNonSignificantWhitespace() error {
836 b, _ := p.reader.Peek(1)
841 case ' ', '\r', '\n', '\t':
852 func (p *TSimpleJSONProtocol) ParseStringBody() (string, error) {
853 line, err := p.reader.ReadString(JSON_QUOTE)
855 return "", NewTProtocolException(err)
858 // count number of escapes to see if we need to keep going
861 if line[l-i-1] != '\\' {
866 v, ok := jsonUnquote(string(JSON_QUOTE) + line)
868 return "", NewTProtocolException(err)
872 s, err := p.ParseQuotedStringBody()
874 return "", NewTProtocolException(err)
876 str := string(JSON_QUOTE) + line + s
877 v, ok := jsonUnquote(str)
879 e := fmt.Errorf("Unable to parse as JSON string %s", str)
880 return "", NewTProtocolExceptionWithType(INVALID_DATA, e)
885 func (p *TSimpleJSONProtocol) ParseQuotedStringBody() (string, error) {
886 line, err := p.reader.ReadString(JSON_QUOTE)
888 return "", NewTProtocolException(err)
891 // count number of escapes to see if we need to keep going
894 if line[l-i-1] != '\\' {
901 s, err := p.ParseQuotedStringBody()
903 return "", NewTProtocolException(err)
909 func (p *TSimpleJSONProtocol) ParseBase64EncodedBody() ([]byte, error) {
910 line, err := p.reader.ReadBytes(JSON_QUOTE)
912 return line, NewTProtocolException(err)
914 line2 := line[0 : len(line)-1]
918 fill := [...]byte{'=', '=', '='}
919 line2 = append(line2, fill[:pad]...)
922 output := make([]byte, base64.StdEncoding.DecodedLen(l))
923 n, err := base64.StdEncoding.Decode(output, line2)
924 return output[0:n], NewTProtocolException(err)
927 func (p *TSimpleJSONProtocol) ParseI64() (int64, bool, error) {
928 if err := p.ParsePreValue(); err != nil {
933 if p.safePeekContains(JSON_NULL) {
934 p.reader.Read(make([]byte, len(JSON_NULL)))
937 num, err := p.readNumeric()
938 isnull = (num == nil)
943 return value, isnull, err
946 return value, isnull, p.ParsePostValue()
949 func (p *TSimpleJSONProtocol) ParseF64() (float64, bool, error) {
950 if err := p.ParsePreValue(); err != nil {
955 if p.safePeekContains(JSON_NULL) {
956 p.reader.Read(make([]byte, len(JSON_NULL)))
959 num, err := p.readNumeric()
960 isnull = (num == nil)
962 value = num.Float64()
965 return value, isnull, err
968 return value, isnull, p.ParsePostValue()
971 func (p *TSimpleJSONProtocol) ParseObjectStart() (bool, error) {
972 if err := p.ParsePreValue(); err != nil {
976 b, err := p.reader.Peek(1)
980 if len(b) > 0 && b[0] == JSON_LBRACE[0] {
982 p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_OBJECT_FIRST))
984 } else if p.safePeekContains(JSON_NULL) {
987 e := fmt.Errorf("Expected '{' or null, but found '%s'", string(b))
988 return false, NewTProtocolExceptionWithType(INVALID_DATA, e)
991 func (p *TSimpleJSONProtocol) ParseObjectEnd() error {
992 if isNull, err := p.readIfNull(); isNull || err != nil {
995 cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1])
996 if (cxt != _CONTEXT_IN_OBJECT_FIRST) && (cxt != _CONTEXT_IN_OBJECT_NEXT_KEY) {
997 e := fmt.Errorf("Expected to be in the Object Context, but not in Object Context (%d)", cxt)
998 return NewTProtocolExceptionWithType(INVALID_DATA, e)
1000 line, err := p.reader.ReadString(JSON_RBRACE[0])
1002 return NewTProtocolException(err)
1004 for _, char := range line {
1007 e := fmt.Errorf("Expecting end of object \"}\", but found: \"%s\"", line)
1008 return NewTProtocolExceptionWithType(INVALID_DATA, e)
1009 case ' ', '\n', '\r', '\t', '}':
1013 p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1]
1014 return p.ParsePostValue()
1017 func (p *TSimpleJSONProtocol) ParseListBegin() (isNull bool, err error) {
1018 if e := p.ParsePreValue(); e != nil {
1022 b, err = p.reader.Peek(1)
1026 if len(b) >= 1 && b[0] == JSON_LBRACKET[0] {
1027 p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_LIST_FIRST))
1030 } else if p.safePeekContains(JSON_NULL) {
1033 err = fmt.Errorf("Expected \"null\" or \"[\", received %q", b)
1035 return isNull, NewTProtocolExceptionWithType(INVALID_DATA, err)
1038 func (p *TSimpleJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) {
1039 if isNull, e := p.ParseListBegin(); isNull || e != nil {
1042 bElemType, err := p.ReadByte()
1043 elemType = TType(bElemType)
1045 return elemType, size, err
1047 nSize, err2 := p.ReadI64()
1049 return elemType, size, err2
1052 func (p *TSimpleJSONProtocol) ParseListEnd() error {
1053 if isNull, err := p.readIfNull(); isNull || err != nil {
1056 cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1])
1057 if cxt != _CONTEXT_IN_LIST {
1058 e := fmt.Errorf("Expected to be in the List Context, but not in List Context (%d)", cxt)
1059 return NewTProtocolExceptionWithType(INVALID_DATA, e)
1061 line, err := p.reader.ReadString(JSON_RBRACKET[0])
1063 return NewTProtocolException(err)
1065 for _, char := range line {
1068 e := fmt.Errorf("Expecting end of list \"]\", but found: \"%v\"", line)
1069 return NewTProtocolExceptionWithType(INVALID_DATA, e)
1070 case ' ', '\n', '\r', '\t', rune(JSON_RBRACKET[0]):
1074 p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1]
1075 if _ParseContext(p.parseContextStack[len(p.parseContextStack)-1]) == _CONTEXT_IN_TOPLEVEL {
1078 return p.ParsePostValue()
1081 func (p *TSimpleJSONProtocol) readSingleValue() (interface{}, TType, error) {
1082 e := p.readNonSignificantWhitespace()
1084 return nil, VOID, NewTProtocolException(e)
1086 b, e := p.reader.Peek(1)
1091 buf := make([]byte, len(JSON_NULL))
1092 _, e := p.reader.Read(buf)
1094 return nil, VOID, NewTProtocolException(e)
1096 if string(JSON_NULL) != string(buf) {
1097 e = mismatch(string(JSON_NULL), string(buf))
1098 return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e)
1100 return nil, VOID, nil
1103 v, e := p.ParseStringBody()
1105 return v, UTF8, NewTProtocolException(e)
1107 if v == JSON_INFINITY {
1108 return INFINITY, DOUBLE, nil
1109 } else if v == JSON_NEGATIVE_INFINITY {
1110 return NEGATIVE_INFINITY, DOUBLE, nil
1111 } else if v == JSON_NAN {
1112 return NAN, DOUBLE, nil
1116 buf := make([]byte, len(JSON_TRUE))
1117 _, e := p.reader.Read(buf)
1119 return true, BOOL, NewTProtocolException(e)
1121 if string(JSON_TRUE) != string(buf) {
1122 e := mismatch(string(JSON_TRUE), string(buf))
1123 return true, BOOL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1125 return true, BOOL, nil
1127 buf := make([]byte, len(JSON_FALSE))
1128 _, e := p.reader.Read(buf)
1130 return false, BOOL, NewTProtocolException(e)
1132 if string(JSON_FALSE) != string(buf) {
1133 e := mismatch(string(JSON_FALSE), string(buf))
1134 return false, BOOL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1136 return false, BOOL, nil
1137 case JSON_LBRACKET[0]:
1138 _, e := p.reader.ReadByte()
1139 return make([]interface{}, 0), LIST, NewTProtocolException(e)
1140 case JSON_LBRACE[0]:
1141 _, e := p.reader.ReadByte()
1142 return make(map[string]interface{}), STRUCT, NewTProtocolException(e)
1143 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'e', 'E', '.', '+', '-', JSON_INFINITY[0], JSON_NAN[0]:
1145 v, e := p.readNumeric()
1148 e := fmt.Errorf("Expected element in list but found '%s' while parsing JSON.", string(c))
1149 return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e)
1152 e = fmt.Errorf("Cannot read a single element while parsing JSON.")
1153 return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e)
1157 func (p *TSimpleJSONProtocol) readIfNull() (bool, error) {
1160 b, _ := p.reader.Peek(1)
1170 case ' ', '\n', '\r', '\t':
1175 if p.safePeekContains(JSON_NULL) {
1176 p.reader.Read(make([]byte, len(JSON_NULL)))
1182 func (p *TSimpleJSONProtocol) readQuoteIfNext() {
1183 b, _ := p.reader.Peek(1)
1184 if len(b) > 0 && b[0] == JSON_QUOTE {
1189 func (p *TSimpleJSONProtocol) readNumeric() (Numeric, error) {
1190 isNull, err := p.readIfNull()
1191 if isNull || err != nil {
1192 return NUMERIC_NULL, err
1194 hasDecimalPoint := false
1195 nextCanBeSign := true
1198 buf := bytes.NewBuffer(make([]byte, 0, MAX_LEN))
1202 c, err := p.reader.ReadByte()
1207 return NUMERIC_NULL, NewTProtocolException(err)
1210 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
1212 nextCanBeSign = false
1214 if hasDecimalPoint {
1215 e := fmt.Errorf("Unable to parse number with multiple decimal points '%s.'", buf.String())
1216 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1219 e := fmt.Errorf("Unable to parse number with decimal points in the exponent '%s.'", buf.String())
1220 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1223 hasDecimalPoint, nextCanBeSign = true, false
1226 e := fmt.Errorf("Unable to parse number with multiple exponents '%s%c'", buf.String(), c)
1227 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1230 hasE, nextCanBeSign = true, true
1233 e := fmt.Errorf("Negative sign within number")
1234 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1237 nextCanBeSign = false
1238 case ' ', 0, '\t', '\n', '\r', JSON_RBRACE[0], JSON_RBRACKET[0], JSON_COMMA[0], JSON_COLON[0]:
1239 p.reader.UnreadByte()
1243 buffer := make([]byte, len(JSON_NAN))
1245 _, e := p.reader.Read(buffer[1:])
1247 return NUMERIC_NULL, NewTProtocolException(e)
1249 if JSON_NAN != string(buffer) {
1250 e := mismatch(JSON_NAN, string(buffer))
1251 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1258 e := fmt.Errorf("Unable to parse number starting with character '%c'", c)
1259 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1261 case JSON_INFINITY[0]:
1262 if buf.Len() == 0 || (buf.Len() == 1 && buf.Bytes()[0] == '+') {
1263 buffer := make([]byte, len(JSON_INFINITY))
1265 _, e := p.reader.Read(buffer[1:])
1267 return NUMERIC_NULL, NewTProtocolException(e)
1269 if JSON_INFINITY != string(buffer) {
1270 e := mismatch(JSON_INFINITY, string(buffer))
1271 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1276 return INFINITY, nil
1277 } else if buf.Len() == 1 && buf.Bytes()[0] == JSON_NEGATIVE_INFINITY[0] {
1278 buffer := make([]byte, len(JSON_NEGATIVE_INFINITY))
1279 buffer[0] = JSON_NEGATIVE_INFINITY[0]
1281 _, e := p.reader.Read(buffer[2:])
1283 return NUMERIC_NULL, NewTProtocolException(e)
1285 if JSON_NEGATIVE_INFINITY != string(buffer) {
1286 e := mismatch(JSON_NEGATIVE_INFINITY, string(buffer))
1287 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1292 return NEGATIVE_INFINITY, nil
1294 e := fmt.Errorf("Unable to parse number starting with character '%c' due to existing buffer %s", c, buf.String())
1295 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1304 e := fmt.Errorf("Unable to parse number starting with character '%c'", c)
1305 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1309 e := fmt.Errorf("Unable to parse number from empty string ''")
1310 return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
1312 return NewNumericFromJSONString(buf.String(), false), nil
1315 // Safely peeks into the buffer, reading only what is necessary
1316 func (p *TSimpleJSONProtocol) safePeekContains(b []byte) bool {
1317 for i := 0; i < len(b); i++ {
1318 a, _ := p.reader.Peek(i + 1)
1319 if len(a) < (i+1) || a[i] != b[i] {
1326 // Reset the context stack to its initial state.
1327 func (p *TSimpleJSONProtocol) resetContextStack() {
1328 p.parseContextStack = []int{int(_CONTEXT_IN_TOPLEVEL)}
1329 p.dumpContext = []int{int(_CONTEXT_IN_TOPLEVEL)}
1332 func (p *TSimpleJSONProtocol) write(b []byte) (int, error) {
1333 n, err := p.writer.Write(b)
1335 p.writer.Reset(p.trans) // THRIFT-3735