You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by cl...@apache.org on 2011/02/20 03:39:21 UTC
svn commit: r1072478 [7/8] - in /thrift/trunk: ./ compiler/cpp/
compiler/cpp/src/generate/ lib/ lib/go/ lib/go/thrift/ test/ tutorial/go/
tutorial/go/src/
Added: thrift/trunk/lib/go/thrift/tsimple_json_protocol.go
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/go/thrift/tsimple_json_protocol.go?rev=1072478&view=auto
==============================================================================
--- thrift/trunk/lib/go/thrift/tsimple_json_protocol.go (added)
+++ thrift/trunk/lib/go/thrift/tsimple_json_protocol.go Sun Feb 20 02:39:19 2011
@@ -0,0 +1,1281 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+ "bufio"
+ "bytes"
+ "container/vector"
+ "encoding/base64"
+ "fmt"
+ "io"
+ "json"
+ "math"
+ "os"
+ "strconv"
+ "strings"
+)
+
+type _ParseContext int
+
+const (
+ _CONTEXT_IN_TOPLEVEL _ParseContext = 1
+ _CONTEXT_IN_LIST_FIRST _ParseContext = 2
+ _CONTEXT_IN_LIST _ParseContext = 3
+ _CONTEXT_IN_OBJECT_FIRST _ParseContext = 4
+ _CONTEXT_IN_OBJECT_NEXT_KEY _ParseContext = 5
+ _CONTEXT_IN_OBJECT_NEXT_VALUE _ParseContext = 6
+)
+
+func (p _ParseContext) String() string {
+ switch p {
+ case _CONTEXT_IN_TOPLEVEL:
+ return "TOPLEVEL"
+ case _CONTEXT_IN_LIST_FIRST:
+ return "LIST-FIRST"
+ case _CONTEXT_IN_LIST:
+ return "LIST"
+ case _CONTEXT_IN_OBJECT_FIRST:
+ return "OBJECT-FIRST"
+ case _CONTEXT_IN_OBJECT_NEXT_KEY:
+ return "OBJECT-NEXT-KEY"
+ case _CONTEXT_IN_OBJECT_NEXT_VALUE:
+ return "OBJECT-NEXT-VALUE"
+ }
+ return "UNKNOWN-PARSE-CONTEXT"
+}
+
+/**
+ * JSON protocol implementation for thrift.
+ *
+ * This protocol produces/consumes a simple output format
+ * suitable for parsing by scripting languages. It should not be
+ * confused with the full-featured TJSONProtocol.
+ *
+ */
+type TSimpleJSONProtocol struct {
+ //TProtocolBase;
+ trans TTransport
+
+ /**
+ * Stack of nested contexts that we may be in.
+ */
+ parseContextStack vector.IntVector
+ /**
+ * Stack of nested contexts that we may be in.
+ */
+ dumpContext vector.IntVector
+
+ /**
+ * Current context that we are in
+ */
+ writer TTransport
+ reader *bufio.Reader
+}
+
+/**
+ * Constructor
+ */
+func NewTSimpleJSONProtocol(t TTransport) *TSimpleJSONProtocol {
+ v := &TSimpleJSONProtocol{trans: t,
+ writer: t,
+ reader: bufio.NewReader(t),
+ }
+ v.parseContextStack.Push(int(_CONTEXT_IN_TOPLEVEL))
+ v.dumpContext.Push(int(_CONTEXT_IN_TOPLEVEL))
+ return v
+}
+
+/**
+ * Factory
+ */
+type TSimpleJSONProtocolFactory struct{}
+
+func (p *TSimpleJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol {
+ return NewTSimpleJSONProtocol(trans)
+}
+
+func NewTSimpleJSONProtocolFactory() *TSimpleJSONProtocolFactory {
+ return &TSimpleJSONProtocolFactory{}
+}
+
+var (
+ JSON_COMMA []byte
+ JSON_COLON []byte
+ JSON_LBRACE []byte
+ JSON_RBRACE []byte
+ JSON_LBRACKET []byte
+ JSON_RBRACKET []byte
+ JSON_QUOTE byte
+ JSON_QUOTE_BYTES []byte
+ JSON_NULL []byte
+ JSON_TRUE []byte
+ JSON_FALSE []byte
+ JSON_INFINITY string
+ JSON_NEGATIVE_INFINITY string
+ JSON_NAN string
+ JSON_INFINITY_BYTES []byte
+ JSON_NEGATIVE_INFINITY_BYTES []byte
+ JSON_NAN_BYTES []byte
+ json_nonbase_map_elem_bytes []byte
+)
+
+func init() {
+ JSON_COMMA = []byte{','}
+ JSON_COLON = []byte{':'}
+ JSON_LBRACE = []byte{'{'}
+ JSON_RBRACE = []byte{'}'}
+ JSON_LBRACKET = []byte{'['}
+ JSON_RBRACKET = []byte{']'}
+ JSON_QUOTE = '"'
+ JSON_QUOTE_BYTES = []byte{'"'}
+ JSON_NULL = []byte{'n', 'u', 'l', 'l'}
+ JSON_TRUE = []byte{'t', 'r', 'u', 'e'}
+ JSON_FALSE = []byte{'f', 'a', 'l', 's', 'e'}
+ JSON_INFINITY = "Infinity"
+ JSON_NEGATIVE_INFINITY = "-Infinity"
+ JSON_NAN = "NaN"
+ JSON_INFINITY_BYTES = []byte{'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'}
+ JSON_NEGATIVE_INFINITY_BYTES = []byte{'-', 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'}
+ JSON_NAN_BYTES = []byte{'N', 'a', 'N'}
+ json_nonbase_map_elem_bytes = []byte{']', ',', '['}
+}
+
+func JsonQuote(s string) string {
+ b, _ := json.Marshal(s)
+ s1 := string(b)
+ return s1
+}
+
+func JsonUnquote(s string) (string, bool) {
+ s1 := new(string)
+ err := json.Unmarshal([]byte(s), s1)
+ return *s1, err == nil
+}
+
+
+func (p *TSimpleJSONProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) TProtocolException {
+ if e := p.OutputListBegin(); e != nil {
+ return e
+ }
+ if e := p.WriteString(name); e != nil {
+ return e
+ }
+ if e := p.WriteByte(byte(typeId)); e != nil {
+ return e
+ }
+ if e := p.WriteI32(seqId); e != nil {
+ return e
+ }
+ return nil
+}
+
+func (p *TSimpleJSONProtocol) WriteMessageEnd() TProtocolException {
+ return p.OutputListEnd()
+}
+
+func (p *TSimpleJSONProtocol) WriteStructBegin(name string) TProtocolException {
+ if e := p.OutputObjectBegin(); e != nil {
+ return e
+ }
+ return nil
+}
+
+func (p *TSimpleJSONProtocol) WriteStructEnd() TProtocolException {
+ return p.OutputObjectEnd()
+}
+
+func (p *TSimpleJSONProtocol) WriteFieldBegin(name string, typeId TType, id int16) TProtocolException {
+ if e := p.WriteString(name); e != nil {
+ return e
+ }
+ return nil
+ /*
+ if e := p.OutputListBegin(); e != nil {
+ return e
+ }
+ if e := p.WriteByte(byte(typeId)); e != nil {
+ return e
+ }
+ return p.WriteI16(id)
+ */
+}
+
+func (p *TSimpleJSONProtocol) WriteFieldEnd() TProtocolException {
+ //return p.OutputListEnd()
+ return nil
+}
+
+func (p *TSimpleJSONProtocol) WriteFieldStop() TProtocolException { return nil }
+
+func (p *TSimpleJSONProtocol) WriteMapBegin(keyType TType, valueType TType, size int) TProtocolException {
+ if e := p.OutputListBegin(); e != nil {
+ return e
+ }
+ if e := p.WriteByte(byte(keyType)); e != nil {
+ return e
+ }
+ if e := p.WriteByte(byte(valueType)); e != nil {
+ return e
+ }
+ return p.WriteI32(int32(size))
+}
+
+func (p *TSimpleJSONProtocol) WriteMapEnd() TProtocolException {
+ return p.OutputListEnd()
+}
+
+func (p *TSimpleJSONProtocol) WriteListBegin(elemType TType, size int) TProtocolException {
+ return p.OutputElemListBegin(elemType, size)
+}
+
+func (p *TSimpleJSONProtocol) WriteListEnd() TProtocolException {
+ return p.OutputListEnd()
+}
+
+func (p *TSimpleJSONProtocol) WriteSetBegin(elemType TType, size int) TProtocolException {
+ return p.OutputElemListBegin(elemType, size)
+}
+
+func (p *TSimpleJSONProtocol) WriteSetEnd() TProtocolException {
+ return p.OutputListEnd()
+}
+
+func (p *TSimpleJSONProtocol) WriteBool(b bool) TProtocolException {
+ return p.OutputBool(b)
+}
+
+func (p *TSimpleJSONProtocol) WriteByte(b byte) TProtocolException {
+ return p.WriteI32(int32(b))
+}
+
+func (p *TSimpleJSONProtocol) WriteI16(v int16) TProtocolException {
+ return p.WriteI32(int32(v))
+}
+
+func (p *TSimpleJSONProtocol) WriteI32(v int32) TProtocolException {
+ return p.OutputI64(int64(v))
+}
+
+func (p *TSimpleJSONProtocol) WriteI64(v int64) TProtocolException {
+ return p.OutputI64(int64(v))
+}
+
+func (p *TSimpleJSONProtocol) WriteDouble(v float64) TProtocolException {
+ return p.OutputF64(v)
+}
+
+func (p *TSimpleJSONProtocol) WriteString(v string) TProtocolException {
+ return p.OutputString(v)
+}
+
+func (p *TSimpleJSONProtocol) WriteBinary(v []byte) TProtocolException {
+ // JSON library only takes in a string,
+ // not an arbitrary byte array, to ensure bytes are transmitted
+ // efficiently we must convert this into a valid JSON string
+ // therefore we use base64 encoding to avoid excessive escaping/quoting
+ if e := p.OutputPreValue(); e != nil {
+ return e
+ }
+ if _, e := p.writer.Write(JSON_QUOTE_BYTES); e != nil {
+ return NewTProtocolExceptionFromOsError(e)
+ }
+ writer := base64.NewEncoder(base64.StdEncoding, p.writer)
+ if _, e := writer.Write(v); e != nil {
+ return NewTProtocolExceptionFromOsError(e)
+ }
+ if e := writer.Close(); e != nil {
+ return NewTProtocolExceptionFromOsError(e)
+ }
+ if _, e := p.writer.Write(JSON_QUOTE_BYTES); e != nil {
+ return NewTProtocolExceptionFromOsError(e)
+ }
+ return p.OutputPostValue()
+}
+
+/**
+ * Reading methods.
+ */
+
+func (p *TSimpleJSONProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err TProtocolException) {
+ if isNull, err := p.ParseListBegin(); isNull || err != nil {
+ return name, typeId, seqId, err
+ }
+ if name, err = p.ReadString(); err != nil {
+ return name, typeId, seqId, err
+ }
+ bTypeId, err := p.ReadByte()
+ typeId = TMessageType(bTypeId)
+ if err != nil {
+ return name, typeId, seqId, err
+ }
+ if seqId, err = p.ReadI32(); err != nil {
+ return name, typeId, seqId, err
+ }
+ return name, typeId, seqId, nil
+}
+
+func (p *TSimpleJSONProtocol) ReadMessageEnd() TProtocolException {
+ return p.ParseListEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadStructBegin() (name string, err TProtocolException) {
+ _, err = p.ParseObjectStart()
+ return "", err
+}
+
+func (p *TSimpleJSONProtocol) ReadStructEnd() TProtocolException {
+ return p.ParseObjectEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadFieldBegin() (string, TType, int16, TProtocolException) {
+ if err := p.ParsePreValue(); err != nil {
+ return "", STOP, 0, err
+ }
+ if p.reader.Buffered() < 1 {
+ return "", STOP, 0, nil
+ }
+ b, _ := p.reader.Peek(1)
+ if len(b) > 0 {
+ switch b[0] {
+ case JSON_RBRACE[0]:
+ return "", STOP, 0, nil
+ case JSON_QUOTE:
+ p.reader.ReadByte()
+ name, err := p.ParseStringBody()
+ if err != nil {
+ return name, STOP, 0, err
+ }
+ return name, GENERIC, -1, p.ParsePostValue()
+ /*
+ if err = p.ParsePostValue(); err != nil {
+ return name, STOP, 0, err
+ }
+ if isNull, err := p.ParseListBegin(); isNull || err != nil {
+ return name, STOP, 0, err
+ }
+ bType, err := p.ReadByte()
+ thetype := TType(bType)
+ if err != nil {
+ return name, thetype, 0, err
+ }
+ id, err := p.ReadI16()
+ return name, thetype, id, err
+ */
+ }
+ return "", STOP, 0, NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected \"}\" or '\"', but found: '", string(b), "'"))
+ }
+ return "", STOP, 0, NewTProtocolExceptionFromOsError(os.EOF)
+}
+
+func (p *TSimpleJSONProtocol) ReadFieldEnd() TProtocolException {
+ return nil
+ //return p.ParseListEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, e TProtocolException) {
+ if isNull, e := p.ParseListBegin(); isNull || e != nil {
+ return VOID, VOID, 0, e
+ }
+
+ // read keyType
+ bKeyType, e := p.ReadByte()
+ keyType = TType(bKeyType)
+ if e != nil {
+ return keyType, valueType, size, e
+ }
+
+ // read valueType
+ bValueType, e := p.ReadByte()
+ valueType = TType(bValueType)
+ if e != nil {
+ return keyType, valueType, size, e
+ }
+
+ // read size
+ iSize, err := p.ReadI64()
+ size = int(iSize)
+ return keyType, valueType, size, err
+}
+
+func (p *TSimpleJSONProtocol) ReadMapEnd() TProtocolException {
+ return p.ParseListEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadListBegin() (elemType TType, size int, e TProtocolException) {
+ return p.ParseElemListBegin()
+}
+
+func (p *TSimpleJSONProtocol) ReadListEnd() TProtocolException {
+ return p.ParseListEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadSetBegin() (elemType TType, size int, e TProtocolException) {
+ return p.ParseElemListBegin()
+}
+
+func (p *TSimpleJSONProtocol) ReadSetEnd() TProtocolException {
+ return p.ParseListEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadBool() (bool, TProtocolException) {
+ var value bool
+ if err := p.ParsePreValue(); err != nil {
+ return value, err
+ }
+ b, _ := p.reader.Peek(len(JSON_FALSE))
+ if len(b) > 0 {
+ switch b[0] {
+ case JSON_TRUE[0]:
+ if string(b[0:len(JSON_TRUE)]) == string(JSON_TRUE) {
+ p.reader.Read(b[0:len(JSON_TRUE)])
+ value = true
+ } else {
+ return value, NewTProtocolException(INVALID_DATA, "Expected \"true\" but found: "+string(b))
+ }
+ break
+ case JSON_FALSE[0]:
+ if string(b[0:len(JSON_FALSE)]) == string(JSON_FALSE) {
+ p.reader.Read(b[0:len(JSON_FALSE)])
+ value = false
+ } else {
+ return value, NewTProtocolException(INVALID_DATA, "Expected \"false\" but found: "+string(b))
+ }
+ break
+ case JSON_NULL[0]:
+ if string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
+ p.reader.Read(b[0:len(JSON_NULL)])
+ value = false
+ } else {
+ return value, NewTProtocolException(INVALID_DATA, "Expected \"null\" but found: "+string(b))
+ }
+ default:
+ return value, NewTProtocolException(INVALID_DATA, "Expected \"true\", \"false\", or \"null\" but found: "+string(b))
+ }
+ }
+ return value, p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) ReadByte() (byte, TProtocolException) {
+ v, err := p.ReadI64()
+ return byte(v), err
+}
+
+func (p *TSimpleJSONProtocol) ReadI16() (int16, TProtocolException) {
+ v, err := p.ReadI64()
+ return int16(v), err
+}
+
+func (p *TSimpleJSONProtocol) ReadI32() (int32, TProtocolException) {
+ v, err := p.ReadI64()
+ return int32(v), err
+}
+
+func (p *TSimpleJSONProtocol) ReadI64() (int64, TProtocolException) {
+ v, _, err := p.ParseI64()
+ return v, err
+}
+
+func (p *TSimpleJSONProtocol) ReadDouble() (float64, TProtocolException) {
+ v, _, err := p.ParseF64()
+ return v, err
+}
+
+func (p *TSimpleJSONProtocol) ReadString() (string, TProtocolException) {
+ var v string
+ if err := p.ParsePreValue(); err != nil {
+ return v, err
+ }
+ b, _ := p.reader.Peek(len(JSON_NULL))
+ if len(b) > 0 && b[0] == JSON_QUOTE {
+ p.reader.ReadByte()
+ value, err := p.ParseStringBody()
+ v = value
+ if err != nil {
+ return v, err
+ }
+ } else if len(b) >= len(JSON_NULL) && string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
+ _, err := p.reader.Read(b[0:len(JSON_NULL)])
+ if err != nil {
+ return v, NewTProtocolExceptionFromOsError(err)
+ }
+ } else {
+ return v, NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected a JSON string, found ", string(b)))
+ }
+ return v, p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) ReadBinary() ([]byte, TProtocolException) {
+ var v []byte
+ if err := p.ParsePreValue(); err != nil {
+ return nil, err
+ }
+ b, _ := p.reader.Peek(len(JSON_NULL))
+ if len(b) > 0 && b[0] == JSON_QUOTE {
+ p.reader.ReadByte()
+ value, err := p.ParseBase64EncodedBody()
+ v = value
+ if err != nil {
+ return v, err
+ }
+ } else if len(b) >= len(JSON_NULL) && string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
+ _, err := p.reader.Read(b[0:len(JSON_NULL)])
+ if err != nil {
+ return v, NewTProtocolExceptionFromOsError(err)
+ }
+ } else {
+ return v, NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected a JSON string, found ", string(b)))
+ }
+ return v, p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) Flush() (err TProtocolException) {
+ return NewTProtocolExceptionFromOsError(p.writer.Flush())
+}
+
+func (p *TSimpleJSONProtocol) Skip(fieldType TType) (err TProtocolException) {
+ return SkipDefaultDepth(p, fieldType)
+}
+
+func (p *TSimpleJSONProtocol) Transport() TTransport {
+ return p.trans
+}
+
+
+func (p *TSimpleJSONProtocol) OutputPreValue() TProtocolException {
+ cxt := _ParseContext(p.dumpContext.Last())
+ switch cxt {
+ case _CONTEXT_IN_LIST, _CONTEXT_IN_OBJECT_NEXT_KEY:
+ if _, e := p.writer.Write(JSON_COMMA); e != nil {
+ return NewTProtocolExceptionFromOsError(e)
+ }
+ break
+ case _CONTEXT_IN_OBJECT_NEXT_VALUE:
+ if _, e := p.writer.Write(JSON_COLON); e != nil {
+ return NewTProtocolExceptionFromOsError(e)
+ }
+ break
+ }
+ return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputPostValue() TProtocolException {
+ cxt := _ParseContext(p.dumpContext.Last())
+ switch cxt {
+ case _CONTEXT_IN_LIST_FIRST:
+ p.dumpContext.Pop()
+ p.dumpContext.Push(int(_CONTEXT_IN_LIST))
+ break
+ case _CONTEXT_IN_OBJECT_FIRST:
+ p.dumpContext.Pop()
+ p.dumpContext.Push(int(_CONTEXT_IN_OBJECT_NEXT_VALUE))
+ break
+ case _CONTEXT_IN_OBJECT_NEXT_KEY:
+ p.dumpContext.Pop()
+ p.dumpContext.Push(int(_CONTEXT_IN_OBJECT_NEXT_VALUE))
+ break
+ case _CONTEXT_IN_OBJECT_NEXT_VALUE:
+ p.dumpContext.Pop()
+ p.dumpContext.Push(int(_CONTEXT_IN_OBJECT_NEXT_KEY))
+ break
+ }
+ return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputBool(value bool) TProtocolException {
+ if e := p.OutputPreValue(); e != nil {
+ return e
+ }
+ var v string
+ if value {
+ v = string(JSON_TRUE)
+ } else {
+ v = string(JSON_FALSE)
+ }
+ switch _ParseContext(p.dumpContext.Last()) {
+ case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
+ v = JsonQuote(v)
+ default:
+ }
+ if e := p.OutputStringData(v); e != nil {
+ return e
+ }
+ return p.OutputPostValue()
+}
+
+func (p *TSimpleJSONProtocol) OutputNull() TProtocolException {
+ if e := p.OutputPreValue(); e != nil {
+ return e
+ }
+ if _, e := p.writer.Write(JSON_NULL); e != nil {
+ return NewTProtocolExceptionFromOsError(e)
+ }
+ return p.OutputPostValue()
+}
+
+func (p *TSimpleJSONProtocol) OutputF64(value float64) TProtocolException {
+ if e := p.OutputPreValue(); e != nil {
+ return e
+ }
+ var v string
+ if math.IsNaN(value) {
+ v = string(JSON_QUOTE) + JSON_NAN + string(JSON_QUOTE)
+ } else if math.IsInf(value, 1) {
+ v = string(JSON_QUOTE) + JSON_INFINITY + string(JSON_QUOTE)
+ } else if math.IsInf(value, -1) {
+ v = string(JSON_QUOTE) + JSON_NEGATIVE_INFINITY + string(JSON_QUOTE)
+ } else {
+ v = strconv.Ftoa64(value, 'g', -1)
+ switch _ParseContext(p.dumpContext.Last()) {
+ case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
+ v = string(JSON_QUOTE) + v + string(JSON_QUOTE)
+ default:
+ }
+ }
+ if e := p.OutputStringData(v); e != nil {
+ return e
+ }
+ return p.OutputPostValue()
+}
+
+func (p *TSimpleJSONProtocol) OutputI64(value int64) TProtocolException {
+ if e := p.OutputPreValue(); e != nil {
+ return e
+ }
+ v := strconv.Itoa64(value)
+ switch _ParseContext(p.dumpContext.Last()) {
+ case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
+ v = JsonQuote(v)
+ default:
+ }
+ if e := p.OutputStringData(v); e != nil {
+ return e
+ }
+ return p.OutputPostValue()
+}
+
+func (p *TSimpleJSONProtocol) OutputString(s string) TProtocolException {
+ if e := p.OutputPreValue(); e != nil {
+ return e
+ }
+ if e := p.OutputStringData(JsonQuote(s)); e != nil {
+ return e
+ }
+ return p.OutputPostValue()
+}
+
+func (p *TSimpleJSONProtocol) OutputStringData(s string) TProtocolException {
+ _, e := io.Copyn(p.writer, strings.NewReader(s), int64(len(s)))
+ return NewTProtocolExceptionFromOsError(e)
+}
+
+func (p *TSimpleJSONProtocol) OutputObjectBegin() TProtocolException {
+ if e := p.OutputPreValue(); e != nil {
+ return e
+ }
+ if _, e := p.writer.Write(JSON_LBRACE); e != nil {
+ return NewTProtocolExceptionFromOsError(e)
+ }
+ p.dumpContext.Push(int(_CONTEXT_IN_OBJECT_FIRST))
+ return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputObjectEnd() TProtocolException {
+ if _, e := p.writer.Write(JSON_RBRACE); e != nil {
+ return NewTProtocolExceptionFromOsError(e)
+ }
+ p.dumpContext.Pop()
+ if e := p.OutputPostValue(); e != nil {
+ return e
+ }
+ return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputListBegin() TProtocolException {
+ if e := p.OutputPreValue(); e != nil {
+ return e
+ }
+ if _, e := p.writer.Write(JSON_LBRACKET); e != nil {
+ return NewTProtocolExceptionFromOsError(e)
+ }
+ p.dumpContext.Push(int(_CONTEXT_IN_LIST_FIRST))
+ return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputListEnd() TProtocolException {
+ if _, e := p.writer.Write(JSON_RBRACKET); e != nil {
+ return NewTProtocolExceptionFromOsError(e)
+ }
+ p.dumpContext.Pop()
+ if e := p.OutputPostValue(); e != nil {
+ return e
+ }
+ return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputElemListBegin(elemType TType, size int) TProtocolException {
+ if e := p.OutputListBegin(); e != nil {
+ return e
+ }
+ if e := p.WriteByte(byte(elemType)); e != nil {
+ return e
+ }
+ if e := p.WriteI64(int64(size)); e != nil {
+ return e
+ }
+ return nil
+}
+
+func (p *TSimpleJSONProtocol) ParsePreValue() TProtocolException {
+ if e := p.readNonSignificantWhitespace(); e != nil {
+ return NewTProtocolExceptionFromOsError(e)
+ }
+ cxt := _ParseContext(p.parseContextStack.Last())
+ if p.reader.Buffered() < 1 {
+ return nil
+ }
+ b, _ := p.reader.Peek(1)
+ switch cxt {
+ case _CONTEXT_IN_LIST:
+ if len(b) > 0 {
+ switch b[0] {
+ case JSON_RBRACKET[0]:
+ return nil
+ case JSON_COMMA[0]:
+ p.reader.ReadByte()
+ if e := p.readNonSignificantWhitespace(); e != nil {
+ return NewTProtocolExceptionFromOsError(e)
+ }
+ return nil
+ default:
+ return NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected \"]\" or \",\" in list context, but found \"", string(b), "\""))
+ }
+ }
+ break
+ case _CONTEXT_IN_OBJECT_NEXT_KEY:
+ if len(b) > 0 {
+ switch b[0] {
+ case JSON_RBRACE[0]:
+ return nil
+ case JSON_COMMA[0]:
+ p.reader.ReadByte()
+ if e := p.readNonSignificantWhitespace(); e != nil {
+ return NewTProtocolExceptionFromOsError(e)
+ }
+ return nil
+ default:
+ return NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected \"}\" or \",\" in object context, but found \"", string(b), "\""))
+ }
+ }
+ break
+ case _CONTEXT_IN_OBJECT_NEXT_VALUE:
+ if len(b) > 0 {
+ switch b[0] {
+ case JSON_COLON[0]:
+ p.reader.ReadByte()
+ if e := p.readNonSignificantWhitespace(); e != nil {
+ return NewTProtocolExceptionFromOsError(e)
+ }
+ return nil
+ default:
+ return NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected \":\" in object context, but found \"", string(b), "\""))
+ }
+ }
+ break
+ }
+ return nil
+}
+
+func (p *TSimpleJSONProtocol) ParsePostValue() TProtocolException {
+ if e := p.readNonSignificantWhitespace(); e != nil {
+ return NewTProtocolExceptionFromOsError(e)
+ }
+ cxt := _ParseContext(p.parseContextStack.Last())
+ switch cxt {
+ case _CONTEXT_IN_LIST_FIRST:
+ p.parseContextStack.Pop()
+ p.parseContextStack.Push(int(_CONTEXT_IN_LIST))
+ break
+ case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
+ p.parseContextStack.Pop()
+ p.parseContextStack.Push(int(_CONTEXT_IN_OBJECT_NEXT_VALUE))
+ break
+ case _CONTEXT_IN_OBJECT_NEXT_VALUE:
+ p.parseContextStack.Pop()
+ p.parseContextStack.Push(int(_CONTEXT_IN_OBJECT_NEXT_KEY))
+ break
+ }
+ return nil
+}
+
+func (p *TSimpleJSONProtocol) readNonSignificantWhitespace() os.Error {
+ for p.reader.Buffered() > 0 {
+ b, _ := p.reader.Peek(1)
+ if len(b) < 1 {
+ return nil
+ }
+ switch b[0] {
+ case ' ', '\r', '\n', '\t':
+ p.reader.ReadByte()
+ continue
+ default:
+ break
+ }
+ break
+ }
+ return nil
+}
+
+func (p *TSimpleJSONProtocol) ParseStringBody() (string, TProtocolException) {
+ line, err := p.reader.ReadString(JSON_QUOTE)
+ if err != nil {
+ return "", NewTProtocolExceptionFromOsError(err)
+ }
+ l := len(line)
+ // count number of escapes to see if we need to keep going
+ i := 1
+ for ; i < l; i++ {
+ if line[l-i-1] != '\\' {
+ break
+ }
+ }
+ if i&0x01 == 1 {
+ v, ok := JsonUnquote(string(JSON_QUOTE) + line)
+ if !ok {
+ return "", NewTProtocolExceptionFromOsError(err)
+ }
+ return v, nil
+ }
+ s, err := p.ParseQuotedStringBody()
+ if err != nil {
+ return "", NewTProtocolExceptionFromOsError(err)
+ }
+ str := string(JSON_QUOTE) + line + s
+ v, ok := JsonUnquote(str)
+ if !ok {
+ return "", NewTProtocolException(INVALID_DATA, "Unable to parse as JSON string "+str)
+ }
+ return v, nil
+}
+
+func (p *TSimpleJSONProtocol) ParseQuotedStringBody() (string, TProtocolException) {
+ line, err := p.reader.ReadString(JSON_QUOTE)
+ if err != nil {
+ return "", NewTProtocolExceptionFromOsError(err)
+ }
+ l := len(line)
+ // count number of escapes to see if we need to keep going
+ i := 1
+ for ; i < l; i++ {
+ if line[l-i-1] != '\\' {
+ break
+ }
+ }
+ if i&0x01 == 1 {
+ return line, nil
+ }
+ s, err := p.ParseQuotedStringBody()
+ if err != nil {
+ return "", NewTProtocolExceptionFromOsError(err)
+ }
+ v := line + s
+ return v, nil
+}
+
+func (p *TSimpleJSONProtocol) ParseBase64EncodedBody() ([]byte, TProtocolException) {
+ line, err := p.reader.ReadBytes(JSON_QUOTE)
+ if err != nil {
+ return line, NewTProtocolExceptionFromOsError(err)
+ }
+ line2 := line[0 : len(line)-1]
+ l := len(line2)
+ output := make([]byte, base64.StdEncoding.DecodedLen(l))
+ n, err := base64.StdEncoding.Decode(output, line2)
+ return output[0:n], NewTProtocolExceptionFromOsError(err)
+}
+
+func (p *TSimpleJSONProtocol) ParseI64() (int64, bool, TProtocolException) {
+ if err := p.ParsePreValue(); err != nil {
+ return 0, false, err
+ }
+ var value int64
+ var isnull bool
+ b, _ := p.reader.Peek(len(JSON_NULL))
+ if len(b) >= len(JSON_NULL) && string(b) == string(JSON_NULL) {
+ p.reader.Read(b[0:len(JSON_NULL)])
+ isnull = true
+ } else {
+ num, err := p.readNumeric()
+ isnull = (num == nil)
+ if !isnull {
+ value = num.Int64()
+ }
+ if err != nil {
+ return value, isnull, err
+ }
+ }
+ return value, isnull, p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) ParseF64() (float64, bool, TProtocolException) {
+ if err := p.ParsePreValue(); err != nil {
+ return 0, false, err
+ }
+ var value float64
+ var isnull bool
+ b, _ := p.reader.Peek(len(JSON_NULL))
+ if len(b) >= len(JSON_NULL) && string(b) == string(JSON_NULL) {
+ p.reader.Read(b[0:len(JSON_NULL)])
+ isnull = true
+ } else {
+ num, err := p.readNumeric()
+ isnull = (num == nil)
+ if !isnull {
+ value = num.Float64()
+ }
+ if err != nil {
+ return value, isnull, err
+ }
+ }
+ return value, isnull, p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) ParseObjectStart() (bool, TProtocolException) {
+ if err := p.ParsePreValue(); err != nil {
+ return false, err
+ }
+ b, _ := p.reader.Peek(len(JSON_NULL))
+ if len(b) > 0 && b[0] == JSON_LBRACE[0] {
+ p.reader.ReadByte()
+ p.parseContextStack.Push(int(_CONTEXT_IN_OBJECT_FIRST))
+ return false, nil
+ } else if len(b) >= len(JSON_NULL) && string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
+ return true, nil
+ }
+ return false, NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected '{' or null, but found '", string(b), "'"))
+}
+
+func (p *TSimpleJSONProtocol) ParseObjectEnd() TProtocolException {
+ if isNull, err := p.readIfNull(); isNull || err != nil {
+ return err
+ }
+ cxt := _ParseContext(p.parseContextStack.Last())
+ if cxt != _CONTEXT_IN_OBJECT_FIRST && cxt != _CONTEXT_IN_OBJECT_NEXT_KEY {
+ return NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected to be in the Object Context, but not in Object Context"))
+ }
+ line, err := p.reader.ReadString(JSON_RBRACE[0])
+ if err != nil {
+ return NewTProtocolExceptionFromOsError(err)
+ }
+ for _, char := range line {
+ switch char {
+ default:
+ return NewTProtocolException(INVALID_DATA, fmt.Sprint("Expecting end of object \"}\", but found: \"", line, "\""))
+ case ' ', '\n', '\r', '\t', '}':
+ break
+ }
+ }
+ p.parseContextStack.Pop()
+ return p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) ParseListBegin() (bool, TProtocolException) {
+ if e := p.ParsePreValue(); e != nil {
+ return false, e
+ }
+ b, e := p.reader.Peek(len(JSON_NULL))
+ if e == nil && len(b) >= 1 && b[0] == JSON_LBRACKET[0] {
+ p.parseContextStack.Push(int(_CONTEXT_IN_LIST_FIRST))
+ p.reader.ReadByte()
+ return false, nil
+ } else if e == nil && len(b) >= len(JSON_NULL) && string(b) == string(JSON_NULL) {
+ return true, nil
+ }
+ return false, NewTProtocolException(INVALID_DATA, fmt.Sprintf("Expected 'null' or '{', received '%q'", b))
+}
+
+func (p *TSimpleJSONProtocol) ParseElemListBegin() (elemType TType, size int, e TProtocolException) {
+ if isNull, e := p.ParseListBegin(); isNull || e != nil {
+ return VOID, 0, e
+ }
+ bElemType, err := p.ReadByte()
+ elemType = TType(bElemType)
+ if err != nil {
+ return elemType, size, err
+ }
+ nSize, err2 := p.ReadI64()
+ size = int(nSize)
+ return elemType, size, err2
+}
+
+func (p *TSimpleJSONProtocol) ParseListEnd() TProtocolException {
+ if isNull, err := p.readIfNull(); isNull || err != nil {
+ return err
+ }
+ if _ParseContext(p.parseContextStack.Last()) != _CONTEXT_IN_LIST {
+ return NewTProtocolException(INVALID_DATA, "Expected to be in the List Context, but not in List Context")
+ }
+ line, err := p.reader.ReadString(JSON_RBRACKET[0])
+ if err != nil {
+ return NewTProtocolExceptionFromOsError(err)
+ }
+ for _, char := range line {
+ switch char {
+ default:
+ return NewTProtocolException(INVALID_DATA, fmt.Sprint("Expecting end of list \"]\", but found: \"", line, "\""))
+ case ' ', '\n', '\r', '\t', int(JSON_RBRACKET[0]):
+ break
+ }
+ }
+ p.parseContextStack.Pop()
+ return p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) readSingleValue() (interface{}, TType, TProtocolException) {
+ e := p.readNonSignificantWhitespace()
+ if e != nil {
+ return nil, VOID, NewTProtocolExceptionFromOsError(e)
+ }
+ b, e := p.reader.Peek(10)
+ if len(b) > 0 {
+ c := b[0]
+ switch c {
+ case JSON_NULL[0]:
+ buf := make([]byte, len(JSON_NULL))
+ _, e := p.reader.Read(buf)
+ if e != nil {
+ return nil, VOID, NewTProtocolExceptionFromOsError(e)
+ }
+ if string(JSON_NULL) != string(buf) {
+ e := NewTProtocolException(INVALID_DATA, "Expected '"+string(JSON_NULL)+"' but found '"+string(buf)+"' while parsing JSON.")
+ return nil, VOID, e
+ }
+ return nil, VOID, nil
+ case JSON_QUOTE:
+ p.reader.ReadByte()
+ v, e := p.ParseStringBody()
+ if e != nil {
+ return v, UTF8, NewTProtocolExceptionFromOsError(e)
+ }
+ if v == JSON_INFINITY {
+ return INFINITY, DOUBLE, nil
+ } else if v == JSON_NEGATIVE_INFINITY {
+ return NEGATIVE_INFINITY, DOUBLE, nil
+ } else if v == JSON_NAN {
+ return NAN, DOUBLE, nil
+ }
+ return v, UTF8, nil
+ case JSON_TRUE[0]:
+ buf := make([]byte, len(JSON_TRUE))
+ _, e := p.reader.Read(buf)
+ if e != nil {
+ return true, BOOL, NewTProtocolExceptionFromOsError(e)
+ }
+ if string(JSON_TRUE) != string(buf) {
+ e := NewTProtocolException(INVALID_DATA, "Expected '"+string(JSON_TRUE)+"' but found '"+string(buf)+"' while parsing JSON.")
+ return true, BOOL, NewTProtocolExceptionFromOsError(e)
+ }
+ return true, BOOL, nil
+ case JSON_FALSE[0]:
+ buf := make([]byte, len(JSON_FALSE))
+ _, e := p.reader.Read(buf)
+ if e != nil {
+ return false, BOOL, NewTProtocolExceptionFromOsError(e)
+ }
+ if string(JSON_FALSE) != string(buf) {
+ e := NewTProtocolException(INVALID_DATA, "Expected '"+string(JSON_FALSE)+"' but found '"+string(buf)+"' while parsing JSON.")
+ return false, BOOL, NewTProtocolExceptionFromOsError(e)
+ }
+ return false, BOOL, nil
+ case JSON_LBRACKET[0]:
+ _, e := p.reader.ReadByte()
+ return make([]interface{}, 0), LIST, NewTProtocolExceptionFromOsError(e)
+ case JSON_LBRACE[0]:
+ _, e := p.reader.ReadByte()
+ return make(map[string]interface{}), STRUCT, NewTProtocolExceptionFromOsError(e)
+ case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'e', 'E', '.', '+', '-', JSON_INFINITY[0], JSON_NAN[0]:
+ // assume numeric
+ v, e := p.readNumeric()
+ return v, DOUBLE, e
+ default:
+ return nil, VOID, NewTProtocolException(INVALID_DATA, "Expected element in list but found '"+string(c)+"' while parsing JSON.")
+ }
+ }
+ return nil, VOID, NewTProtocolException(INVALID_DATA, "Cannot read a single element while parsing JSON.")
+
+}
+
+
+func (p *TSimpleJSONProtocol) readIfNull() (bool, TProtocolException) {
+ cont := true
+ for p.reader.Buffered() > 0 && cont {
+ b, _ := p.reader.Peek(1)
+ if len(b) < 1 {
+ return false, nil
+ }
+ switch b[0] {
+ default:
+ return false, nil
+ case JSON_NULL[0]:
+ cont = false
+ break
+ case ' ', '\n', '\r', '\t':
+ p.reader.ReadByte()
+ break
+ }
+ }
+ if p.reader.Buffered() == 0 {
+ return false, nil
+ }
+ b, _ := p.reader.Peek(len(JSON_NULL))
+ if string(b) == string(JSON_NULL) {
+ p.reader.Read(b[0:len(JSON_NULL)])
+ return true, nil
+ }
+ return false, nil
+}
+
+func (p *TSimpleJSONProtocol) readQuoteIfNext() {
+ if p.reader.Buffered() < 1 {
+ return
+ }
+ b, _ := p.reader.Peek(1)
+ if len(b) > 0 && b[0] == JSON_QUOTE {
+ p.reader.ReadByte()
+ }
+}
+
+func (p *TSimpleJSONProtocol) readNumeric() (Numeric, TProtocolException) {
+ isNull, err := p.readIfNull()
+ if isNull || err != nil {
+ return NUMERIC_NULL, err
+ }
+ hasDecimalPoint := false
+ nextCanBeSign := true
+ hasE := false
+ MAX_LEN := 40
+ buf := bytes.NewBuffer(make([]byte, 0, MAX_LEN))
+ continueFor := true
+ inQuotes := false
+ for continueFor {
+ c, err := p.reader.ReadByte()
+ if err != nil {
+ if err == os.EOF {
+ break
+ }
+ return NUMERIC_NULL, NewTProtocolExceptionFromOsError(err)
+ }
+ switch c {
+ case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ buf.WriteByte(c)
+ nextCanBeSign = false
+ case '.':
+ if hasDecimalPoint {
+ return NUMERIC_NULL, NewTProtocolException(INVALID_DATA, fmt.Sprintf("Unable to parse number with multiple decimal points '%s.'", buf.String()))
+ }
+ if hasE {
+ return NUMERIC_NULL, NewTProtocolException(INVALID_DATA, fmt.Sprintf("Unable to parse number with decimal points in the exponent '%s.'", buf.String()))
+ }
+ buf.WriteByte(c)
+ hasDecimalPoint, nextCanBeSign = true, false
+ case 'e', 'E':
+ if hasE {
+ return NUMERIC_NULL, NewTProtocolException(INVALID_DATA, fmt.Sprintf("Unable to parse number with multiple exponents '%s%c'", buf.String(), c))
+ }
+ buf.WriteByte(c)
+ hasE, nextCanBeSign = true, true
+ case '-', '+':
+ if !nextCanBeSign {
+ return NUMERIC_NULL, NewTProtocolException(INVALID_DATA, fmt.Sprint("Negative sign within number"))
+ }
+ buf.WriteByte(c)
+ nextCanBeSign = false
+ case ' ', 0, '\t', '\n', '\r', JSON_RBRACE[0], JSON_RBRACKET[0], JSON_COMMA[0], JSON_COLON[0]:
+ p.reader.UnreadByte()
+ continueFor = false
+ case JSON_NAN[0]:
+ if buf.Len() == 0 {
+ buffer := make([]byte, len(JSON_NAN))
+ buffer[0] = c
+ _, e := p.reader.Read(buffer[1:])
+ if e != nil {
+ return NUMERIC_NULL, NewTProtocolExceptionFromOsError(e)
+ }
+ if JSON_NAN != string(buffer) {
+ e := NewTProtocolException(INVALID_DATA, "Expected '"+JSON_NAN+"' but found '"+string(buffer)+"' while parsing JSON.")
+ return NUMERIC_NULL, e
+ }
+ if inQuotes {
+ p.readQuoteIfNext()
+ }
+ return NAN, nil
+ } else {
+ return NUMERIC_NULL, NewTProtocolException(INVALID_DATA, fmt.Sprintf("Unable to parse number starting with character '%c'", c))
+ }
+ case JSON_INFINITY[0]:
+ if buf.Len() == 0 || (buf.Len() == 1 && buf.Bytes()[0] == '+') {
+ buffer := make([]byte, len(JSON_INFINITY))
+ buffer[0] = c
+ _, e := p.reader.Read(buffer[1:])
+ if e != nil {
+ return NUMERIC_NULL, NewTProtocolExceptionFromOsError(e)
+ }
+ if JSON_INFINITY != string(buffer) {
+ e := NewTProtocolException(INVALID_DATA, "Expected '"+JSON_INFINITY+"' but found '"+string(buffer)+"' while parsing JSON.")
+ return NUMERIC_NULL, e
+ }
+ if inQuotes {
+ p.readQuoteIfNext()
+ }
+ return INFINITY, nil
+ } else if buf.Len() == 1 && buf.Bytes()[0] == JSON_NEGATIVE_INFINITY[0] {
+ buffer := make([]byte, len(JSON_NEGATIVE_INFINITY))
+ buffer[0] = JSON_NEGATIVE_INFINITY[0]
+ buffer[1] = c
+ _, e := p.reader.Read(buffer[2:])
+ if e != nil {
+ return NUMERIC_NULL, NewTProtocolExceptionFromOsError(e)
+ }
+ if JSON_NEGATIVE_INFINITY != string(buffer) {
+ e := NewTProtocolException(INVALID_DATA, "Expected '"+JSON_NEGATIVE_INFINITY+"' but found '"+string(buffer)+"' while parsing JSON.")
+ return NUMERIC_NULL, e
+ }
+ if inQuotes {
+ p.readQuoteIfNext()
+ }
+ return NEGATIVE_INFINITY, nil
+ } else {
+ return NUMERIC_NULL, NewTProtocolException(INVALID_DATA, fmt.Sprintf("Unable to parse number starting with character '%c' due to existing buffer %s", c, buf.String()))
+ }
+ case JSON_QUOTE:
+ if !inQuotes {
+ inQuotes = true
+ } else {
+ break
+ }
+ default:
+ return NUMERIC_NULL, NewTProtocolException(INVALID_DATA, fmt.Sprintf("Unable to parse number starting with character '%c'", c))
+ }
+ }
+ if buf.Len() == 0 {
+ return NUMERIC_NULL, NewTProtocolException(INVALID_DATA, fmt.Sprint("Unable to parse number from empty string ''"))
+ }
+ return NewNumericFromJSONString(buf.String(), false), nil
+}
Added: thrift/trunk/lib/go/thrift/tsimple_json_protocol_test.go
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/go/thrift/tsimple_json_protocol_test.go?rev=1072478&view=auto
==============================================================================
--- thrift/trunk/lib/go/thrift/tsimple_json_protocol_test.go (added)
+++ thrift/trunk/lib/go/thrift/tsimple_json_protocol_test.go Sun Feb 20 02:39:19 2011
@@ -0,0 +1,662 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift_test
+
+import (
+ . "thrift"
+ "encoding/base64"
+ "fmt"
+ "json"
+ "math"
+ "strconv"
+ "strings"
+ "testing"
+)
+
+func TestWriteSimpleJSONProtocolBool(t *testing.T) {
+ thetype := "boolean"
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ for _, value := range BOOL_VALUES {
+ if e := p.WriteBool(value); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+ }
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+ }
+ s := trans.String()
+ if s != fmt.Sprint(value) {
+ t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+ }
+ v := false
+ if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+ }
+ trans.Reset()
+ }
+ trans.Close()
+}
+
+func TestReadSimpleJSONProtocolBool(t *testing.T) {
+ thetype := "boolean"
+ for _, value := range BOOL_VALUES {
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ if value {
+ trans.Write(JSON_TRUE)
+ } else {
+ trans.Write(JSON_FALSE)
+ }
+ trans.Flush()
+ s := trans.String()
+ v, e := p.ReadBool()
+ if e != nil {
+ t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+ }
+ if v != value {
+ t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+ }
+ if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+ }
+ trans.Reset()
+ trans.Close()
+ }
+}
+
+func TestWriteSimpleJSONProtocolByte(t *testing.T) {
+ thetype := "byte"
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ for _, value := range BYTE_VALUES {
+ if e := p.WriteByte(value); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+ }
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+ }
+ s := trans.String()
+ if s != fmt.Sprint(value) {
+ t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+ }
+ v := byte(0)
+ if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+ }
+ trans.Reset()
+ }
+ trans.Close()
+}
+
+func TestReadSimpleJSONProtocolByte(t *testing.T) {
+ thetype := "byte"
+ for _, value := range BYTE_VALUES {
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ trans.WriteString(strconv.Itoa(int(value)))
+ trans.Flush()
+ s := trans.String()
+ v, e := p.ReadByte()
+ if e != nil {
+ t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+ }
+ if v != value {
+ t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+ }
+ if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+ }
+ trans.Reset()
+ trans.Close()
+ }
+}
+
+func TestWriteSimpleJSONProtocolI16(t *testing.T) {
+ thetype := "int16"
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ for _, value := range INT16_VALUES {
+ if e := p.WriteI16(value); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+ }
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+ }
+ s := trans.String()
+ if s != fmt.Sprint(value) {
+ t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+ }
+ v := int16(0)
+ if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+ }
+ trans.Reset()
+ }
+ trans.Close()
+}
+
+func TestReadSimpleJSONProtocolI16(t *testing.T) {
+ thetype := "int16"
+ for _, value := range INT16_VALUES {
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ trans.WriteString(strconv.Itoa(int(value)))
+ trans.Flush()
+ s := trans.String()
+ v, e := p.ReadI16()
+ if e != nil {
+ t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+ }
+ if v != value {
+ t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+ }
+ if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+ }
+ trans.Reset()
+ trans.Close()
+ }
+}
+
+func TestWriteSimpleJSONProtocolI32(t *testing.T) {
+ thetype := "int32"
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ for _, value := range INT32_VALUES {
+ if e := p.WriteI32(value); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+ }
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+ }
+ s := trans.String()
+ if s != fmt.Sprint(value) {
+ t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+ }
+ v := int32(0)
+ if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+ }
+ trans.Reset()
+ }
+ trans.Close()
+}
+
+func TestReadSimpleJSONProtocolI32(t *testing.T) {
+ thetype := "int32"
+ for _, value := range INT32_VALUES {
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ trans.WriteString(strconv.Itoa(int(value)))
+ trans.Flush()
+ s := trans.String()
+ v, e := p.ReadI32()
+ if e != nil {
+ t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+ }
+ if v != value {
+ t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+ }
+ if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+ }
+ trans.Reset()
+ trans.Close()
+ }
+}
+
+func TestWriteSimpleJSONProtocolI64(t *testing.T) {
+ thetype := "int64"
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ for _, value := range INT64_VALUES {
+ if e := p.WriteI64(value); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+ }
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+ }
+ s := trans.String()
+ if s != fmt.Sprint(value) {
+ t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+ }
+ v := int64(0)
+ if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+ }
+ trans.Reset()
+ }
+ trans.Close()
+}
+
+func TestReadSimpleJSONProtocolI64(t *testing.T) {
+ thetype := "int64"
+ for _, value := range INT64_VALUES {
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ trans.WriteString(strconv.Itoa64(value))
+ trans.Flush()
+ s := trans.String()
+ v, e := p.ReadI64()
+ if e != nil {
+ t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+ }
+ if v != value {
+ t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+ }
+ if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+ }
+ trans.Reset()
+ trans.Close()
+ }
+}
+
+func TestWriteSimpleJSONProtocolDouble(t *testing.T) {
+ thetype := "double"
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ for _, value := range DOUBLE_VALUES {
+ if e := p.WriteDouble(value); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+ }
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+ }
+ s := trans.String()
+ if math.IsInf(value, 1) {
+ if s != JsonQuote(JSON_INFINITY) {
+ t.Fatalf("Bad value for %s %v, wrote: %v, expected: %v", thetype, value, s, JsonQuote(JSON_INFINITY))
+ }
+ } else if math.IsInf(value, -1) {
+ if s != JsonQuote(JSON_NEGATIVE_INFINITY) {
+ t.Fatalf("Bad value for %s %v, wrote: %v, expected: %v", thetype, value, s, JsonQuote(JSON_NEGATIVE_INFINITY))
+ }
+ } else if math.IsNaN(value) {
+ if s != JsonQuote(JSON_NAN) {
+ t.Fatalf("Bad value for %s %v, wrote: %v, expected: %v", thetype, value, s, JsonQuote(JSON_NAN))
+ }
+ } else {
+ if s != fmt.Sprint(value) {
+ t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+ }
+ v := float64(0)
+ if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+ }
+ }
+ trans.Reset()
+ }
+ trans.Close()
+}
+
+func TestReadSimpleJSONProtocolDouble(t *testing.T) {
+ thetype := "double"
+ for _, value := range DOUBLE_VALUES {
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ n := NewNumericFromDouble(value)
+ trans.WriteString(n.String())
+ trans.Flush()
+ s := trans.String()
+ v, e := p.ReadDouble()
+ if e != nil {
+ t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+ }
+ if math.IsInf(value, 1) {
+ if !math.IsInf(v, 1) {
+ t.Fatalf("Bad value for %s %v, wrote: %v, received: %v", thetype, value, s, v)
+ }
+ } else if math.IsInf(value, -1) {
+ if !math.IsInf(v, -1) {
+ t.Fatalf("Bad value for %s %v, wrote: %v, received: %v", thetype, value, s, v)
+ }
+ } else if math.IsNaN(value) {
+ if !math.IsNaN(v) {
+ t.Fatalf("Bad value for %s %v, wrote: %v, received: %v", thetype, value, s, v)
+ }
+ } else {
+ if v != value {
+ t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+ }
+ if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+ }
+ }
+ trans.Reset()
+ trans.Close()
+ }
+}
+
+func TestWriteSimpleJSONProtocolString(t *testing.T) {
+ thetype := "string"
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ for _, value := range STRING_VALUES {
+ if e := p.WriteString(value); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+ }
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+ }
+ s := trans.String()
+ if s[0] != '"' || s[len(s)-1] != '"' {
+ t.Fatalf("Bad value for %s '%v', wrote '%v', expected: %v", thetype, value, s, fmt.Sprint("\"", value, "\""))
+ }
+ v := new(string)
+ if err := json.Unmarshal([]byte(s), v); err != nil || *v != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v)
+ }
+ trans.Reset()
+ }
+ trans.Close()
+}
+
+func TestReadSimpleJSONProtocolString(t *testing.T) {
+ thetype := "string"
+ for _, value := range STRING_VALUES {
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ trans.WriteString(JsonQuote(value))
+ trans.Flush()
+ s := trans.String()
+ v, e := p.ReadString()
+ if e != nil {
+ t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+ }
+ if v != value {
+ t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+ }
+ v1 := new(string)
+ if err := json.Unmarshal([]byte(s), v1); err != nil || *v1 != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v1)
+ }
+ trans.Reset()
+ trans.Close()
+ }
+}
+
+func TestWriteSimpleJSONProtocolBinary(t *testing.T) {
+ thetype := "binary"
+ value := protocol_bdata
+ b64value := make([]byte, base64.StdEncoding.EncodedLen(len(protocol_bdata)))
+ base64.StdEncoding.Encode(b64value, value)
+ b64String := string(b64value)
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ if e := p.WriteBinary(value); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+ }
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+ }
+ s := trans.String()
+ if s != fmt.Sprint("\"", b64String, "\"") {
+ t.Fatalf("Bad value for %s %v\n wrote: %v\nexpected: %v", thetype, value, s, "\""+b64String+"\"")
+ }
+ v1 := new(string)
+ if err := json.Unmarshal([]byte(s), v1); err != nil || *v1 != b64String {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v1)
+ }
+ trans.Close()
+}
+
+func TestReadSimpleJSONProtocolBinary(t *testing.T) {
+ thetype := "binary"
+ value := protocol_bdata
+ b64value := make([]byte, base64.StdEncoding.EncodedLen(len(protocol_bdata)))
+ base64.StdEncoding.Encode(b64value, value)
+ b64String := string(b64value)
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ trans.WriteString(JsonQuote(b64String))
+ trans.Flush()
+ s := trans.String()
+ v, e := p.ReadBinary()
+ if e != nil {
+ t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+ }
+ if len(v) != len(value) {
+ t.Fatalf("Bad value for %s value length %v, wrote: %v, received length: %v", thetype, len(value), s, len(v))
+ }
+ for i := 0; i < len(v); i++ {
+ if v[i] != value[i] {
+ t.Fatalf("Bad value for %s at index %d value %v, wrote: %v, received: %v", thetype, i, value[i], s, v[i])
+ }
+ }
+ v1 := new(string)
+ if err := json.Unmarshal([]byte(s), v1); err != nil || *v1 != b64String {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v1)
+ }
+ trans.Reset()
+ trans.Close()
+}
+
+func TestWriteSimpleJSONProtocolList(t *testing.T) {
+ thetype := "list"
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ p.WriteListBegin(TType(DOUBLE), len(DOUBLE_VALUES))
+ for _, value := range DOUBLE_VALUES {
+ if e := p.WriteDouble(value); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+ }
+ }
+ p.WriteListEnd()
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.String())
+ }
+ str := trans.String()
+ str1 := new([]interface{})
+ err := json.Unmarshal([]byte(str), str1)
+ if err != nil {
+ t.Fatalf("Unable to decode %s, wrote: %s", thetype, str)
+ }
+ l := *str1
+ if len(l) < 2 {
+ t.Fatalf("List must be at least of length two to include metadata")
+ }
+ if int(l[0].(float64)) != DOUBLE {
+ t.Fatal("Invalid type for list, expected: ", DOUBLE, ", but was: ", l[0])
+ }
+ if int(l[1].(float64)) != len(DOUBLE_VALUES) {
+ t.Fatal("Invalid length for list, expected: ", len(DOUBLE_VALUES), ", but was: ", l[1])
+ }
+ for k, value := range DOUBLE_VALUES {
+ s := l[k+2]
+ if math.IsInf(value, 1) {
+ if s.(string) != JSON_INFINITY {
+ t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_INFINITY), str)
+ }
+ } else if math.IsInf(value, 0) {
+ if s.(string) != JSON_NEGATIVE_INFINITY {
+ t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_NEGATIVE_INFINITY), str)
+ }
+ } else if math.IsNaN(value) {
+ if s.(string) != JSON_NAN {
+ t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_NAN), str)
+ }
+ } else {
+ if s.(float64) != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s'", thetype, value, s)
+ }
+ }
+ trans.Reset()
+ }
+ trans.Close()
+}
+
+func TestWriteSimpleJSONProtocolSet(t *testing.T) {
+ thetype := "set"
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ p.WriteSetBegin(TType(DOUBLE), len(DOUBLE_VALUES))
+ for _, value := range DOUBLE_VALUES {
+ if e := p.WriteDouble(value); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+ }
+ }
+ p.WriteSetEnd()
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.String())
+ }
+ str := trans.String()
+ str1 := new([]interface{})
+ err := json.Unmarshal([]byte(str), str1)
+ if err != nil {
+ t.Fatalf("Unable to decode %s, wrote: %s", thetype, str)
+ }
+ l := *str1
+ if len(l) < 2 {
+ t.Fatalf("Set must be at least of length two to include metadata")
+ }
+ if int(l[0].(float64)) != DOUBLE {
+ t.Fatal("Invalid type for set, expected: ", DOUBLE, ", but was: ", l[0])
+ }
+ if int(l[1].(float64)) != len(DOUBLE_VALUES) {
+ t.Fatal("Invalid length for set, expected: ", len(DOUBLE_VALUES), ", but was: ", l[1])
+ }
+ for k, value := range DOUBLE_VALUES {
+ s := l[k+2]
+ if math.IsInf(value, 1) {
+ if s.(string) != JSON_INFINITY {
+ t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_INFINITY), str)
+ }
+ } else if math.IsInf(value, 0) {
+ if s.(string) != JSON_NEGATIVE_INFINITY {
+ t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_NEGATIVE_INFINITY), str)
+ }
+ } else if math.IsNaN(value) {
+ if s.(string) != JSON_NAN {
+ t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_NAN), str)
+ }
+ } else {
+ if s.(float64) != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s'", thetype, value, s)
+ }
+ }
+ trans.Reset()
+ }
+ trans.Close()
+}
+
+func TestWriteSimpleJSONProtocolMap(t *testing.T) {
+ thetype := "map"
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ p.WriteMapBegin(TType(I32), TType(DOUBLE), len(DOUBLE_VALUES))
+ for k, value := range DOUBLE_VALUES {
+ if e := p.WriteI32(int32(k)); e != nil {
+ t.Fatalf("Unable to write %s key int32 value %v due to error: %s", thetype, k, e.String())
+ }
+ if e := p.WriteDouble(value); e != nil {
+ t.Fatalf("Unable to write %s value float64 value %v due to error: %s", thetype, value, e.String())
+ }
+ }
+ p.WriteMapEnd()
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.String())
+ }
+ str := trans.String()
+ if str[0] != '[' || str[len(str)-1] != ']' {
+ t.Fatalf("Bad value for %s, wrote: %q, in go: %q", thetype, str, DOUBLE_VALUES)
+ }
+ l := strings.Split(str[1:len(str)-1], ",", -1)
+ if len(l) < 3 {
+ t.Fatal("Expected list of at least length 3 for map for metadata, but was of length ", len(l))
+ }
+ expectedKeyType, _ := strconv.Atoi(l[0])
+ expectedValueType, _ := strconv.Atoi(l[1])
+ expectedSize, _ := strconv.Atoi(l[2])
+ if expectedKeyType != I32 {
+ t.Fatal("Expected map key type ", I32, ", but was ", l[0])
+ }
+ if expectedValueType != DOUBLE {
+ t.Fatal("Expected map value type ", DOUBLE, ", but was ", l[1])
+ }
+ if expectedSize != len(DOUBLE_VALUES) {
+ t.Fatal("Expected map size of ", len(DOUBLE_VALUES), ", but was ", l[2])
+ }
+ for k, value := range DOUBLE_VALUES {
+ strk := l[k*2+3]
+ strv := l[k*2+4]
+ ik, err := strconv.Atoi(strk)
+ if err != nil {
+ t.Fatalf("Bad value for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, strk, string(k), err.String())
+ }
+ if ik != k {
+ t.Fatalf("Bad value for %s index %v, wrote: %v, expected: %v", thetype, k, strk, k)
+ }
+ s := strv
+ if math.IsInf(value, 1) {
+ if s != JsonQuote(JSON_INFINITY) {
+ t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected: %v", thetype, k, value, s, JsonQuote(JSON_INFINITY))
+ }
+ } else if math.IsInf(value, 0) {
+ if s != JsonQuote(JSON_NEGATIVE_INFINITY) {
+ t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected: %v", thetype, k, value, s, JsonQuote(JSON_NEGATIVE_INFINITY))
+ }
+ } else if math.IsNaN(value) {
+ if s != JsonQuote(JSON_NAN) {
+ t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected: %v", thetype, k, value, s, JsonQuote(JSON_NAN))
+ }
+ } else {
+ expected := strconv.Ftoa64(value, 'g', 10)
+ if s != expected {
+ t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected %v", thetype, k, value, s, expected)
+ }
+ v := float64(0)
+ if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+ t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+ }
+ }
+ trans.Reset()
+ }
+ trans.Close()
+}
+
+
+func TestReadWriteSimpleJSONStruct(t *testing.T) {
+ thetype := "struct"
+ trans := NewTMemoryBuffer()
+ p := NewTSimpleJSONProtocol(trans)
+ orig := NewWork()
+ orig.Num1 = 25
+ orig.Num2 = 102
+ orig.Op = ADD
+ orig.Comment = "Add: 25 + 102"
+ if e := orig.Write(p); e != nil {
+ t.Fatalf("Unable to write %s value %#v due to error: %s", thetype, orig, e.String())
+ }
+ t.Log("Memory buffer contents: ", trans.String())
+ read := NewWork()
+ e := read.Read(p)
+ t.Logf("Read %s value: %#v", thetype, read)
+ if e != nil {
+ t.Fatalf("Unable to read %s due to error: %s", thetype, e.String())
+ }
+ if !orig.Equals(read) {
+ t.Fatalf("Original Write != Read: %#v != %#v ", orig, read)
+ }
+}
+
+func TestReadWriteSimpleJSONProtocol(t *testing.T) {
+ ReadWriteProtocolTest(t, NewTSimpleJSONProtocolFactory())
+}
Added: thrift/trunk/lib/go/thrift/tsimple_server.go
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/go/thrift/tsimple_server.go?rev=1072478&view=auto
==============================================================================
--- thrift/trunk/lib/go/thrift/tsimple_server.go (added)
+++ thrift/trunk/lib/go/thrift/tsimple_server.go Sun Feb 20 02:39:19 2011
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+ "os"
+)
+
+
+/**
+ * Simple singlethreaded server for testing.
+ *
+ */
+type TSimpleServer struct {
+ stopped bool
+
+ processorFactory TProcessorFactory
+ serverTransport TServerTransport
+ inputTransportFactory TTransportFactory
+ outputTransportFactory TTransportFactory
+ inputProtocolFactory TProtocolFactory
+ outputProtocolFactory TProtocolFactory
+}
+
+func NewTSimpleServer2(processor TProcessor, serverTransport TServerTransport) *TSimpleServer {
+ return NewTSimpleServerFactory2(NewTProcessorFactory(processor), serverTransport)
+}
+
+func NewTSimpleServer4(processor TProcessor, serverTransport TServerTransport, transportFactory TTransportFactory, protocolFactory TProtocolFactory) *TSimpleServer {
+ return NewTSimpleServerFactory4(NewTProcessorFactory(processor),
+ serverTransport,
+ transportFactory,
+ protocolFactory,
+ )
+}
+
+func NewTSimpleServer6(processor TProcessor, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TSimpleServer {
+ return NewTSimpleServerFactory6(NewTProcessorFactory(processor),
+ serverTransport,
+ inputTransportFactory,
+ outputTransportFactory,
+ inputProtocolFactory,
+ outputProtocolFactory,
+ )
+}
+
+func NewTSimpleServerFactory2(processorFactory TProcessorFactory, serverTransport TServerTransport) *TSimpleServer {
+ return NewTSimpleServerFactory6(processorFactory,
+ serverTransport,
+ NewTTransportFactory(),
+ NewTTransportFactory(),
+ NewTBinaryProtocolFactoryDefault(),
+ NewTBinaryProtocolFactoryDefault(),
+ )
+}
+
+func NewTSimpleServerFactory4(processorFactory TProcessorFactory, serverTransport TServerTransport, transportFactory TTransportFactory, protocolFactory TProtocolFactory) *TSimpleServer {
+ return NewTSimpleServerFactory6(processorFactory,
+ serverTransport,
+ transportFactory,
+ transportFactory,
+ protocolFactory,
+ protocolFactory,
+ )
+}
+
+func NewTSimpleServerFactory6(processorFactory TProcessorFactory, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TSimpleServer {
+ return &TSimpleServer{processorFactory: processorFactory,
+ serverTransport: serverTransport,
+ inputTransportFactory: inputTransportFactory,
+ outputTransportFactory: outputTransportFactory,
+ inputProtocolFactory: inputProtocolFactory,
+ outputProtocolFactory: outputProtocolFactory,
+ }
+}
+
+func (p *TSimpleServer) ProcessorFactory() TProcessorFactory {
+ return p.processorFactory
+}
+
+func (p *TSimpleServer) ServerTransport() TServerTransport {
+ return p.serverTransport
+}
+
+func (p *TSimpleServer) InputTransportFactory() TTransportFactory {
+ return p.inputTransportFactory
+}
+
+func (p *TSimpleServer) OutputTransportFactory() TTransportFactory {
+ return p.outputTransportFactory
+}
+
+func (p *TSimpleServer) InputProtocolFactory() TProtocolFactory {
+ return p.inputProtocolFactory
+}
+
+func (p *TSimpleServer) OutputProtocolFactory() TProtocolFactory {
+ return p.outputProtocolFactory
+}
+
+func (p *TSimpleServer) Serve() os.Error {
+ p.stopped = false
+ err := p.serverTransport.Listen()
+ if err != nil {
+ return err
+ }
+ for !p.stopped {
+ client, err := p.serverTransport.Accept()
+ if err != nil {
+ return err
+ }
+ if client != nil {
+ p.processRequest(client)
+ }
+ }
+ return nil
+}
+
+func (p *TSimpleServer) Stop() os.Error {
+ p.stopped = true
+ p.serverTransport.Interrupt()
+ return nil
+}
+
+func (p *TSimpleServer) processRequest(client TTransport) {
+ processor := p.processorFactory.GetProcessor(client)
+ inputTransport := p.inputTransportFactory.GetTransport(client)
+ outputTransport := p.outputTransportFactory.GetTransport(client)
+ inputProtocol := p.inputProtocolFactory.GetProtocol(inputTransport)
+ outputProtocol := p.outputProtocolFactory.GetProtocol(outputTransport)
+ if inputTransport != nil {
+ defer inputTransport.Close()
+ }
+ if outputTransport != nil {
+ defer outputTransport.Close()
+ }
+ for {
+ ok, e := processor.Process(inputProtocol, outputProtocol)
+ if e != nil {
+ if !p.stopped {
+ // TODO(pomack) log error
+ break
+ }
+ }
+ if !ok {
+ break
+ }
+ }
+}
Added: thrift/trunk/lib/go/thrift/tsocket.go
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/go/thrift/tsocket.go?rev=1072478&view=auto
==============================================================================
--- thrift/trunk/lib/go/thrift/tsocket.go (added)
+++ thrift/trunk/lib/go/thrift/tsocket.go Sun Feb 20 02:39:19 2011
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+ "net"
+ "os"
+ "bytes"
+)
+
+/**
+ * Socket implementation of the TTransport interface. To be commented soon!
+ *
+ */
+type TSocket struct {
+ writeBuffer *bytes.Buffer
+ /**
+ * Wrapped Socket object
+ */
+ conn net.Conn
+ /**
+ * Remote Addr
+ */
+ addr net.Addr
+ /**
+ * Socket timeout in nanoseconds
+ */
+ nsecTimeout int64
+}
+
+/**
+ * Constructor that takes an already created socket.
+ *
+ * @param socket Already created socket object
+ * @throws TTransportException if there is an error setting up the streams
+ */
+func NewTSocketConn(connection net.Conn) (*TSocket, TTransportException) {
+ address := connection.RemoteAddr()
+ if address == nil {
+ address = connection.LocalAddr()
+ }
+ p := &TSocket{conn: connection, addr: address, nsecTimeout: 0, writeBuffer: bytes.NewBuffer(make([]byte, 0, 4096))}
+ return p, nil
+}
+
+/**
+ * Creates a new unconnected socket that will connect to the given host
+ * on the given port.
+ *
+ * @param host Remote host
+ * @param port Remote port
+ */
+func NewTSocketAddr(address net.Addr) *TSocket {
+ return NewTSocket(address, 0)
+}
+
+/**
+ * Creates a new unconnected socket that will connect to the given host
+ * on the given port.
+ *
+ * @param host Remote host
+ * @param port Remote port
+ * @param nsecTimeout Socket timeout
+ */
+func NewTSocket(address net.Addr, nsecTimeout int64) *TSocket {
+ sock := &TSocket{addr: address, nsecTimeout: nsecTimeout, writeBuffer: bytes.NewBuffer(make([]byte, 0, 4096))}
+ return sock
+}
+
+/**
+ * Sets the socket timeout
+ *
+ * @param timeout Nanoseconds timeout
+ */
+func (p *TSocket) SetTimeout(nsecTimeout int64) os.Error {
+ p.nsecTimeout = nsecTimeout
+ if p.IsOpen() {
+ if err := p.conn.SetTimeout(nsecTimeout); err != nil {
+ LOGGER.Print("Could not set socket timeout.", err)
+ return err
+ }
+ }
+ return nil
+}
+
+/**
+ * Returns a reference to the underlying socket.
+ */
+func (p *TSocket) Conn() net.Conn {
+ return p.conn
+}
+
+/**
+ * Checks whether the socket is connected.
+ */
+func (p *TSocket) IsOpen() bool {
+ if p.conn == nil {
+ return false
+ }
+ return true
+}
+
+/**
+ * Connects the socket, creating a new socket object if necessary.
+ */
+func (p *TSocket) Open() os.Error {
+ if p.IsOpen() {
+ return NewTTransportException(ALREADY_OPEN, "Socket already connected.")
+ }
+ if p.addr == nil {
+ return NewTTransportException(NOT_OPEN, "Cannot open nil address.")
+ }
+ if len(p.addr.Network()) == 0 {
+ return NewTTransportException(NOT_OPEN, "Cannot open bad network name.")
+ }
+ if len(p.addr.String()) == 0 {
+ return NewTTransportException(NOT_OPEN, "Cannot open bad address.")
+ }
+ var err os.Error
+ if p.conn, err = net.Dial(p.addr.Network(), "", p.addr.String()); err != nil {
+ LOGGER.Print("Could not open socket", err.String())
+ return NewTTransportException(NOT_OPEN, err.String())
+ }
+ if p.conn != nil {
+ p.conn.SetTimeout(p.nsecTimeout)
+ }
+ return nil
+}
+
+/**
+ * Closes the socket.
+ */
+func (p *TSocket) Close() os.Error {
+ // Close the socket
+ if p.conn != nil {
+ err := p.conn.Close()
+ if err != nil {
+ LOGGER.Print("Could not close socket. ", err.String())
+ return err
+ }
+ p.conn = nil
+ }
+ return nil
+}
+
+
+func (p *TSocket) Read(buf []byte) (int, os.Error) {
+ if !p.IsOpen() {
+ return 0, NewTTransportException(NOT_OPEN, "Connection not open")
+ }
+ n, err := p.conn.Read(buf)
+ return n, NewTTransportExceptionFromOsError(err)
+}
+
+
+func (p *TSocket) ReadAll(buf []byte) (int, os.Error) {
+ return ReadAllTransport(p, buf)
+}
+
+func (p *TSocket) Write(buf []byte) (int, os.Error) {
+ if !p.IsOpen() {
+ return 0, NewTTransportException(NOT_OPEN, "Connection not open")
+ }
+ p.writeBuffer.Write(buf)
+ return len(buf), nil
+}
+
+func (p *TSocket) Peek() bool {
+ return p.IsOpen()
+}
+
+func (p *TSocket) Flush() os.Error {
+ if !p.IsOpen() {
+ return NewTTransportException(NOT_OPEN, "Connection not open")
+ }
+ _, err := p.writeBuffer.WriteTo(p.conn)
+ return NewTTransportExceptionFromOsError(err)
+}
+
+func (p *TSocket) Interrupt() os.Error {
+ if !p.IsOpen() {
+ return nil
+ }
+ // TODO(pomack) fix Interrupt as this is probably wrong
+ return p.conn.Close()
+}
Added: thrift/trunk/lib/go/thrift/tstruct.go
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/go/thrift/tstruct.go?rev=1072478&view=auto
==============================================================================
--- thrift/trunk/lib/go/thrift/tstruct.go (added)
+++ thrift/trunk/lib/go/thrift/tstruct.go Sun Feb 20 02:39:19 2011
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+/**
+ * Helper class that encapsulates struct metadata.
+ *
+ */
+type TStruct interface {
+ TFieldContainer
+ TStructName() string
+ ThriftName() string
+ TStructFields() TFieldContainer
+ String() string
+ AttributeFromFieldId(fieldId int) interface{}
+ AttributeFromFieldName(fieldName string) interface{}
+}
+
+type tStruct struct {
+ TFieldContainer
+ name string
+}
+
+func NewTStructEmpty(name string) TStruct {
+ return &tStruct{
+ name: name,
+ TFieldContainer: NewTFieldContainer(make([]TField, 0, 0)),
+ }
+}
+
+func NewTStruct(name string, fields []TField) TStruct {
+ return &tStruct{
+ name: name,
+ TFieldContainer: NewTFieldContainer(fields),
+ }
+}
+
+func (p *tStruct) TStructName() string {
+ return p.name
+}
+
+func (p *tStruct) ThriftName() string {
+ return p.name
+}
+
+func (p *tStruct) TStructFields() TFieldContainer {
+ return p.TFieldContainer
+}
+
+func (p *tStruct) String() string {
+ return p.name
+}
+
+func (p *tStruct) Equals(other interface{}) bool {
+ cmp, ok := p.CompareTo(other)
+ return ok && cmp == 0
+}
+
+func (p *tStruct) CompareTo(other interface{}) (int, bool) {
+ return TType(STRUCT).Compare(p, other)
+}
+
+func (p *tStruct) AttributeFromFieldId(fieldId int) interface{} {
+ return nil
+}
+
+func (p *tStruct) AttributeFromFieldName(fieldName string) interface{} {
+ return p.AttributeFromFieldId(p.FieldIdFromFieldName(fieldName))
+}
+
+
+var ANONYMOUS_STRUCT TStruct
+
+func init() {
+ ANONYMOUS_STRUCT = NewTStructEmpty("")
+}
Added: thrift/trunk/lib/go/thrift/ttransport.go
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/go/thrift/ttransport.go?rev=1072478&view=auto
==============================================================================
--- thrift/trunk/lib/go/thrift/ttransport.go (added)
+++ thrift/trunk/lib/go/thrift/ttransport.go Sun Feb 20 02:39:19 2011
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+ "os"
+ "log"
+)
+
+type Flusher interface {
+ Flush() (err os.Error)
+}
+
+/**
+ * Generic class that encapsulates the I/O layer. This is basically a thin
+ * wrapper around the combined functionality of Java input/output streams.
+ *
+ */
+type TTransport interface {
+ /**
+ * Queries whether the transport is open.
+ *
+ * @return True if the transport is open.
+ */
+ IsOpen() bool
+
+ /**
+ * Opens the transport for reading/writing.
+ *
+ * @returns TTransportException if the transport could not be opened
+ */
+ Open() (err os.Error)
+
+ /**
+ * Closes the transport.
+ */
+ Close() (err os.Error)
+
+ /**
+ * Reads up to len bytes into buffer buf, starting att offset off.
+ *
+ * @param buf Array to read into
+ * @param off Index to start reading at
+ * @param len Maximum number of bytes to read
+ * @return The number of bytes actually read
+ * @return TTransportException if there was an error reading data
+ */
+ Read(buf []byte) (n int, err os.Error)
+
+ /**
+ * Guarantees that all of len bytes are actually read off the transport.
+ *
+ * @param buf Array to read into
+ * @param off Index to start reading at
+ * @param len Maximum number of bytes to read
+ * @return The number of bytes actually read, which must be equal to len
+ * @return TTransportException if there was an error reading data
+ */
+ ReadAll(buf []byte) (n int, err os.Error)
+
+ /**
+ * Writes the buffer to the output
+ *
+ * @param buf The output data buffer
+ * @return Number of bytes written
+ * @return TTransportException if an error occurs writing data
+ */
+ Write(buf []byte) (n int, err os.Error)
+
+ /**
+ * Flush any pending data out of a transport buffer.
+ *
+ * @return TTransportException if there was an error writing out data.
+ */
+ Flush() (err os.Error)
+
+ /**
+ * Is there more data to be read?
+ *
+ * @return True if the remote side is still alive and feeding us
+ */
+ Peek() bool
+}
+/*
+type TTransportBase struct {
+}
+
+func (p* TTransportBase) IsOpen() bool {
+ return false;
+};
+
+func (p* TTransportBase) Peek() bool {
+ return p.IsOpen();
+}
+
+func (p* TTransportBase) Open() os.Error {
+ return NewTTransportException(UNKNOWN, "Subclasses must implement TTransportBase.Open()");
+}
+
+func (p* TTransportBase) Close() os.Error {
+ return NewTTransportException(UNKNOWN, "Subclasses must implement TTransportBase.Close()");
+}
+
+func (p* TTransportBase) Read(buf []byte) (int, os.Error) {
+ return 0, NewTTransportExceptionDefaultString("Subclasses must implement TTransportBase.Read()");
+}
+
+func (p* TTransportBase) ReadAll(buf []byte) (n int, err os.Error){
+ ret := 0;
+ size := len(buf);
+ for (n < size) {
+ ret, err = p.Read(buf[n:]);
+ if ret <= 0 {
+ if err != nil {
+ err = NewTTransportExceptionDefaultString("Cannot read. Remote side has closed. Tried to read " + string(size) + " bytes, but only got " + string(n) + " bytes.");
+ }
+ return ret, err;
+ }
+ n += ret;
+ }
+ return n, err;
+}
+
+func (p* TTransportBase) Write(buf []byte) (int, os.Error) {
+ return 0, NewTTransportExceptionDefaultString("Subclasses must implement TTransportBase.Write()");
+}
+
+func (p* TTransportBase) Flush() os.Error {
+ return nil;
+}
+*/
+/**
+ * Guarantees that all of len bytes are actually read off the transport.
+ *
+ * @param buf Array to read into
+ * @param off Index to start reading at
+ * @param len Maximum number of bytes to read
+ * @return The number of bytes actually read, which must be equal to len
+ * @return TTransportException if there was an error reading data
+ */
+func ReadAllTransport(p TTransport, buf []byte) (n int, err os.Error) {
+ ret := 0
+ size := len(buf)
+ for n < size {
+ ret, err = p.Read(buf[n:])
+ if ret <= 0 {
+ if err != nil {
+ err = NewTTransportExceptionDefaultString("Cannot read. Remote side has closed. Tried to read " + string(size) + " bytes, but only got " + string(n) + " bytes.")
+ }
+ return ret, err
+ }
+ n += ret
+ }
+ return n, err
+}
+
+
+var (
+ LOGGER *log.Logger
+)
+
+func init() {
+ LOGGER = log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile)
+}
Added: thrift/trunk/lib/go/thrift/ttransport_exception.go
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/go/thrift/ttransport_exception.go?rev=1072478&view=auto
==============================================================================
--- thrift/trunk/lib/go/thrift/ttransport_exception.go (added)
+++ thrift/trunk/lib/go/thrift/ttransport_exception.go Sun Feb 20 02:39:19 2011
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+ "os"
+)
+
+/**
+ * Transport exceptions.
+ *
+ */
+type TTransportException interface {
+ TException
+ TypeId() int
+}
+
+const (
+ UNKNOWN_TRANSPORT_EXCEPTION = 0
+ NOT_OPEN = 1
+ ALREADY_OPEN = 2
+ TIMED_OUT = 3
+ END_OF_FILE = 4
+)
+
+type tTransportException struct {
+ typeId int
+ message string
+}
+
+func (p *tTransportException) TypeId() int {
+ return p.typeId
+}
+
+func (p *tTransportException) String() string {
+ return p.message
+}
+
+func NewTTransportExceptionDefault() TTransportException {
+ return NewTTransportExceptionDefaultType(UNKNOWN_TRANSPORT_EXCEPTION)
+}
+
+func NewTTransportExceptionDefaultType(t int) TTransportException {
+ return NewTTransportException(t, "")
+}
+
+func NewTTransportExceptionDefaultString(m string) TTransportException {
+ return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, m)
+}
+
+func NewTTransportException(t int, m string) TTransportException {
+ return &tTransportException{typeId: t, message: m}
+}
+
+func NewTTransportExceptionFromOsError(e os.Error) TTransportException {
+ if e == nil {
+ return nil
+ }
+ t, ok := e.(TTransportException)
+ if ok {
+ return t
+ }
+ if e == os.EOF {
+ return NewTTransportException(END_OF_FILE, e.String())
+ }
+ return NewTTransportExceptionDefaultString(e.String())
+}
Added: thrift/trunk/lib/go/thrift/ttransport_factory.go
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/go/thrift/ttransport_factory.go?rev=1072478&view=auto
==============================================================================
--- thrift/trunk/lib/go/thrift/ttransport_factory.go (added)
+++ thrift/trunk/lib/go/thrift/ttransport_factory.go Sun Feb 20 02:39:19 2011
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+/**
+ * Factory class used to create wrapped instance of Transports.
+ * This is used primarily in servers, which get Transports from
+ * a ServerTransport and then may want to mutate them (i.e. create
+ * a BufferedTransport from the underlying base transport)
+ *
+ */
+type TTransportFactory interface {
+ GetTransport(trans TTransport) TTransport
+}
+
+type tTransportFactory struct{}
+
+/**
+ * Return a wrapped instance of the base Transport.
+ *
+ * @param trans The base transport
+ * @return Wrapped Transport
+ */
+func (p *tTransportFactory) GetTransport(trans TTransport) TTransport {
+ return trans
+}
+
+func NewTTransportFactory() TTransportFactory {
+ return &tTransportFactory{}
+}