pax_global_header00006660000000000000000000000064122267752340014524gustar00rootroot0000000000000052 comment=3aaedd528c7b10caac2a023b4236555a1fd5fef9 golang-thrift-0.0~git20121118/000077500000000000000000000000001222677523400156525ustar00rootroot00000000000000golang-thrift-0.0~git20121118/tapplication_exception.go000066400000000000000000000073751222677523400227620ustar00rootroot00000000000000/* * 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 ( "errors" ) const ( UNKNOWN_APPLICATION_EXCEPTION = 0 UNKNOWN_METHOD = 1 INVALID_MESSAGE_TYPE_EXCEPTION = 2 WRONG_METHOD_NAME = 3 BAD_SEQUENCE_ID = 4 MISSING_RESULT = 5 INTERNAL_ERROR = 6 PROTOCOL_ERROR = 7 ) /** * Application level exception * */ type TApplicationException interface { TException TypeId() int32 Read(iprot TProtocol) (TApplicationException, error) Write(oprot TProtocol) error } type tApplicationException struct { TException type_ int32 } func NewTApplicationExceptionDefault() TApplicationException { return NewTApplicationException(UNKNOWN_APPLICATION_EXCEPTION, "UNKNOWN") } func NewTApplicationExceptionType(type_ int32) TApplicationException { return NewTApplicationException(type_, "UNKNOWN") } func NewTApplicationException(type_ int32, message string) TApplicationException { return &tApplicationException{TException: NewTException(message), type_: type_} } func NewTApplicationExceptionMessage(message string) TApplicationException { return NewTApplicationException(UNKNOWN_APPLICATION_EXCEPTION, message) } func (p *tApplicationException) TypeId() int32 { return p.type_ } func (p *tApplicationException) Read(iprot TProtocol) (error TApplicationException, err error) { _, err = iprot.ReadStructBegin() // this shouldn't be needed er := errors.New("empty") if er == nil { return } if err != nil { return } message := "" type_ := int32(UNKNOWN_APPLICATION_EXCEPTION) for { _, ttype, id, er := iprot.ReadFieldBegin() if er != nil { return nil, er } if ttype == STOP { break } switch id { case 1: if ttype == STRING { message, err = iprot.ReadString() if err != nil { return } } else { err = SkipDefaultDepth(iprot, ttype) if err != nil { return } } break case 2: if ttype == I32 { type_, err = iprot.ReadI32() if err != nil { return } } else { err = SkipDefaultDepth(iprot, ttype) if err != nil { return } } break default: err = SkipDefaultDepth(iprot, ttype) if err != nil { return } break } err = iprot.ReadFieldEnd() if err != nil { return } } err = iprot.ReadStructEnd() error = NewTApplicationException(type_, message) return } func (p *tApplicationException) Write(oprot TProtocol) (err error) { err = oprot.WriteStructBegin("TApplicationException") if len(p.Error()) > 0 { err = oprot.WriteFieldBegin("message", STRING, 1) if err != nil { return } err = oprot.WriteString(p.Error()) if err != nil { return } err = oprot.WriteFieldEnd() if err != nil { return } } err = oprot.WriteFieldBegin("type", I32, 2) if err != nil { return } err = oprot.WriteI32(p.type_) if err != nil { return } err = oprot.WriteFieldEnd() if err != nil { return } err = oprot.WriteFieldStop() if err != nil { return } err = oprot.WriteStructEnd() return } golang-thrift-0.0~git20121118/tapplication_exception_test.go000066400000000000000000000027531222677523400240140ustar00rootroot00000000000000/* * 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 TestTApplicationException(t *testing.T) { exc := NewTApplicationException(UNKNOWN_APPLICATION_EXCEPTION, "") if exc.Error() != "" { t.Fatalf("Expected empty string for exception but found '%s'", exc.Error()) } if exc.TypeId() != UNKNOWN_APPLICATION_EXCEPTION { t.Fatalf("Expected type UNKNOWN for exception but found '%s'", exc.TypeId()) } exc = NewTApplicationException(WRONG_METHOD_NAME, "junk_method") if exc.Error() != "junk_method" { t.Fatalf("Expected 'junk_method' for exception but found '%s'", exc.Error()) } if exc.TypeId() != WRONG_METHOD_NAME { t.Fatalf("Expected type WRONG_METHOD_NAME for exception but found '%s'", exc.TypeId()) } } golang-thrift-0.0~git20121118/tbase.go000066400000000000000000000032331222677523400173000ustar00rootroot00000000000000/* * 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 /** * Generic base interface for generated Thrift objects. * */ type TBase interface { /** * Reads the TObject from the given input protocol * * @param iprot Input protocol */ Read(iprot TProtocol) (err TException) /** * Writes the objects out to the protocol * * @param oprot Output protocol */ Write(oprot TProtocol) (err TException) /** * Check if a field is currently set or unset. * * @param field */ IsSet(field TField) bool /** * Get a field's value by field variable. Primitive types will be wrapped in * the appropriate "boxed" types. * * @param field */ FieldValue(field TField) interface{} /** * Set a field's value by field variable. Primitive types must be "boxed" in * the appropriate object wrapper type. * * @param field */ SetFieldValue(field TField, value interface{}) DeepCopy() TBase } golang-thrift-0.0~git20121118/tbinary_protocol.go000066400000000000000000000276401222677523400216030ustar00rootroot00000000000000/* * 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/binary" "io" "math" "strings" ) type TBinaryProtocol struct { //TProtocolBase; trans TTransport _StrictRead bool _StrictWrite bool _ReadLength int _CheckReadLength bool } type TBinaryProtocolFactory struct { _StrictRead bool _StrictWrite bool } func NewTBinaryProtocolTransport(t TTransport) *TBinaryProtocol { return NewTBinaryProtocol(t, false, true) } func NewTBinaryProtocol(t TTransport, strictRead, strictWrite bool) *TBinaryProtocol { //return &TBinaryProtocol{TProtocolBase:TProtocolBase{trans:t}, _StrictRead:strictRead, _StrictWrite:strictWrite, _ReadLength:0, _CheckReadLength:false}; return &TBinaryProtocol{trans: t, _StrictRead: strictRead, _StrictWrite: strictWrite, _ReadLength: 0, _CheckReadLength: false} } func NewTBinaryProtocolFactoryDefault() *TBinaryProtocolFactory { return NewTBinaryProtocolFactory(false, true) } func NewTBinaryProtocolFactory(strictRead, strictWrite bool) *TBinaryProtocolFactory { return &TBinaryProtocolFactory{_StrictRead: strictRead, _StrictWrite: strictWrite} } func (p *TBinaryProtocolFactory) GetProtocol(t TTransport) TProtocol { return NewTBinaryProtocol(t, p._StrictRead, p._StrictWrite) } /** * Writing Methods */ func (p *TBinaryProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) TProtocolException { if p._StrictWrite { version := uint32(VERSION_1) | uint32(typeId) e := p.WriteI32(int32(version)) if e != nil { return e } e = p.WriteString(name) if e != nil { return e } e = p.WriteI32(seqId) return e } else { e := p.WriteString(name) if e != nil { return e } e = p.WriteByte(byte(typeId)) if e != nil { return e } e = p.WriteI32(seqId) return e } return nil } func (p *TBinaryProtocol) WriteMessageEnd() TProtocolException { return nil } func (p *TBinaryProtocol) WriteStructBegin(name string) TProtocolException { return nil } func (p *TBinaryProtocol) WriteStructEnd() TProtocolException { return nil } func (p *TBinaryProtocol) WriteFieldBegin(name string, typeId TType, id int16) TProtocolException { e := p.WriteByte(typeId.ThriftTypeId()) if e != nil { return e } e = p.WriteI16(id) return e } func (p *TBinaryProtocol) WriteFieldEnd() TProtocolException { return nil } func (p *TBinaryProtocol) WriteFieldStop() TProtocolException { e := p.WriteByte(STOP) return e } func (p *TBinaryProtocol) WriteMapBegin(keyType TType, valueType TType, size int) TProtocolException { e := p.WriteByte(keyType.ThriftTypeId()) if e != nil { return e } e = p.WriteByte(valueType.ThriftTypeId()) if e != nil { return e } e = p.WriteI32(int32(size)) return e } func (p *TBinaryProtocol) WriteMapEnd() TProtocolException { return nil } func (p *TBinaryProtocol) WriteListBegin(elemType TType, size int) TProtocolException { e := p.WriteByte(elemType.ThriftTypeId()) if e != nil { return e } e = p.WriteI32(int32(size)) return e } func (p *TBinaryProtocol) WriteListEnd() TProtocolException { return nil } func (p *TBinaryProtocol) WriteSetBegin(elemType TType, size int) TProtocolException { e := p.WriteByte(elemType.ThriftTypeId()) if e != nil { return e } e = p.WriteI32(int32(size)) return e } func (p *TBinaryProtocol) WriteSetEnd() TProtocolException { return nil } func (p *TBinaryProtocol) WriteBool(value bool) TProtocolException { if value { return p.WriteByte(1) } return p.WriteByte(0) } func (p *TBinaryProtocol) WriteByte(value byte) TProtocolException { v := []byte{value} _, e := p.trans.Write(v) return NewTProtocolExceptionFromOsError(e) } func (p *TBinaryProtocol) WriteI16(value int16) TProtocolException { h := byte(0xff & (value >> 8)) l := byte(0xff & value) v := []byte{h, l} _, e := p.trans.Write(v) return NewTProtocolExceptionFromOsError(e) } func (p *TBinaryProtocol) WriteI32(value int32) TProtocolException { a := byte(0xff & (value >> 24)) b := byte(0xff & (value >> 16)) c := byte(0xff & (value >> 8)) d := byte(0xff & value) v := []byte{a, b, c, d} _, e := p.trans.Write(v) return NewTProtocolExceptionFromOsError(e) } func (p *TBinaryProtocol) WriteI64(value int64) TProtocolException { a := byte(0xff & (value >> 56)) b := byte(0xff & (value >> 48)) c := byte(0xff & (value >> 40)) d := byte(0xff & (value >> 32)) e := byte(0xff & (value >> 24)) f := byte(0xff & (value >> 16)) g := byte(0xff & (value >> 8)) h := byte(0xff & value) v := []byte{a, b, c, d, e, f, g, h} _, err := p.trans.Write(v) return NewTProtocolExceptionFromOsError(err) } func (p *TBinaryProtocol) WriteDouble(value float64) TProtocolException { return p.WriteI64(int64(math.Float64bits(value))) } func (p *TBinaryProtocol) WriteString(value string) TProtocolException { return p.WriteBinaryFromReader(strings.NewReader(value), len(value)) } func (p *TBinaryProtocol) WriteBinary(value []byte) TProtocolException { e := p.WriteI32(int32(len(value))) if e != nil { return e } _, err := p.trans.Write(value) return NewTProtocolExceptionFromOsError(err) } func (p *TBinaryProtocol) WriteBinaryFromReader(reader io.Reader, size int) TProtocolException { e := p.WriteI32(int32(size)) if e != nil { return e } _, err := io.CopyN(p.trans, reader, int64(size)) return NewTProtocolExceptionFromOsError(err) } /** * Reading methods */ func (p *TBinaryProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err TProtocolException) { size, e := p.ReadI32() if e != nil { return "", typeId, 0, NewTProtocolExceptionFromOsError(e) } if size < 0 { typeId = TMessageType(size & 0x0ff) version := int64(int64(size) & VERSION_MASK) if version != VERSION_1 { return name, typeId, seqId, NewTProtocolException(BAD_VERSION, "Bad version in ReadMessageBegin") } name, e = p.ReadString() if e != nil { return name, typeId, seqId, NewTProtocolExceptionFromOsError(e) } seqId, e = p.ReadI32() if e != nil { return name, typeId, seqId, NewTProtocolExceptionFromOsError(e) } return name, typeId, seqId, nil } if p._StrictRead { return name, typeId, seqId, NewTProtocolException(BAD_VERSION, "Missing version in ReadMessageBegin") } name, e2 := p.readStringBody(int(size)) if e2 != nil { return name, typeId, seqId, e2 } b, e3 := p.ReadByte() if e3 != nil { return name, typeId, seqId, e3 } typeId = TMessageType(b) seqId, e4 := p.ReadI32() if e4 != nil { return name, typeId, seqId, e4 } return name, typeId, seqId, nil } func (p *TBinaryProtocol) ReadMessageEnd() TProtocolException { return nil } func (p *TBinaryProtocol) ReadStructBegin() (name string, err TProtocolException) { return } func (p *TBinaryProtocol) ReadStructEnd() TProtocolException { return nil } func (p *TBinaryProtocol) ReadFieldBegin() (name string, typeId TType, seqId int16, err TProtocolException) { t, err := p.ReadByte() typeId = TType(t) if err != nil { return name, typeId, seqId, err } if t != STOP { seqId, err = p.ReadI16() } return name, typeId, seqId, err } func (p *TBinaryProtocol) ReadFieldEnd() TProtocolException { return nil } func (p *TBinaryProtocol) ReadMapBegin() (kType, vType TType, size int, err TProtocolException) { k, e := p.ReadByte() if e != nil { err = NewTProtocolExceptionFromOsError(e) return } kType = TType(k) v, e := p.ReadByte() if e != nil { err = NewTProtocolExceptionFromOsError(e) return } vType = TType(v) size32, e := p.ReadI32() size = int(size32) if e != nil { err = NewTProtocolExceptionFromOsError(e) return } return kType, vType, size, nil } func (p *TBinaryProtocol) ReadMapEnd() TProtocolException { return nil } func (p *TBinaryProtocol) ReadListBegin() (elemType TType, size int, err TProtocolException) { b, e := p.ReadByte() if e != nil { err = NewTProtocolExceptionFromOsError(e) return } elemType = TType(b) size32, e := p.ReadI32() size = int(size32) if e != nil { err = NewTProtocolExceptionFromOsError(e) return } return elemType, size, nil } func (p *TBinaryProtocol) ReadListEnd() TProtocolException { return nil } func (p *TBinaryProtocol) ReadSetBegin() (elemType TType, size int, err TProtocolException) { b, e := p.ReadByte() if e != nil { err = NewTProtocolExceptionFromOsError(e) return } elemType = TType(b) size32, e := p.ReadI32() size = int(size32) if e != nil { err = NewTProtocolExceptionFromOsError(e) return } return elemType, size, nil } func (p *TBinaryProtocol) ReadSetEnd() TProtocolException { return nil } func (p *TBinaryProtocol) ReadBool() (bool, TProtocolException) { b, e := p.ReadByte() v := true if b != 1 { v = false } return v, e } func (p *TBinaryProtocol) ReadByte() (value byte, err TProtocolException) { buf := []byte{0} err = p.readAll(buf) return buf[0], err } func (p *TBinaryProtocol) ReadI16() (value int16, err TProtocolException) { buf := []byte{0, 0} err = p.readAll(buf) value = int16(binary.BigEndian.Uint16(buf)) return value, err } func (p *TBinaryProtocol) ReadI32() (value int32, err TProtocolException) { buf := []byte{0, 0, 0, 0} err = p.readAll(buf) value = int32(binary.BigEndian.Uint32(buf)) return value, err } func (p *TBinaryProtocol) ReadI64() (value int64, err TProtocolException) { buf := []byte{0, 0, 0, 0, 0, 0, 0, 0} err = p.readAll(buf) value = int64(binary.BigEndian.Uint64(buf)) return value, err } func (p *TBinaryProtocol) ReadDouble() (value float64, err TProtocolException) { buf := []byte{0, 0, 0, 0, 0, 0, 0, 0} err = p.readAll(buf) value = math.Float64frombits(binary.BigEndian.Uint64(buf)) return value, err } func (p *TBinaryProtocol) ReadString() (value string, err TProtocolException) { size, e := p.ReadI32() if e != nil { return "", e } return p.readStringBody(int(size)) } func (p *TBinaryProtocol) ReadBinary() ([]byte, TProtocolException) { size, e := p.ReadI32() if e != nil { return nil, e } isize := int(size) e = p.checkReadLength(isize) if e != nil { return nil, e } buf := make([]byte, isize) _, err := p.trans.ReadAll(buf) return buf, NewTProtocolExceptionFromOsError(err) } func (p *TBinaryProtocol) Flush() (err TProtocolException) { return NewTProtocolExceptionFromOsError(p.trans.Flush()) } func (p *TBinaryProtocol) Skip(fieldType TType) (err TProtocolException) { return SkipDefaultDepth(p, fieldType) } func (p *TBinaryProtocol) Transport() TTransport { return p.trans } func (p *TBinaryProtocol) readAll(buf []byte) TProtocolException { e := p.checkReadLength(len(buf)) if e != nil { return e } _, err := p.trans.ReadAll(buf) return NewTProtocolExceptionFromOsError(err) } func (p *TBinaryProtocol) setReadLength(readLength int) { p._ReadLength = readLength p._CheckReadLength = true } func (p *TBinaryProtocol) checkReadLength(length int) TProtocolException { if p._CheckReadLength { p._ReadLength = p._ReadLength - length if p._ReadLength < 0 { return NewTProtocolException(UNKNOWN_PROTOCOL_EXCEPTION, "Message length exceeded: "+string(length)) } } return nil } func (p *TBinaryProtocol) readStringBody(size int) (value string, err TProtocolException) { if size < 0 { return "", nil } err = p.checkReadLength(size) if err != nil { return "", err } isize := int(size) buf := make([]byte, isize) _, e := p.trans.ReadAll(buf) return string(buf), NewTProtocolExceptionFromOsError(e) } golang-thrift-0.0~git20121118/tbinary_protocol_test.go000066400000000000000000000016751222677523400226420ustar00rootroot00000000000000/* * 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 TestReadWriteBinaryProtocol(t *testing.T) { ReadWriteProtocolTest(t, NewTBinaryProtocolFactoryDefault()) } golang-thrift-0.0~git20121118/tcompact_protocol.go000066400000000000000000000546721222677523400217520ustar00rootroot00000000000000/* * 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/binary" "fmt" "math" "strings" ) const ( COMPACT_PROTOCOL_ID = 0x082 COMPACT_VERSION = 1 COMPACT_VERSION_MASK = 0x1f COMPACT_TYPE_MASK = 0x0E0 COMPACT_TYPE_SHIFT_AMOUNT = 5 ) type TCompactType byte const ( COMPACT_BOOLEAN_TRUE = 0x01 COMPACT_BOOLEAN_FALSE = 0x02 COMPACT_BYTE = 0x03 COMPACT_I16 = 0x04 COMPACT_I32 = 0x05 COMPACT_I64 = 0x06 COMPACT_DOUBLE = 0x07 COMPACT_BINARY = 0x08 COMPACT_LIST = 0x09 COMPACT_SET = 0x0A COMPACT_MAP = 0x0B COMPACT_STRUCT = 0x0C ) var ( _TTypeToCompactType []TCompactType _TSTOP TField ) func init() { _TSTOP = NewTField("", STOP, 0) _TTypeToCompactType = make([]TCompactType, int(UTF16)+1) _TTypeToCompactType[int(STOP)] = STOP _TTypeToCompactType[int(BOOL)] = COMPACT_BOOLEAN_TRUE _TTypeToCompactType[int(BYTE)] = COMPACT_BYTE _TTypeToCompactType[int(I16)] = COMPACT_I16 _TTypeToCompactType[int(I32)] = COMPACT_I32 _TTypeToCompactType[int(I64)] = COMPACT_I64 _TTypeToCompactType[int(DOUBLE)] = COMPACT_DOUBLE _TTypeToCompactType[int(STRING)] = COMPACT_BINARY _TTypeToCompactType[int(LIST)] = COMPACT_LIST _TTypeToCompactType[int(SET)] = COMPACT_SET _TTypeToCompactType[int(MAP)] = COMPACT_MAP _TTypeToCompactType[int(STRUCT)] = COMPACT_STRUCT } type TCompactProtocolFactory struct{} func NewTCompactProtocolFactory() *TCompactProtocolFactory { return &TCompactProtocolFactory{} } func (p *TCompactProtocolFactory) GetProtocol(trans TTransport) TProtocol { return NewTCompactProtocol(trans) } type TCompactProtocol struct { trans TTransport /** * Used to keep track of the last field for the current and previous structs, * so we can do the delta stuff. */ lastField []int lastFieldId int /** * If we encounter a boolean field begin, save the TField here so it can * have the value incorporated. */ booleanField TField /** * If we read a field header, and it's a boolean field, save the boolean * value here so that readBool can use it. */ boolValue bool boolValueIsNotNull bool } /** * Create a TCompactProtocol. * * @param transport the TTransport object to read from or write to. */ func NewTCompactProtocol(trans TTransport) *TCompactProtocol { return &TCompactProtocol{trans: trans, lastField: make([]int, 0)} } // // Public Writing methods. // /** * Write a message header to the wire. Compact Protocol messages contain the * protocol version so we can migrate forwards in the future if need be. */ func (p *TCompactProtocol) WriteMessageBegin(name string, typeId TMessageType, seqid int32) TProtocolException { _, err := p.writeByteDirect(COMPACT_PROTOCOL_ID) if err != nil { return NewTProtocolExceptionFromOsError(err) } _, err = p.writeByteDirect((COMPACT_VERSION & COMPACT_VERSION_MASK) | ((byte(typeId) << COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_MASK)) if err != nil { return NewTProtocolExceptionFromOsError(err) } _, err = p.writeVarint32(seqid) if err != nil { return NewTProtocolExceptionFromOsError(err) } e := p.WriteString(name) return e } func (p *TCompactProtocol) WriteMessageEnd() TProtocolException { return nil } /** * Write a struct begin. This doesn't actually put anything on the wire. We * use it as an opportunity to put special placeholder markers on the field * stack so we can get the field id deltas correct. */ func (p *TCompactProtocol) WriteStructBegin(name string) TProtocolException { p.lastField = append(p.lastField, p.lastFieldId) p.lastFieldId = 0 return nil } /** * Write a struct end. This doesn't actually put anything on the wire. We use * this as an opportunity to pop the last field from the current struct off * of the field stack. */ func (p *TCompactProtocol) WriteStructEnd() TProtocolException { p.lastFieldId = p.lastField[len(p.lastField)-1] p.lastField = p.lastField[:len(p.lastField)-1] return nil } func (p *TCompactProtocol) WriteFieldBegin(name string, typeId TType, id int16) TProtocolException { if typeId == BOOL { // we want to possibly include the value, so we'll wait. p.booleanField = NewTField(name, typeId, int(id)) return nil } _, err := p.writeFieldBeginInternal(name, typeId, id, 0xFF) return NewTProtocolExceptionFromOsError(err) } /** * The workhorse of writeFieldBegin. It has the option of doing a * 'type override' of the type header. This is used specifically in the * boolean field case. */ func (p *TCompactProtocol) writeFieldBeginInternal(name string, typeId TType, id int16, typeOverride byte) (int, error) { // short lastField = lastField_.pop(); // if there's a type override, use that. var typeToWrite byte if typeOverride == 0xFF { typeToWrite = byte(p.getCompactType(typeId)) } else { typeToWrite = typeOverride } // check if we can use delta encoding for the field id fieldId := int(id) written := 0 if fieldId > p.lastFieldId && fieldId-p.lastFieldId <= 15 { // write them together written, err := p.writeByteDirect(byte((fieldId-p.lastFieldId)<<4) | typeToWrite) if err != nil { return written, err } } else { // write them separate n, err := p.writeByteDirect(typeToWrite) if err != nil { return n, err } err = p.WriteI16(id) written = n + 2 if err != nil { return written, err } } p.lastFieldId = fieldId // p.lastField.Push(field.id); return written, nil } func (p *TCompactProtocol) WriteFieldEnd() TProtocolException { return nil } func (p *TCompactProtocol) WriteFieldStop() TProtocolException { _, err := p.writeByteDirect(STOP) return NewTProtocolExceptionFromOsError(err) } func (p *TCompactProtocol) WriteMapBegin(keyType TType, valueType TType, size int) TProtocolException { if size == 0 { _, err := p.writeByteDirect(0) return NewTProtocolExceptionFromOsError(err) } _, err := p.writeVarint32(int32(size)) if err != nil { return NewTProtocolExceptionFromOsError(err) } _, err = p.writeByteDirect(byte(p.getCompactType(keyType))<<4 | byte(p.getCompactType(valueType))) return NewTProtocolExceptionFromOsError(err) } func (p *TCompactProtocol) WriteMapEnd() TProtocolException { return nil } /** * Write a list header. */ func (p *TCompactProtocol) WriteListBegin(elemType TType, size int) TProtocolException { _, err := p.writeCollectionBegin(elemType, size) return NewTProtocolExceptionFromOsError(err) } func (p *TCompactProtocol) WriteListEnd() TProtocolException { return nil } /** * Write a set header. */ func (p *TCompactProtocol) WriteSetBegin(elemType TType, size int) TProtocolException { _, err := p.writeCollectionBegin(elemType, size) return NewTProtocolExceptionFromOsError(err) } func (p *TCompactProtocol) WriteSetEnd() TProtocolException { return nil } func (p *TCompactProtocol) WriteBool(value bool) TProtocolException { v := byte(COMPACT_BOOLEAN_FALSE) if value { v = byte(COMPACT_BOOLEAN_TRUE) } if p.booleanField != nil { // we haven't written the field header yet _, err := p.writeFieldBeginInternal(p.booleanField.Name(), p.booleanField.TypeId(), int16(p.booleanField.Id()), v) p.booleanField = nil return NewTProtocolExceptionFromOsError(err) } // we're not part of a field, so just write the value. _, err := p.writeByteDirect(v) return NewTProtocolExceptionFromOsError(err) } /** * Write a byte. Nothing to see here! */ func (p *TCompactProtocol) WriteByte(value byte) TProtocolException { _, err := p.writeByteDirect(value) return NewTProtocolExceptionFromOsError(err) } /** * Write an I16 as a zigzag varint. */ func (p *TCompactProtocol) WriteI16(value int16) TProtocolException { _, err := p.writeVarint32(p.int32ToZigzag(int32(value))) return NewTProtocolExceptionFromOsError(err) } /** * Write an i32 as a zigzag varint. */ func (p *TCompactProtocol) WriteI32(value int32) TProtocolException { _, err := p.writeVarint32(p.int32ToZigzag(value)) return NewTProtocolExceptionFromOsError(err) } /** * Write an i64 as a zigzag varint. */ func (p *TCompactProtocol) WriteI64(value int64) TProtocolException { _, err := p.writeVarint64(p.int64ToZigzag(value)) return NewTProtocolExceptionFromOsError(err) } /** * Write a double to the wire as 8 bytes. */ func (p *TCompactProtocol) WriteDouble(value float64) TProtocolException { buf := make([]byte, 8) binary.LittleEndian.PutUint64(buf, math.Float64bits(value)) _, err := p.trans.Write(buf) return NewTProtocolExceptionFromOsError(err) } /** * Write a string to the wire with a varint size preceeding. */ func (p *TCompactProtocol) WriteString(value string) TProtocolException { buf := make([]byte, len(value)) strings.NewReader(value).Read(buf) return p.WriteBinary(buf) } /** * Write a byte array, using a varint for the size. */ func (p *TCompactProtocol) WriteBinary(bin []byte) TProtocolException { _, e := p.writeVarint32(int32(len(bin))) if e != nil { return NewTProtocolExceptionFromOsError(e) } if len(bin) > 0 { _, e = p.trans.Write(bin) return NewTProtocolExceptionFromOsError(e) } return nil } // // Reading methods. // /** * Read a message header. */ func (p *TCompactProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err TProtocolException) { protocolId, err := p.ReadByte() if protocolId != COMPACT_PROTOCOL_ID { s := fmt.Sprintf("Expected protocol id %02x but got %02x", COMPACT_PROTOCOL_ID, protocolId) return "", typeId, seqId, NewTProtocolException(BAD_VERSION, s) } versionAndType, err := p.ReadByte() version := versionAndType & COMPACT_VERSION_MASK typeId = TMessageType((versionAndType >> COMPACT_TYPE_SHIFT_AMOUNT) & 0x03) if err != nil { return } if version != COMPACT_VERSION { s := fmt.Sprintf("Expected version %02x but got %02x", COMPACT_VERSION, version) err = NewTProtocolException(BAD_VERSION, s) return } seqId, e := p.readVarint32() if e != nil { err = NewTProtocolExceptionFromOsError(e) return } name, err = p.ReadString() return } func (p *TCompactProtocol) ReadMessageEnd() TProtocolException { return nil } /** * Read a struct begin. There's nothing on the wire for this, but it is our * opportunity to push a new struct begin marker onto the field stack. */ func (p *TCompactProtocol) ReadStructBegin() (name string, err TProtocolException) { p.lastField = append(p.lastField, p.lastFieldId) p.lastFieldId = 0 return } /** * Doesn't actually consume any wire data, just removes the last field for * this struct from the field stack. */ func (p *TCompactProtocol) ReadStructEnd() TProtocolException { // consume the last field we read off the wire. p.lastFieldId = p.lastField[len(p.lastField)-1] return nil } /** * Read a field header off the wire. */ func (p *TCompactProtocol) ReadFieldBegin() (name string, typeId TType, id int16, err TProtocolException) { t, err := p.ReadByte() if err != nil { return } // if it's a stop, then we can return immediately, as the struct is over. if (t & 0x0f) == STOP { return _TSTOP.Name(), _TSTOP.TypeId(), int16(_TSTOP.Id()), nil } // mask off the 4 MSB of the type header. it could contain a field id delta. modifier := int16((t & 0xf0) >> 4) if modifier == 0 { // not a delta. look ahead for the zigzag varint field id. id, err = p.ReadI16() if err != nil { return } } else { // has a delta. add the delta to the last read field id. id = int16(p.lastFieldId) + modifier } typeId, e := p.getTType(TCompactType(t & 0x0f)) if e != nil { err = NewTProtocolExceptionFromOsError(e) return } // if this happens to be a boolean field, the value is encoded in the type if p.isBoolType(t) { // save the boolean value in a special instance variable. p.boolValue = (byte(t)&0x0f == COMPACT_BOOLEAN_TRUE) p.boolValueIsNotNull = true } // push the new field onto the field stack so we can keep the deltas going. p.lastFieldId = int(id) return } func (p *TCompactProtocol) ReadFieldEnd() TProtocolException { return nil } /** * Read a map header off the wire. If the size is zero, skip reading the key * and value type. This means that 0-length maps will yield TMaps without the * "correct" types. */ func (p *TCompactProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, err TProtocolException) { size32, e := p.readVarint32() size = int(size32) if e != nil { err = NewTProtocolExceptionFromOsError(e) return } keyAndValueType := byte(STOP) if size != 0 { keyAndValueType, err = p.ReadByte() if err != nil { return } } keyType, _ = p.getTType(TCompactType(keyAndValueType >> 4)) valueType, _ = p.getTType(TCompactType(keyAndValueType & 0xf)) return } func (p *TCompactProtocol) ReadMapEnd() TProtocolException { return nil } /** * Read a list header off the wire. If the list size is 0-14, the size will * be packed into the element type header. If it's a longer list, the 4 MSB * of the element type header will be 0xF, and a varint will follow with the * true size. */ func (p *TCompactProtocol) ReadListBegin() (elemType TType, size int, err TProtocolException) { size_and_type, err := p.ReadByte() if err != nil { return } size = int((size_and_type >> 4) & 0x0f) if size == 15 { size2, e := p.readVarint32() if e != nil { err = NewTProtocolExceptionFromOsError(e) return } size = int(size2) } elemType, e := p.getTType(TCompactType(size_and_type)) if e != nil { err = NewTProtocolExceptionFromOsError(e) return } return } func (p *TCompactProtocol) ReadListEnd() TProtocolException { return nil } /** * Read a set header off the wire. If the set size is 0-14, the size will * be packed into the element type header. If it's a longer set, the 4 MSB * of the element type header will be 0xF, and a varint will follow with the * true size. */ func (p *TCompactProtocol) ReadSetBegin() (elemType TType, size int, err TProtocolException) { return p.ReadListBegin() } func (p *TCompactProtocol) ReadSetEnd() TProtocolException { return nil } /** * Read a boolean off the wire. If this is a boolean field, the value should * already have been read during readFieldBegin, so we'll just consume the * pre-stored value. Otherwise, read a byte. */ func (p *TCompactProtocol) ReadBool() (value bool, err TProtocolException) { if p.boolValueIsNotNull { p.boolValueIsNotNull = false return p.boolValue, nil } v, err := p.ReadByte() return v == COMPACT_BOOLEAN_TRUE, err } /** * Read a single byte off the wire. Nothing interesting here. */ func (p *TCompactProtocol) ReadByte() (value byte, err TProtocolException) { buf := []byte{0} _, e := p.trans.ReadAll(buf) if e != nil { return 0, NewTProtocolExceptionFromOsError(e) } return buf[0], nil } /** * Read an i16 from the wire as a zigzag varint. */ func (p *TCompactProtocol) ReadI16() (value int16, err TProtocolException) { v, err := p.ReadI32() return int16(v), err } /** * Read an i32 from the wire as a zigzag varint. */ func (p *TCompactProtocol) ReadI32() (value int32, err TProtocolException) { v, e := p.readVarint32() if e != nil { return 0, NewTProtocolExceptionFromOsError(e) } value = p.zigzagToInt32(v) return value, nil } /** * Read an i64 from the wire as a zigzag varint. */ func (p *TCompactProtocol) ReadI64() (value int64, err TProtocolException) { v, e := p.readVarint64() if e != nil { return 0, NewTProtocolExceptionFromOsError(e) } value = p.zigzagToInt64(v) return value, nil } /** * No magic here - just read a double off the wire. */ func (p *TCompactProtocol) ReadDouble() (value float64, err TProtocolException) { longBits := make([]byte, 8) _, e := p.trans.ReadAll(longBits) if e != nil { return 0.0, NewTProtocolExceptionFromOsError(e) } return math.Float64frombits(p.bytesToUint64(longBits)), nil } /** * Reads a []byte (via readBinary), and then UTF-8 decodes it. */ func (p *TCompactProtocol) ReadString() (value string, err TProtocolException) { v, e := p.ReadBinary() return string(v), NewTProtocolExceptionFromOsError(e) } /** * Read a []byte from the wire. */ func (p *TCompactProtocol) ReadBinary() (value []byte, err TProtocolException) { length, e := p.readVarint32() if e != nil { return []byte{}, NewTProtocolExceptionFromOsError(e) } if length == 0 { return []byte{}, nil } buf := make([]byte, length) p.trans.ReadAll(buf) return buf, nil } func (p *TCompactProtocol) Flush() (err TProtocolException) { return NewTProtocolExceptionFromOsError(p.trans.Flush()) } func (p *TCompactProtocol) Skip(fieldType TType) (err TProtocolException) { return SkipDefaultDepth(p, fieldType) } func (p *TCompactProtocol) Transport() TTransport { return p.trans } // // Internal writing methods // /** * Abstract method for writing the start of lists and sets. List and sets on * the wire differ only by the type indicator. */ func (p *TCompactProtocol) writeCollectionBegin(elemType TType, size int) (int, error) { if size <= 14 { return p.writeByteDirect(byte(int32(size<<4) | int32(p.getCompactType(elemType)))) } n, err := p.writeByteDirect(0xf0 | byte(p.getCompactType(elemType))) if err != nil { return n, err } m, err := p.writeVarint32(int32(size)) return n + m, err } /** * Write an i32 as a varint. Results in 1-5 bytes on the wire. * TODO(pomack): make a permanent buffer like writeVarint64? */ func (p *TCompactProtocol) writeVarint32(n int32) (int, error) { i32buf := make([]byte, 5) idx := 0 for { if (n & ^0x7F) == 0 { i32buf[idx] = byte(n) idx++ // p.writeByteDirect(byte(n)); break // return; } else { i32buf[idx] = byte((n & 0x7F) | 0x80) idx++ // p.writeByteDirect(byte(((n & 0x7F) | 0x80))); u := uint32(n) n = int32(u >> 7) } } return p.trans.Write(i32buf[0:idx]) } /** * Write an i64 as a varint. Results in 1-10 bytes on the wire. */ func (p *TCompactProtocol) writeVarint64(n int64) (int, error) { varint64out := make([]byte, 10) idx := 0 for { if (n & ^0x7F) == 0 { varint64out[idx] = byte(n) idx++ break } else { varint64out[idx] = byte((n & 0x7F) | 0x80) idx++ u := uint64(n) n = int64(u >> 7) } } return p.trans.Write(varint64out[0:idx]) } /** * Convert l into a zigzag long. This allows negative numbers to be * represented compactly as a varint. */ func (p *TCompactProtocol) int64ToZigzag(l int64) int64 { return (l << 1) ^ (l >> 63) } /** * Convert l into a zigzag long. This allows negative numbers to be * represented compactly as a varint. */ func (p *TCompactProtocol) int32ToZigzag(n int32) int32 { return (n << 1) ^ (n >> 31) } func (p *TCompactProtocol) fixedUint64ToBytes(n uint64, buf []byte) { binary.LittleEndian.PutUint64(buf, n) } func (p *TCompactProtocol) fixedInt64ToBytes(n int64, buf []byte) { binary.LittleEndian.PutUint64(buf, uint64(n)) } /** * Writes a byte without any possiblity of all that field header nonsense. * Used internally by other writing methods that know they need to write a byte. */ func (p *TCompactProtocol) writeByteDirect(b byte) (int, error) { return p.trans.Write([]byte{b}) } /** * Writes a byte without any possiblity of all that field header nonsense. */ func (p *TCompactProtocol) writeIntAsByteDirect(n int) (int, error) { return p.writeByteDirect(byte(n)) } // // Internal reading methods // /** * Read an i32 from the wire as a varint. The MSB of each byte is set * if there is another byte to follow. This can read up to 5 bytes. */ func (p *TCompactProtocol) readVarint32() (int32, error) { // if the wire contains the right stuff, this will just truncate the i64 we // read and get us the right sign. v, err := p.readVarint64() return int32(v), err } /** * Read an i64 from the wire as a proper varint. The MSB of each byte is set * if there is another byte to follow. This can read up to 10 bytes. */ func (p *TCompactProtocol) readVarint64() (int64, error) { shift := uint(0) result := int64(0) for { b, err := p.ReadByte() if err != nil { return 0, err } result |= int64(b&0x7f) << shift if (b & 0x80) != 0x80 { break } shift += 7 } return result, nil } // // encoding helpers // /** * Convert from zigzag int to int. */ func (p *TCompactProtocol) zigzagToInt32(n int32) int32 { u := uint32(n) return int32(u>>1) ^ -(n & 1) } /** * Convert from zigzag long to long. */ func (p *TCompactProtocol) zigzagToInt64(n int64) int64 { u := uint64(n) return int64(u>>1) ^ -(n & 1) } /** * Note that it's important that the mask bytes are long literals, * otherwise they'll default to ints, and when you shift an int left 56 bits, * you just get a messed up int. */ func (p *TCompactProtocol) bytesToInt64(b []byte) int64 { return int64(binary.LittleEndian.Uint64(b)) } /** * Note that it's important that the mask bytes are long literals, * otherwise they'll default to ints, and when you shift an int left 56 bits, * you just get a messed up int. */ func (p *TCompactProtocol) bytesToUint64(b []byte) uint64 { return binary.LittleEndian.Uint64(b) } // // type testing and converting // func (p *TCompactProtocol) isBoolType(b byte) bool { return (b&0x0f) == COMPACT_BOOLEAN_TRUE || (b&0x0f) == COMPACT_BOOLEAN_FALSE } /** * Given a TCompactType constant, convert it to its corresponding * TType value. */ func (p *TCompactProtocol) getTType(t TCompactType) (TType, error) { switch byte(t) & 0x0f { case STOP: return STOP, nil case COMPACT_BOOLEAN_FALSE: case COMPACT_BOOLEAN_TRUE: return BOOL, nil case COMPACT_BYTE: return BYTE, nil case COMPACT_I16: return I16, nil case COMPACT_I32: return I32, nil case COMPACT_I64: return I64, nil case COMPACT_DOUBLE: return DOUBLE, nil case COMPACT_BINARY: return STRING, nil case COMPACT_LIST: return LIST, nil case COMPACT_SET: return SET, nil case COMPACT_MAP: return MAP, nil case COMPACT_STRUCT: return STRUCT, nil } return STOP, NewTException("don't know what type: " + string(t&0x0f)) } /** * Given a TType value, find the appropriate TCompactProtocol.Types constant. */ func (p *TCompactProtocol) getCompactType(t TType) TCompactType { return _TTypeToCompactType[int(t)] } golang-thrift-0.0~git20121118/tcompact_protocol_test.go000066400000000000000000000033751222677523400230030ustar00rootroot00000000000000/* * 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 TestReadWriteCompactProtocol(t *testing.T) { ReadWriteProtocolTest(t, NewTCompactProtocolFactory()) /* transports := []TTransport{ NewTMemoryBuffer(), NewTIOStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 16384))), NewTFramedTransport(NewTMemoryBuffer()), } for _, trans := range transports { p := NewTCompactProtocol(trans); ReadWriteBool(t, p, trans); p = NewTCompactProtocol(trans); ReadWriteByte(t, p, trans); p = NewTCompactProtocol(trans); ReadWriteI16(t, p, trans); p = NewTCompactProtocol(trans); ReadWriteI32(t, p, trans); p = NewTCompactProtocol(trans); ReadWriteI64(t, p, trans); p = NewTCompactProtocol(trans); ReadWriteDouble(t, p, trans); p = NewTCompactProtocol(trans); ReadWriteString(t, p, trans); p = NewTCompactProtocol(trans); ReadWriteBinary(t, p, trans); trans.Close(); } */ } golang-thrift-0.0~git20121118/tcompare.go000066400000000000000000000037121222677523400200160ustar00rootroot00000000000000/* * 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 func CompareInt(i, j int) int { if i > j { return 1 } if i < j { return -1 } return 0 } func CompareInt16(i, j int16) int { if i > j { return 1 } if i < j { return -1 } return 0 } func CompareInt32(i, j int32) int { if i > j { return 1 } if i < j { return -1 } return 0 } func CompareInt64(i, j int32) int { if i > j { return 1 } if i < j { return -1 } return 0 } func CompareStringArray(i, j []string) int { if cmp := CompareInt(len(i), len(j)); cmp != 0 { return cmp } size := len(i) for k := 0; k < size; k++ { if cmp := CompareString(i[k], j[k]); cmp != 0 { return cmp } } return 0 } func CompareString(i, j string) int { if i > j { return 1 } if i < j { return -1 } return 0 } func CompareFloat(i, j float32) int { if i > j { return 1 } if i < j { return -1 } return 0 } func CompareDouble(i, j float64) int { if i > j { return 1 } if i < j { return -1 } return 0 } func CompareByte(i, j byte) int { if i > j { return 1 } if i < j { return -1 } return 0 } func CompareBool(i, j bool) int { if i { if j { return 0 } return 1 } if j { return -1 } return 0 } golang-thrift-0.0~git20121118/tcontainer.go000066400000000000000000000017111222677523400203470ustar00rootroot00000000000000/* * 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 TContainer interface { Len() int Contains(data interface{}) bool Equals(other interface{}) bool CompareTo(other interface{}) (int, bool) } golang-thrift-0.0~git20121118/texception.go000066400000000000000000000023741222677523400203710ustar00rootroot00000000000000/* * 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 () /** * Generic exception class for Thrift. * */ type TException interface { Error() string } type tException struct { message string } func (p *tException) Error() string { return p.message } func NewTException(m string) TException { return &tException{message: m} } func NewTExceptionFromOsError(e error) TException { if e == nil { return nil } t, ok := e.(TException) if ok { return t } return NewTException(e.Error()) } golang-thrift-0.0~git20121118/texception_test.go000066400000000000000000000022231222677523400214210ustar00rootroot00000000000000/* * 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 ( "io" "testing" ) func TestTException(t *testing.T) { exc := NewTException("") if exc.Error() != "" { t.Fatalf("Expected empty string for exception but found '%s'", exc.Error()) } exc = NewTExceptionFromOsError(io.EOF) if exc.Error() != io.EOF.Error() { t.Fatalf("Expected '%s', but found '%s'", io.EOF.Error(), exc.Error()) } } golang-thrift-0.0~git20121118/tfield.go000066400000000000000000000133421222677523400174530ustar00rootroot00000000000000/* * 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 ( "sort" ) /** * Helper class that encapsulates field metadata. * */ type TField interface { Name() string TypeId() TType Id() int String() string CompareTo(other interface{}) (int, bool) Equals(other interface{}) bool } type tField struct { name string typeId TType id int } func NewTFieldDefault() TField { return ANONYMOUS_FIELD } func NewTField(n string, t TType, i int) TField { return &tField{name: n, typeId: t, id: i} } func (p *tField) Name() string { if p == nil { return "" } return p.name } func (p *tField) TypeId() TType { if p == nil { return TType(VOID) } return p.typeId } func (p *tField) Id() int { if p == nil { return -1 } return p.id } func (p *tField) String() string { if p == nil { return "" } return "" } func (p *tField) CompareTo(other interface{}) (int, bool) { if other == nil { return 1, true } if data, ok := other.(TField); ok { if p.Id() != data.Id() { return CompareInt(p.Id(), data.Id()), true } if p.TypeId() != data.TypeId() { return CompareByte(byte(p.TypeId()), byte(data.TypeId())), true } return CompareString(p.Name(), data.Name()), true } return 0, false } func (p *tField) Equals(other interface{}) bool { if p == nil { return other == nil } if other == nil { return false } if data, ok := other.(TField); ok { return p.TypeId() == data.TypeId() && p.Id() == data.Id() } return false } var ANONYMOUS_FIELD TField type tFieldArray []TField func (p tFieldArray) Len() int { return len(p) } func (p tFieldArray) Less(i, j int) bool { return p[i].Id() < p[j].Id() } func (p tFieldArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] } type TFieldContainer interface { TContainer FieldNameFromFieldId(id int) string FieldIdFromFieldName(name string) int FieldFromFieldId(id int) TField FieldFromFieldName(name string) TField At(i int) TField Iter() <-chan TField } type tFieldContainer struct { fields []TField nameToFieldMap map[string]TField idToFieldMap map[int]TField } func NewTFieldContainer(fields []TField) TFieldContainer { sortedFields := make([]TField, len(fields)) nameToFieldMap := make(map[string]TField) idToFieldMap := make(map[int]TField) for i, field := range fields { sortedFields[i] = field idToFieldMap[field.Id()] = field if field.Name() != "" { nameToFieldMap[field.Name()] = field } } sort.Sort(tFieldArray(sortedFields)) return &tFieldContainer{ fields: fields, nameToFieldMap: nameToFieldMap, idToFieldMap: idToFieldMap, } } func (p *tFieldContainer) FieldNameFromFieldId(id int) string { if field, ok := p.idToFieldMap[id]; ok { return field.Name() } return "" } func (p *tFieldContainer) FieldIdFromFieldName(name string) int { if field, ok := p.nameToFieldMap[name]; ok { return field.Id() } return -1 } func (p *tFieldContainer) FieldFromFieldId(id int) TField { if field, ok := p.idToFieldMap[id]; ok { return field } return ANONYMOUS_FIELD } func (p *tFieldContainer) FieldFromFieldName(name string) TField { if field, ok := p.nameToFieldMap[name]; ok { return field } return ANONYMOUS_FIELD } func (p *tFieldContainer) Len() int { return len(p.fields) } func (p *tFieldContainer) At(i int) TField { return p.FieldFromFieldId(i) } func (p *tFieldContainer) Contains(data interface{}) bool { if i, ok := data.(int); ok { for _, field := range p.fields { if field.Id() == i { return true } } } else if i, ok := data.(int16); ok { for _, field := range p.fields { if field.Id() == int(i) { return true } } } else if s, ok := data.(string); ok { for _, field := range p.fields { if field.Name() == s { return true } } } else if f, ok := data.(TField); ok { for _, field := range p.fields { if field.Equals(f) { return true } } } return false } func (p *tFieldContainer) Equals(other interface{}) bool { if other == nil { return false } if data, ok := other.(TFieldContainer); ok { if p.Len() != data.Len() { return false } for _, field := range p.fields { if !data.Contains(field) { return false } } return true } return false } func (p *tFieldContainer) CompareTo(other interface{}) (int, bool) { if other == nil { return 1, true } if data, ok := other.(TFieldContainer); ok { cont, ok2 := data.(*tFieldContainer) if ok2 && p == cont { return 0, true } if cmp := CompareInt(p.Len(), data.Len()); cmp != 0 { return cmp, true } for _, field := range p.fields { if cmp, ok3 := field.CompareTo(data.At(field.Id())); !ok3 || cmp != 0 { return cmp, ok3 } } return 0, true } return 0, false } func (p *tFieldContainer) Iter() <-chan TField { c := make(chan TField) go p.iterate(c) return c } func (p *tFieldContainer) iterate(c chan<- TField) { for _, v := range p.fields { c <- v } close(c) } func init() { ANONYMOUS_FIELD = NewTField("", STOP, 0) } golang-thrift-0.0~git20121118/tframed_transport.go000066400000000000000000000070071222677523400217430ustar00rootroot00000000000000/* * 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" "encoding/binary" ) type TFramedTransport struct { transport TTransport writeBuffer *bytes.Buffer readBuffer *bytes.Buffer } type tFramedTransportFactory struct { factory TTransportFactory } func NewTFramedTransportFactory(factory TTransportFactory) TTransportFactory { return &tFramedTransportFactory{factory: factory} } func (p *tFramedTransportFactory) GetTransport(base TTransport) TTransport { return NewTFramedTransport(p.factory.GetTransport(base)) } func NewTFramedTransport(transport TTransport) *TFramedTransport { writeBuf := make([]byte, 0, 1024) readBuf := make([]byte, 0, 1024) return &TFramedTransport{transport: transport, writeBuffer: bytes.NewBuffer(writeBuf), readBuffer: bytes.NewBuffer(readBuf)} } func (p *TFramedTransport) Open() error { return p.transport.Open() } func (p *TFramedTransport) IsOpen() bool { return p.transport.IsOpen() } func (p *TFramedTransport) Peek() bool { return p.transport.Peek() } func (p *TFramedTransport) Close() error { return p.transport.Close() } func (p *TFramedTransport) Read(buf []byte) (int, error) { if p.readBuffer.Len() > 0 { got, err := p.readBuffer.Read(buf) if got > 0 { return got, NewTTransportExceptionFromOsError(err) } } // Read another frame of data p.readFrame() got, err := p.readBuffer.Read(buf) return got, NewTTransportExceptionFromOsError(err) } func (p *TFramedTransport) ReadAll(buf []byte) (int, error) { return ReadAllTransport(p, buf) } func (p *TFramedTransport) Write(buf []byte) (int, error) { n, err := p.writeBuffer.Write(buf) return n, NewTTransportExceptionFromOsError(err) } func (p *TFramedTransport) Flush() error { size := p.writeBuffer.Len() buf := []byte{0, 0, 0, 0} binary.BigEndian.PutUint32(buf, uint32(size)) _, err := p.transport.Write(buf) if err != nil { return NewTTransportExceptionFromOsError(err) } if size > 0 { n, err := p.writeBuffer.WriteTo(p.transport) if err != nil { print("Error while flushing write buffer of size ", size, " to transport, only wrote ", n, " bytes: ", err.Error(), "\n") return NewTTransportExceptionFromOsError(err) } } err = p.transport.Flush() return NewTTransportExceptionFromOsError(err) } func (p *TFramedTransport) readFrame() (int, error) { buf := []byte{0, 0, 0, 0} _, err := p.transport.ReadAll(buf) if err != nil { return 0, err } size := int(binary.BigEndian.Uint32(buf)) if size < 0 { // TODO(pomack) log error return 0, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "Read a negative frame size ("+string(size)+")") } if size == 0 { return 0, nil } buf2 := make([]byte, size) n, err := p.transport.ReadAll(buf2) if err != nil { return n, err } p.readBuffer = bytes.NewBuffer(buf2) return size, nil } golang-thrift-0.0~git20121118/tframed_transport_test.go000066400000000000000000000017111222677523400227760ustar00rootroot00000000000000/* * 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 TestFramedTransport(t *testing.T) { trans := NewTFramedTransport(NewTMemoryBuffer()) TransportTest(t, trans, trans) } golang-thrift-0.0~git20121118/thttp_client.go000066400000000000000000000072161222677523400207100ustar00rootroot00000000000000/* * 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" "net/http" "net/url" "strconv" ) type THttpClient struct { response *http.Response url *url.URL requestBuffer *bytes.Buffer nsecConnectTimeout int64 nsecReadTimeout int64 } type THttpClientTransportFactory struct { url string isPost bool } func (p *THttpClientTransportFactory) GetTransport(trans TTransport) TTransport { if trans != nil { t, ok := trans.(*THttpClient) if ok && t.url != nil { if t.requestBuffer != nil { t2, _ := NewTHttpPostClient(t.url.String()) return t2 } t2, _ := NewTHttpClient(t.url.String()) return t2 } } if p.isPost { s, _ := NewTHttpPostClient(p.url) return s } s, _ := NewTHttpClient(p.url) return s } func NewTHttpClientTransportFactory(url string) *THttpClientTransportFactory { return &THttpClientTransportFactory{url: url, isPost: false} } func NewTHttpPostClientTransportFactory(url string) *THttpClientTransportFactory { return &THttpClientTransportFactory{url: url, isPost: true} } func NewTHttpClient(urlstr string) (TTransport, error) { parsedURL, err := url.Parse(urlstr) if err != nil { return nil, err } response, err := http.Get(urlstr) if err != nil { return nil, err } return &THttpClient{response: response, url: parsedURL}, nil } func NewTHttpPostClient(urlstr string) (TTransport, error) { parsedURL, err := url.Parse(urlstr) if err != nil { return nil, err } buf := make([]byte, 0, 1024) return &THttpClient{url: parsedURL, requestBuffer: bytes.NewBuffer(buf)}, nil } func (p *THttpClient) Open() error { // do nothing return nil } func (p *THttpClient) IsOpen() bool { return p.response != nil || p.requestBuffer != nil } func (p *THttpClient) Peek() bool { return p.IsOpen() } func (p *THttpClient) Close() error { if p.response != nil && p.response.Body != nil { err := p.response.Body.Close() p.response = nil return err } if p.requestBuffer != nil { p.requestBuffer.Reset() p.requestBuffer = nil } return nil } func (p *THttpClient) Read(buf []byte) (int, error) { if p.response == nil { return 0, NewTTransportException(NOT_OPEN, "Response buffer is empty, no request.") } n, err := p.response.Body.Read(buf) return n, NewTTransportExceptionFromOsError(err) } func (p *THttpClient) ReadAll(buf []byte) (int, error) { return ReadAllTransport(p, buf) } func (p *THttpClient) Write(buf []byte) (int, error) { n, err := p.requestBuffer.Write(buf) return n, err } func (p *THttpClient) Flush() error { response, err := http.Post(p.url.String(), "application/x-thrift", p.requestBuffer) if err != nil { return NewTTransportExceptionFromOsError(err) } if response.StatusCode != http.StatusOK { // TODO(pomack) log bad response return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "HTTP Response code: "+strconv.Itoa(response.StatusCode)) } p.response = response return nil } golang-thrift-0.0~git20121118/thttp_client_test.go000066400000000000000000000021671222677523400217470ustar00rootroot00000000000000/* * 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 TestHttpClient(t *testing.T) { l, addr := HttpClientSetupForTest(t) if l != nil { defer l.Close() } trans, err := NewTHttpPostClient("http://" + addr.String()) if err != nil { l.Close() t.Fatalf("Unable to connect to %s: %s", addr.String(), err) } TransportTest(t, trans, trans) } golang-thrift-0.0~git20121118/tiostream_transport.go000066400000000000000000000137541222677523400223360ustar00rootroot00000000000000/* * 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" "io" ) /** * This is the most commonly used base transport. It takes an InputStream * and an OutputStream and uses those to perform all transport operations. * This allows for compatibility with all the nice constructs Java already * has to provide a variety of types of streams. * */ type TIOStreamTransport struct { Reader io.Reader Writer io.Writer IsReadWriter bool } type TIOStreamTransportFactory struct { Reader io.Reader Writer io.Writer IsReadWriter bool } func (p *TIOStreamTransportFactory) GetTransport(trans TTransport) TTransport { if trans != nil { t, ok := trans.(*TIOStreamTransport) if ok { if t.IsReadWriter { return NewTIOStreamTransportRW(t.Reader.(io.ReadWriter)) } if t.Reader != nil && t.Writer != nil { return NewTIOStreamTransportRAndW(t.Reader, t.Writer) } if t.Reader != nil && t.Writer == nil { return NewTIOStreamTransportR(t.Reader) } if t.Reader == nil && t.Writer != nil { return NewTIOStreamTransportW(t.Writer) } return NewTIOStreamTransportDefault() } } if p.IsReadWriter { return NewTIOStreamTransportRW(p.Reader.(io.ReadWriter)) } if p.Reader != nil && p.Writer != nil { return NewTIOStreamTransportRAndW(p.Reader, p.Writer) } if p.Reader != nil && p.Writer == nil { return NewTIOStreamTransportR(p.Reader) } if p.Reader == nil && p.Writer != nil { return NewTIOStreamTransportW(p.Writer) } return NewTIOStreamTransportDefault() } func NewTIOStreamTransportFactory(reader io.Reader, writer io.Writer, isReadWriter bool) *TIOStreamTransportFactory { return &TIOStreamTransportFactory{Reader: reader, Writer: writer, IsReadWriter: isReadWriter} } /** * Subclasses can invoke the default constructor and then assign the input * streams in the open method. */ func NewTIOStreamTransportDefault() *TIOStreamTransport { return &TIOStreamTransport{} } /** * Input stream constructor. * * @param is Input stream to read from */ func NewTIOStreamTransportR(r io.Reader) *TIOStreamTransport { return &TIOStreamTransport{Reader: bufio.NewReader(r)} } /** * Output stream constructor. * * @param os Output stream to read from */ func NewTIOStreamTransportW(w io.Writer) *TIOStreamTransport { return &TIOStreamTransport{Writer: bufio.NewWriter(w)} } /** * Two-way stream constructor. * * @param is Input stream to read from * @param os Output stream to read from */ func NewTIOStreamTransportRAndW(r io.Reader, w io.Writer) *TIOStreamTransport { return &TIOStreamTransport{Reader: bufio.NewReader(r), Writer: bufio.NewWriter(w)} } /** * Two-way stream constructor. * * @param is Input stream to read from * @param os Output stream to read from */ func NewTIOStreamTransportRW(rw io.ReadWriter) *TIOStreamTransport { // bufio has a bug where once a Reader hits EOF, a new Write never brings the reader out of EOF // even if reader and writer use the same underlier //bufrw := bufio.NewReadWriter(bufio.NewReader(rw), bufio.NewWriter(rw)); return &TIOStreamTransport{Reader: rw, Writer: rw, IsReadWriter: true} } /** * The streams must already be open at construction time, so this should * always return true. * * @return true */ func (p *TIOStreamTransport) IsOpen() bool { return true } /** * The streams must already be open. This method does nothing. */ func (p *TIOStreamTransport) Open() error { return nil } func (p *TIOStreamTransport) Peek() bool { return p.IsOpen() } /** * Closes both the input and output streams. */ func (p *TIOStreamTransport) Close() error { closedReader := false if p.Reader != nil { c, ok := p.Reader.(io.Closer) if ok { e := c.Close() closedReader = true if e != nil { LOGGER.Print("Error closing input stream.", e) } } p.Reader = nil } if p.Writer != nil && (!closedReader || !p.IsReadWriter) { c, ok := p.Writer.(io.Closer) if ok { e := c.Close() if e != nil { LOGGER.Print("Error closing output stream.", e) } } p.Writer = nil } return nil } /** * Reads from the underlying input stream if not null. */ func (p *TIOStreamTransport) Read(buf []byte) (int, error) { if p.Reader == nil { return 0, NewTTransportException(NOT_OPEN, "Cannot read from null inputStream") } n, err := p.Reader.Read(buf) return n, NewTTransportExceptionFromOsError(err) } func (p *TIOStreamTransport) ReadAll(buf []byte) (int, error) { return ReadAllTransport(p, buf) } /** * Writes to the underlying output stream if not null. */ func (p *TIOStreamTransport) Write(buf []byte) (int, error) { if p.Writer == nil { LOGGER.Print("Could not write to iostream as Writer is null\n") return 0, NewTTransportException(NOT_OPEN, "Cannot write to null outputStream") } n, err := p.Writer.Write(buf) if n == 0 || err != nil { LOGGER.Print("Error writing to iostream, only wrote ", n, " bytes: ", err.Error(), "\n") } return n, NewTTransportExceptionFromOsError(err) } /** * Flushes the underlying output stream if not null. */ func (p *TIOStreamTransport) Flush() error { if p.Writer == nil { return NewTTransportException(NOT_OPEN, "Cannot flush null outputStream") } f, ok := p.Writer.(Flusher) if ok { err := f.Flush() if err != nil { return NewTTransportExceptionFromOsError(err) } } return nil } golang-thrift-0.0~git20121118/tiostream_transport_test.go000066400000000000000000000017541222677523400233720ustar00rootroot00000000000000/* * 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 TestIOStreamTransport(t *testing.T) { trans := NewTIOStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 1024))) TransportTest(t, trans, trans) } golang-thrift-0.0~git20121118/tjson_protocol.go000066400000000000000000000321221222677523400212570ustar00rootroot00000000000000/* * 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) TProtocolException { 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() TProtocolException { return p.OutputListEnd() } func (p *TJSONProtocol) WriteStructBegin(name string) TProtocolException { if e := p.OutputObjectBegin(); e != nil { return e } return nil } func (p *TJSONProtocol) WriteStructEnd() TProtocolException { return p.OutputObjectEnd() } func (p *TJSONProtocol) WriteFieldBegin(name string, typeId TType, id int16) TProtocolException { 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() TProtocolException { return p.OutputObjectEnd() } func (p *TJSONProtocol) WriteFieldStop() TProtocolException { return nil } func (p *TJSONProtocol) WriteMapBegin(keyType TType, valueType TType, size int) TProtocolException { 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() TProtocolException { return p.OutputListEnd() } func (p *TJSONProtocol) WriteListBegin(elemType TType, size int) TProtocolException { return p.OutputElemListBegin(elemType, size) } func (p *TJSONProtocol) WriteListEnd() TProtocolException { return p.OutputListEnd() } func (p *TJSONProtocol) WriteSetBegin(elemType TType, size int) TProtocolException { return p.OutputElemListBegin(elemType, size) } func (p *TJSONProtocol) WriteSetEnd() TProtocolException { return p.OutputListEnd() } func (p *TJSONProtocol) WriteBool(b bool) TProtocolException { return p.OutputBool(b) } func (p *TJSONProtocol) WriteByte(b byte) TProtocolException { return p.WriteI32(int32(b)) } func (p *TJSONProtocol) WriteI16(v int16) TProtocolException { return p.WriteI32(int32(v)) } func (p *TJSONProtocol) WriteI32(v int32) TProtocolException { return p.OutputI64(int64(v)) } func (p *TJSONProtocol) WriteI64(v int64) TProtocolException { return p.OutputI64(int64(v)) } func (p *TJSONProtocol) WriteDouble(v float64) TProtocolException { return p.OutputF64(v) } func (p *TJSONProtocol) WriteString(v string) TProtocolException { return p.OutputString(v) } func (p *TJSONProtocol) 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 } p.writer.Write(JSON_QUOTE_BYTES) writer := base64.NewEncoder(base64.StdEncoding, p.writer) if _, e := writer.Write(v); e != nil { return NewTProtocolExceptionFromOsError(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 TProtocolException) { 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 { return name, typeId, seqId, NewTProtocolException(INVALID_DATA, fmt.Sprint("Unknown Protocol version ", version, ", expected version ", THRIFT_JSON_PROTOCOL_VERSION, "\n")) } 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() TProtocolException { err := p.ParseListEnd() return err } func (p *TJSONProtocol) ReadStructBegin() (name string, err TProtocolException) { _, err = p.ParseObjectStart() return "", err } func (p *TJSONProtocol) ReadStructEnd() TProtocolException { return p.ParseObjectEnd() } func (p *TJSONProtocol) ReadFieldBegin() (string, TType, int16, TProtocolException) { 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() TProtocolException { return p.ParseObjectEnd() } func (p *TJSONProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, e TProtocolException) { 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() TProtocolException { return p.ParseListEnd() } func (p *TJSONProtocol) ReadListBegin() (elemType TType, size int, e TProtocolException) { return p.ParseElemListBegin() } func (p *TJSONProtocol) ReadListEnd() TProtocolException { return p.ParseListEnd() } func (p *TJSONProtocol) ReadSetBegin() (elemType TType, size int, e TProtocolException) { return p.ParseElemListBegin() } func (p *TJSONProtocol) ReadSetEnd() TProtocolException { return p.ParseListEnd() } func (p *TJSONProtocol) 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 *TJSONProtocol) ReadByte() (byte, TProtocolException) { v, err := p.ReadI64() return byte(v), err } func (p *TJSONProtocol) ReadI16() (int16, TProtocolException) { v, err := p.ReadI64() return int16(v), err } func (p *TJSONProtocol) ReadI32() (int32, TProtocolException) { v, err := p.ReadI64() return int32(v), err } func (p *TJSONProtocol) ReadI64() (int64, TProtocolException) { v, _, err := p.ParseI64() return v, err } func (p *TJSONProtocol) ReadDouble() (float64, TProtocolException) { v, _, err := p.ParseF64() return v, err } func (p *TJSONProtocol) 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 *TJSONProtocol) 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 *TJSONProtocol) Flush() (err TProtocolException) { return NewTProtocolExceptionFromOsError(p.writer.Flush()) } func (p *TJSONProtocol) Skip(fieldType TType) (err TProtocolException) { return SkipDefaultDepth(p, fieldType) } func (p *TJSONProtocol) Transport() TTransport { return p.trans } func (p *TJSONProtocol) readElemListBegin() (elemType TType, size int, e TProtocolException) { 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) TProtocolException { 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 ENUM: return "i32" case UTF16: return "str" case GENERIC: return "gen" } 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 "enm": return TType(ENUM) case "u16": return TType(UTF16) case "gen": return TType(GENERIC) } return TType(STOP) } golang-thrift-0.0~git20121118/tjson_protocol_test.go000066400000000000000000000532751222677523400223320ustar00rootroot00000000000000/* * 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 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 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 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 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() } func TestReadWriteJSONStruct(t *testing.T) { thetype := "struct" trans := NewTMemoryBuffer() p := NewTJSONProtocol(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.Error()) } p.Flush() t.Log("Memory buffer contents: ", trans.String()) expectedString := "{\"1\":{\"i32\":25},\"2\":{\"i32\":102},\"3\":{\"i32\":1},\"4\":{\"str\":\"Add: 25 + 102\"}}" if expectedString != trans.String() { t.Fatalf("Expected JSON Struct with value %#v but have %#v", expectedString, 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.Error()) } if !orig.Equals(read) { t.Fatalf("Original Write != Read: %#v != %#v ", orig, read) } } func TestReadWriteJSONProtocol(t *testing.T) { ReadWriteProtocolTest(t, NewTJSONProtocolFactory()) } golang-thrift-0.0~git20121118/tlist.go000066400000000000000000000112251222677523400173410ustar00rootroot00000000000000/* * 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" ) /** * Helper class that encapsulates list metadata. * * Note that lists of structs requires pointers, not struct values. */ type TList interface { TContainer ElemType() TType At(i int) interface{} Set(i int, data interface{}) Push(data interface{}) Pop() interface{} Swap(i, j int) Insert(i int, data interface{}) Delete(i int) Less(i, j int) bool Iter() <-chan interface{} } type tList struct { elemType TType l []interface{} } func NewTList(t TType, s int) TList { //this automatically grows using append so 0 v := make([]interface{}, 0) return &tList{elemType: t, l: v} } func NewTListDefault() TList { return &tList{elemType: TType(STOP), l: make([]interface{}, 0)} } func (p *tList) ElemType() TType { return p.elemType } func (p *tList) Len() int { return len(p.l) } func (p *tList) At(i int) interface{} { return p.l[i] } func (p *tList) Set(i int, data interface{}) { if p.elemType.IsEmptyType() { p.elemType = TypeFromValue(data) } if data, ok := p.elemType.CoerceData(data); ok { if len(p.l) >= i { p.l[i] = data } else { p.l = append(p.l, data) } } } func (p *tList) Push(data interface{}) { if p.elemType.IsEmptyType() { p.elemType = TypeFromValue(data) } data, ok := p.elemType.CoerceData(data) if ok { p.l = append(p.l, data) } } func (p *tList) Pop() interface{} { var x interface{} x, p.l = p.l[len(p.l)-1], p.l[:len(p.l)-1] return x } func (p *tList) Swap(i, j int) { x, y := p.l[i], p.l[j] p.l[i] = y p.l[j] = x } func (p *tList) Insert(i int, data interface{}) { newl := make([]interface{}, 1) newl[0] = data p.l = append(p.l[:i], append(newl, p.l[i:]...)...) } func (p *tList) Delete(i int) { p.l = append(p.l[:i], p.l[i+1:]...) } func (p *tList) Contains(data interface{}) bool { return p.indexOf(data) >= 0 } func (p *tList) Less(i, j int) bool { _, less := p.elemType.Compare(p.l[i], p.l[j]) return less } func (p *tList) Iter() <-chan interface{} { c := make(chan interface{}) go p.iterate(c) return c } func (p *tList) iterate(c chan<- interface{}) { for _, elem := range p.l { c <- elem } close(c) } func (p *tList) indexOf(data interface{}) int { if data == nil { size := len(p.l) for i := 0; i < size; i++ { if p.l[i] == nil { return i } } return -1 } data, ok := p.elemType.CoerceData(data) if data == nil || !ok { return -1 } size := len(p.l) if p.elemType == BINARY { for i := 0; i < size; i++ { if bytes.Compare(data.([]byte), p.l[i].([]byte)) == 0 { return i } } return -1 } if p.elemType.IsBaseType() || p.elemType.IsEnum() { for i := 0; i < size; i++ { if data == p.l[i] { return i } } return -1 } if cmp, ok := data.(EqualsOtherInterface); ok { for i := 0; i < size; i++ { if cmp.Equals(p.l[i]) { return i } } return -1 } switch p.elemType { case MAP: if cmp, ok := data.(EqualsMap); ok { for i := 0; i < size; i++ { v := p.l[i] if v == nil { continue } if cmp.Equals(v.(TMap)) { return i } } return -1 } case SET: if cmp, ok := data.(EqualsSet); ok { for i := 0; i < size; i++ { v := p.l[i] if v == nil { continue } if cmp.Equals(v.(TSet)) { return i } } return -1 } case LIST: if cmp, ok := data.(EqualsList); ok { for i := 0; i < size; i++ { v := p.l[i] if v == nil { continue } if cmp.Equals(v.(TList)) { return i } } return -1 } case STRUCT: if cmp, ok := data.(EqualsStruct); ok { for i := 0; i < size; i++ { v := p.l[i] if v == nil { continue } if cmp.Equals(v.(TStruct)) { return i } } return -1 } } return -1 } func (p *tList) Equals(other interface{}) bool { c, cok := p.CompareTo(other) return cok && c == 0 } func (p *tList) CompareTo(other interface{}) (int, bool) { return TType(LIST).Compare(p, other) } golang-thrift-0.0~git20121118/tmap.go000066400000000000000000000350141222677523400171450ustar00rootroot00000000000000/* * 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" "container/list" "reflect" ) /** * Helper class that encapsulates map metadata. * */ type TMap interface { KeyType() TType ValueType() TType Len() int Set(key, value interface{}) Get(key interface{}) (interface{}, bool) Contains(key interface{}) bool Iter() <-chan TMapElem KeyIter() <-chan interface{} ValueIter() <-chan interface{} Keys() []interface{} Values() []interface{} Less(other interface{}) bool Equals(other interface{}) bool CompareTo(other interface{}) (int, bool) } type TMapElem interface { Key() interface{} Value() interface{} } type tMap struct { keyType TType valueType TType size int l *list.List b map[bool]interface{} i08 map[byte]interface{} i16 map[int16]interface{} i32 map[int32]interface{} i64 map[int64]interface{} f64 map[float64]interface{} s map[string]interface{} } type tMapElem struct { key interface{} value interface{} } func (p *tMapElem) Key() interface{} { return p.key } func (p *tMapElem) Value() interface{} { return p.value } func NewTMapElem(k, v interface{}) TMapElem { return &tMapElem{key: k, value: v} } func NewTMap(k, v TType, s int) TMap { return &tMap{keyType: k, valueType: v, size: s, l: list.New()} } func NewTMapDefault() TMap { return NewTMap(STOP, STOP, 0) } func (p *tMap) KeyType() TType { return p.keyType } func (p *tMap) ValueType() TType { return p.valueType } func (p *tMap) Len() int { if p.l.Len() != 0 { return p.l.Len() } switch p.KeyType() { case STOP, VOID: return 0 case BOOL: return len(p.b) case BYTE: return len(p.i08) case I16: return len(p.i16) case I32: return len(p.i32) case I64: return len(p.i64) case DOUBLE: return len(p.f64) case STRING, UTF8, UTF16: return len(p.s) default: return p.size } return p.size } func (p *tMap) Get(key interface{}) (interface{}, bool) { if p.KeyType().IsEmptyType() { return nil, false } if key == nil { for elem := p.l.Front(); elem != nil; elem = elem.Next() { e := elem.Value.(TMapElem) k := e.Key() if k == nil { return e.Value(), true } } return nil, false } useKey, ok := p.KeyType().CoerceData(key) if !ok { return nil, false } switch p.KeyType() { case STOP, VOID: // if here, then we don't have a key type yet and key is not nil // so this is pretty much an empty map return nil, false case BOOL: m := p.b if m == nil { return nil, false } if v, ok := m[useKey.(bool)]; ok { return v, true } return nil, true case BYTE: m := p.i08 if v, ok := m[useKey.(byte)]; ok { return v, true } return nil, false case DOUBLE: m := p.f64 if m == nil { return nil, false } if v, ok := m[useKey.(float64)]; ok { return v, true } return nil, false case I16: m := p.i16 if m == nil { return nil, false } if v, ok := m[useKey.(int16)]; ok { return v, true } return nil, false case I32: m := p.i32 if m == nil { return nil, false } if v, ok := m[useKey.(int32)]; ok { return v, true } return nil, false case I64: m := p.i64 if m == nil { return nil, false } if v, ok := m[useKey.(int64)]; ok { return v, true } return nil, false case STRING, UTF8, UTF16: // TODO(pomack) properly handle ENUM m := p.s if m == nil { return nil, false } if v, ok := m[useKey.(string)]; ok { return v, true } return nil, false case BINARY: for elem := p.l.Front(); elem != nil; elem = elem.Next() { e := elem.Value.(TMapElem) k := e.Key() if k == nil { continue } binkey, ok := k.([]byte) if ok { if bytes.Compare(binkey, useKey.([]byte)) == 0 { return e.Value(), true } continue } if reflect.DeepEqual(useKey, k) { return e.Value(), true } } return nil, false case STRUCT: for elem := p.l.Front(); elem != nil; elem = elem.Next() { e := elem.Value.(TMapElem) k := e.Key() if k == nil { continue } structkey, ok := k.(TStruct) if ok { if structkey.Equals(useKey.(TStruct)) { return e.Value(), true } continue } if reflect.DeepEqual(useKey, k) { return e.Value(), true } } return nil, false case MAP: for elem := p.l.Front(); elem != nil; elem = elem.Next() { e := elem.Value.(TMapElem) k := e.Key() if k == nil { continue } mapkey, ok := k.(TMap) if ok { if mapkey.Equals(useKey.(TMap)) { return e.Value(), true } continue } if reflect.DeepEqual(useKey, k) { return e.Value(), true } } return nil, false case SET: for elem := p.l.Front(); elem != nil; elem = elem.Next() { e := elem.Value.(TMapElem) k := e.Key() if k == nil { continue } setkey, ok := k.(TSet) if ok { if setkey.Equals(useKey.(TSet)) { return e.Value(), true } continue } if reflect.DeepEqual(useKey, k) { return e.Value(), true } } return nil, false case LIST: for elem := p.l.Front(); elem != nil; elem = elem.Next() { e := elem.Value.(TMapElem) k := e.Key() if k == nil { continue } listkey, ok := k.(TList) if ok { if listkey.Equals(useKey.(TList)) { return e.Value(), true } continue } if reflect.DeepEqual(useKey, k) { return e.Value(), true } } return nil, false default: panic("Invalid Thrift element type") } return nil, false } func (p *tMap) Set(key, value interface{}) { if p.KeyType() == STOP || p.KeyType() == VOID { p.keyType = TypeFromValue(key) } coercedKey, ok := p.KeyType().CoerceData(key) if !ok { return } if p.ValueType() == STOP || p.ValueType() == VOID { p.valueType = TypeFromValue(value) } coercedValue, ok := p.ValueType().CoerceData(value) if !ok { return } newElem := NewTMapElem(coercedKey, coercedValue) if !p.KeyType().IsBaseType() || p.KeyType() == BINARY { for elem := p.l.Front(); elem != nil; elem = elem.Next() { k := elem.Value.(TMapElem).Key() if cmp, ok := p.KeyType().Compare(coercedKey, k); ok && cmp >= 0 { if cmp == 0 { p.l.InsertAfter(newElem, elem) p.l.Remove(elem) return } p.l.InsertBefore(newElem, elem) return } } p.l.PushBack(newElem) return } if key == nil { return } switch p.KeyType() { case STOP, VOID: // if here, then we don't have a key type yet and key is not nil // so this is pretty much an empty map return case BOOL: if p.b == nil { p.b = make(map[bool]interface{}) } b := coercedKey.(bool) p.b[b] = value case BYTE: if p.i08 == nil { p.i08 = make(map[byte]interface{}) } b := coercedKey.(byte) p.i08[b] = value case DOUBLE: if p.f64 == nil { p.f64 = make(map[float64]interface{}) } b := coercedKey.(float64) p.f64[b] = value case I16: if p.i16 == nil { p.i16 = make(map[int16]interface{}) } b := coercedKey.(int16) p.i16[b] = value case I32: if p.i32 == nil { p.i32 = make(map[int32]interface{}) } b := coercedKey.(int32) p.i32[b] = value case I64: if p.i64 == nil { p.i64 = make(map[int64]interface{}) } b := coercedKey.(int64) p.i64[b] = value case STRING, UTF8, UTF16: if p.s == nil { p.s = make(map[string]interface{}) } b := coercedKey.(string) p.s[b] = value case BINARY, STRUCT, MAP, SET, LIST: panic("Should never be here because type is " + p.KeyType().String()) default: panic("Should never be here because type is " + p.KeyType().String()) } } func (p *tMap) Contains(key interface{}) bool { coercedKey, ok := p.KeyType().CoerceData(key) if !ok { return false } if coercedKey == nil { for elem := p.l.Front(); elem != nil; elem = elem.Next() { k := elem.Value.(TMapElem).Key() if k == nil { return true } } return false } if !ok { return false } switch p.KeyType() { case STOP: // if here, then we don't have a key type yet and key is not nil // so this is pretty much an empty map return false case VOID: // if here, then we don't have a key type yet and key is not nil // so this is pretty much an empty map return false case BOOL: m := p.b if m == nil { return false } _, ok := m[coercedKey.(bool)] return ok case BYTE: m := p.i08 _, ok := m[coercedKey.(byte)] return ok case DOUBLE: m := p.f64 if m == nil { return false } _, ok := m[coercedKey.(float64)] return ok case I16: m := p.i16 if m == nil { return false } _, ok := m[coercedKey.(int16)] return ok case I32: m := p.i32 if m == nil { return false } _, ok := m[coercedKey.(int32)] return ok case I64: m := p.i64 if m == nil { return false } _, ok := m[coercedKey.(int64)] return ok case STRING, UTF8, UTF16: // TODO(pomack) properly handle ENUM m := p.s if m == nil { return false } _, ok := m[coercedKey.(string)] return ok case BINARY: for elem := p.l.Front(); elem != nil; elem = elem.Next() { e := elem.Value.(TMapElem) k := e.Key() if k == nil { continue } binkey, ok := k.([]byte) if ok { if bytes.Compare(binkey, coercedKey.([]byte)) == 0 { return true } continue } if reflect.DeepEqual(coercedKey, k) { return true } } return false case STRUCT: for elem := p.l.Front(); elem != nil; elem = elem.Next() { e := elem.Value.(TMapElem) k := e.Key() if k == nil { continue } structkey, ok := k.(TStruct) if ok { if structkey.Equals(coercedKey.(TStruct)) { return true } continue } if reflect.DeepEqual(coercedKey, k) { return true } } return false case MAP: for elem := p.l.Front(); elem != nil; elem = elem.Next() { e := elem.Value.(TMapElem) k := e.Key() if k == nil { continue } mapkey, ok := k.(TMap) if ok { if mapkey.Equals(coercedKey.(TMap)) { return true } continue } } return false case SET: for elem := p.l.Front(); elem != nil; elem = elem.Next() { e := elem.Value.(TMapElem) k := e.Key() if k == nil { continue } setkey, ok := k.(TSet) if ok { if setkey.Equals(coercedKey.(TSet)) { return true } continue } } return false case LIST: for elem := p.l.Front(); elem != nil; elem = elem.Next() { e := elem.Value.(TMapElem) k := e.Key() if k == nil { continue } listkey, ok := k.(TList) if ok { if listkey.Equals(coercedKey.(TList)) { return true } continue } } return false default: panic("Invalid Thrift element type") } return false } // Iterate over all elements; driver for range func (p *tMap) iterate(c chan<- TMapElem) { switch p.KeyType() { case STOP, VOID: close(c) case BOOL: for k, v := range p.b { c <- NewTMapElem(k, v) } close(c) case BYTE: for k, v := range p.i08 { c <- NewTMapElem(k, v) } close(c) case I16: for k, v := range p.i16 { c <- NewTMapElem(k, v) } close(c) case I32: for k, v := range p.i32 { c <- NewTMapElem(k, v) } close(c) case I64: for k, v := range p.i64 { c <- NewTMapElem(k, v) } close(c) case DOUBLE: for k, v := range p.f64 { c <- NewTMapElem(k, v) } close(c) case STRING, UTF8, UTF16: for k, v := range p.s { c <- NewTMapElem(k, v) } close(c) case BINARY, STRUCT, LIST, SET: for v := p.l.Front(); v != nil; v = v.Next() { c <- v.Value.(TMapElem) } close(c) default: panic("Invalid Thrift type") } } // Channel iterator for range. func (p *tMap) Iter() <-chan TMapElem { c := make(chan TMapElem) go p.iterate(c) return c } // Iterate over all keys; driver for range func (p *tMap) iterateKeys(c chan<- interface{}) { switch p.KeyType() { case STOP, VOID: close(c) case BOOL: for k, _ := range p.b { c <- k } close(c) case BYTE: for k, _ := range p.i08 { c <- k } close(c) case I16: for k, _ := range p.i16 { c <- k } close(c) case I32: for k, _ := range p.i32 { c <- k } close(c) case I64: for k, _ := range p.i64 { c <- k } close(c) case DOUBLE: for k, _ := range p.f64 { c <- k } close(c) case STRING, UTF8, UTF16: for k, _ := range p.s { c <- k } close(c) case BINARY, STRUCT, LIST, SET: for v := p.l.Front(); v != nil; v = v.Next() { c <- v.Value.(TMapElem).Key() } close(c) default: panic("Invalid Thrift type") } } func (p *tMap) KeyIter() <-chan interface{} { c := make(chan interface{}) go p.iterateKeys(c) return c } // Iterate over all values; driver for range func (p *tMap) iterateValues(c chan<- interface{}) { switch p.KeyType() { case STOP, VOID: close(c) case BOOL: for _, v := range p.b { c <- v } close(c) case BYTE: for _, v := range p.i08 { c <- v } close(c) case I16: for _, v := range p.i16 { c <- v } close(c) case I32: for _, v := range p.i32 { c <- v } close(c) case I64: for _, v := range p.i64 { c <- v } close(c) case DOUBLE: for _, v := range p.f64 { c <- v } close(c) case STRING, UTF8, UTF16: for _, v := range p.s { c <- v } close(c) case BINARY, STRUCT, LIST, SET: for v := p.l.Front(); v != nil; v = v.Next() { c <- v.Value.(TMapElem).Value() } close(c) default: panic("Invalid Thrift type") } } func (p *tMap) ValueIter() <-chan interface{} { c := make(chan interface{}) go p.iterateValues(c) return c } func (p *tMap) Less(other interface{}) bool { cmp, ok := p.CompareTo(other) return ok && cmp > 0 } func (p *tMap) Equals(other interface{}) bool { c, cok := p.CompareTo(other) return cok && c == 0 } func (p *tMap) CompareTo(other interface{}) (int, bool) { return TType(MAP).Compare(p, other) } func (p *tMap) Keys() []interface{} { size := p.Len() values := make([]interface{}, size, size) i := 0 for k := range p.KeyIter() { values[i] = k i++ } return values } func (p *tMap) Values() []interface{} { size := p.Len() values := make([]interface{}, size, size) i := 0 for v := range p.ValueIter() { values[i] = v i++ } return values } golang-thrift-0.0~git20121118/tmap_test.go000066400000000000000000000045301222677523400202030ustar00rootroot00000000000000package thrift import ( "testing" ) func TestMapSetI32(t *testing.T) { tm := NewTMap(I32, BOOL, 1) tm.Set(15, true) tm.Set(32, false) if !tm.Contains(15) { t.Errorf("Expected a key of 15, but not found in set") } if !tm.Contains(32) { t.Errorf("Expected a key of 32, but not found in set") } if tm.Contains(37) { t.Errorf("Expected not to find a key of 37, but found in set") } if v, found := tm.Get(15); !v.(bool) || !found { t.Errorf("Expected key of 15 => true, true, but was %v, %v", v, found) } if v, found := tm.Get(32); v.(bool) || !found { t.Errorf("Expected key of 32 => false, true, but was %v, %v", v, found) } if v, found := tm.Get(37); found { t.Errorf("Expected key of 37 => false, false, but was %v, %v", v, found) } } func TestMapSetString(t *testing.T) { tm := NewTMap(STRING, BOOL, 1) tm.Set("a", true) tm.Set("b", false) if !tm.Contains("a") { t.Errorf("Expected a key of \"a\", but not found in set") } if !tm.Contains("b") { t.Errorf("Expected a key of \"b\", but not found in set") } if tm.Contains("c") { t.Errorf("Expected not to find a key of \"c\", but found in set") } if v, found := tm.Get("a"); !v.(bool) || !found { t.Errorf("Expected key of \"a\" => true, true, but was %v, %v", v, found) } if v, found := tm.Get("b"); v.(bool) || !found { t.Errorf("Expected key of \"b\" => false, true, but was %v, %v", v, found) } if v, found := tm.Get("c"); found { t.Errorf("Expected key of \"c\" => false, false, but was %v, %v", v, found) } } func TestMapSetBinary(t *testing.T) { tm := NewTMap(BINARY, BOOL, 1) tm.Set([]byte("a"), true) tm.Set([]byte("b"), false) if !tm.Contains([]byte("a")) { t.Errorf("Expected a key of []byte(\"a\"), but not found in set") } if !tm.Contains([]byte("b")) { t.Errorf("Expected a key of []byte(\"b\"), but not found in set") } if tm.Contains([]byte("c")) { t.Errorf("Expected not to find a key of []byte(\"c\"), but found in set") } if v, found := tm.Get([]byte("a")); !v.(bool) || !found { t.Errorf("Expected key of []byte(\"a\") => true, true, but was %v, %v", v, found) } if v, found := tm.Get([]byte("b")); v.(bool) || !found { t.Errorf("Expected key of []byte(\"b\") => false, true, but was %v, %v", v, found) } if v, found := tm.Get([]byte("c")); found { t.Errorf("Expected key of []byte(\"c\") => false, false, but was %v, %v", v, found) } } golang-thrift-0.0~git20121118/tmemory_buffer.go000066400000000000000000000054151222677523400212330ustar00rootroot00000000000000/* * 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" ) /** * Memory buffer-based implementation of the TTransport interface. * */ type TMemoryBuffer struct { buf *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{buf: &bytes.Buffer{}, size: 0} } func NewTMemoryBufferLen(size int) *TMemoryBuffer { buf := make([]byte, 0, size) return &TMemoryBuffer{buf: 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.buf.Reset() return nil } func (p *TMemoryBuffer) Read(buf []byte) (int, error) { return p.buf.Read(buf) } func (p *TMemoryBuffer) ReadAll(buf []byte) (int, error) { return ReadAllTransport(p, buf) } func (p *TMemoryBuffer) ReadByte() (byte, error) { return p.buf.ReadByte() } func (p *TMemoryBuffer) ReadFrom(r io.Reader) (int64, error) { return p.buf.ReadFrom(r) } func (p *TMemoryBuffer) Write(buf []byte) (int, error) { return p.buf.Write(buf) } func (p *TMemoryBuffer) WriteString(buf string) (int, error) { return p.buf.WriteString(buf) } func (p *TMemoryBuffer) WriteTo(w io.Writer) (int64, error) { return p.buf.WriteTo(w) } func (p *TMemoryBuffer) Flush() error { return nil } func (p *TMemoryBuffer) Reset() { p.buf.Reset() } func (p *TMemoryBuffer) Bytes() []byte { return p.buf.Bytes() } func (p *TMemoryBuffer) Len() int { return p.buf.Len() } func (p *TMemoryBuffer) String() string { return p.buf.String() } golang-thrift-0.0~git20121118/tmemory_buffer_test.go000066400000000000000000000016701222677523400222710ustar00rootroot00000000000000/* * 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) } golang-thrift-0.0~git20121118/tmessage.go000066400000000000000000000033711222677523400200150ustar00rootroot00000000000000/* * 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 TMessage interface { Name() string TypeId() TMessageType SeqId() int Equals(other TMessage) bool } type tMessage struct { name string typeId TMessageType seqid int } func NewTMessageDefault() TMessage { return NewTMessage("", STOP, 0) } func NewTMessage(n string, t TMessageType, s int) TMessage { return &tMessage{name: n, typeId: t, seqid: s} } func (p *tMessage) Name() string { return p.name } func (p *tMessage) TypeId() TMessageType { return p.typeId } func (p *tMessage) SeqId() int { return p.seqid } func (p *tMessage) String() string { return "" } func (p *tMessage) Equals(other TMessage) bool { return p.name == other.Name() && p.typeId == other.TypeId() && p.seqid == other.SeqId() } var EMPTY_MESSAGE TMessage func init() { EMPTY_MESSAGE = NewTMessageDefault() } golang-thrift-0.0~git20121118/tmessagetype.go000066400000000000000000000021351222677523400207140ustar00rootroot00000000000000/* * 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 ) golang-thrift-0.0~git20121118/tnonblocking_server.go000066400000000000000000000131471222677523400222640ustar00rootroot00000000000000/* * 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 () /** * A nonblocking TServer implementation. This allows for fairness amongst all * connected clients in terms of invocations. * * This server is inherently single-threaded. If you want a limited thread pool * coupled with invocation-fairness, see THsHaServer. * * To use this server, you MUST use a TFramedTransport at the outermost * transport, otherwise this server will be unable to determine when a whole * method call has been read off the wire. Clients must also use TFramedTransport. */ type TNonblockingServer struct { /** Flag for stopping the server */ stopped bool processorFactory TProcessorFactory serverTransport TServerTransport inputTransportFactory TTransportFactory outputTransportFactory TTransportFactory inputProtocolFactory TProtocolFactory outputProtocolFactory TProtocolFactory } func NewTNonblockingServer2(processor TProcessor, serverTransport TServerTransport) *TNonblockingServer { return NewTNonblockingServerFactory2(NewTProcessorFactory(processor), serverTransport) } func NewTNonblockingServer4(processor TProcessor, serverTransport TServerTransport, transportFactory TTransportFactory, protocolFactory TProtocolFactory) *TNonblockingServer { return NewTNonblockingServerFactory4(NewTProcessorFactory(processor), serverTransport, transportFactory, protocolFactory, ) } func NewTNonblockingServer6(processor TProcessor, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TNonblockingServer { return NewTNonblockingServerFactory6(NewTProcessorFactory(processor), serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory, ) } func NewTNonblockingServerFactory2(processorFactory TProcessorFactory, serverTransport TServerTransport) *TNonblockingServer { return NewTNonblockingServerFactory6(processorFactory, serverTransport, NewTTransportFactory(), NewTTransportFactory(), NewTBinaryProtocolFactoryDefault(), NewTBinaryProtocolFactoryDefault(), ) } func NewTNonblockingServerFactory4(processorFactory TProcessorFactory, serverTransport TServerTransport, transportFactory TTransportFactory, protocolFactory TProtocolFactory) *TNonblockingServer { return NewTNonblockingServerFactory6(processorFactory, serverTransport, transportFactory, transportFactory, protocolFactory, protocolFactory, ) } func NewTNonblockingServerFactory6(processorFactory TProcessorFactory, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TNonblockingServer { return &TNonblockingServer{processorFactory: processorFactory, serverTransport: serverTransport, inputTransportFactory: inputTransportFactory, outputTransportFactory: outputTransportFactory, inputProtocolFactory: inputProtocolFactory, outputProtocolFactory: outputProtocolFactory, } } func (p *TNonblockingServer) ProcessorFactory() TProcessorFactory { return p.processorFactory } func (p *TNonblockingServer) ServerTransport() TServerTransport { return p.serverTransport } func (p *TNonblockingServer) InputTransportFactory() TTransportFactory { return p.inputTransportFactory } func (p *TNonblockingServer) OutputTransportFactory() TTransportFactory { return p.outputTransportFactory } func (p *TNonblockingServer) InputProtocolFactory() TProtocolFactory { return p.inputProtocolFactory } func (p *TNonblockingServer) OutputProtocolFactory() TProtocolFactory { return p.outputProtocolFactory } func (p *TNonblockingServer) Serve() 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 { go p.processRequest(client) } } return nil } func (p *TNonblockingServer) Stop() error { p.stopped = true p.serverTransport.Interrupt() return nil } func (p *TNonblockingServer) IsStopped() bool { return p.stopped } func (p *TNonblockingServer) 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 } } } golang-thrift-0.0~git20121118/tnonblocking_server_socket.go000066400000000000000000000110131222677523400236220ustar00rootroot00000000000000/* * 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" ) /** * Socket implementation of the TTransport interface. To be commented soon! */ type TNonblockingServerSocket struct { listener net.Listener addr net.Addr /** * Socket timeout */ nsecTimeout int64 } type TNonblockingServerSocketTransportFactory struct { addr net.Addr } func (p *TNonblockingServerSocketTransportFactory) GetTransport(trans TTransport) TTransport { if trans != nil { t, ok := trans.(*TNonblockingServerSocket) if ok && t.addr != nil { s, _ := NewTNonblockingServerSocketAddrTimeout(t.addr, t.nsecTimeout) return s } } s, _ := NewTNonblockingServerSocketAddr(p.addr) return s } func NewTNonblockingServerSocketTransportFactory(addr net.Addr) *TNonblockingServerSocketTransportFactory { return &TNonblockingServerSocketTransportFactory{addr: addr} } func NewTNonblockingServerSocketListener(listener net.Listener) (*TNonblockingServerSocket, TTransportException) { s := &TNonblockingServerSocket{listener: listener, addr: listener.Addr()} return s, nil } func NewTNonblockingServerSocketAddr(addr net.Addr) (*TNonblockingServerSocket, TTransportException) { s := &TNonblockingServerSocket{addr: addr} return s, nil } func NewTNonblockingServerSocketAddrTimeout(addr net.Addr, nsecTimeout int64) (*TNonblockingServerSocket, TTransportException) { s := &TNonblockingServerSocket{addr: addr, nsecTimeout: nsecTimeout} return s, nil } func (p *TNonblockingServerSocket) Listen() error { return p.Open() } /** * Sets the socket timeout * * @param timeout Nanoseconds timeout */ func (p *TNonblockingServerSocket) SetTimeout(nsecTimeout int64) error { p.nsecTimeout = nsecTimeout return nil } /** * Checks whether the socket is connected. */ func (p *TNonblockingServerSocket) IsOpen() bool { return p.listener != nil } /** * Connects the socket, creating a new socket object if necessary. */ func (p *TNonblockingServerSocket) Open() error { if !p.IsOpen() { l, err := net.Listen(p.addr.Network(), p.addr.String()) if err != nil { return err } p.listener = l return nil } return NewTTransportException(ALREADY_OPEN, "Server socket already open") } /** * Perform a nonblocking read into buffer. */ func (p *TNonblockingServerSocket) Read(buf []byte) (int, error) { return 0, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "TNonblockingServerSocket.Read([]byte) is not implemented") } func (p *TNonblockingServerSocket) ReadAll(buf []byte) (int, error) { return ReadAllTransport(p, buf) } /** * Perform a nonblocking write of the data in buffer; */ func (p *TNonblockingServerSocket) Write(buf []byte) (int, error) { return 0, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "TNonblockingServerSocket.Write([]byte) is not implemented") } /** * Flushes the underlying output stream if not null. */ func (p *TNonblockingServerSocket) Flush() error { return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "TNonblockingServerSocket.Flush() is not implemented") } func (p *TNonblockingServerSocket) Addr() net.Addr { return p.addr } func (p *TNonblockingServerSocket) Accept() (TTransport, error) { if !p.IsOpen() { return nil, NewTTransportException(NOT_OPEN, "No underlying server socket") } conn, err := p.listener.Accept() if err != nil { return nil, NewTTransportExceptionFromOsError(err) } return NewTSocketConnTimeout(conn, p.nsecTimeout) } func (p *TNonblockingServerSocket) Peek() bool { return p.IsOpen() } /** * Closes the socket. */ func (p *TNonblockingServerSocket) Close() (err error) { if p.IsOpen() { err := p.listener.Close() if err != nil { return NewTTransportExceptionFromOsError(err) } p.listener = nil } return nil } func (p *TNonblockingServerSocket) Interrupt() error { // probably not right return p.Close() } golang-thrift-0.0~git20121118/tnonblocking_socket.go000066400000000000000000000116001222677523400222360ustar00rootroot00000000000000/* * 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" ) /** * Socket implementation of the TTransport interface. To be commented soon! */ type TNonblockingSocket struct { conn net.Conn addr net.Addr /** * Socket timeout */ nsecTimeout int64 } type TNonblockingSocketTransportFactory struct { addr net.Addr } func (p *TNonblockingSocketTransportFactory) GetTransport(trans TTransport) TTransport { if trans != nil { t, ok := trans.(*TNonblockingSocket) if ok { s, _ := NewTNonblockingSocketAddrTimeout(t.addr, t.nsecTimeout) return s } } s, _ := NewTNonblockingSocketAddr(p.addr) return s } func NewTNonblockingSocketTransportFactory(addr net.Addr) *TNonblockingSocketTransportFactory { return &TNonblockingSocketTransportFactory{addr: addr} } func NewTNonblockingSocketConn(conn net.Conn) (*TNonblockingSocket, TTransportException) { s := &TNonblockingSocket{conn: conn, addr: conn.RemoteAddr()} return s, nil } func NewTNonblockingSocketAddr(addr net.Addr) (*TNonblockingSocket, TTransportException) { s := &TNonblockingSocket{addr: addr} return s, nil } func NewTNonblockingSocketAddrTimeout(addr net.Addr, nsecTimeout int64) (*TNonblockingSocket, TTransportException) { s := &TNonblockingSocket{addr: addr, nsecTimeout: nsecTimeout} return s, nil } /** * Sets the socket timeout * * @param nsecTimeout Nanoseconds timeout */ func (p *TNonblockingSocket) SetTimeout(nsecTimeout int64) error { p.nsecTimeout = nsecTimeout return nil } func (p *TNonblockingSocket) pushDeadline(read, write bool) { var t time.Time if p.nsecTimeout > 0 { t = time.Now().Add(time.Duration(p.nsecTimeout)) } if read && write { p.conn.SetDeadline(t) } else if read { p.conn.SetReadDeadline(t) } else if write { p.conn.SetWriteDeadline(t) } } /** * Checks whether the socket is connected. */ func (p *TNonblockingSocket) IsOpen() bool { return p.conn != nil } /** * Connects the socket, creating a new socket object if necessary. */ func (p *TNonblockingSocket) Open() 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 error if p.conn, err = net.Dial(p.addr.Network(), p.addr.String()); err != nil { LOGGER.Print("Could not open socket", err.Error()) return NewTTransportException(NOT_OPEN, err.Error()) } return nil } /** * Perform a nonblocking read into buffer. */ func (p *TNonblockingSocket) Read(buf []byte) (int, error) { if !p.IsOpen() { return 0, NewTTransportException(NOT_OPEN, "Connection not open") } p.pushDeadline(true, false) n, err := p.conn.Read(buf) return n, NewTTransportExceptionFromOsError(err) } func (p *TNonblockingSocket) ReadAll(buf []byte) (int, error) { return ReadAllTransport(p, buf) } /** * Perform a nonblocking write of the data in buffer; */ func (p *TNonblockingSocket) Write(buf []byte) (int, error) { if !p.IsOpen() { return 0, NewTTransportException(NOT_OPEN, "Connection not open") } p.pushDeadline(false, true) return p.conn.Write(buf) } /** * Flushes the underlying output stream if not null. */ func (p *TNonblockingSocket) Flush() error { if !p.IsOpen() { return NewTTransportException(NOT_OPEN, "Connection not open") } f, ok := p.conn.(Flusher) if ok { err := f.Flush() if err != nil { return NewTTransportExceptionFromOsError(err) } } return nil } func (p *TNonblockingSocket) Addr() net.Addr { return p.addr } func (p *TNonblockingSocket) Peek() bool { return p.IsOpen() } /** * Closes the socket. */ func (p *TNonblockingSocket) Close() error { if p.conn != nil { if err := p.conn.Close(); err != nil { LOGGER.Print("Could not close socket.", err.Error()) return err } p.conn = nil } return nil } func (p *TNonblockingSocket) Interrupt() error { if !p.IsOpen() { return nil } // TODO(pomack) fix Interrupt as it is probably not right return p.Close() } golang-thrift-0.0~git20121118/tnonblocking_transport.go000066400000000000000000000015521222677523400230070ustar00rootroot00000000000000/* * 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 TNonblockingTransport interface { TTransport } golang-thrift-0.0~git20121118/tnonblocking_transport_test.go000066400000000000000000000051061222677523400240450ustar00rootroot00000000000000/* * 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" "testing" ) func TestNonblockingTransportServerToClient(t *testing.T) { addr, err := FindAvailableTCPServerPort(40000) if err != nil { t.Fatalf("Unable to find available tcp port addr: %s", err) } trans1, err := NewTNonblockingServerSocketAddr(addr) if err != nil { t.Fatalf("Unable to setup server socket listener: %s", err) } trans1.Open() trans2, err := NewTNonblockingSocketAddr(addr) if err != nil { t.Fatalf("Unable to setup client socket: %s", err) } trans1.SetTimeout(10) trans2.SetTimeout(10) err = trans2.Open() if err != nil { t.Fatalf("Unable to connect client to server: %s", err) } s, err := trans1.Accept() if err != nil { t.Fatalf("Unable to accept client connection from server: %s", err) } //s.SetTimeout(10) TransportTest(t, NewTFramedTransport(s), NewTFramedTransport(trans2)) trans1.Close() } func TestNonblockingTransportClientToServer(t *testing.T) { addr, err := FindAvailableTCPServerPort(40000) if err != nil { t.Fatalf("Unable to find available tcp port addr: %s", err) } l, err := net.Listen(addr.Network(), addr.String()) if err != nil { t.Fatalf("Unable to setup listener: %s", err) } trans1, err := NewTNonblockingServerSocketListener(l) if err != nil { t.Fatalf("Unable to setup server socket listener: %s", err) } trans2, err := NewTNonblockingSocketAddr(l.Addr()) if err != nil { t.Fatalf("Unable to setup client socket: %s", err) } trans1.SetTimeout(10) trans2.SetTimeout(10) err = trans2.Open() if err != nil { t.Fatalf("Unable to connect client to server: %s", err) } s, err := trans1.Accept() if err != nil { t.Fatalf("Unable to accept client connection from server: %s", err) } //s.SetTimeout(10) TransportTest(t, NewTFramedTransport(trans2), NewTFramedTransport(s)) trans1.Close() } golang-thrift-0.0~git20121118/tnumeric.go000066400000000000000000000075401222677523400200350ustar00rootroot00000000000000/* * 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} } golang-thrift-0.0~git20121118/tprocessor.go000066400000000000000000000021341222677523400204040ustar00rootroot00000000000000/* * 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) } golang-thrift-0.0~git20121118/tprocessor_factory.go000066400000000000000000000033241222677523400221350ustar00rootroot00000000000000/* * 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 } golang-thrift-0.0~git20121118/tprotocol.go000066400000000000000000000135611222677523400202340ustar00rootroot00000000000000/* * 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 EmptyInterface interface{} type TProtocol interface { WriteMessageBegin(name string, typeId TMessageType, seqid int32) TProtocolException WriteMessageEnd() TProtocolException WriteStructBegin(name string) TProtocolException WriteStructEnd() TProtocolException WriteFieldBegin(name string, typeId TType, id int16) TProtocolException WriteFieldEnd() TProtocolException WriteFieldStop() TProtocolException WriteMapBegin(keyType TType, valueType TType, size int) TProtocolException WriteMapEnd() TProtocolException WriteListBegin(elemType TType, size int) TProtocolException WriteListEnd() TProtocolException WriteSetBegin(elemType TType, size int) TProtocolException WriteSetEnd() TProtocolException WriteBool(value bool) TProtocolException WriteByte(value byte) TProtocolException WriteI16(value int16) TProtocolException WriteI32(value int32) TProtocolException WriteI64(value int64) TProtocolException WriteDouble(value float64) TProtocolException WriteString(value string) TProtocolException WriteBinary(value []byte) TProtocolException ReadMessageBegin() (name string, typeId TMessageType, seqid int32, err TProtocolException) ReadMessageEnd() TProtocolException ReadStructBegin() (name string, err TProtocolException) ReadStructEnd() TProtocolException ReadFieldBegin() (name string, typeId TType, id int16, err TProtocolException) ReadFieldEnd() TProtocolException ReadMapBegin() (keyType TType, valueType TType, size int, err TProtocolException) ReadMapEnd() TProtocolException ReadListBegin() (elemType TType, size int, err TProtocolException) ReadListEnd() TProtocolException ReadSetBegin() (elemType TType, size int, err TProtocolException) ReadSetEnd() TProtocolException ReadBool() (value bool, err TProtocolException) ReadByte() (value byte, err TProtocolException) ReadI16() (value int16, err TProtocolException) ReadI32() (value int32, err TProtocolException) ReadI64() (value int64, err TProtocolException) ReadDouble() (value float64, err TProtocolException) ReadString() (value string, err TProtocolException) ReadBinary() (value []byte, err TProtocolException) Skip(fieldType TType) (err TProtocolException) Flush() (err TProtocolException) Transport() TTransport } /** * The maximum recursive depth the skip() function will traverse before * throwing a TException. */ var ( MaxSkipDepth = 1<<31 - 1 ) /** * Specifies the maximum recursive depth that the skip function will * traverse before throwing a TException. This is a global setting, so * any call to skip in this JVM will enforce this value. * * @param depth the maximum recursive depth. A value of 2 would allow * the skip function to skip a structure or collection with basic children, * but it would not permit skipping a struct that had a field containing * a child struct. A value of 1 would only allow skipping of simple * types and empty structs/collections. */ func SetMaxSkipDepth(depth int) { MaxSkipDepth = depth } /** * Skips over the next data element from the provided input TProtocol object. * * @param prot the protocol object to read from * @param type the next value will be intepreted as this TType value. */ func SkipDefaultDepth(prot TProtocol, typeId TType) (err TProtocolException) { return Skip(prot, typeId, MaxSkipDepth) } /** * Skips over the next data element from the provided input TProtocol object. * * @param prot the protocol object to read from * @param type the next value will be intepreted as this TType value. * @param maxDepth this function will only skip complex objects to this * recursive depth, to prevent Java stack overflow. */ func Skip(self TProtocol, fieldType TType, maxDepth int) (err TProtocolException) { 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: { _, err = self.ReadStructBegin() if err != nil { return } for { _, typeId, _, _ := self.ReadFieldBegin() if typeId == STOP { break } Skip(self, typeId, maxDepth-1) self.ReadFieldEnd() } return self.ReadStructEnd() } case MAP: { keyType, valueType, l, err := self.ReadMapBegin() if err != nil { return err } size := int(l) for i := 0; i < size; i++ { Skip(self, keyType, maxDepth-1) self.Skip(valueType) } return self.ReadMapEnd() } case SET: { elemType, l, err := self.ReadSetBegin() if err != nil { return err } size := int(l) for i := 0; i < size; i++ { Skip(self, elemType, maxDepth-1) } return self.ReadSetEnd() } case LIST: { elemType, l, err := self.ReadListBegin() if err != nil { return err } size := int(l) for i := 0; i < size; i++ { Skip(self, elemType, maxDepth-1) } return self.ReadListEnd() } } return nil } golang-thrift-0.0~git20121118/tprotocol_exception.go000066400000000000000000000073171222677523400223140ustar00rootroot00000000000000/* * 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" ) /** * Protocol exceptions. * */ 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 NewTProtocolExceptionDefault() TProtocolException { return NewTProtocolExceptionDefaultType(UNKNOWN_PROTOCOL_EXCEPTION) } func NewTProtocolExceptionDefaultType(t int) TProtocolException { return NewTProtocolException(t, "") } func NewTProtocolExceptionDefaultString(m string) TProtocolException { return NewTProtocolException(UNKNOWN_PROTOCOL_EXCEPTION, m) } func NewTProtocolException(t int, m string) TProtocolException { return &tProtocolException{typeId: t, message: m} } func NewTProtocolExceptionReadField(fieldId int, fieldName string, structName string, e TProtocolException) TProtocolException { t := e.TypeId() if t == UNKNOWN_PROTOCOL_EXCEPTION { t = INVALID_DATA } return NewTProtocolException(t, "Unable to read field "+string(fieldId)+" ("+fieldName+") in "+structName+" due to: "+e.Error()) } func NewTProtocolExceptionWriteField(fieldId int, fieldName string, structName string, e TProtocolException) TProtocolException { t := e.TypeId() if t == UNKNOWN_PROTOCOL_EXCEPTION { t = INVALID_DATA } return NewTProtocolException(t, "Unable to write field "+string(fieldId)+" ("+fieldName+") in "+structName+" due to: "+e.Error()) } func NewTProtocolExceptionReadStruct(structName string, e TProtocolException) TProtocolException { t := e.TypeId() if t == UNKNOWN_PROTOCOL_EXCEPTION { t = INVALID_DATA } return NewTProtocolException(t, "Unable to read struct "+structName+" due to: "+e.Error()) } func NewTProtocolExceptionWriteStruct(structName string, e TProtocolException) TProtocolException { t := e.TypeId() if t == UNKNOWN_PROTOCOL_EXCEPTION { t = INVALID_DATA } return NewTProtocolException(t, "Unable to write struct "+structName+" due to: "+e.Error()) } func NewTProtocolExceptionFromOsError(e error) TProtocolException { if e == nil { return nil } if t, ok := e.(TProtocolException); ok { return t } if te, ok := e.(TTransportException); ok { return NewTProtocolExceptionFromTransportException(te) } if _, ok := e.(base64.CorruptInputError); ok { return NewTProtocolException(INVALID_DATA, e.Error()) } return NewTProtocolExceptionDefaultString(e.Error()) } func NewTProtocolExceptionFromTransportException(e TTransportException) TProtocolException { if e == nil { return nil } if t, ok := e.(TProtocolException); ok { return t } return NewTProtocolExceptionDefaultString(e.Error()) } golang-thrift-0.0~git20121118/tprotocol_factory.go000066400000000000000000000017071222677523400217620ustar00rootroot00000000000000/* * 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 } golang-thrift-0.0~git20121118/tprotocol_test.go000066400000000000000000001357351222677523400213030ustar00rootroot00000000000000/* * 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" "fmt" "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"} } 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), NewTIOStreamTransportFactory(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) ReadWriteWork(t, p, trans) trans.Close() } for _, tf := range transports { trans := tf.GetTransport(nil) p := protocolFactory.GetProtocol(trans) ReadWriteCalculate(t, p, trans) trans.Close() } // this test doesn't work in all cases due to EOF issues between // buffer read and buffer write when using the same bufio for both //for _, tf := range transports { // trans := tf.GetTransport(nil) // p := 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) } } } } func ReadWriteWork(t *testing.T, p TProtocol, trans TTransport) { thetype := "struct" orig := NewWork() orig.Num1 = 25 orig.Num2 = 102 orig.Op = ADD orig.Comment = "Add: 25 + 102" return if e := orig.Write(p); e != nil { t.Fatalf("Unable to write %s value %#v due to error: %s", thetype, orig, e.Error()) } read := NewWork() e := read.Read(p) if e != nil { t.Fatalf("Unable to read %s due to error: %s", thetype, e.Error()) } if !orig.Equals(read) { t.Fatalf("Original Write != Read: %#v != %#v ", orig, read) } } func ReadWriteCalculate(t *testing.T, p TProtocol, trans TTransport) { messageName := "calculate" logid := int32(12) seqId := int32(35) w := NewWork() w.Num1 = 25 w.Num2 = 102 w.Op = ADD w.Comment = "Add: 25 + 102" args31 := NewCalculateArgs() args31.Logid = logid args31.W = w p.WriteMessageBegin(messageName, CALL, seqId) if err := args31.Write(p); err != nil { t.Fatalf("%s: %T %T Unable to write message: %s", messageName, p, trans, err.Error()) } p.WriteMessageEnd() p.Transport().Flush() name, ttype, seqid, err1 := p.ReadMessageBegin() if err1 != nil { t.Fatalf("%s: %T %T Unable to read message begin: %s", messageName, p, trans, err1.Error()) } if name != messageName { t.Errorf("%s: %T %T Expected message named \"%s\", but was: \"%s\"", messageName, p, trans, messageName, name) } if ttype != CALL { t.Errorf("%s: %T %T Expected message type \"%s\", but was: \"%s\"", messageName, p, trans, CALL, ttype) } if seqid != seqId { t.Errorf("%s: %T %T Expected message type \"%s\", but was: \"%s\"", messageName, p, trans, seqId, seqid) } calcArgs := NewCalculateArgs() err2 := calcArgs.Read(p) if !args31.Equals(calcArgs) { //cmp1, _ := args31.W.CompareTo(calcArgs.W) cmp2, ok := args31.CompareTo(calcArgs) t.Errorf("%s: %T %T Calculate args not as expected, %T vs %T, cmp: %#v, ok: %#v, equals: %#v", messageName, p, trans, args31, calcArgs, cmp2, ok, args31.Equals(calcArgs)) } if err2 != nil { t.Fatalf("%s: %T %T Unable to read message end: %s", messageName, p, trans, err2.Error()) } err3 := p.ReadMessageEnd() if err3 != nil { t.Fatalf("%s: %T %T Unable to read message end: %s", messageName, p, trans, err3.Error()) } } /** *You can define enums, which are just 32 bit integers. Values are optional *and start at 1 if not supplied, C style again. */ type Operation int const ( ADD Operation = 1 SUBTRACT Operation = 2 MULTIPLY Operation = 3 DIVIDE Operation = 4 ) func (p Operation) String() string { switch p { case ADD: return "ADD" case SUBTRACT: return "SUBTRACT" case MULTIPLY: return "MULTIPLY" case DIVIDE: return "DIVIDE" } return "" } func FromOperationString(s string) Operation { switch s { case "ADD": return ADD case "SUBTRACT": return SUBTRACT case "MULTIPLY": return MULTIPLY case "DIVIDE": return DIVIDE } return Operation(-10000) } func (p Operation) Value() int { return int(p) } func (p Operation) IsEnum() bool { return true } /** *Thrift lets you do typedefs to get pretty names for your types. Standard *C style here. */ type MyInteger int32 const INT32CONSTANT = 9853 var MAPCONSTANT TMap /** * Structs are the basic complex data structures. They are comprised of fields * which each have an integer identifier, a type, a symbolic name, and an * optional default value. * * Fields can be declared "optional", which ensures they will not be included * in the serialized output if they aren't set. Note that this requires some * manual management in some languages. * * Attributes: * - Num1 * - Num2 * - Op * - Comment */ type Work struct { TStruct _ interface{} "num1" // nil # 0 Num1 int32 "num1" // 1 Num2 int32 "num2" // 2 Op Operation "op" // 3 Comment string "comment" // 4 } func NewWork() *Work { output := &Work{ TStruct: NewTStruct("Work", []TField{ NewTField("num1", I32, 1), NewTField("num2", I32, 2), NewTField("op", I32, 3), NewTField("comment", STRING, 4), }), } { output.Num1 = 0 } return output } func (p *Work) Read(iprot TProtocol) (err TProtocolException) { _, err = iprot.ReadStructBegin() if err != nil { return NewTProtocolExceptionReadStruct(p.ThriftName(), err) } for { fieldName, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() if fieldId < 0 { fieldId = int16(p.FieldIdFromFieldName(fieldName)) } else if fieldName == "" { fieldName = p.FieldNameFromFieldId(int(fieldId)) } if fieldTypeId == GENERIC { fieldTypeId = p.FieldFromFieldId(int(fieldId)).TypeId() } if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } if fieldTypeId == STOP { break } if fieldId == 1 || fieldName == "num1" { if fieldTypeId == I32 { err = p.ReadField1(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else if fieldTypeId == VOID { err = iprot.Skip(fieldTypeId) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else { err = p.ReadField1(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } } else if fieldId == 2 || fieldName == "num2" { if fieldTypeId == I32 { err = p.ReadField2(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else if fieldTypeId == VOID { err = iprot.Skip(fieldTypeId) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else { err = p.ReadField2(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } } else if fieldId == 3 || fieldName == "op" { if fieldTypeId == I32 { err = p.ReadField3(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else if fieldTypeId == VOID { err = iprot.Skip(fieldTypeId) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else { err = p.ReadField3(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } } else if fieldId == 4 || fieldName == "comment" { if fieldTypeId == STRING { err = p.ReadField4(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else if fieldTypeId == VOID { err = iprot.Skip(fieldTypeId) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else { err = p.ReadField4(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } } else { err = iprot.Skip(fieldTypeId) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } err = iprot.ReadFieldEnd() if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } err = iprot.ReadStructEnd() if err != nil { return NewTProtocolExceptionReadStruct(p.ThriftName(), err) } return err } func (p *Work) ReadField1(iprot TProtocol) (err TProtocolException) { v4, err5 := iprot.ReadI32() if err5 != nil { return NewTProtocolExceptionReadField(1, "num1", p.ThriftName(), err5) } p.Num1 = v4 return err } func (p *Work) ReadFieldNum1(iprot TProtocol) TProtocolException { return p.ReadField1(iprot) } func (p *Work) ReadField2(iprot TProtocol) (err TProtocolException) { v6, err7 := iprot.ReadI32() if err7 != nil { return NewTProtocolExceptionReadField(2, "num2", p.ThriftName(), err7) } p.Num2 = v6 return err } func (p *Work) ReadFieldNum2(iprot TProtocol) TProtocolException { return p.ReadField2(iprot) } func (p *Work) ReadField3(iprot TProtocol) (err TProtocolException) { v8, err9 := iprot.ReadI32() if err9 != nil { return NewTProtocolExceptionReadField(3, "op", p.ThriftName(), err9) } p.Op = Operation(v8) return err } func (p *Work) ReadFieldOp(iprot TProtocol) TProtocolException { return p.ReadField3(iprot) } func (p *Work) ReadField4(iprot TProtocol) (err TProtocolException) { v10, err11 := iprot.ReadString() if err11 != nil { return NewTProtocolExceptionReadField(4, "comment", p.ThriftName(), err11) } p.Comment = v10 return err } func (p *Work) ReadFieldComment(iprot TProtocol) TProtocolException { return p.ReadField4(iprot) } func (p *Work) Write(oprot TProtocol) (err TProtocolException) { err = oprot.WriteStructBegin("Work") if err != nil { return NewTProtocolExceptionWriteStruct(p.ThriftName(), err) } err = p.WriteField1(oprot) if err != nil { return err } err = p.WriteField2(oprot) if err != nil { return err } err = p.WriteField3(oprot) if err != nil { return err } err = p.WriteField4(oprot) if err != nil { return err } err = oprot.WriteFieldStop() if err != nil { return NewTProtocolExceptionWriteField(-1, "STOP", p.ThriftName(), err) } err = oprot.WriteStructEnd() if err != nil { return NewTProtocolExceptionWriteStruct(p.ThriftName(), err) } return err } func (p *Work) WriteField1(oprot TProtocol) (err TProtocolException) { err = oprot.WriteFieldBegin("num1", I32, 1) if err != nil { return NewTProtocolExceptionWriteField(1, "num1", p.ThriftName(), err) } err = oprot.WriteI32(int32(p.Num1)) if err != nil { return NewTProtocolExceptionWriteField(1, "num1", p.ThriftName(), err) } err = oprot.WriteFieldEnd() if err != nil { return NewTProtocolExceptionWriteField(1, "num1", p.ThriftName(), err) } return err } func (p *Work) WriteFieldNum1(oprot TProtocol) TProtocolException { return p.WriteField1(oprot) } func (p *Work) WriteField2(oprot TProtocol) (err TProtocolException) { err = oprot.WriteFieldBegin("num2", I32, 2) if err != nil { return NewTProtocolExceptionWriteField(2, "num2", p.ThriftName(), err) } err = oprot.WriteI32(int32(p.Num2)) if err != nil { return NewTProtocolExceptionWriteField(2, "num2", p.ThriftName(), err) } err = oprot.WriteFieldEnd() if err != nil { return NewTProtocolExceptionWriteField(2, "num2", p.ThriftName(), err) } return err } func (p *Work) WriteFieldNum2(oprot TProtocol) TProtocolException { return p.WriteField2(oprot) } func (p *Work) WriteField3(oprot TProtocol) (err TProtocolException) { err = oprot.WriteFieldBegin("op", I32, 3) if err != nil { return NewTProtocolExceptionWriteField(3, "op", p.ThriftName(), err) } err = oprot.WriteI32(int32(p.Op)) if err != nil { return NewTProtocolExceptionWriteField(3, "op", p.ThriftName(), err) } err = oprot.WriteFieldEnd() if err != nil { return NewTProtocolExceptionWriteField(3, "op", p.ThriftName(), err) } return err } func (p *Work) WriteFieldOp(oprot TProtocol) TProtocolException { return p.WriteField3(oprot) } func (p *Work) WriteField4(oprot TProtocol) (err TProtocolException) { err = oprot.WriteFieldBegin("comment", STRING, 4) if err != nil { return NewTProtocolExceptionWriteField(4, "comment", p.ThriftName(), err) } err = oprot.WriteString(string(p.Comment)) if err != nil { return NewTProtocolExceptionWriteField(4, "comment", p.ThriftName(), err) } err = oprot.WriteFieldEnd() if err != nil { return NewTProtocolExceptionWriteField(4, "comment", p.ThriftName(), err) } return err } func (p *Work) WriteFieldComment(oprot TProtocol) TProtocolException { return p.WriteField4(oprot) } func (p *Work) TStructName() string { return "Work" } func (p *Work) ThriftName() string { return "Work" } func (p *Work) String() string { if p == nil { return "" } return fmt.Sprintf("Work(%+v)", *p) } func (p *Work) CompareTo(other interface{}) (int, bool) { if other == nil { return 1, true } data, ok := other.(*Work) if !ok { return 0, false } if p.Num1 != data.Num1 { if p.Num1 < data.Num1 { return -1, true } return 1, true } if p.Num2 != data.Num2 { if p.Num2 < data.Num2 { return -1, true } return 1, true } if p.Op != data.Op { if p.Op < data.Op { return -1, true } return 1, true } if p.Comment != data.Comment { if p.Comment < data.Comment { return -1, true } return 1, true } return 0, true } func (p *Work) AttributeByFieldId(id int) interface{} { switch id { default: return nil case 1: return p.Num1 case 2: return p.Num2 case 3: return p.Op case 4: return p.Comment } return nil } func (p *Work) TStructFields() TFieldContainer { return NewTFieldContainer([]TField{ NewTField("num1", I32, 1), NewTField("num2", I32, 2), NewTField("op", I32, 3), NewTField("comment", STRING, 4), }) } type ICalculator interface { /** * Parameters: * - Key */ Calculate(logid int32, w *Work) (retval30 int32, ouch *InvalidOperation, err error) } type CalculatorClient struct { Transport TTransport ProtocolFactory TProtocolFactory InputProtocol TProtocol OutputProtocol TProtocol SeqId int32 } func NewCalculatorClientFactory(t TTransport, f TProtocolFactory) *CalculatorClient { return &CalculatorClient{Transport: t, ProtocolFactory: f, InputProtocol: f.GetProtocol(t), OutputProtocol: f.GetProtocol(t), SeqId: 0, } } func NewCalculatorClientProtocol(t TTransport, iprot TProtocol, oprot TProtocol) *CalculatorClient { return &CalculatorClient{Transport: t, ProtocolFactory: nil, InputProtocol: iprot, OutputProtocol: oprot, SeqId: 0, } } /** * Parameters: * - Logid * - W */ func (p *CalculatorClient) Calculate(logid int32, w *Work) (retval30 int32, ouch *InvalidOperation, err error) { err = p.SendCalculate(logid, w) if err != nil { return } return p.RecvCalculate() } func (p *CalculatorClient) SendCalculate(logid int32, w *Work) (err error) { oprot := p.OutputProtocol if oprot != nil { oprot = p.ProtocolFactory.GetProtocol(p.Transport) p.OutputProtocol = oprot } oprot.WriteMessageBegin("calculate", CALL, p.SeqId) args31 := NewCalculateArgs() args31.Logid = logid args31.W = w err = args31.Write(oprot) oprot.WriteMessageEnd() oprot.Transport().Flush() return } func (p *CalculatorClient) RecvCalculate() (value int32, ouch *InvalidOperation, err error) { iprot := p.InputProtocol if iprot == nil { iprot = p.ProtocolFactory.GetProtocol(p.Transport) p.InputProtocol = iprot } _, mTypeId, _, er := iprot.ReadMessageBegin() if er != nil { err = er return } if mTypeId == EXCEPTION { error33 := NewTApplicationExceptionDefault() error34, er := error33.Read(iprot) if er != nil { err = er return } if err = iprot.ReadMessageEnd(); err != nil { return } err = error34 return } result32 := NewCalculateResult() err = result32.Read(iprot) iprot.ReadMessageEnd() value = result32.Success if result32.Ouch != nil { ouch = result32.Ouch } return } /** * Attributes: * - Logid * - W */ type CalculateArgs struct { TStruct _ interface{} "logid" // nil # 0 Logid int32 "logid" // 1 W *Work "w" // 2 } func NewCalculateArgs() *CalculateArgs { output := &CalculateArgs{ TStruct: NewTStruct("calculate_args", []TField{ NewTField("logid", I32, 1), NewTField("w", STRUCT, 2), }), } { } return output } func (p *CalculateArgs) Read(iprot TProtocol) (err TProtocolException) { _, err = iprot.ReadStructBegin() if err != nil { return NewTProtocolExceptionReadStruct(p.ThriftName(), err) } for { fieldName, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() if fieldId < 0 { fieldId = int16(p.FieldIdFromFieldName(fieldName)) } else if fieldName == "" { fieldName = p.FieldNameFromFieldId(int(fieldId)) } if fieldTypeId == GENERIC { fieldTypeId = p.FieldFromFieldId(int(fieldId)).TypeId() } if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } if fieldTypeId == STOP { break } if fieldId == 1 || fieldName == "logid" { if fieldTypeId == I32 { err = p.ReadField1(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else if fieldTypeId == VOID { err = iprot.Skip(fieldTypeId) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else { err = p.ReadField1(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } } else if fieldId == 2 || fieldName == "w" { if fieldTypeId == STRUCT { err = p.ReadField2(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else if fieldTypeId == VOID { err = iprot.Skip(fieldTypeId) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else { err = p.ReadField2(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } } else { err = iprot.Skip(fieldTypeId) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } err = iprot.ReadFieldEnd() if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } err = iprot.ReadStructEnd() if err != nil { return NewTProtocolExceptionReadStruct(p.ThriftName(), err) } return err } func (p *CalculateArgs) ReadField1(iprot TProtocol) (err TProtocolException) { v47, err48 := iprot.ReadI32() if err48 != nil { return NewTProtocolExceptionReadField(1, "logid", p.ThriftName(), err48) } p.Logid = v47 return err } func (p *CalculateArgs) ReadFieldLogid(iprot TProtocol) TProtocolException { return p.ReadField1(iprot) } func (p *CalculateArgs) ReadField2(iprot TProtocol) (err TProtocolException) { p.W = NewWork() err51 := p.W.Read(iprot) if err51 != nil { return NewTProtocolExceptionReadStruct("p.WWork", err51) } return err } func (p *CalculateArgs) ReadFieldW(iprot TProtocol) TProtocolException { return p.ReadField2(iprot) } func (p *CalculateArgs) Write(oprot TProtocol) (err TProtocolException) { err = oprot.WriteStructBegin("calculate_args") if err != nil { return NewTProtocolExceptionWriteStruct(p.ThriftName(), err) } err = p.WriteField1(oprot) if err != nil { return err } err = p.WriteField2(oprot) if err != nil { return err } err = oprot.WriteFieldStop() if err != nil { return NewTProtocolExceptionWriteField(-1, "STOP", p.ThriftName(), err) } err = oprot.WriteStructEnd() if err != nil { return NewTProtocolExceptionWriteStruct(p.ThriftName(), err) } return err } func (p *CalculateArgs) WriteField1(oprot TProtocol) (err TProtocolException) { err = oprot.WriteFieldBegin("logid", I32, 1) if err != nil { return NewTProtocolExceptionWriteField(1, "logid", p.ThriftName(), err) } err = oprot.WriteI32(int32(p.Logid)) if err != nil { return NewTProtocolExceptionWriteField(1, "logid", p.ThriftName(), err) } err = oprot.WriteFieldEnd() if err != nil { return NewTProtocolExceptionWriteField(1, "logid", p.ThriftName(), err) } return err } func (p *CalculateArgs) WriteFieldLogid(oprot TProtocol) TProtocolException { return p.WriteField1(oprot) } func (p *CalculateArgs) WriteField2(oprot TProtocol) (err TProtocolException) { if p.W != nil { err = oprot.WriteFieldBegin("w", STRUCT, 2) if err != nil { return NewTProtocolExceptionWriteField(2, "w", p.ThriftName(), err) } err = p.W.Write(oprot) if err != nil { return NewTProtocolExceptionWriteStruct("Work", err) } err = oprot.WriteFieldEnd() if err != nil { return NewTProtocolExceptionWriteField(2, "w", p.ThriftName(), err) } } return err } func (p *CalculateArgs) WriteFieldW(oprot TProtocol) TProtocolException { return p.WriteField2(oprot) } func (p *CalculateArgs) TStructName() string { return "CalculateArgs" } func (p *CalculateArgs) ThriftName() string { return "calculate_args" } func (p *CalculateArgs) String() string { if p == nil { return "" } return fmt.Sprintf("CalculateArgs(%+v)", *p) } func (p *CalculateArgs) CompareTo(other interface{}) (int, bool) { if other == nil { return 1, true } data, ok := other.(*CalculateArgs) if !ok { return 0, false } if p.Logid != data.Logid { if p.Logid < data.Logid { return -1, true } return 1, true } if cmp, ok := p.W.CompareTo(data.W); !ok || cmp != 0 { return cmp, ok } return 0, true } func (p *CalculateArgs) AttributeByFieldId(id int) interface{} { switch id { default: return nil case 1: return p.Logid case 2: return p.W } return nil } func (p *CalculateArgs) TStructFields() TFieldContainer { return NewTFieldContainer([]TField{ NewTField("logid", I32, 1), NewTField("w", STRUCT, 2), }) } /** * Attributes: * - Success * - Ouch */ type CalculateResult struct { TStruct Success int32 "success" // 0 Ouch *InvalidOperation "ouch" // 1 } func NewCalculateResult() *CalculateResult { output := &CalculateResult{ TStruct: NewTStruct("calculate_result", []TField{ NewTField("success", I32, 0), NewTField("ouch", STRUCT, 1), }), } { } return output } func (p *CalculateResult) Read(iprot TProtocol) (err TProtocolException) { _, err = iprot.ReadStructBegin() if err != nil { return NewTProtocolExceptionReadStruct(p.ThriftName(), err) } for { fieldName, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() if fieldId < 0 { fieldId = int16(p.FieldIdFromFieldName(fieldName)) } else if fieldName == "" { fieldName = p.FieldNameFromFieldId(int(fieldId)) } if fieldTypeId == GENERIC { fieldTypeId = p.FieldFromFieldId(int(fieldId)).TypeId() } if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } if fieldTypeId == STOP { break } if fieldId == 0 || fieldName == "success" { if fieldTypeId == I32 { err = p.ReadField0(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else if fieldTypeId == VOID { err = iprot.Skip(fieldTypeId) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else { err = p.ReadField0(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } } else if fieldId == 1 || fieldName == "ouch" { if fieldTypeId == STRUCT { err = p.ReadField1(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else if fieldTypeId == VOID { err = iprot.Skip(fieldTypeId) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else { err = p.ReadField1(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } } else { err = iprot.Skip(fieldTypeId) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } err = iprot.ReadFieldEnd() if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } err = iprot.ReadStructEnd() if err != nil { return NewTProtocolExceptionReadStruct(p.ThriftName(), err) } return err } func (p *CalculateResult) ReadField0(iprot TProtocol) (err TProtocolException) { v52, err53 := iprot.ReadI32() if err53 != nil { return NewTProtocolExceptionReadField(0, "success", p.ThriftName(), err53) } p.Success = v52 return err } func (p *CalculateResult) ReadFieldSuccess(iprot TProtocol) TProtocolException { return p.ReadField0(iprot) } func (p *CalculateResult) ReadField1(iprot TProtocol) (err TProtocolException) { p.Ouch = NewInvalidOperation() err56 := p.Ouch.Read(iprot) if err56 != nil { return NewTProtocolExceptionReadStruct("p.OuchInvalidOperation", err56) } return err } func (p *CalculateResult) ReadFieldOuch(iprot TProtocol) TProtocolException { return p.ReadField1(iprot) } func (p *CalculateResult) Write(oprot TProtocol) (err TProtocolException) { err = oprot.WriteStructBegin("calculate_result") if err != nil { return NewTProtocolExceptionWriteStruct(p.ThriftName(), err) } err = p.WriteField0(oprot) if err != nil { return err } err = p.WriteField1(oprot) if err != nil { return err } err = oprot.WriteFieldStop() if err != nil { return NewTProtocolExceptionWriteField(-1, "STOP", p.ThriftName(), err) } err = oprot.WriteStructEnd() if err != nil { return NewTProtocolExceptionWriteStruct(p.ThriftName(), err) } return err } func (p *CalculateResult) WriteField0(oprot TProtocol) (err TProtocolException) { err = oprot.WriteFieldBegin("success", I32, 0) if err != nil { return NewTProtocolExceptionWriteField(0, "success", p.ThriftName(), err) } err = oprot.WriteI32(int32(p.Success)) if err != nil { return NewTProtocolExceptionWriteField(0, "success", p.ThriftName(), err) } err = oprot.WriteFieldEnd() if err != nil { return NewTProtocolExceptionWriteField(0, "success", p.ThriftName(), err) } return err } func (p *CalculateResult) WriteFieldSuccess(oprot TProtocol) TProtocolException { return p.WriteField0(oprot) } func (p *CalculateResult) WriteField1(oprot TProtocol) (err TProtocolException) { if p.Ouch != nil { err = oprot.WriteFieldBegin("ouch", STRUCT, 1) if err != nil { return NewTProtocolExceptionWriteField(1, "ouch", p.ThriftName(), err) } err = p.Ouch.Write(oprot) if err != nil { return NewTProtocolExceptionWriteStruct("InvalidOperation", err) } err = oprot.WriteFieldEnd() if err != nil { return NewTProtocolExceptionWriteField(1, "ouch", p.ThriftName(), err) } } return err } func (p *CalculateResult) WriteFieldOuch(oprot TProtocol) TProtocolException { return p.WriteField1(oprot) } func (p *CalculateResult) TStructName() string { return "CalculateResult" } func (p *CalculateResult) ThriftName() string { return "calculate_result" } func (p *CalculateResult) String() string { if p == nil { return "" } return fmt.Sprintf("CalculateResult(%+v)", *p) } func (p *CalculateResult) CompareTo(other interface{}) (int, bool) { if other == nil { return 1, true } data, ok := other.(*CalculateResult) if !ok { return 0, false } if p.Success != data.Success { if p.Success < data.Success { return -1, true } return 1, true } if cmp, ok := p.Ouch.CompareTo(data.Ouch); !ok || cmp != 0 { return cmp, ok } return 0, true } func (p *CalculateResult) AttributeByFieldId(id int) interface{} { switch id { default: return nil case 0: return p.Success case 1: return p.Ouch } return nil } func (p *CalculateResult) TStructFields() TFieldContainer { return NewTFieldContainer([]TField{ NewTField("success", I32, 0), NewTField("ouch", STRUCT, 1), }) } /** * Structs can also be exceptions, if they are nasty. * * Attributes: * - What * - Why */ type InvalidOperation struct { TStruct _ interface{} "what" // nil # 0 What int32 "what" // 1 Why string "why" // 2 } func NewInvalidOperation() *InvalidOperation { output := &InvalidOperation{ TStruct: NewTStruct("InvalidOperation", []TField{ NewTField("what", I32, 1), NewTField("why", STRING, 2), }), } { } return output } func (p *InvalidOperation) Read(iprot TProtocol) (err TProtocolException) { _, err = iprot.ReadStructBegin() if err != nil { return NewTProtocolExceptionReadStruct(p.ThriftName(), err) } for { fieldName, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() if fieldId < 0 { fieldId = int16(p.FieldIdFromFieldName(fieldName)) } else if fieldName == "" { fieldName = p.FieldNameFromFieldId(int(fieldId)) } if fieldTypeId == GENERIC { fieldTypeId = p.FieldFromFieldId(int(fieldId)).TypeId() } if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } if fieldTypeId == STOP { break } if fieldId == 1 || fieldName == "what" { if fieldTypeId == I32 { err = p.ReadField1(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else if fieldTypeId == VOID { err = iprot.Skip(fieldTypeId) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else { err = p.ReadField1(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } } else if fieldId == 2 || fieldName == "why" { if fieldTypeId == STRING { err = p.ReadField2(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else if fieldTypeId == VOID { err = iprot.Skip(fieldTypeId) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } else { err = p.ReadField2(iprot) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } } else { err = iprot.Skip(fieldTypeId) if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } err = iprot.ReadFieldEnd() if err != nil { return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err) } } err = iprot.ReadStructEnd() if err != nil { return NewTProtocolExceptionReadStruct(p.ThriftName(), err) } return err } func (p *InvalidOperation) ReadField1(iprot TProtocol) (err TProtocolException) { v12, err13 := iprot.ReadI32() if err13 != nil { return NewTProtocolExceptionReadField(1, "what", p.ThriftName(), err13) } p.What = v12 return err } func (p *InvalidOperation) ReadFieldWhat(iprot TProtocol) TProtocolException { return p.ReadField1(iprot) } func (p *InvalidOperation) ReadField2(iprot TProtocol) (err TProtocolException) { v14, err15 := iprot.ReadString() if err15 != nil { return NewTProtocolExceptionReadField(2, "why", p.ThriftName(), err15) } p.Why = v14 return err } func (p *InvalidOperation) ReadFieldWhy(iprot TProtocol) TProtocolException { return p.ReadField2(iprot) } func (p *InvalidOperation) Write(oprot TProtocol) (err TProtocolException) { err = oprot.WriteStructBegin("InvalidOperation") if err != nil { return NewTProtocolExceptionWriteStruct(p.ThriftName(), err) } err = p.WriteField1(oprot) if err != nil { return err } err = p.WriteField2(oprot) if err != nil { return err } err = oprot.WriteFieldStop() if err != nil { return NewTProtocolExceptionWriteField(-1, "STOP", p.ThriftName(), err) } err = oprot.WriteStructEnd() if err != nil { return NewTProtocolExceptionWriteStruct(p.ThriftName(), err) } return err } func (p *InvalidOperation) WriteField1(oprot TProtocol) (err TProtocolException) { err = oprot.WriteFieldBegin("what", I32, 1) if err != nil { return NewTProtocolExceptionWriteField(1, "what", p.ThriftName(), err) } err = oprot.WriteI32(int32(p.What)) if err != nil { return NewTProtocolExceptionWriteField(1, "what", p.ThriftName(), err) } err = oprot.WriteFieldEnd() if err != nil { return NewTProtocolExceptionWriteField(1, "what", p.ThriftName(), err) } return err } func (p *InvalidOperation) WriteFieldWhat(oprot TProtocol) TProtocolException { return p.WriteField1(oprot) } func (p *InvalidOperation) WriteField2(oprot TProtocol) (err TProtocolException) { err = oprot.WriteFieldBegin("why", STRING, 2) if err != nil { return NewTProtocolExceptionWriteField(2, "why", p.ThriftName(), err) } err = oprot.WriteString(string(p.Why)) if err != nil { return NewTProtocolExceptionWriteField(2, "why", p.ThriftName(), err) } err = oprot.WriteFieldEnd() if err != nil { return NewTProtocolExceptionWriteField(2, "why", p.ThriftName(), err) } return err } func (p *InvalidOperation) WriteFieldWhy(oprot TProtocol) TProtocolException { return p.WriteField2(oprot) } func (p *InvalidOperation) TStructName() string { return "InvalidOperation" } func (p *InvalidOperation) ThriftName() string { return "InvalidOperation" } func (p *InvalidOperation) String() string { if p == nil { return "" } return fmt.Sprintf("InvalidOperation(%+v)", *p) } func (p *InvalidOperation) CompareTo(other interface{}) (int, bool) { if other == nil { return 1, true } data, ok := other.(*InvalidOperation) if !ok { return 0, false } if p.What != data.What { if p.What < data.What { return -1, true } return 1, true } if p.Why != data.Why { if p.Why < data.Why { return -1, true } return 1, true } return 0, true } func (p *InvalidOperation) AttributeByFieldId(id int) interface{} { switch id { default: return nil case 1: return p.What case 2: return p.Why } return nil } func (p *InvalidOperation) TStructFields() TFieldContainer { return NewTFieldContainer([]TField{ NewTField("what", I32, 1), NewTField("why", STRING, 2), }) } golang-thrift-0.0~git20121118/tserver.go000066400000000000000000000030221222677523400176700ustar00rootroot00000000000000/* * 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 () type TServer interface { /** * Core processor */ ProcessorFactory() TProcessorFactory /** * Server transport */ ServerTransport() TServerTransport /** * Input Transport Factory */ InputTransportFactory() TTransportFactory /** * Output Transport Factory */ OutputTransportFactory() TTransportFactory /** * Input Protocol Factory */ InputProtocolFactory() TProtocolFactory /** * Output Protocol Factory */ OutputProtocolFactory() TProtocolFactory /** * The run method fires up the server and gets things going. */ Serve() error /** * Stop the server. This is optional on a per-implementation basis. Not * all servers are required to be cleanly stoppable. */ Stop() error } golang-thrift-0.0~git20121118/tserver_socket.go000066400000000000000000000114241222677523400212450ustar00rootroot00000000000000/* * 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" ) type TServerSocket struct { /** * Underlying socket conection object */ conn net.Conn /** * Underlying socket conection object */ listener net.Listener /** * Address to listen on */ addr net.Addr /** * Client timeout in nanoseconds */ nsecClientTimeout int64 } type TServerSocketTransportFactory struct { addr net.Addr nsecClientTimeout int64 } func (p *TServerSocketTransportFactory) GetTransport(trans TTransport) TTransport { if trans != nil { t, ok := trans.(*TServerSocket) if ok && t.addr != nil { s, _ := NewTServerSocketAddrTimeout(t.addr, t.nsecClientTimeout) return s } } s, _ := NewTServerSocketAddrTimeout(p.addr, p.nsecClientTimeout) return s } func NewTServerSocketTransportFactory(addr net.Addr, nsecClientTimeout int64) *TServerSocketTransportFactory { return &TServerSocketTransportFactory{addr: addr, nsecClientTimeout: nsecClientTimeout} } func NewTServerSocketConn(conn net.Conn) *TServerSocket { return NewTServerSocketConnTimeout(conn, 0) } func NewTServerSocketConnTimeout(conn net.Conn, nsecClientTimeout int64) *TServerSocket { v := &TServerSocket{conn: conn, addr: conn.LocalAddr(), nsecClientTimeout: nsecClientTimeout} return v } func NewTServerSocketAddr(addr net.Addr) (*TServerSocket, TTransportException) { return NewTServerSocketAddrTimeout(addr, 0) } func NewTServerSocketAddrTimeout(addr net.Addr, nsecClientTimeout int64) (*TServerSocket, TTransportException) { s := &TServerSocket{addr: addr, nsecClientTimeout: nsecClientTimeout} return s, nil } func (p *TServerSocket) Listen() (err error) { if p.listener == nil { if p.listener, err = net.Listen("tcp", p.addr.String()); err != nil { return err } } return nil } func (p *TServerSocket) Accept() (TTransport, error) { if p.listener == nil { if err := p.Listen(); err != nil { return nil, NewTTransportExceptionFromOsError(err) } if p.listener == nil { return nil, NewTTransportException(NOT_OPEN, "No underlying server socket") } } conn, err := p.listener.Accept() if err != nil { return nil, NewTTransportExceptionFromOsError(err) } return NewTSocketConnTimeout(conn, p.nsecClientTimeout) } /** * Checks whether the socket is connected. */ func (p *TServerSocket) IsOpen() bool { return p.listener != nil } /** * Connects the socket, creating a new socket object if necessary. */ func (p *TServerSocket) Open() error { if !p.IsOpen() { l, err := net.Listen(p.addr.Network(), p.addr.String()) if err != nil { return err } p.listener = l return nil } return NewTTransportException(ALREADY_OPEN, "Server socket already open") } /** * Perform a nonblocking read into buffer. */ func (p *TServerSocket) Read(buf []byte) (int, error) { return 0, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "TServerSocket.Read([]byte) is not implemented") } func (p *TServerSocket) ReadAll(buf []byte) (int, error) { return ReadAllTransport(p, buf) } /** * Perform a nonblocking write of the data in buffer; */ func (p *TServerSocket) Write(buf []byte) (int, error) { return 0, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "TServerSocket.Write([]byte) is not implemented") } /** * Flushes the underlying output stream if not null. */ func (p *TServerSocket) Flush() error { return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "TServerSocket.Flush() is not implemented") } func (p *TServerSocket) Addr() net.Addr { return p.addr } func (p *TServerSocket) Peek() bool { return p.IsOpen() } /** * Closes the socket. */ func (p *TServerSocket) Close() (err error) { if p.IsOpen() { err := p.listener.Close() if err != nil { return NewTTransportExceptionFromOsError(err) } p.listener = nil } if p.conn != nil { err := p.conn.Close() if err != nil { return NewTTransportExceptionFromOsError(err) } p.conn = nil } return nil } func (p *TServerSocket) Interrupt() error { // TODO(pomack) fix Interrupt as it is probably not right return NewTTransportExceptionFromOsError(p.Close()) } golang-thrift-0.0~git20121118/tserver_test.go000066400000000000000000000015601222677523400207340ustar00rootroot00000000000000/* * 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) { } golang-thrift-0.0~git20121118/tserver_transport.go000066400000000000000000000024731222677523400220150ustar00rootroot00000000000000/* * 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 } golang-thrift-0.0~git20121118/tset.go000066400000000000000000000110171222677523400171600ustar00rootroot00000000000000/* * 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" "container/list" ) /** * Helper class that encapsulates set metadata. * * Note that sets of structs requires pointers, not struct values. */ type TSet interface { TContainer ElemType() TType Add(data interface{}) Remove(data interface{}) Less(other interface{}) bool Front() *list.Element Back() *list.Element Values() []interface{} } type tSet struct { elemType TType size int l *list.List } func NewTSet(t TType, s int) TSet { return &tSet{elemType: t, size: s, l: list.New()} } func NewTSetDefault() TSet { return NewTSet(STOP, 0) } func (p *tSet) ElemType() TType { return p.elemType } func (p *tSet) Front() *list.Element { return p.l.Front() } func (p *tSet) Back() *list.Element { return p.l.Back() } func (p *tSet) Len() int { if p.l.Len() != 0 { return p.l.Len() } return p.size } func (p *tSet) Contains(data interface{}) bool { return p.find(data) != nil } func (p *tSet) Add(other interface{}) { if data, ok := p.elemType.CoerceData(other); ok { if p.l.Front() == nil { p.l.PushFront(data) } else { for elem := p.l.Front(); elem != nil; elem = elem.Next() { if cmp, ok := p.elemType.Compare(data, elem.Value); ok && cmp >= 0 { if cmp > 0 { p.l.InsertBefore(data, elem) } return } } } } } func (p *tSet) Remove(data interface{}) { elem := p.find(data) if elem != nil { p.l.Remove(elem) } } func (p *tSet) Less(other interface{}) bool { cmp, ok := p.CompareTo(other) return ok && cmp > 0 } func (p *tSet) Equals(other interface{}) bool { c, cok := p.CompareTo(other) return cok && c == 0 } func (p *tSet) CompareTo(other interface{}) (int, bool) { return TType(SET).Compare(p, other) } func (p *tSet) find(data interface{}) *list.Element { if data == nil { for elem := p.l.Front(); elem != nil; elem = elem.Next() { if elem.Value == nil { return elem } } return nil } data, ok := p.elemType.CoerceData(data) if data == nil || !ok { return nil } if p.elemType == BINARY { for elem := p.l.Front(); elem != nil; elem = elem.Next() { if bytes.Compare(data.([]byte), elem.Value.([]byte)) == 0 { return elem } } return nil } if p.elemType.IsBaseType() || p.elemType.IsEnum() { for elem := p.l.Front(); elem != nil; elem = elem.Next() { if data == elem.Value { return elem } } return nil } if cmp, ok := data.(EqualsOtherInterface); ok { for elem := p.l.Front(); elem != nil; elem = elem.Next() { if cmp.Equals(elem.Value) { return elem } } return nil } switch p.elemType { case MAP: if cmp, ok := data.(EqualsMap); ok { for elem := p.l.Front(); elem != nil; elem = elem.Next() { v := elem.Value if v == nil { continue } if cmp.Equals(v.(TMap)) { return elem } } return nil } case SET: if cmp, ok := data.(EqualsSet); ok { for elem := p.l.Front(); elem != nil; elem = elem.Next() { v := elem.Value if v == nil { continue } if cmp.Equals(v.(TSet)) { return elem } } return nil } case LIST: if cmp, ok := data.(EqualsList); ok { for elem := p.l.Front(); elem != nil; elem = elem.Next() { v := elem.Value if v == nil { continue } if cmp.Equals(v.(TList)) { return elem } } return nil } case STRUCT: if cmp, ok := data.(EqualsStruct); ok { for elem := p.l.Front(); elem != nil; elem = elem.Next() { v := elem.Value if v == nil { continue } if cmp.Equals(v.(TStruct)) { return elem } } return nil } } return nil } func (p *tSet) Values() []interface{} { size := p.l.Len() values := make([]interface{}, size, size) i := 0 for v := p.l.Front(); v != nil; v = v.Next() { values[i] = v.Value i++ } return values } golang-thrift-0.0~git20121118/tsimple_json_protocol.go000066400000000000000000001062631222677523400226400ustar00rootroot00000000000000/* * 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" "encoding/base64" "encoding/json" "fmt" "io" "math" "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 []int /** * Stack of nested contexts that we may be in. */ dumpContext []int /** * 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 = append(v.parseContextStack, int(_CONTEXT_IN_TOPLEVEL)) v.dumpContext = append(v.dumpContext, 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 } 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(io.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[len(p.dumpContext)-1]) 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[len(p.dumpContext)-1]) switch cxt { case _CONTEXT_IN_LIST_FIRST: p.dumpContext = p.dumpContext[:len(p.dumpContext)-1] p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_LIST)) break case _CONTEXT_IN_OBJECT_FIRST: p.dumpContext = p.dumpContext[:len(p.dumpContext)-1] p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_VALUE)) break case _CONTEXT_IN_OBJECT_NEXT_KEY: p.dumpContext = p.dumpContext[:len(p.dumpContext)-1] p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_VALUE)) break case _CONTEXT_IN_OBJECT_NEXT_VALUE: p.dumpContext = p.dumpContext[:len(p.dumpContext)-1] p.dumpContext = append(p.dumpContext, 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[len(p.dumpContext)-1]) { 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.FormatFloat(value, 'g', -1, 64) switch _ParseContext(p.dumpContext[len(p.dumpContext)-1]) { 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.FormatInt(value, 10) switch _ParseContext(p.dumpContext[len(p.dumpContext)-1]) { 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 = append(p.dumpContext, 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 = p.dumpContext[:len(p.dumpContext)-1] 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 = append(p.dumpContext, 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 = p.dumpContext[:len(p.dumpContext)-1] 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[len(p.parseContextStack)-1]) 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[len(p.parseContextStack)-1]) switch cxt { case _CONTEXT_IN_LIST_FIRST: p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1] p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_LIST)) break case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY: p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1] p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_OBJECT_NEXT_VALUE)) break case _CONTEXT_IN_OBJECT_NEXT_VALUE: p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1] p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_OBJECT_NEXT_KEY)) break } return nil } func (p *TSimpleJSONProtocol) readNonSignificantWhitespace() 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 = append(p.parseContextStack, 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[len(p.parseContextStack)-1]) 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 = p.parseContextStack[:len(p.parseContextStack)-1] 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 = append(p.parseContextStack, 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[len(p.parseContextStack)-1]) != _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', rune(JSON_RBRACKET[0]): break } } p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1] 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 == io.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 } golang-thrift-0.0~git20121118/tsimple_json_protocol_test.go000066400000000000000000000527521222677523400237020ustar00rootroot00000000000000/* * 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" "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.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 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.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 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.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 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.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 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.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 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.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 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.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 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.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 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.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 TestReadSimpleJSONProtocolI64(t *testing.T) { thetype := "int64" for _, value := range INT64_VALUES { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(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 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.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 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.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 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.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 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.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 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.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("\"", 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.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 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.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 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.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 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.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) } l := strings.Split(str[1:len(str)-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.Error()) } 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.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() } 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.Error()) } 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.Error()) } if !orig.Equals(read) { t.Fatalf("Original Write != Read: %#v != %#v ", orig, read) } } func TestReadWriteSimpleJSONProtocol(t *testing.T) { ReadWriteProtocolTest(t, NewTSimpleJSONProtocolFactory()) } golang-thrift-0.0~git20121118/tsimple_server.go000066400000000000000000000116431222677523400212510ustar00rootroot00000000000000/* * 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 /** * 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() 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() 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 } } } golang-thrift-0.0~git20121118/tsocket.go000066400000000000000000000127011222677523400176560ustar00rootroot00000000000000/* * 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" "net" "time" ) /** * 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) { return NewTSocketConnTimeout(connection, 0) } /** * 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 NewTSocketConnTimeout(connection net.Conn, nsecTimeout int64) (*TSocket, TTransportException) { address := connection.RemoteAddr() if address == nil { address = connection.LocalAddr() } p := &TSocket{conn: connection, addr: address, nsecTimeout: nsecTimeout, 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) error { p.nsecTimeout = nsecTimeout return nil } func (p *TSocket) pushDeadline(read, write bool) { var t time.Time if p.nsecTimeout > 0 { t = time.Now().Add(time.Duration(p.nsecTimeout)) } if read && write { p.conn.SetDeadline(t) } else if read { p.conn.SetReadDeadline(t) } else if write { p.conn.SetWriteDeadline(t) } } /** * 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() 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 error if p.nsecTimeout > 0 { if p.conn, err = net.DialTimeout(p.addr.Network(), p.addr.String(), time.Duration(p.nsecTimeout)); err != nil { LOGGER.Print("Could not open socket", err.Error()) return NewTTransportException(NOT_OPEN, err.Error()) } } else { if p.conn, err = net.Dial(p.addr.Network(), p.addr.String()); err != nil { LOGGER.Print("Could not open socket", err.Error()) return NewTTransportException(NOT_OPEN, err.Error()) } } return nil } /** * Closes the socket. */ func (p *TSocket) Close() error { // Close the socket if p.conn != nil { err := p.conn.Close() if err != nil { LOGGER.Print("Could not close socket. ", err.Error()) return err } p.conn = nil } return nil } func (p *TSocket) Read(buf []byte) (int, error) { if !p.IsOpen() { return 0, NewTTransportException(NOT_OPEN, "Connection not open") } p.pushDeadline(true, false) n, err := p.conn.Read(buf) return n, NewTTransportExceptionFromOsError(err) } func (p *TSocket) ReadAll(buf []byte) (int, error) { return ReadAllTransport(p, buf) } func (p *TSocket) Write(buf []byte) (int, error) { if !p.IsOpen() { return 0, NewTTransportException(NOT_OPEN, "Connection not open") } p.pushDeadline(false, true) p.writeBuffer.Write(buf) return len(buf), nil } func (p *TSocket) Peek() bool { return p.IsOpen() } func (p *TSocket) Flush() error { if !p.IsOpen() { return NewTTransportException(NOT_OPEN, "Connection not open") } _, err := p.writeBuffer.WriteTo(p.conn) return NewTTransportExceptionFromOsError(err) } func (p *TSocket) Interrupt() error { if !p.IsOpen() { return nil } // TODO(pomack) fix Interrupt as this is probably wrong return p.conn.Close() } golang-thrift-0.0~git20121118/tstruct.go000066400000000000000000000043201222677523400177100ustar00rootroot00000000000000/* * 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("") } golang-thrift-0.0~git20121118/ttransport.go000066400000000000000000000113061222677523400204220ustar00rootroot00000000000000/* * 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 ( "log" "os" "strconv" ) type Flusher interface { Flush() (err 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 error) /** * Closes the transport. */ Close() (err 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 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 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 error) /** * Flush any pending data out of a transport buffer. * * @return TTransportException if there was an error writing out data. */ Flush() (err 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() error { return NewTTransportException(UNKNOWN, "Subclasses must implement TTransportBase.Open()"); } func (p* TTransportBase) Close() error { return NewTTransportException(UNKNOWN, "Subclasses must implement TTransportBase.Close()"); } func (p* TTransportBase) Read(buf []byte) (int, error) { return 0, NewTTransportExceptionDefaultString("Subclasses must implement TTransportBase.Read()"); } func (p* TTransportBase) ReadAll(buf []byte) (n int, err 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, error) { return 0, NewTTransportExceptionDefaultString("Subclasses must implement TTransportBase.Write()"); } func (p* TTransportBase) Flush() 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 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 " + strconv.Itoa(size) + " bytes, but only got " + strconv.Itoa(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) } golang-thrift-0.0~git20121118/ttransport_exception.go000066400000000000000000000040771222677523400225070ustar00rootroot00000000000000/* * 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 ( "io" ) /** * 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) Error() 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 error) TTransportException { if e == nil { return nil } t, ok := e.(TTransportException) if ok { return t } if e == io.EOF { return NewTTransportException(END_OF_FILE, e.Error()) } return NewTTransportExceptionDefaultString(e.Error()) } golang-thrift-0.0~git20121118/ttransport_factory.go000066400000000000000000000027271222677523400221600ustar00rootroot00000000000000/* * 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{} } golang-thrift-0.0~git20121118/ttransport_test.go000066400000000000000000000101511222677523400214560ustar00rootroot00000000000000/* * 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" "strconv" "testing" ) const TRANSPORT_BINARY_DATA_SIZE = 4096 var ( transport_bdata []byte // test data for writing; same as data ) func init() { transport_bdata = make([]byte, TRANSPORT_BINARY_DATA_SIZE) for i := 0; i < TRANSPORT_BINARY_DATA_SIZE; i++ { transport_bdata[i] = byte((i + 'a') % 255) } } func TransportTest(t *testing.T, writeTrans TTransport, readTrans TTransport) { buf := make([]byte, TRANSPORT_BINARY_DATA_SIZE) if !writeTrans.IsOpen() { err := writeTrans.Open() if err != nil { t.Fatalf("Transport %T cannot open write transport: %s", writeTrans, err) } } if !readTrans.IsOpen() { err := readTrans.Open() if err != nil { t.Fatalf("Transport %T cannot open read transport: %s", readTrans, err) } } _, err := writeTrans.Write(transport_bdata) if err != nil { t.Fatalf("Transport %T cannot write binary data of length %d: %s", writeTrans, len(transport_bdata), err) } err = writeTrans.Flush() if err != nil { t.Fatalf("Transport %T cannot flush write of binary data: %s", writeTrans, err) } n, err := readTrans.ReadAll(buf) if err != nil { t.Errorf("Transport %T cannot read binary data of length %d: %s", readTrans, TRANSPORT_BINARY_DATA_SIZE, err) } if n != TRANSPORT_BINARY_DATA_SIZE { t.Errorf("Transport %T read only %d instead of %d bytes of binary data", readTrans, n, TRANSPORT_BINARY_DATA_SIZE) } for k, v := range buf { if v != transport_bdata[k] { t.Fatalf("Transport %T read %d instead of %d for index %d of binary data 2", readTrans, v, transport_bdata[k], k) } } _, err = writeTrans.Write(transport_bdata) if err != nil { t.Fatalf("Transport %T cannot write binary data 2 of length %d: %s", writeTrans, len(transport_bdata), err) } err = writeTrans.Flush() if err != nil { t.Fatalf("Transport %T cannot flush write binary data 2: %s", writeTrans, err) } b := readTrans.Peek() if b != true { t.Errorf("Transport %T returned %s for Peek()", readTrans, b) } buf = make([]byte, TRANSPORT_BINARY_DATA_SIZE) read := 1 for n = 0; n < TRANSPORT_BINARY_DATA_SIZE && read != 0; { read, err = readTrans.Read(buf[n:]) if err != nil { t.Errorf("Transport %T cannot read binary data 2 of total length %d from offset %d: %s", readTrans, TRANSPORT_BINARY_DATA_SIZE, n, err) } n += read } if n != TRANSPORT_BINARY_DATA_SIZE { t.Errorf("Transport %T read only %d instead of %d bytes of binary data 2", readTrans, n, TRANSPORT_BINARY_DATA_SIZE) } for k, v := range buf { if v != transport_bdata[k] { t.Fatalf("Transport %T read %d instead of %d for index %d of binary data 2", readTrans, v, transport_bdata[k], k) } } } func CloseTransports(t *testing.T, readTrans TTransport, writeTrans TTransport) { err := readTrans.Close() if err != nil { t.Errorf("Transport %T cannot close read transport: %s", readTrans, err) } if writeTrans != readTrans { err = writeTrans.Close() if err != nil { t.Errorf("Transport %T cannot close write transport: %s", writeTrans, err) } } } func FindAvailableTCPServerPort(startPort int) (net.Addr, error) { for i := startPort; i < 65535; i++ { s := "127.0.0.1:" + strconv.Itoa(i) l, err := net.Listen("tcp", s) if err == nil { l.Close() return net.ResolveTCPAddr("tcp", s) } } return nil, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "Could not find available server port") } golang-thrift-0.0~git20121118/ttype.go000066400000000000000000000511331222677523400173510ustar00rootroot00000000000000/* * 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" "container/list" "strconv" ) /** * Type constants in the Thrift protocol. */ type TType byte const ( STOP = 0 VOID = 1 BOOL = 2 BYTE = 3 I08 = 3 DOUBLE = 4 I16 = 6 I32 = 8 I64 = 10 STRING = 11 UTF7 = 11 STRUCT = 12 MAP = 13 SET = 14 LIST = 15 ENUM = 16 UTF8 = 16 UTF16 = 17 BINARY = 18 GENERIC = 127 ) func (p TType) ThriftTypeId() byte { switch p { default: return byte(p) case BINARY: return byte(STRING) } return byte(0) } func (p TType) String() string { switch p { case STOP: return "STOP" case VOID: return "VOID" case BOOL: return "BOOL" case BYTE: return "BYTE" case DOUBLE: return "DOUBLE" case I16: return "I16" case I32: return "I32" case I64: return "I64" case STRING: return "STRING" case STRUCT: return "STRUCT" case MAP: return "MAP" case SET: return "SET" case LIST: return "LIST" case ENUM: return "ENUM" case UTF16: return "UTF16" case GENERIC: return "GENERIC" case BINARY: return "BINARY" } return "Unknown" } func (p TType) IsBaseType() bool { switch p { case BOOL, BYTE, DOUBLE, I16, I32, I64, STRING, UTF8, UTF16, BINARY: return true default: return false } return false } func (p TType) IsEmptyType() bool { switch p { case STOP, VOID: return true default: return false } return false } func (p TType) IsEnum() bool { switch p { case ENUM: return true default: return false } return false } func (p TType) IsNumericType() bool { switch p { case ENUM, BOOL, BYTE, DOUBLE, I16, I32, I64: return true default: return false } return false } func (p TType) IsStringType() bool { switch p { case STRING, UTF8, UTF16, BINARY: return true default: return false } return false } func (p TType) IsContainer() bool { switch p { case MAP, SET, LIST: return true default: return false } return false } func (p TType) IsStruct() bool { switch p { case STRUCT: return true default: return false } return false } func (p TType) IsMap() bool { switch p { case MAP: return true default: return false } return false } func (p TType) IsList() bool { switch p { case LIST: return true default: return false } return false } func (p TType) IsSet() bool { switch p { case SET: return true default: return false } return false } func (p TType) IsInt() bool { switch p { case BYTE, I16, I32, I64: return true default: return false } return false } func (p TType) Coerce(other interface{}) TType { if other == nil { return TType(STOP) } switch b := other.(type) { default: return TType(STOP) case nil: return TType(STOP) case TType: return b case byte: return TType(b) case int: return TType(byte(b)) case int8: return TType(byte(b)) case int32: return TType(byte(b)) case int64: return TType(byte(b)) case uint: return TType(byte(b)) case uint32: return TType(byte(b)) case uint64: return TType(byte(b)) case float32: return TType(byte(int(b))) case float64: return TType(byte(int(b))) } return TType(STOP) } func (p TType) LessType(other interface{}) bool { return p < p.Coerce(other) } func (p TType) Less(i, j interface{}) bool { cmp, ok := p.Compare(i, j) return ok && cmp > 0 } func (p TType) Compare(i, j interface{}) (int, bool) { if p != BINARY { if i == j { return 0, true } } if i == nil { if j == nil { return 0, true } return -1, true } if j == nil { return 1, true } ci, iok := p.CoerceData(i) cj, jok := p.CoerceData(j) if iok && !jok { return 1, true } if !iok && jok { return -1, true } // hopefully this doesn't happen as Compare() would continuously return 0, false if !iok && !jok { return 0, false } if p != BINARY { if ci == cj { return 0, true } } if ci == nil { if cj == nil { return 0, true } return -1, true } if cj == nil { return 1, true } switch p { case STOP, VOID: // hopefully this doesn't happen as Compare() would continuously return 0, false return 0, false case BOOL: vi, iok := ci.(bool) vj, jok := cj.(bool) if !iok || !jok { return 0, false } if vi == vj { return 0, true } if vi == false { return -1, true } return 1, true case BYTE: vi, iok := ci.(byte) vj, jok := cj.(byte) if !iok || !jok { return 0, false } if vi == vj { return 0, true } if vi < vj { return -1, true } return 1, true case DOUBLE: vi, iok := ci.(float64) vj, jok := cj.(float64) if !iok || !jok { return 0, false } if vi == vj { return 0, true } if vi < vj { return -1, true } return 1, true case I16: vi, iok := ci.(int16) vj, jok := cj.(int16) if !iok || !jok { return 0, false } if vi == vj { return 0, true } if vi < vj { return -1, true } return 1, true case I32: vi, iok := ci.(int32) vj, jok := cj.(int32) if !iok || !jok { return 0, false } if vi == vj { return 0, true } if vi < vj { return -1, true } return 1, true case I64: vi, iok := ci.(int64) vj, jok := cj.(int64) if !iok || !jok { return 0, false } if vi == vj { return 0, true } if vi < vj { return -1, true } return 1, true case STRING, UTF8, UTF16: vi, iok := ci.(string) vj, jok := cj.(string) if !iok || !jok { return 0, false } if vi == vj { return 0, true } if vi < vj { return -1, true } return 1, true case BINARY: vi, iok := ci.([]byte) vj, jok := cj.([]byte) if !iok || !jok { return 0, false } return bytes.Compare(vi, vj), true case STRUCT: si, iok := ci.(TStruct) sj, jok := cj.(TStruct) if !iok || !jok { return 0, false } if cmp := CompareString(si.ThriftName(), sj.ThriftName()); cmp != 0 { return cmp, true } if cmp, ok := si.TStructFields().CompareTo(sj.TStructFields()); !ok || cmp != 0 { return cmp, ok } for field := range si.TStructFields().Iter() { a := si.AttributeFromFieldId(field.Id()) b := sj.AttributeFromFieldId(field.Id()) if cmp, ok := field.TypeId().Compare(a, b); !ok || cmp != 0 { return cmp, ok } } return 0, true case MAP: mi, iok := ci.(TMap) mj, jok := cj.(TMap) if !iok || !jok { return 0, false } ki := mi.KeyType() if kj := mj.KeyType(); ki != kj { return CompareInt(int(ki), int(kj)), true } vi := mi.ValueType() if vj := mj.ValueType(); vi != vj { return CompareInt(int(vi), int(vj)), true } if size := mi.Len(); size != mj.Len() { return CompareInt(size, mj.Len()), true } if c, cok := ki.CompareValueArrays(mi.Keys(), mj.Keys()); c != 0 || !cok { return c, cok } return vi.CompareValueArrays(mi.Values(), mj.Values()) case LIST: li, iok := ci.(TList) lj, jok := cj.(TList) if !iok || !jok { return 0, false } ei := li.ElemType() ej := lj.ElemType() if ei != ej { return CompareInt(int(ei), int(ej)), true } size := li.Len() if size != lj.Len() { return CompareInt(size, lj.Len()), true } for k := 0; k < size; k++ { vi := li.At(k) vj := lj.At(k) c, cok := ei.Compare(vi, vj) if c != 0 || !cok { return c, cok } } return 0, true case SET: li, iok := ci.(TSet) lj, jok := cj.(TSet) if !iok || !jok { return 0, false } ei := li.ElemType() ej := lj.ElemType() if ei != ej { return CompareInt(int(ei), int(ej)), true } size := li.Len() if size != lj.Len() { return CompareInt(size, lj.Len()), true } return ei.CompareValueArrays(li.Values(), lj.Values()) default: panic("Invalid thrift type to coerce") } return 0, false } func (p TType) CompareValueArrays(li, lj []interface{}) (int, bool) { size := len(li) if cmp := CompareInt(size, len(lj)); cmp != 0 { return cmp, true } for i := 0; i < size; i++ { vi := li[i] vj := lj[i] c, cok := p.Compare(vi, vj) if c != 0 || !cok { return c, cok } } return 0, true } func (p TType) Equals(other interface{}) bool { return p == p.Coerce(other) } type Stringer interface { String() string } type Enumer interface { String() string Value() int IsEnum() bool } func TypeFromValue(data interface{}) TType { switch data.(type) { default: return STOP case nil: return VOID case bool: return BOOL case float32, float64: return DOUBLE case int, int32: return I32 case byte: return BYTE case int8: return I08 case int16: return I16 case int64: return I64 case string: return STRING case []byte: return BINARY case TStruct: return STRUCT case TMap: return MAP case TSet: return SET case []interface{}, *list.List, TList: return LIST } return STOP } func (p TType) CoerceData(data interface{}) (interface{}, bool) { if data == nil { switch p { case STOP: return nil, true case VOID: return nil, true case BOOL: return false, true case BYTE: return byte(0), true case DOUBLE: return float64(0), true case I16: return int16(0), true case I32: return int32(0), true case I64: return int64(0), true case STRING, UTF8, UTF16: return "", true case BINARY: return nil, true case STRUCT: return NewTStructEmpty(""), true case MAP: return NewTMapDefault(), true case LIST: return NewTListDefault(), true case SET: return NewTSetDefault(), true default: panic("Invalid thrift type to coerce") } } switch p { case STOP: return nil, true case VOID: return nil, true case BOOL: switch b := data.(type) { default: return false, false case bool: return b, true case Numeric: return bool(b.Int() != 0), true case int: return b != 0, true case byte: return b != 0, true case int8: return b != 0, true case int16: return b != 0, true case int32: return b != 0, true case int64: return b != 0, true case uint: return b != 0, true case uint16: return b != 0, true case uint32: return b != 0, true case uint64: return b != 0, true case float32: return b != 0, true case float64: return b != 0, true case []byte: return len(b) > 1 || (len(b) == 1 && b[0] != 0), true case Stringer: v := b.String() if v == "false" || v == "0" || len(v) == 0 { return false, true } return true, true case string: if b == "false" || b == "0" || len(b) == 0 { return false, true } return true, true } case BYTE: if b, ok := data.(byte); ok { return b, true } if b, ok := data.(Numeric); ok { return b.Byte(), true } if b, ok := data.(bool); ok { if b { return byte(1), true } return byte(0), true } if b, ok := data.(int); ok { return byte(b), true } if b, ok := data.(int8); ok { return byte(b), true } if b, ok := data.(int16); ok { return byte(b), true } if b, ok := data.(int32); ok { return byte(b), true } if b, ok := data.(int64); ok { return byte(b), true } if b, ok := data.(uint); ok { return byte(b), true } if b, ok := data.(uint8); ok { return byte(b), true } if b, ok := data.(uint16); ok { return byte(b), true } if b, ok := data.(uint32); ok { return byte(b), true } if b, ok := data.(uint64); ok { return byte(b), true } if b, ok := data.(float32); ok { return byte(int(b)), true } if b, ok := data.(float64); ok { return byte(int(b)), true } if b, ok := data.([]byte); ok { if len(b) > 0 { return b[0], true } return byte(0), true } if b, ok := data.(Stringer); ok { data = b.String() } if b, ok := data.(string); ok { i1, err := strconv.Atoi(b) if err != nil { return byte(int(i1)), true } } return byte(0), false case DOUBLE: if b, ok := data.(float32); ok { return float64(b), true } if b, ok := data.(float64); ok { return b, true } if b, ok := data.(Numeric); ok { return bool(b.Float64() != 0.0), true } if b, ok := data.(byte); ok { return float64(b), true } if b, ok := data.(bool); ok { if b { return float64(1.0), true } return float64(0.0), true } if b, ok := data.(int); ok { return float64(b), true } if b, ok := data.(int8); ok { return float64(b), true } if b, ok := data.(int16); ok { return float64(b), true } if b, ok := data.(int32); ok { return float64(b), true } if b, ok := data.(int64); ok { return float64(b), true } if b, ok := data.(uint); ok { return float64(b), true } if b, ok := data.(uint8); ok { return float64(b), true } if b, ok := data.(uint16); ok { return float64(b), true } if b, ok := data.(uint32); ok { return float64(b), true } if b, ok := data.(uint64); ok { return float64(b), true } if b, ok := data.([]byte); ok { if len(b) > 0 { return float64(b[0]), true } return float64(0), true } if b, ok := data.(Stringer); ok { data = b.String() } if b, ok := data.(string); ok { d1, err := strconv.ParseFloat(b, 64) if err != nil { return d1, true } } return float64(0), false case I16: if b, ok := data.(int16); ok { return b, true } if b, ok := data.(int); ok { return int16(b), true } if b, ok := data.(Numeric); ok { return bool(b.Int16() != 0), true } if b, ok := data.(byte); ok { return int16(b), true } if b, ok := data.(bool); ok { if b { return int16(1.0), true } return int16(0.0), true } if b, ok := data.(int8); ok { return int16(b), true } if b, ok := data.(int32); ok { return int16(b), true } if b, ok := data.(int64); ok { return int16(b), true } if b, ok := data.(uint); ok { return int16(b), true } if b, ok := data.(uint8); ok { return int16(b), true } if b, ok := data.(uint16); ok { return int16(b), true } if b, ok := data.(uint32); ok { return int16(b), true } if b, ok := data.(uint64); ok { return int16(b), true } if b, ok := data.(float32); ok { return int16(int(b)), true } if b, ok := data.(float64); ok { return int16(int(b)), true } if b, ok := data.(Stringer); ok { data = b.String() } if b, ok := data.(string); ok { i1, err := strconv.Atoi(b) if err != nil { return int16(i1), true } } return int16(0), false case I32: if b, ok := data.(int32); ok { return b, true } if b, ok := data.(int); ok { return int32(b), true } if b, ok := data.(Numeric); ok { return bool(b.Int32() != 0), true } if b, ok := data.(byte); ok { return int32(b), true } if b, ok := data.(bool); ok { if b { return int32(1.0), true } return int32(0.0), true } if b, ok := data.(int8); ok { return int32(b), true } if b, ok := data.(int16); ok { return int32(b), true } if b, ok := data.(int64); ok { return int32(b), true } if b, ok := data.(uint); ok { return int32(b), true } if b, ok := data.(uint8); ok { return int32(b), true } if b, ok := data.(uint16); ok { return int32(b), true } if b, ok := data.(uint32); ok { return int32(b), true } if b, ok := data.(uint64); ok { return int32(b), true } if b, ok := data.(float32); ok { return int32(int(b)), true } if b, ok := data.(float64); ok { return int32(int(b)), true } if b, ok := data.(Stringer); ok { data = b.String() } if b, ok := data.(string); ok { i1, err := strconv.Atoi(b) if err != nil { return int32(i1), true } } return int32(0), false case I64: if b, ok := data.(int64); ok { return b, true } if b, ok := data.(int32); ok { return int64(b), true } if b, ok := data.(int); ok { return int64(b), true } if b, ok := data.(Numeric); ok { return bool(b.Int64() != 0), true } if b, ok := data.(byte); ok { return int64(b), true } if b, ok := data.(bool); ok { if b { return int64(1.0), true } return int64(0.0), true } if b, ok := data.(int8); ok { return int64(b), true } if b, ok := data.(int16); ok { return int64(b), true } if b, ok := data.(uint); ok { return int64(b), true } if b, ok := data.(uint8); ok { return int64(b), true } if b, ok := data.(uint16); ok { return int64(b), true } if b, ok := data.(uint32); ok { return int64(b), true } if b, ok := data.(uint64); ok { return int64(b), true } if b, ok := data.(float32); ok { return int64(b), true } if b, ok := data.(float64); ok { return int64(b), true } if b, ok := data.(Stringer); ok { data = b.String() } if b, ok := data.(string); ok { i1, err := strconv.ParseInt(b, 10, 64) if err != nil { return i1, true } } return int64(0), false case STRING, UTF8, UTF16: if b, ok := data.([]byte); ok { return string(b), true } if b, ok := data.(Enumer); ok { if i1, ok := data.(int); ok { return string(i1), true } return b.String(), true } if b, ok := data.(Stringer); ok { return b.String(), true } if b, ok := data.(string); ok { return b, true } if b, ok := data.(int); ok { return string(b), true } if b, ok := data.(byte); ok { return string(b), true } if b, ok := data.(bool); ok { if b { return "true", true } return "false", true } if b, ok := data.(int8); ok { return string(b), true } if b, ok := data.(int16); ok { return string(b), true } if b, ok := data.(int32); ok { return string(b), true } if b, ok := data.(int64); ok { return string(b), true } if b, ok := data.(uint); ok { return string(b), true } if b, ok := data.(uint8); ok { return string(b), true } if b, ok := data.(uint16); ok { return string(b), true } if b, ok := data.(uint32); ok { return string(b), true } if b, ok := data.(uint64); ok { return string(b), true } if b, ok := data.(float32); ok { return strconv.FormatFloat(float64(b), 'g', -1, 32), true } if b, ok := data.(float64); ok { return strconv.FormatFloat(b, 'g', -1, 64), true } return "", false case BINARY: if b, ok := data.([]byte); ok { return b, true } if b, ok := data.(Enumer); ok { if i1, ok := data.(int); ok { return []byte(string(i1)), true } return []byte(b.String()), true } if b, ok := data.(Stringer); ok { return []byte(b.String()), true } if b, ok := data.(string); ok { return []byte(b), true } if b, ok := data.(int); ok { return []byte(string(b)), true } if b, ok := data.(byte); ok { return []byte(string(b)), true } if b, ok := data.(bool); ok { if b { return []byte("true"), true } return []byte("false"), true } if b, ok := data.(int8); ok { return []byte(string(b)), true } if b, ok := data.(int16); ok { return []byte(string(b)), true } if b, ok := data.(int32); ok { return []byte(string(b)), true } if b, ok := data.(int64); ok { return []byte(string(b)), true } if b, ok := data.(uint); ok { return []byte(string(b)), true } if b, ok := data.(uint8); ok { return []byte(string(b)), true } if b, ok := data.(uint16); ok { return []byte(string(b)), true } if b, ok := data.(uint32); ok { return []byte(string(b)), true } if b, ok := data.(uint64); ok { return []byte(string(b)), true } if b, ok := data.(float32); ok { return []byte(strconv.FormatFloat(float64(b), 'g', -1, 32)), true } if b, ok := data.(float64); ok { return []byte(strconv.FormatFloat(b, 'g', -1, 64)), true } return "", false case STRUCT: if b, ok := data.(TStruct); ok { return b, true } return NewTStructEmpty(""), true case MAP: if b, ok := data.(TMap); ok { return b, true } return NewTMapDefault(), false case LIST: if b, ok := data.(TList); ok { return b, true } return NewTListDefault(), false case SET: if b, ok := data.(TSet); ok { return b, true } return NewTSetDefault(), false default: panic("Invalid thrift type to coerce") } return nil, false } type EqualsOtherInterface interface { Equals(other interface{}) bool } type EqualsMap interface { Equals(other TMap) bool } type EqualsSet interface { Equals(other TSet) bool } type EqualsList interface { Equals(other TList) bool } type EqualsStruct interface { Equals(other TStruct) bool }