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