You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by je...@apache.org on 2013/06/18 22:29:11 UTC
[07/10] THRIFT-2012 Modernizing Go
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/iostream_transport_test.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/iostream_transport_test.go b/lib/go/thrift/iostream_transport_test.go
new file mode 100644
index 0000000..15ea2d4
--- /dev/null
+++ b/lib/go/thrift/iostream_transport_test.go
@@ -0,0 +1,30 @@
+/*
+ * 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 (
+ "bytes"
+ "testing"
+)
+
+func TestStreamTransport(t *testing.T) {
+ trans := NewStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 1024)))
+ TransportTest(t, trans, trans)
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/json_protocol.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/json_protocol.go b/lib/go/thrift/json_protocol.go
new file mode 100644
index 0000000..5e8453a
--- /dev/null
+++ b/lib/go/thrift/json_protocol.go
@@ -0,0 +1,556 @@
+/*
+ * 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 (
+ "encoding/base64"
+ "fmt"
+)
+
+const (
+ THRIFT_JSON_PROTOCOL_VERSION = 1
+)
+
+// for references to _ParseContext see tsimplejson_protocol.go
+
+// 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 TJSONProtocol struct {
+ *TSimpleJSONProtocol
+}
+
+// Constructor
+func NewTJSONProtocol(t TTransport) *TJSONProtocol {
+ v := &TJSONProtocol{TSimpleJSONProtocol: NewTSimpleJSONProtocol(t)}
+ v.parseContextStack = append(v.parseContextStack, int(_CONTEXT_IN_TOPLEVEL))
+ v.dumpContext = append(v.dumpContext, int(_CONTEXT_IN_TOPLEVEL))
+ return v
+}
+
+// Factory
+type TJSONProtocolFactory struct{}
+
+func (p *TJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol {
+ return NewTJSONProtocol(trans)
+}
+
+func NewTJSONProtocolFactory() *TJSONProtocolFactory {
+ return &TJSONProtocolFactory{}
+}
+
+func (p *TJSONProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) error {
+ if e := p.OutputListBegin(); e != nil {
+ return e
+ }
+ if e := p.WriteI32(THRIFT_JSON_PROTOCOL_VERSION); 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 *TJSONProtocol) WriteMessageEnd() error {
+ return p.OutputListEnd()
+}
+
+func (p *TJSONProtocol) WriteStructBegin(name string) error {
+ if e := p.OutputObjectBegin(); e != nil {
+ return e
+ }
+ return nil
+}
+
+func (p *TJSONProtocol) WriteStructEnd() error {
+ return p.OutputObjectEnd()
+}
+
+func (p *TJSONProtocol) WriteFieldBegin(name string, typeId TType, id int16) error {
+ if e := p.WriteI16(id); e != nil {
+ return e
+ }
+ if e := p.OutputObjectBegin(); e != nil {
+ return e
+ }
+ if e := p.WriteString(p.TypeIdToString(typeId)); e != nil {
+ return e
+ }
+ return nil
+}
+
+func (p *TJSONProtocol) WriteFieldEnd() error {
+ return p.OutputObjectEnd()
+}
+
+func (p *TJSONProtocol) WriteFieldStop() error { return nil }
+
+func (p *TJSONProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error {
+ if e := p.OutputListBegin(); e != nil {
+ return e
+ }
+ if e := p.WriteString(p.TypeIdToString(keyType)); e != nil {
+ return e
+ }
+ if e := p.WriteString(p.TypeIdToString(valueType)); e != nil {
+ return e
+ }
+ return p.WriteI64(int64(size))
+}
+
+func (p *TJSONProtocol) WriteMapEnd() error {
+ return p.OutputListEnd()
+}
+
+func (p *TJSONProtocol) WriteListBegin(elemType TType, size int) error {
+ return p.OutputElemListBegin(elemType, size)
+}
+
+func (p *TJSONProtocol) WriteListEnd() error {
+ return p.OutputListEnd()
+}
+
+func (p *TJSONProtocol) WriteSetBegin(elemType TType, size int) error {
+ return p.OutputElemListBegin(elemType, size)
+}
+
+func (p *TJSONProtocol) WriteSetEnd() error {
+ return p.OutputListEnd()
+}
+
+func (p *TJSONProtocol) WriteBool(b bool) error {
+ return p.OutputBool(b)
+}
+
+func (p *TJSONProtocol) WriteByte(b byte) error {
+ return p.WriteI32(int32(b))
+}
+
+func (p *TJSONProtocol) WriteI16(v int16) error {
+ return p.WriteI32(int32(v))
+}
+
+func (p *TJSONProtocol) WriteI32(v int32) error {
+ return p.OutputI64(int64(v))
+}
+
+func (p *TJSONProtocol) WriteI64(v int64) error {
+ return p.OutputI64(int64(v))
+}
+
+func (p *TJSONProtocol) WriteDouble(v float64) error {
+ return p.OutputF64(v)
+}
+
+func (p *TJSONProtocol) WriteString(v string) error {
+ return p.OutputString(v)
+}
+
+func (p *TJSONProtocol) WriteBinary(v []byte) error {
+ // 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
+ }
+ p.writer.Write(JSON_QUOTE_BYTES)
+ writer := base64.NewEncoder(base64.StdEncoding, p.writer)
+ if _, e := writer.Write(v); e != nil {
+ return NewTProtocolException(e)
+ }
+ writer.Close()
+ p.writer.Write(JSON_QUOTE_BYTES)
+ return p.OutputPostValue()
+}
+
+// Reading methods.
+
+func (p *TJSONProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) {
+ if isNull, err := p.ParseListBegin(); isNull || err != nil {
+ return name, typeId, seqId, err
+ }
+ version, err := p.ReadI32()
+ if err != nil {
+ return name, typeId, seqId, err
+ }
+ if version != THRIFT_JSON_PROTOCOL_VERSION {
+ e := fmt.Errorf("Unknown Protocol version %d, expected version %d", version, THRIFT_JSON_PROTOCOL_VERSION)
+ return name, typeId, seqId, NewTProtocolExceptionWithType(INVALID_DATA, e)
+
+ }
+ 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 *TJSONProtocol) ReadMessageEnd() error {
+ err := p.ParseListEnd()
+ return err
+}
+
+func (p *TJSONProtocol) ReadStructBegin() (name string, err error) {
+ _, err = p.ParseObjectStart()
+ return "", err
+}
+
+func (p *TJSONProtocol) ReadStructEnd() error {
+ return p.ParseObjectEnd()
+}
+
+func (p *TJSONProtocol) ReadFieldBegin() (string, TType, int16, error) {
+ if p.reader.Buffered() < 1 {
+ return "", STOP, -1, nil
+ }
+ b, _ := p.reader.Peek(1)
+ if len(b) < 1 || b[0] == JSON_RBRACE[0] || b[0] == JSON_RBRACKET[0] {
+ return "", STOP, -1, nil
+ }
+ fieldId, err := p.ReadI16()
+ if err != nil {
+ return "", STOP, fieldId, err
+ }
+ if _, err = p.ParseObjectStart(); err != nil {
+ return "", STOP, fieldId, err
+ }
+ sType, err := p.ReadString()
+ fType := p.StringToTypeId(sType)
+ return "", fType, fieldId, err
+}
+
+func (p *TJSONProtocol) ReadFieldEnd() error {
+ return p.ParseObjectEnd()
+}
+
+func (p *TJSONProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, e error) {
+ if isNull, e := p.ParseListBegin(); isNull || e != nil {
+ return VOID, VOID, 0, e
+ }
+
+ // read keyType
+ sKeyType, e := p.ReadString()
+ keyType = p.StringToTypeId(sKeyType)
+ if e != nil {
+ return keyType, valueType, size, e
+ }
+
+ // read valueType
+ sValueType, e := p.ReadString()
+ valueType = p.StringToTypeId(sValueType)
+ if e != nil {
+ return keyType, valueType, size, e
+ }
+
+ // read size
+ iSize, err := p.ReadI64()
+ size = int(iSize)
+ return keyType, valueType, size, err
+}
+
+func (p *TJSONProtocol) ReadMapEnd() error {
+ return p.ParseListEnd()
+}
+
+func (p *TJSONProtocol) ReadListBegin() (elemType TType, size int, e error) {
+ return p.ParseElemListBegin()
+}
+
+func (p *TJSONProtocol) ReadListEnd() error {
+ return p.ParseListEnd()
+}
+
+func (p *TJSONProtocol) ReadSetBegin() (elemType TType, size int, e error) {
+ return p.ParseElemListBegin()
+}
+
+func (p *TJSONProtocol) ReadSetEnd() error {
+ return p.ParseListEnd()
+}
+
+func (p *TJSONProtocol) ReadBool() (bool, error) {
+ 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 {
+ e := fmt.Errorf("Expected \"true\" but found: %s", string(b))
+ return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
+ }
+ 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 {
+ e := fmt.Errorf("Expected \"false\" but found: %s", string(b))
+ return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
+ }
+ 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 {
+ e := fmt.Errorf("Expected \"null\" but found: %s", string(b))
+ return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
+ }
+ default:
+ e := fmt.Errorf("Expected \"true\", \"false\", or \"null\" but found: %s", string(b))
+ return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
+ }
+ }
+ return value, p.ParsePostValue()
+}
+
+func (p *TJSONProtocol) ReadByte() (byte, error) {
+ v, err := p.ReadI64()
+ return byte(v), err
+}
+
+func (p *TJSONProtocol) ReadI16() (int16, error) {
+ v, err := p.ReadI64()
+ return int16(v), err
+}
+
+func (p *TJSONProtocol) ReadI32() (int32, error) {
+ v, err := p.ReadI64()
+ return int32(v), err
+}
+
+func (p *TJSONProtocol) ReadI64() (int64, error) {
+ v, _, err := p.ParseI64()
+ return v, err
+}
+
+func (p *TJSONProtocol) ReadDouble() (float64, error) {
+ v, _, err := p.ParseF64()
+ return v, err
+}
+
+func (p *TJSONProtocol) ReadString() (string, error) {
+ 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, NewTProtocolException(err)
+ }
+ } else {
+ e := fmt.Errorf("Expected a JSON string, found %s", string(b))
+ return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
+ }
+ return v, p.ParsePostValue()
+}
+
+func (p *TJSONProtocol) ReadBinary() ([]byte, error) {
+ 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, NewTProtocolException(err)
+ }
+ } else {
+ e := fmt.Errorf("Expected a JSON string, found %s", string(b))
+ return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
+ }
+ return v, p.ParsePostValue()
+}
+
+func (p *TJSONProtocol) Flush() (err error) {
+ return NewTProtocolException(p.writer.Flush())
+}
+
+func (p *TJSONProtocol) Skip(fieldType TType) (err error) {
+ return SkipDefaultDepth(p, fieldType)
+}
+
+func (p *TJSONProtocol) Transport() TTransport {
+ return p.trans
+}
+
+func (p *TJSONProtocol) OutputElemListBegin(elemType TType, size int) error {
+ if e := p.OutputListBegin(); e != nil {
+ return e
+ }
+ if e := p.WriteString(p.TypeIdToString(elemType)); e != nil {
+ return e
+ }
+ if e := p.WriteI64(int64(size)); e != nil {
+ return e
+ }
+ return nil
+}
+
+
+func (p *TJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) {
+ if isNull, e := p.ParseListBegin(); isNull || e != nil {
+ return VOID, 0, e
+ }
+ sElemType, err := p.ReadString()
+ elemType = p.StringToTypeId(sElemType)
+ if err != nil {
+ return elemType, size, err
+ }
+ nSize, err2 := p.ReadI64()
+ size = int(nSize)
+ return elemType, size, err2
+}
+
+func (p *TJSONProtocol) readElemListBegin() (elemType TType, size int, e error) {
+ if isNull, e := p.ParseListBegin(); isNull || e != nil {
+ return VOID, 0, e
+ }
+ sElemType, err := p.ReadString()
+ elemType = p.StringToTypeId(sElemType)
+ if err != nil {
+ return elemType, size, err
+ }
+ nSize, err2 := p.ReadI64()
+ size = int(nSize)
+ return elemType, size, err2
+}
+
+func (p *TJSONProtocol) writeElemListBegin(elemType TType, size int) error {
+ if e := p.OutputListBegin(); e != nil {
+ return e
+ }
+ if e := p.OutputString(p.TypeIdToString(elemType)); e != nil {
+ return e
+ }
+ if e := p.OutputI64(int64(size)); e != nil {
+ return e
+ }
+ return nil
+}
+
+func (p *TJSONProtocol) TypeIdToString(fieldType TType) string {
+ switch byte(fieldType) {
+ case STOP:
+ return "stp"
+ case VOID:
+ return "v"
+ case BOOL:
+ return "tf"
+ case BYTE:
+ return "i8"
+ case DOUBLE:
+ return "dbl"
+ case I16:
+ return "i16"
+ case I32:
+ return "i32"
+ case I64:
+ return "i64"
+ case STRING:
+ return "str"
+ case STRUCT:
+ return "rec"
+ case MAP:
+ return "map"
+ case SET:
+ return "set"
+ case LIST:
+ return "lst"
+ case UTF16:
+ return "str"
+ }
+ return ""
+}
+
+func (p *TJSONProtocol) StringToTypeId(fieldType string) TType {
+ switch fieldType {
+ case "stp":
+ return TType(STOP)
+ case "v":
+ return TType(VOID)
+ case "tf":
+ return TType(BOOL)
+ case "i8":
+ return TType(BYTE)
+ case "dbl":
+ return TType(DOUBLE)
+ case "16":
+ return TType(I16)
+ case "i32":
+ return TType(I32)
+ case "i64":
+ return TType(I64)
+ case "str":
+ return TType(STRING)
+ case "rec":
+ return TType(STRUCT)
+ case "map":
+ return TType(MAP)
+ case "set":
+ return TType(SET)
+ case "lst":
+ return TType(LIST)
+ case "u16":
+ return TType(UTF16)
+ }
+ return TType(STOP)
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/json_protocol_test.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/json_protocol_test.go b/lib/go/thrift/json_protocol_test.go
new file mode 100644
index 0000000..cb626cc
--- /dev/null
+++ b/lib/go/thrift/json_protocol_test.go
@@ -0,0 +1,639 @@
+/*
+ * 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 (
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "math"
+ "strconv"
+ "testing"
+)
+
+func TestWriteJSONProtocolBool(t *testing.T) {
+ thetype := "boolean"
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(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.Error())
+ }
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+ }
+ 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 TestReadJSONProtocolBool(t *testing.T) {
+ thetype := "boolean"
+ for _, value := range BOOL_VALUES {
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(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.Error())
+ }
+ 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 TestWriteJSONProtocolByte(t *testing.T) {
+ thetype := "byte"
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(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.Error())
+ }
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+ }
+ 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 TestReadJSONProtocolByte(t *testing.T) {
+ thetype := "byte"
+ for _, value := range BYTE_VALUES {
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(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.Error())
+ }
+ 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 TestWriteJSONProtocolI16(t *testing.T) {
+ thetype := "int16"
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(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.Error())
+ }
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+ }
+ 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 TestReadJSONProtocolI16(t *testing.T) {
+ thetype := "int16"
+ for _, value := range INT16_VALUES {
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(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.Error())
+ }
+ 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 TestWriteJSONProtocolI32(t *testing.T) {
+ thetype := "int32"
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(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.Error())
+ }
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+ }
+ 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 TestReadJSONProtocolI32(t *testing.T) {
+ thetype := "int32"
+ for _, value := range INT32_VALUES {
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(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.Error())
+ }
+ 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 TestWriteJSONProtocolI64(t *testing.T) {
+ thetype := "int64"
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(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.Error())
+ }
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+ }
+ 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 TestReadJSONProtocolI64(t *testing.T) {
+ thetype := "int64"
+ for _, value := range INT64_VALUES {
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(trans)
+ trans.WriteString(strconv.FormatInt(value, 10))
+ 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.Error())
+ }
+ 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 TestWriteJSONProtocolDouble(t *testing.T) {
+ thetype := "double"
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(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.Error())
+ }
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+ }
+ 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 TestReadJSONProtocolDouble(t *testing.T) {
+ thetype := "double"
+ for _, value := range DOUBLE_VALUES {
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(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.Error())
+ }
+ 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 TestWriteJSONProtocolString(t *testing.T) {
+ thetype := "string"
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(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.Error())
+ }
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+ }
+ 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 TestReadJSONProtocolString(t *testing.T) {
+ thetype := "string"
+ for _, value := range STRING_VALUES {
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(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.Error())
+ }
+ 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 TestWriteJSONProtocolBinary(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 := NewTJSONProtocol(trans)
+ if e := p.WriteBinary(value); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error())
+ }
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+ }
+ s := trans.String()
+ expectedString := fmt.Sprint("\"", b64String, "\"")
+ if s != expectedString {
+ t.Fatalf("Bad value for %s %v\n wrote: \"%v\"\nexpected: \"%v\"", thetype, value, s, expectedString)
+ }
+ v1, err := p.ReadBinary()
+ if err != nil {
+ t.Fatalf("Unable to read binary: %s", err.Error())
+ }
+ if len(v1) != len(value) {
+ t.Fatalf("Invalid value for binary\nexpected: \"%v\"\n read: \"%v\"", value, v1)
+ }
+ for k, v := range value {
+ if v1[k] != v {
+ t.Fatalf("Invalid value for binary at %v\nexpected: \"%v\"\n read: \"%v\"", k, v, v1[k])
+ }
+ }
+ trans.Close()
+}
+
+func TestReadJSONProtocolBinary(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 := NewTJSONProtocol(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.Error())
+ }
+ 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 TestWriteJSONProtocolList(t *testing.T) {
+ thetype := "list"
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(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.Error())
+ }
+ }
+ p.WriteListEnd()
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error())
+ }
+ 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 l[0] != "dbl" {
+ t.Fatal("Invalid type for list, expected: ", STRING, ", 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 TestWriteJSONProtocolSet(t *testing.T) {
+ thetype := "set"
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(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.Error())
+ }
+ }
+ p.WriteSetEnd()
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error())
+ }
+ 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 l[0] != "dbl" {
+ 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 TestWriteJSONProtocolMap(t *testing.T) {
+ thetype := "map"
+ trans := NewTMemoryBuffer()
+ p := NewTJSONProtocol(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.Error())
+ }
+ if e := p.WriteDouble(value); e != nil {
+ t.Fatalf("Unable to write %s value float64 value %v due to error: %s", thetype, value, e.Error())
+ }
+ }
+ p.WriteMapEnd()
+ if e := p.Flush(); e != nil {
+ t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error())
+ }
+ 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)
+ }
+ expectedKeyType, expectedValueType, expectedSize, err := p.ReadMapBegin()
+ if err != nil {
+ t.Fatalf("Error while reading map begin: %s", err.Error())
+ }
+ if expectedKeyType != I32 {
+ t.Fatal("Expected map key type ", I32, ", but was ", expectedKeyType)
+ }
+ if expectedValueType != DOUBLE {
+ t.Fatal("Expected map value type ", DOUBLE, ", but was ", expectedValueType)
+ }
+ if expectedSize != len(DOUBLE_VALUES) {
+ t.Fatal("Expected map size of ", len(DOUBLE_VALUES), ", but was ", expectedSize)
+ }
+ for k, value := range DOUBLE_VALUES {
+ ik, err := p.ReadI32()
+ if err != nil {
+ t.Fatalf("Bad key for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, ik, string(k), err.Error())
+ }
+ if int(ik) != k {
+ t.Fatalf("Bad key for %s index %v, wrote: %v, expected: %v", thetype, k, ik, k)
+ }
+ dv, err := p.ReadDouble()
+ if err != nil {
+ t.Fatalf("Bad value for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, dv, value, err.Error())
+ }
+ s := strconv.FormatFloat(dv, 'g', 10, 64)
+ if math.IsInf(value, 1) {
+ if !math.IsInf(dv, 1) {
+ 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 !math.IsInf(dv, 0) {
+ 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 !math.IsNaN(dv) {
+ t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected: %v", thetype, k, value, s, jsonQuote(JSON_NAN))
+ }
+ } else {
+ expected := strconv.FormatFloat(value, 'g', 10, 64)
+ 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()
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/memory_buffer.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/memory_buffer.go b/lib/go/thrift/memory_buffer.go
new file mode 100644
index 0000000..c48e089
--- /dev/null
+++ b/lib/go/thrift/memory_buffer.go
@@ -0,0 +1,79 @@
+/*
+ * 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 (
+ "bytes"
+)
+
+// Memory buffer-based implementation of the TTransport interface.
+type TMemoryBuffer struct {
+ *bytes.Buffer
+ size int
+}
+
+type TMemoryBufferTransportFactory struct {
+ size int
+}
+
+func (p *TMemoryBufferTransportFactory) GetTransport(trans TTransport) TTransport {
+ if trans != nil {
+ t, ok := trans.(*TMemoryBuffer)
+ if ok && t.size > 0 {
+ return NewTMemoryBufferLen(t.size)
+ }
+ }
+ return NewTMemoryBufferLen(p.size)
+}
+
+func NewTMemoryBufferTransportFactory(size int) *TMemoryBufferTransportFactory {
+ return &TMemoryBufferTransportFactory{size: size}
+}
+
+func NewTMemoryBuffer() *TMemoryBuffer {
+ return &TMemoryBuffer{Buffer: &bytes.Buffer{}, size: 0}
+}
+
+func NewTMemoryBufferLen(size int) *TMemoryBuffer {
+ buf := make([]byte, 0, size)
+ return &TMemoryBuffer{Buffer: bytes.NewBuffer(buf), size: size}
+}
+
+func (p *TMemoryBuffer) IsOpen() bool {
+ return true
+}
+
+func (p *TMemoryBuffer) Open() error {
+ return nil
+}
+
+func (p *TMemoryBuffer) Peek() bool {
+ return p.IsOpen()
+}
+
+func (p *TMemoryBuffer) Close() error {
+ p.Buffer.Reset()
+ return nil
+}
+
+// Flushing a memory buffer is a no-op
+func (p *TMemoryBuffer) Flush() error {
+ return nil
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/memory_buffer_test.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/memory_buffer_test.go b/lib/go/thrift/memory_buffer_test.go
new file mode 100644
index 0000000..af2e8bf
--- /dev/null
+++ b/lib/go/thrift/memory_buffer_test.go
@@ -0,0 +1,29 @@
+/*
+ * 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 (
+ "testing"
+)
+
+func TestMemoryBuffer(t *testing.T) {
+ trans := NewTMemoryBufferLen(1024)
+ TransportTest(t, trans, trans)
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/messagetype.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/messagetype.go b/lib/go/thrift/messagetype.go
new file mode 100644
index 0000000..25ab2e9
--- /dev/null
+++ b/lib/go/thrift/messagetype.go
@@ -0,0 +1,31 @@
+/*
+ * 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
+
+// Message type constants in the Thrift protocol.
+type TMessageType int32
+
+const (
+ INVALID_TMESSAGE_TYPE TMessageType = 0
+ CALL TMessageType = 1
+ REPLY TMessageType = 2
+ EXCEPTION TMessageType = 3
+ ONEWAY TMessageType = 4
+)
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/numeric.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/numeric.go b/lib/go/thrift/numeric.go
new file mode 100644
index 0000000..aa8daa9
--- /dev/null
+++ b/lib/go/thrift/numeric.go
@@ -0,0 +1,164 @@
+/*
+ * 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 (
+ "math"
+ "strconv"
+)
+
+type Numeric interface {
+ Int64() int64
+ Int32() int32
+ Int16() int16
+ Byte() byte
+ Int() int
+ Float64() float64
+ Float32() float32
+ String() string
+ isNull() bool
+}
+
+type numeric struct {
+ iValue int64
+ dValue float64
+ sValue string
+ isNil bool
+}
+
+var (
+ INFINITY Numeric
+ NEGATIVE_INFINITY Numeric
+ NAN Numeric
+ ZERO Numeric
+ NUMERIC_NULL Numeric
+)
+
+func NewNumericFromDouble(dValue float64) Numeric {
+ if math.IsInf(dValue, 1) {
+ return INFINITY
+ }
+ if math.IsInf(dValue, -1) {
+ return NEGATIVE_INFINITY
+ }
+ if math.IsNaN(dValue) {
+ return NAN
+ }
+ iValue := int64(dValue)
+ sValue := strconv.FormatFloat(dValue, 'g', 10, 64)
+ isNil := false
+ return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil}
+}
+
+func NewNumericFromI64(iValue int64) Numeric {
+ dValue := float64(iValue)
+ sValue := string(iValue)
+ isNil := false
+ return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil}
+}
+
+func NewNumericFromI32(iValue int32) Numeric {
+ dValue := float64(iValue)
+ sValue := string(iValue)
+ isNil := false
+ return &numeric{iValue: int64(iValue), dValue: dValue, sValue: sValue, isNil: isNil}
+}
+
+func NewNumericFromString(sValue string) Numeric {
+ if sValue == INFINITY.String() {
+ return INFINITY
+ }
+ if sValue == NEGATIVE_INFINITY.String() {
+ return NEGATIVE_INFINITY
+ }
+ if sValue == NAN.String() {
+ return NAN
+ }
+ iValue, _ := strconv.ParseInt(sValue, 10, 64)
+ dValue, _ := strconv.ParseFloat(sValue, 64)
+ isNil := len(sValue) == 0
+ return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil}
+}
+
+func NewNumericFromJSONString(sValue string, isNull bool) Numeric {
+ if isNull {
+ return NewNullNumeric()
+ }
+ if sValue == JSON_INFINITY {
+ return INFINITY
+ }
+ if sValue == JSON_NEGATIVE_INFINITY {
+ return NEGATIVE_INFINITY
+ }
+ if sValue == JSON_NAN {
+ return NAN
+ }
+ iValue, _ := strconv.ParseInt(sValue, 10, 64)
+ dValue, _ := strconv.ParseFloat(sValue, 64)
+ return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNull}
+}
+
+func NewNullNumeric() Numeric {
+ return &numeric{iValue: 0, dValue: 0.0, sValue: "", isNil: true}
+}
+
+func (p *numeric) Int64() int64 {
+ return p.iValue
+}
+
+func (p *numeric) Int32() int32 {
+ return int32(p.iValue)
+}
+
+func (p *numeric) Int16() int16 {
+ return int16(p.iValue)
+}
+
+func (p *numeric) Byte() byte {
+ return byte(p.iValue)
+}
+
+func (p *numeric) Int() int {
+ return int(p.iValue)
+}
+
+func (p *numeric) Float64() float64 {
+ return p.dValue
+}
+
+func (p *numeric) Float32() float32 {
+ return float32(p.dValue)
+}
+
+func (p *numeric) String() string {
+ return p.sValue
+}
+
+func (p *numeric) isNull() bool {
+ return p.isNil
+}
+
+func init() {
+ INFINITY = &numeric{iValue: 0, dValue: math.Inf(1), sValue: "Infinity", isNil: false}
+ NEGATIVE_INFINITY = &numeric{iValue: 0, dValue: math.Inf(-1), sValue: "-Infinity", isNil: false}
+ NAN = &numeric{iValue: 0, dValue: math.NaN(), sValue: "NaN", isNil: false}
+ ZERO = &numeric{iValue: 0, dValue: 0, sValue: "0", isNil: false}
+ NUMERIC_NULL = &numeric{iValue: 0, dValue: 0, sValue: "0", isNil: true}
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/processor.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/processor.go b/lib/go/thrift/processor.go
new file mode 100644
index 0000000..ca0d3fa
--- /dev/null
+++ b/lib/go/thrift/processor.go
@@ -0,0 +1,30 @@
+/*
+ * 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
+
+// A processor is a generic object which operates upon an input stream and
+// writes to some output stream.
+type TProcessor interface {
+ Process(in, out TProtocol) (bool, TException)
+}
+
+type TProcessorFunction interface {
+ Process(seqId int32, in, out TProtocol) (bool, TException)
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/processor_factory.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/processor_factory.go b/lib/go/thrift/processor_factory.go
new file mode 100644
index 0000000..9d645df
--- /dev/null
+++ b/lib/go/thrift/processor_factory.go
@@ -0,0 +1,58 @@
+/*
+ * 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
+
+// The default processor factory just returns a singleton
+// instance.
+type TProcessorFactory interface {
+ GetProcessor(trans TTransport) TProcessor
+}
+
+type tProcessorFactory struct {
+ processor TProcessor
+}
+
+func NewTProcessorFactory(p TProcessor) TProcessorFactory {
+ return &tProcessorFactory{processor: p}
+}
+
+func (p *tProcessorFactory) GetProcessor(trans TTransport) TProcessor {
+ return p.processor
+}
+
+/**
+ * The default processor factory just returns a singleton
+ * instance.
+ */
+type TProcessorFunctionFactory interface {
+ GetProcessorFunction(trans TTransport) TProcessorFunction
+}
+
+type tProcessorFunctionFactory struct {
+ processor TProcessorFunction
+}
+
+func NewTProcessorFunctionFactory(p TProcessorFunction) TProcessorFunctionFactory {
+ return &tProcessorFunctionFactory{processor: p}
+}
+
+func (p *tProcessorFunctionFactory) GetProcessorFunction(trans TTransport) TProcessorFunction {
+ return p.processor
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/protocol.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/protocol.go b/lib/go/thrift/protocol.go
new file mode 100644
index 0000000..87ceaad
--- /dev/null
+++ b/lib/go/thrift/protocol.go
@@ -0,0 +1,154 @@
+/*
+ * 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
+
+const (
+ VERSION_MASK = 0xffff0000
+ VERSION_1 = 0x80010000
+)
+
+type TProtocol interface {
+ WriteMessageBegin(name string, typeId TMessageType, seqid int32) error
+ WriteMessageEnd() error
+ WriteStructBegin(name string) error
+ WriteStructEnd() error
+ WriteFieldBegin(name string, typeId TType, id int16) error
+ WriteFieldEnd() error
+ WriteFieldStop() error
+ WriteMapBegin(keyType TType, valueType TType, size int) error
+ WriteMapEnd() error
+ WriteListBegin(elemType TType, size int) error
+ WriteListEnd() error
+ WriteSetBegin(elemType TType, size int) error
+ WriteSetEnd() error
+ WriteBool(value bool) error
+ WriteByte(value byte) error
+ WriteI16(value int16) error
+ WriteI32(value int32) error
+ WriteI64(value int64) error
+ WriteDouble(value float64) error
+ WriteString(value string) error
+ WriteBinary(value []byte) error
+
+ ReadMessageBegin() (name string, typeId TMessageType, seqid int32, err error)
+ ReadMessageEnd() error
+ ReadStructBegin() (name string, err error)
+ ReadStructEnd() error
+ ReadFieldBegin() (name string, typeId TType, id int16, err error)
+ ReadFieldEnd() error
+ ReadMapBegin() (keyType TType, valueType TType, size int, err error)
+ ReadMapEnd() error
+ ReadListBegin() (elemType TType, size int, err error)
+ ReadListEnd() error
+ ReadSetBegin() (elemType TType, size int, err error)
+ ReadSetEnd() error
+ ReadBool() (value bool, err error)
+ ReadByte() (value byte, err error)
+ ReadI16() (value int16, err error)
+ ReadI32() (value int32, err error)
+ ReadI64() (value int64, err error)
+ ReadDouble() (value float64, err error)
+ ReadString() (value string, err error)
+ ReadBinary() (value []byte, err error)
+
+ Skip(fieldType TType) (err error)
+ Flush() (err error)
+
+ Transport() TTransport
+}
+
+// The maximum recursive depth the skip() function will traverse
+var MaxSkipDepth = 1<<31 - 1
+
+// Skips over the next data element from the provided input TProtocol object.
+func SkipDefaultDepth(prot TProtocol, typeId TType) (err error) {
+ return Skip(prot, typeId, MaxSkipDepth)
+}
+
+// Skips over the next data element from the provided input TProtocol object.
+func Skip(self TProtocol, fieldType TType, maxDepth int) (err error) {
+ switch fieldType {
+ case STOP:
+ return
+ case BOOL:
+ _, err = self.ReadBool()
+ return
+ case BYTE:
+ _, err = self.ReadByte()
+ return
+ case I16:
+ _, err = self.ReadI16()
+ return
+ case I32:
+ _, err = self.ReadI32()
+ return
+ case I64:
+ _, err = self.ReadI64()
+ return
+ case DOUBLE:
+ _, err = self.ReadDouble()
+ return
+ case STRING:
+ _, err = self.ReadString()
+ return
+ case STRUCT:
+ if _, err = self.ReadStructBegin(); err != nil {
+ return err
+ }
+ for {
+ _, typeId, _, _ := self.ReadFieldBegin()
+ if typeId == STOP {
+ break
+ }
+ Skip(self, typeId, maxDepth-1)
+ self.ReadFieldEnd()
+ }
+ return self.ReadStructEnd()
+ case MAP:
+ keyType, valueType, size, err := self.ReadMapBegin()
+ if err != nil {
+ return err
+ }
+ for i := 0; i < size; i++ {
+ Skip(self, keyType, maxDepth-1)
+ self.Skip(valueType)
+ }
+ return self.ReadMapEnd()
+ case SET:
+ elemType, size, err := self.ReadSetBegin()
+ if err != nil {
+ return err
+ }
+ for i := 0; i < size; i++ {
+ Skip(self, elemType, maxDepth-1)
+ }
+ return self.ReadSetEnd()
+ case LIST:
+ elemType, size, err := self.ReadListBegin()
+ if err != nil {
+ return err
+ }
+ for i := 0; i < size; i++ {
+ Skip(self, elemType, maxDepth-1)
+ }
+ return self.ReadListEnd()
+ }
+ return nil
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/protocol_exception.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/protocol_exception.go b/lib/go/thrift/protocol_exception.go
new file mode 100644
index 0000000..f1a164a
--- /dev/null
+++ b/lib/go/thrift/protocol_exception.go
@@ -0,0 +1,77 @@
+/*
+ * 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 (
+ "encoding/base64"
+)
+
+// Thrift Protocol exception
+type TProtocolException interface {
+ TException
+ TypeId() int
+}
+
+const (
+ UNKNOWN_PROTOCOL_EXCEPTION = 0
+ INVALID_DATA = 1
+ NEGATIVE_SIZE = 2
+ SIZE_LIMIT = 3
+ BAD_VERSION = 4
+ NOT_IMPLEMENTED = 5
+)
+
+type tProtocolException struct {
+ typeId int
+ message string
+}
+
+func (p *tProtocolException) TypeId() int {
+ return p.typeId
+}
+
+func (p *tProtocolException) String() string {
+ return p.message
+}
+
+func (p *tProtocolException) Error() string {
+ return p.message
+}
+
+func NewTProtocolException(err error) TProtocolException {
+ if err == nil {
+ return nil
+ }
+ if e,ok := err.(TProtocolException); ok {
+ return e
+ }
+ if _, ok := err.(base64.CorruptInputError); ok {
+ return &tProtocolException{INVALID_DATA, err.Error()}
+ }
+ return &tProtocolException{UNKNOWN_PROTOCOL_EXCEPTION, err.Error()}
+}
+
+func NewTProtocolExceptionWithType(errType int, err error) TProtocolException {
+ if err == nil {
+ return nil
+ }
+ return &tProtocolException{errType, err.Error()}
+}
+
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/protocol_factory.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/protocol_factory.go b/lib/go/thrift/protocol_factory.go
new file mode 100644
index 0000000..c40f796
--- /dev/null
+++ b/lib/go/thrift/protocol_factory.go
@@ -0,0 +1,25 @@
+/*
+ * 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 interface for constructing protocol instances.
+type TProtocolFactory interface {
+ GetProtocol(trans TTransport) TProtocol
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/protocol_test.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/protocol_test.go b/lib/go/thrift/protocol_test.go
new file mode 100644
index 0000000..632098c
--- /dev/null
+++ b/lib/go/thrift/protocol_test.go
@@ -0,0 +1,458 @@
+/*
+ * 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 (
+ "bytes"
+ "io/ioutil"
+ "math"
+ "net"
+ "net/http"
+ "testing"
+)
+
+const PROTOCOL_BINARY_DATA_SIZE = 155
+
+var (
+ data string // test data for writing
+ protocol_bdata []byte // test data for writing; same as data
+ BOOL_VALUES []bool
+ BYTE_VALUES []byte
+ INT16_VALUES []int16
+ INT32_VALUES []int32
+ INT64_VALUES []int64
+ DOUBLE_VALUES []float64
+ STRING_VALUES []string
+)
+
+func init() {
+ protocol_bdata = make([]byte, PROTOCOL_BINARY_DATA_SIZE)
+ for i := 0; i < PROTOCOL_BINARY_DATA_SIZE; i++ {
+ protocol_bdata[i] = byte((i + 'a') % 255)
+ }
+ data = string(protocol_bdata)
+ BOOL_VALUES = []bool{false, true, false, false, true}
+ BYTE_VALUES = []byte{117, 0, 1, 32, 127, 128, 255}
+ INT16_VALUES = []int16{459, 0, 1, -1, -128, 127, 32767, -32768}
+ INT32_VALUES = []int32{459, 0, 1, -1, -128, 127, 32767, 2147483647, -2147483535}
+ INT64_VALUES = []int64{459, 0, 1, -1, -128, 127, 32767, 2147483647, -2147483535, 34359738481, -35184372088719, -9223372036854775808, 9223372036854775807}
+ DOUBLE_VALUES = []float64{459.3, 0.0, -1.0, 1.0, 0.5, 0.3333, 3.14159, 1.537e-38, 1.673e25, 6.02214179e23, -6.02214179e23, INFINITY.Float64(), NEGATIVE_INFINITY.Float64(), NAN.Float64()}
+ STRING_VALUES = []string{"", "a", "st[uf]f", "st,u:ff with spaces", "stuff\twith\nescape\\characters'...\"lots{of}fun</xml>"}
+}
+
+type HTTPEchoServer struct{}
+
+func (p *HTTPEchoServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+ buf, err := ioutil.ReadAll(req.Body)
+ if err != nil {
+ w.WriteHeader(http.StatusBadRequest)
+ w.Write(buf)
+ } else {
+ w.WriteHeader(http.StatusOK)
+ w.Write(buf)
+ }
+}
+
+func HttpClientSetupForTest(t *testing.T) (net.Listener, net.Addr) {
+ addr, err := FindAvailableTCPServerPort(40000)
+ if err != nil {
+ t.Fatalf("Unable to find available tcp port addr: %s", err)
+ return nil, addr
+ }
+ l, err := net.Listen(addr.Network(), addr.String())
+ if err != nil {
+ t.Fatalf("Unable to setup tcp listener on %s: %s", addr.String(), err)
+ return l, addr
+ }
+ go http.Serve(l, &HTTPEchoServer{})
+ return l, addr
+}
+
+func ReadWriteProtocolTest(t *testing.T, protocolFactory TProtocolFactory) {
+ buf := bytes.NewBuffer(make([]byte, 0, 1024))
+ l, addr := HttpClientSetupForTest(t)
+ defer l.Close()
+ transports := []TTransportFactory{
+ NewTMemoryBufferTransportFactory(1024),
+ NewStreamTransportFactory(buf, buf, true),
+ NewTFramedTransportFactory(NewTMemoryBufferTransportFactory(1024)),
+ NewTHttpPostClientTransportFactory("http://" + addr.String()),
+ }
+ for _, tf := range transports {
+ trans := tf.GetTransport(nil)
+ p := protocolFactory.GetProtocol(trans)
+ ReadWriteBool(t, p, trans)
+ trans.Close()
+ }
+ for _, tf := range transports {
+ trans := tf.GetTransport(nil)
+ p := protocolFactory.GetProtocol(trans)
+ ReadWriteByte(t, p, trans)
+ trans.Close()
+ }
+ for _, tf := range transports {
+ trans := tf.GetTransport(nil)
+ p := protocolFactory.GetProtocol(trans)
+ ReadWriteI16(t, p, trans)
+ trans.Close()
+ }
+ for _, tf := range transports {
+ trans := tf.GetTransport(nil)
+ p := protocolFactory.GetProtocol(trans)
+ ReadWriteI32(t, p, trans)
+ trans.Close()
+ }
+ for _, tf := range transports {
+ trans := tf.GetTransport(nil)
+ p := protocolFactory.GetProtocol(trans)
+ ReadWriteI64(t, p, trans)
+ trans.Close()
+ }
+ for _, tf := range transports {
+ trans := tf.GetTransport(nil)
+ p := protocolFactory.GetProtocol(trans)
+ ReadWriteDouble(t, p, trans)
+ trans.Close()
+ }
+ for _, tf := range transports {
+ trans := tf.GetTransport(nil)
+ p := protocolFactory.GetProtocol(trans)
+ ReadWriteString(t, p, trans)
+ trans.Close()
+ }
+ for _, tf := range transports {
+ trans := tf.GetTransport(nil)
+ p := protocolFactory.GetProtocol(trans)
+ ReadWriteBinary(t, p, trans)
+ trans.Close()
+ }
+
+ for _, tf := range transports {
+ trans := tf.GetTransport(nil)
+ p := protocolFactory.GetProtocol(trans);
+ ReadWriteI64(t, p, trans);
+ ReadWriteDouble(t, p, trans);
+ ReadWriteBinary(t, p, trans);
+ ReadWriteByte(t, p, trans);
+ trans.Close()
+ }
+
+}
+
+func ReadWriteBool(t *testing.T, p TProtocol, trans TTransport) {
+ thetype := TType(BOOL)
+ thelen := len(BOOL_VALUES)
+ err := p.WriteListBegin(thetype, thelen)
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error writing list begin: %q", "ReadWriteBool", p, trans, err, thetype)
+ }
+ for k, v := range BOOL_VALUES {
+ err = p.WriteBool(v)
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error writing bool in list at index %d: %q", "ReadWriteBool", p, trans, err, k, v)
+ }
+ }
+ p.WriteListEnd()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error writing list end: %q", "ReadWriteBool", p, trans, err, BOOL_VALUES)
+ }
+ p.Flush()
+ thetype2, thelen2, err := p.ReadListBegin()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteBool", p, trans, err, BOOL_VALUES)
+ }
+ _, ok := p.(*TSimpleJSONProtocol)
+ if !ok {
+ if thetype != thetype2 {
+ t.Errorf("%s: %T %T type %s != type %s", "ReadWriteBool", p, trans, thetype, thetype2)
+ }
+ if thelen != thelen2 {
+ t.Errorf("%s: %T %T len %s != len %s", "ReadWriteBool", p, trans, thelen, thelen2)
+ }
+ }
+ for k, v := range BOOL_VALUES {
+ value, err := p.ReadBool()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error reading bool at index %d: %q", "ReadWriteBool", p, trans, err, k, v)
+ }
+ if v != value {
+ t.Errorf("%s: index %d %q %q %q != %q", "ReadWriteBool", k, p, trans, v, value)
+ }
+ }
+ err = p.ReadListEnd()
+ if err != nil {
+ t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteBool", p, trans, err)
+ }
+}
+
+func ReadWriteByte(t *testing.T, p TProtocol, trans TTransport) {
+ thetype := TType(BYTE)
+ thelen := len(BYTE_VALUES)
+ err := p.WriteListBegin(thetype, thelen)
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error writing list begin: %q", "ReadWriteByte", p, trans, err, thetype)
+ }
+ for k, v := range BYTE_VALUES {
+ err = p.WriteByte(v)
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error writing byte in list at index %d: %q", "ReadWriteByte", p, trans, err, k, v)
+ }
+ }
+ err = p.WriteListEnd()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error writing list end: %q", "ReadWriteByte", p, trans, err, BYTE_VALUES)
+ }
+ err = p.Flush()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error flushing list of bytes: %q", "ReadWriteByte", p, trans, err, BYTE_VALUES)
+ }
+ thetype2, thelen2, err := p.ReadListBegin()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteByte", p, trans, err, BYTE_VALUES)
+ }
+ _, ok := p.(*TSimpleJSONProtocol)
+ if !ok {
+ if thetype != thetype2 {
+ t.Errorf("%s: %T %T type %s != type %s", "ReadWriteByte", p, trans, thetype, thetype2)
+ }
+ if thelen != thelen2 {
+ t.Errorf("%s: %T %T len %s != len %s", "ReadWriteByte", p, trans, thelen, thelen2)
+ }
+ }
+ for k, v := range BYTE_VALUES {
+ value, err := p.ReadByte()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error reading byte at index %d: %q", "ReadWriteByte", p, trans, err, k, v)
+ }
+ if v != value {
+ t.Errorf("%s: %T %T %d != %d", "ReadWriteByte", p, trans, v, value)
+ }
+ }
+ err = p.ReadListEnd()
+ if err != nil {
+ t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteByte", p, trans, err)
+ }
+}
+
+func ReadWriteI16(t *testing.T, p TProtocol, trans TTransport) {
+ thetype := TType(I16)
+ thelen := len(INT16_VALUES)
+ p.WriteListBegin(thetype, thelen)
+ for _, v := range INT16_VALUES {
+ p.WriteI16(v)
+ }
+ p.WriteListEnd()
+ p.Flush()
+ thetype2, thelen2, err := p.ReadListBegin()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteI16", p, trans, err, INT16_VALUES)
+ }
+ _, ok := p.(*TSimpleJSONProtocol)
+ if !ok {
+ if thetype != thetype2 {
+ t.Errorf("%s: %T %T type %s != type %s", "ReadWriteI16", p, trans, thetype, thetype2)
+ }
+ if thelen != thelen2 {
+ t.Errorf("%s: %T %T len %s != len %s", "ReadWriteI16", p, trans, thelen, thelen2)
+ }
+ }
+ for k, v := range INT16_VALUES {
+ value, err := p.ReadI16()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error reading int16 at index %d: %q", "ReadWriteI16", p, trans, err, k, v)
+ }
+ if v != value {
+ t.Errorf("%s: %T %T %d != %d", "ReadWriteI16", p, trans, v, value)
+ }
+ }
+ err = p.ReadListEnd()
+ if err != nil {
+ t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteI16", p, trans, err)
+ }
+}
+
+func ReadWriteI32(t *testing.T, p TProtocol, trans TTransport) {
+ thetype := TType(I32)
+ thelen := len(INT32_VALUES)
+ p.WriteListBegin(thetype, thelen)
+ for _, v := range INT32_VALUES {
+ p.WriteI32(v)
+ }
+ p.WriteListEnd()
+ p.Flush()
+ thetype2, thelen2, err := p.ReadListBegin()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteI32", p, trans, err, INT32_VALUES)
+ }
+ _, ok := p.(*TSimpleJSONProtocol)
+ if !ok {
+ if thetype != thetype2 {
+ t.Errorf("%s: %T %T type %s != type %s", "ReadWriteI32", p, trans, thetype, thetype2)
+ }
+ if thelen != thelen2 {
+ t.Errorf("%s: %T %T len %s != len %s", "ReadWriteI32", p, trans, thelen, thelen2)
+ }
+ }
+ for k, v := range INT32_VALUES {
+ value, err := p.ReadI32()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error reading int32 at index %d: %q", "ReadWriteI32", p, trans, err, k, v)
+ }
+ if v != value {
+ t.Errorf("%s: %T %T %d != %d", "ReadWriteI32", p, trans, v, value)
+ }
+ }
+ if err != nil {
+ t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteI32", p, trans, err)
+ }
+}
+
+func ReadWriteI64(t *testing.T, p TProtocol, trans TTransport) {
+ thetype := TType(I64)
+ thelen := len(INT64_VALUES)
+ p.WriteListBegin(thetype, thelen)
+ for _, v := range INT64_VALUES {
+ p.WriteI64(v)
+ }
+ p.WriteListEnd()
+ p.Flush()
+ thetype2, thelen2, err := p.ReadListBegin()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteI64", p, trans, err, INT64_VALUES)
+ }
+ _, ok := p.(*TSimpleJSONProtocol)
+ if !ok {
+ if thetype != thetype2 {
+ t.Errorf("%s: %T %T type %s != type %s", "ReadWriteI64", p, trans, thetype, thetype2)
+ }
+ if thelen != thelen2 {
+ t.Errorf("%s: %T %T len %s != len %s", "ReadWriteI64", p, trans, thelen, thelen2)
+ }
+ }
+ for k, v := range INT64_VALUES {
+ value, err := p.ReadI64()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error reading int64 at index %d: %q", "ReadWriteI64", p, trans, err, k, v)
+ }
+ if v != value {
+ t.Errorf("%s: %T %T %q != %q", "ReadWriteI64", p, trans, v, value)
+ }
+ }
+ if err != nil {
+ t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteI64", p, trans, err)
+ }
+}
+
+func ReadWriteDouble(t *testing.T, p TProtocol, trans TTransport) {
+ thetype := TType(DOUBLE)
+ thelen := len(DOUBLE_VALUES)
+ p.WriteListBegin(thetype, thelen)
+ for _, v := range DOUBLE_VALUES {
+ p.WriteDouble(v)
+ }
+ p.WriteListEnd()
+ p.Flush()
+ wrotebuffer := ""
+ if memtrans, ok := trans.(*TMemoryBuffer); ok {
+ wrotebuffer = memtrans.String()
+ }
+ thetype2, thelen2, err := p.ReadListBegin()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error reading list: %q, wrote: %v", "ReadWriteDouble", p, trans, err, DOUBLE_VALUES, wrotebuffer)
+ }
+ if thetype != thetype2 {
+ t.Errorf("%s: %T %T type %s != type %s", "ReadWriteDouble", p, trans, thetype, thetype2)
+ }
+ if thelen != thelen2 {
+ t.Errorf("%s: %T %T len %s != len %s", "ReadWriteDouble", p, trans, thelen, thelen2)
+ }
+ for k, v := range DOUBLE_VALUES {
+ value, err := p.ReadDouble()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error reading double at index %d: %q", "ReadWriteDouble", p, trans, err, k, v)
+ }
+ if math.IsNaN(v) {
+ if !math.IsNaN(value) {
+ t.Errorf("%s: %T %T math.IsNaN(%q) != math.IsNaN(%q)", "ReadWriteDouble", p, trans, v, value)
+ }
+ } else if v != value {
+ t.Errorf("%s: %T %T %v != %q", "ReadWriteDouble", p, trans, v, value)
+ }
+ }
+ err = p.ReadListEnd()
+ if err != nil {
+ t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteDouble", p, trans, err)
+ }
+}
+
+func ReadWriteString(t *testing.T, p TProtocol, trans TTransport) {
+ thetype := TType(STRING)
+ thelen := len(STRING_VALUES)
+ p.WriteListBegin(thetype, thelen)
+ for _, v := range STRING_VALUES {
+ p.WriteString(v)
+ }
+ p.WriteListEnd()
+ p.Flush()
+ thetype2, thelen2, err := p.ReadListBegin()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteString", p, trans, err, STRING_VALUES)
+ }
+ _, ok := p.(*TSimpleJSONProtocol)
+ if !ok {
+ if thetype != thetype2 {
+ t.Errorf("%s: %T %T type %s != type %s", "ReadWriteString", p, trans, thetype, thetype2)
+ }
+ if thelen != thelen2 {
+ t.Errorf("%s: %T %T len %s != len %s", "ReadWriteString", p, trans, thelen, thelen2)
+ }
+ }
+ for k, v := range STRING_VALUES {
+ value, err := p.ReadString()
+ if err != nil {
+ t.Errorf("%s: %T %T %q Error reading string at index %d: %q", "ReadWriteString", p, trans, err, k, v)
+ }
+ if v != value {
+ t.Errorf("%s: %T %T %d != %d", "ReadWriteString", p, trans, v, value)
+ }
+ }
+ if err != nil {
+ t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteString", p, trans, err)
+ }
+}
+
+func ReadWriteBinary(t *testing.T, p TProtocol, trans TTransport) {
+ v := protocol_bdata
+ p.WriteBinary(v)
+ p.Flush()
+ value, err := p.ReadBinary()
+ if err != nil {
+ t.Errorf("%s: %T %T Unable to read binary: %s", "ReadWriteBinary", p, trans, err.Error())
+ }
+ if len(v) != len(value) {
+ t.Errorf("%s: %T %T len(v) != len(value)... %d != %d", "ReadWriteBinary", p, trans, len(v), len(value))
+ } else {
+ for i := 0; i < len(v); i++ {
+ if v[i] != value[i] {
+ t.Errorf("%s: %T %T %s != %s", "ReadWriteBinary", p, trans, v, value)
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/server.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/server.go b/lib/go/thrift/server.go
new file mode 100644
index 0000000..f813fa3
--- /dev/null
+++ b/lib/go/thrift/server.go
@@ -0,0 +1,35 @@
+/*
+ * 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
+
+type TServer interface {
+ ProcessorFactory() TProcessorFactory
+ ServerTransport() TServerTransport
+ InputTransportFactory() TTransportFactory
+ OutputTransportFactory() TTransportFactory
+ InputProtocolFactory() TProtocolFactory
+ OutputProtocolFactory() TProtocolFactory
+
+ // Starts the server
+ Serve() error
+ // Stops the server. This is optional on a per-implementation basis. Not
+ // all servers are required to be cleanly stoppable.
+ Stop() error
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/server_socket.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/server_socket.go b/lib/go/thrift/server_socket.go
new file mode 100644
index 0000000..1a01095
--- /dev/null
+++ b/lib/go/thrift/server_socket.go
@@ -0,0 +1,107 @@
+/*
+ * 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"
+ "time"
+)
+
+type TServerSocket struct {
+ listener net.Listener
+ addr net.Addr
+ clientTimeout time.Duration
+ interrupted bool
+}
+
+func NewTServerSocket(listenAddr string) (*TServerSocket, error) {
+ return NewTServerSocketTimeout(listenAddr, 0)
+}
+
+func NewTServerSocketTimeout(listenAddr string, clientTimeout time.Duration) (*TServerSocket, error) {
+ addr, err := net.ResolveTCPAddr("tcp", listenAddr)
+ if err != nil {
+ return nil, err
+ }
+ return &TServerSocket{addr: addr, clientTimeout: clientTimeout}, nil
+}
+
+func (p *TServerSocket) Listen() error {
+ if p.IsListening() {
+ return nil
+ }
+ l, err := net.Listen(p.addr.Network(), p.addr.String())
+ if err != nil {
+ return err
+ }
+ p.listener = l
+ return nil
+}
+
+func (p *TServerSocket) Accept() (TTransport, error) {
+ if p.interrupted {
+ return nil, errTransportInterrupted
+ }
+ if p.listener == nil {
+ return nil, NewTTransportException(NOT_OPEN, "No underlying server socket")
+ }
+ conn, err := p.listener.Accept()
+ if err != nil {
+ return nil, NewTTransportExceptionFromError(err)
+ }
+ return NewTSocketFromConnTimeout(conn, p.clientTimeout), nil
+}
+
+// Checks whether the socket is listening.
+func (p *TServerSocket) IsListening() bool {
+ return p.listener != nil
+}
+
+// Connects the socket, creating a new socket object if necessary.
+func (p *TServerSocket) Open() error {
+ if p.IsListening() {
+ return NewTTransportException(ALREADY_OPEN, "Server socket already open")
+ }
+ if l, err := net.Listen(p.addr.Network(), p.addr.String()); err != nil {
+ return err
+ } else {
+ p.listener = l
+ }
+ return nil
+}
+
+func (p *TServerSocket) Addr() net.Addr {
+ return p.addr
+}
+
+func (p *TServerSocket) Close() error {
+ defer func() {
+ p.listener = nil
+ }()
+ if p.IsListening() {
+ return p.listener.Close()
+ }
+ return nil
+}
+
+func (p *TServerSocket) Interrupt() error {
+ p.interrupted = true
+ return nil
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/server_test.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/server_test.go b/lib/go/thrift/server_test.go
new file mode 100644
index 0000000..ffaf457
--- /dev/null
+++ b/lib/go/thrift/server_test.go
@@ -0,0 +1,28 @@
+/*
+ * 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 (
+ "testing"
+)
+
+func TestNothing(t *testing.T) {
+
+}
http://git-wip-us.apache.org/repos/asf/thrift/blob/0e87c46c/lib/go/thrift/server_transport.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/server_transport.go b/lib/go/thrift/server_transport.go
new file mode 100644
index 0000000..51c40b6
--- /dev/null
+++ b/lib/go/thrift/server_transport.go
@@ -0,0 +1,34 @@
+/*
+ * 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
+
+// Server transport. Object which provides client transports.
+type TServerTransport interface {
+ Listen() error
+ Accept() (TTransport, error)
+ Close() error
+
+ // Optional method implementation. This signals to the server transport
+ // that it should break out of any accept() or listen() that it is currently
+ // blocked on. This method, if implemented, MUST be thread safe, as it may
+ // be called from a different thread context than the other TServerTransport
+ // methods.
+ Interrupt() error
+}