1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20package thrift 21 22import ( 23 "context" 24 "errors" 25 "fmt" 26) 27 28const ( 29 VERSION_MASK = 0xffff0000 30 VERSION_1 = 0x80010000 31) 32 33type TProtocol interface { 34 WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqid int32) error 35 WriteMessageEnd(ctx context.Context) error 36 WriteStructBegin(ctx context.Context, name string) error 37 WriteStructEnd(ctx context.Context) error 38 WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error 39 WriteFieldEnd(ctx context.Context) error 40 WriteFieldStop(ctx context.Context) error 41 WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error 42 WriteMapEnd(ctx context.Context) error 43 WriteListBegin(ctx context.Context, elemType TType, size int) error 44 WriteListEnd(ctx context.Context) error 45 WriteSetBegin(ctx context.Context, elemType TType, size int) error 46 WriteSetEnd(ctx context.Context) error 47 WriteBool(ctx context.Context, value bool) error 48 WriteByte(ctx context.Context, value int8) error 49 WriteI16(ctx context.Context, value int16) error 50 WriteI32(ctx context.Context, value int32) error 51 WriteI64(ctx context.Context, value int64) error 52 WriteDouble(ctx context.Context, value float64) error 53 WriteString(ctx context.Context, value string) error 54 WriteBinary(ctx context.Context, value []byte) error 55 56 ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqid int32, err error) 57 ReadMessageEnd(ctx context.Context) error 58 ReadStructBegin(ctx context.Context) (name string, err error) 59 ReadStructEnd(ctx context.Context) error 60 ReadFieldBegin(ctx context.Context) (name string, typeId TType, id int16, err error) 61 ReadFieldEnd(ctx context.Context) error 62 ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, err error) 63 ReadMapEnd(ctx context.Context) error 64 ReadListBegin(ctx context.Context) (elemType TType, size int, err error) 65 ReadListEnd(ctx context.Context) error 66 ReadSetBegin(ctx context.Context) (elemType TType, size int, err error) 67 ReadSetEnd(ctx context.Context) error 68 ReadBool(ctx context.Context) (value bool, err error) 69 ReadByte(ctx context.Context) (value int8, err error) 70 ReadI16(ctx context.Context) (value int16, err error) 71 ReadI32(ctx context.Context) (value int32, err error) 72 ReadI64(ctx context.Context) (value int64, err error) 73 ReadDouble(ctx context.Context) (value float64, err error) 74 ReadString(ctx context.Context) (value string, err error) 75 ReadBinary(ctx context.Context) (value []byte, err error) 76 77 Skip(ctx context.Context, fieldType TType) (err error) 78 Flush(ctx context.Context) (err error) 79 80 Transport() TTransport 81} 82 83// The maximum recursive depth the skip() function will traverse 84const DEFAULT_RECURSION_DEPTH = 64 85 86// Skips over the next data element from the provided input TProtocol object. 87func SkipDefaultDepth(ctx context.Context, prot TProtocol, typeId TType) (err error) { 88 return Skip(ctx, prot, typeId, DEFAULT_RECURSION_DEPTH) 89} 90 91// Skips over the next data element from the provided input TProtocol object. 92func Skip(ctx context.Context, self TProtocol, fieldType TType, maxDepth int) (err error) { 93 94 if maxDepth <= 0 { 95 return NewTProtocolExceptionWithType(DEPTH_LIMIT, errors.New("Depth limit exceeded")) 96 } 97 98 switch fieldType { 99 case BOOL: 100 _, err = self.ReadBool(ctx) 101 return 102 case BYTE: 103 _, err = self.ReadByte(ctx) 104 return 105 case I16: 106 _, err = self.ReadI16(ctx) 107 return 108 case I32: 109 _, err = self.ReadI32(ctx) 110 return 111 case I64: 112 _, err = self.ReadI64(ctx) 113 return 114 case DOUBLE: 115 _, err = self.ReadDouble(ctx) 116 return 117 case STRING: 118 _, err = self.ReadString(ctx) 119 return 120 case STRUCT: 121 if _, err = self.ReadStructBegin(ctx); err != nil { 122 return err 123 } 124 for { 125 _, typeId, _, _ := self.ReadFieldBegin(ctx) 126 if typeId == STOP { 127 break 128 } 129 err := Skip(ctx, self, typeId, maxDepth-1) 130 if err != nil { 131 return err 132 } 133 self.ReadFieldEnd(ctx) 134 } 135 return self.ReadStructEnd(ctx) 136 case MAP: 137 keyType, valueType, size, err := self.ReadMapBegin(ctx) 138 if err != nil { 139 return err 140 } 141 for i := 0; i < size; i++ { 142 err := Skip(ctx, self, keyType, maxDepth-1) 143 if err != nil { 144 return err 145 } 146 self.Skip(ctx, valueType) 147 } 148 return self.ReadMapEnd(ctx) 149 case SET: 150 elemType, size, err := self.ReadSetBegin(ctx) 151 if err != nil { 152 return err 153 } 154 for i := 0; i < size; i++ { 155 err := Skip(ctx, self, elemType, maxDepth-1) 156 if err != nil { 157 return err 158 } 159 } 160 return self.ReadSetEnd(ctx) 161 case LIST: 162 elemType, size, err := self.ReadListBegin(ctx) 163 if err != nil { 164 return err 165 } 166 for i := 0; i < size; i++ { 167 err := Skip(ctx, self, elemType, maxDepth-1) 168 if err != nil { 169 return err 170 } 171 } 172 return self.ReadListEnd(ctx) 173 default: 174 return NewTProtocolExceptionWithType(INVALID_DATA, errors.New(fmt.Sprintf("Unknown data type %d", fieldType))) 175 } 176 return nil 177} 178