blob: b57b528df6c715f272ca1e387c54a18eab0dde7b [file] [log] [blame]
Jens Geyer0e87c462013-06-18 22:25:07 +02001/*
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 "encoding/binary"
24 "fmt"
25 "io"
26 "math"
Jens Geyer0e87c462013-06-18 22:25:07 +020027)
28
29type TBinaryProtocol struct {
Jens Geyer7d952462013-07-26 01:01:11 +020030 trans TTransport
Jens Geyer0e87c462013-06-18 22:25:07 +020031 strictRead bool
32 strictWrite bool
Jens Geyer7d952462013-07-26 01:01:11 +020033 buffer [8]byte
Jens Geyer0e87c462013-06-18 22:25:07 +020034}
35
36type TBinaryProtocolFactory struct {
37 strictRead bool
38 strictWrite bool
39}
40
41func NewTBinaryProtocolTransport(t TTransport) *TBinaryProtocol {
42 return NewTBinaryProtocol(t, false, true)
43}
44
45func NewTBinaryProtocol(t TTransport, strictRead, strictWrite bool) *TBinaryProtocol {
Carl Yeksigian2ca9c202013-08-14 19:37:54 -040046 return &TBinaryProtocol{trans: t, strictRead: strictRead, strictWrite: strictWrite}
Jens Geyer0e87c462013-06-18 22:25:07 +020047}
48
49func NewTBinaryProtocolFactoryDefault() *TBinaryProtocolFactory {
50 return NewTBinaryProtocolFactory(false, true)
51}
52
53func NewTBinaryProtocolFactory(strictRead, strictWrite bool) *TBinaryProtocolFactory {
54 return &TBinaryProtocolFactory{strictRead: strictRead, strictWrite: strictWrite}
55}
56
57func (p *TBinaryProtocolFactory) GetProtocol(t TTransport) TProtocol {
58 return NewTBinaryProtocol(t, p.strictRead, p.strictWrite)
59}
60
61/**
62 * Writing Methods
63 */
64
65func (p *TBinaryProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) error {
66 if p.strictWrite {
67 version := uint32(VERSION_1) | uint32(typeId)
68 e := p.WriteI32(int32(version))
69 if e != nil {
70 return e
71 }
72 e = p.WriteString(name)
73 if e != nil {
74 return e
75 }
76 e = p.WriteI32(seqId)
77 return e
78 } else {
79 e := p.WriteString(name)
80 if e != nil {
81 return e
82 }
83 e = p.WriteByte(byte(typeId))
84 if e != nil {
85 return e
86 }
87 e = p.WriteI32(seqId)
88 return e
89 }
90 return nil
91}
92
93func (p *TBinaryProtocol) WriteMessageEnd() error {
94 return nil
95}
96
97func (p *TBinaryProtocol) WriteStructBegin(name string) error {
98 return nil
99}
100
101func (p *TBinaryProtocol) WriteStructEnd() error {
102 return nil
103}
104
105func (p *TBinaryProtocol) WriteFieldBegin(name string, typeId TType, id int16) error {
106 e := p.WriteByte(byte(typeId))
107 if e != nil {
108 return e
109 }
110 e = p.WriteI16(id)
111 return e
112}
113
114func (p *TBinaryProtocol) WriteFieldEnd() error {
115 return nil
116}
117
118func (p *TBinaryProtocol) WriteFieldStop() error {
119 e := p.WriteByte(STOP)
120 return e
121}
122
123func (p *TBinaryProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error {
124 e := p.WriteByte(byte(keyType))
125 if e != nil {
126 return e
127 }
128 e = p.WriteByte(byte(valueType))
129 if e != nil {
130 return e
131 }
132 e = p.WriteI32(int32(size))
133 return e
134}
135
136func (p *TBinaryProtocol) WriteMapEnd() error {
137 return nil
138}
139
140func (p *TBinaryProtocol) WriteListBegin(elemType TType, size int) error {
141 e := p.WriteByte(byte(elemType))
142 if e != nil {
143 return e
144 }
145 e = p.WriteI32(int32(size))
146 return e
147}
148
149func (p *TBinaryProtocol) WriteListEnd() error {
150 return nil
151}
152
153func (p *TBinaryProtocol) WriteSetBegin(elemType TType, size int) error {
154 e := p.WriteByte(byte(elemType))
155 if e != nil {
156 return e
157 }
158 e = p.WriteI32(int32(size))
159 return e
160}
161
162func (p *TBinaryProtocol) WriteSetEnd() error {
163 return nil
164}
165
166func (p *TBinaryProtocol) WriteBool(value bool) error {
167 if value {
168 return p.WriteByte(1)
169 }
170 return p.WriteByte(0)
171}
172
173func (p *TBinaryProtocol) WriteByte(value byte) error {
174 v := []byte{value}
175 _, e := p.trans.Write(v)
176 return NewTProtocolException(e)
177}
178
179func (p *TBinaryProtocol) WriteI16(value int16) error {
Jens Geyer7d952462013-07-26 01:01:11 +0200180 v := p.buffer[0:2]
181 binary.BigEndian.PutUint16(v, uint16(value))
Jens Geyer0e87c462013-06-18 22:25:07 +0200182 _, e := p.trans.Write(v)
183 return NewTProtocolException(e)
184}
185
186func (p *TBinaryProtocol) WriteI32(value int32) error {
Jens Geyer7d952462013-07-26 01:01:11 +0200187 v := p.buffer[0:4]
188 binary.BigEndian.PutUint32(v, uint32(value))
Jens Geyer0e87c462013-06-18 22:25:07 +0200189 _, e := p.trans.Write(v)
190 return NewTProtocolException(e)
191}
192
193func (p *TBinaryProtocol) WriteI64(value int64) error {
Jens Geyer7d952462013-07-26 01:01:11 +0200194 v := p.buffer[:]
195 binary.BigEndian.PutUint64(v, uint64(value))
Jens Geyer0e87c462013-06-18 22:25:07 +0200196 _, err := p.trans.Write(v)
197 return NewTProtocolException(err)
198}
199
200func (p *TBinaryProtocol) WriteDouble(value float64) error {
201 return p.WriteI64(int64(math.Float64bits(value)))
202}
203
204func (p *TBinaryProtocol) WriteString(value string) error {
Jens Geyer7d952462013-07-26 01:01:11 +0200205 return p.WriteBinary([]byte(value))
Jens Geyer0e87c462013-06-18 22:25:07 +0200206}
207
208func (p *TBinaryProtocol) WriteBinary(value []byte) error {
209 e := p.WriteI32(int32(len(value)))
210 if e != nil {
211 return e
212 }
213 _, err := p.trans.Write(value)
214 return NewTProtocolException(err)
215}
216
Jens Geyer0e87c462013-06-18 22:25:07 +0200217/**
218 * Reading methods
219 */
220
221func (p *TBinaryProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) {
222 size, e := p.ReadI32()
223 if e != nil {
224 return "", typeId, 0, NewTProtocolException(e)
225 }
226 if size < 0 {
227 typeId = TMessageType(size & 0x0ff)
228 version := int64(int64(size) & VERSION_MASK)
229 if version != VERSION_1 {
230 return name, typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, fmt.Errorf("Bad version in ReadMessageBegin"))
231 }
232 name, e = p.ReadString()
233 if e != nil {
234 return name, typeId, seqId, NewTProtocolException(e)
235 }
236 seqId, e = p.ReadI32()
237 if e != nil {
238 return name, typeId, seqId, NewTProtocolException(e)
239 }
240 return name, typeId, seqId, nil
241 }
242 if p.strictRead {
243 return name, typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, fmt.Errorf("Missing version in ReadMessageBegin"))
244 }
245 name, e2 := p.readStringBody(int(size))
246 if e2 != nil {
247 return name, typeId, seqId, e2
248 }
249 b, e3 := p.ReadByte()
250 if e3 != nil {
251 return name, typeId, seqId, e3
252 }
253 typeId = TMessageType(b)
254 seqId, e4 := p.ReadI32()
255 if e4 != nil {
256 return name, typeId, seqId, e4
257 }
258 return name, typeId, seqId, nil
259}
260
261func (p *TBinaryProtocol) ReadMessageEnd() error {
262 return nil
263}
264
265func (p *TBinaryProtocol) ReadStructBegin() (name string, err error) {
266 return
267}
268
269func (p *TBinaryProtocol) ReadStructEnd() error {
270 return nil
271}
272
273func (p *TBinaryProtocol) ReadFieldBegin() (name string, typeId TType, seqId int16, err error) {
274 t, err := p.ReadByte()
275 typeId = TType(t)
276 if err != nil {
277 return name, typeId, seqId, err
278 }
279 if t != STOP {
280 seqId, err = p.ReadI16()
281 }
282 return name, typeId, seqId, err
283}
284
285func (p *TBinaryProtocol) ReadFieldEnd() error {
286 return nil
287}
288
289func (p *TBinaryProtocol) ReadMapBegin() (kType, vType TType, size int, err error) {
290 k, e := p.ReadByte()
291 if e != nil {
292 err = NewTProtocolException(e)
293 return
294 }
295 kType = TType(k)
296 v, e := p.ReadByte()
297 if e != nil {
298 err = NewTProtocolException(e)
299 return
300 }
301 vType = TType(v)
302 size32, e := p.ReadI32()
303 size = int(size32)
304 if e != nil {
305 err = NewTProtocolException(e)
306 return
307 }
308 return kType, vType, size, nil
309}
310
311func (p *TBinaryProtocol) ReadMapEnd() error {
312 return nil
313}
314
315func (p *TBinaryProtocol) ReadListBegin() (elemType TType, size int, err error) {
316 b, e := p.ReadByte()
317 if e != nil {
318 err = NewTProtocolException(e)
319 return
320 }
321 elemType = TType(b)
322 size32, e := p.ReadI32()
323 size = int(size32)
324 if e != nil {
325 err = NewTProtocolException(e)
326 return
327 }
328 return elemType, size, nil
329}
330
331func (p *TBinaryProtocol) ReadListEnd() error {
332 return nil
333}
334
335func (p *TBinaryProtocol) ReadSetBegin() (elemType TType, size int, err error) {
336 b, e := p.ReadByte()
337 if e != nil {
338 err = NewTProtocolException(e)
339 return
340 }
341 elemType = TType(b)
342 size32, e := p.ReadI32()
343 size = int(size32)
344 if e != nil {
345 err = NewTProtocolException(e)
346 return
347 }
348 return elemType, size, nil
349}
350
351func (p *TBinaryProtocol) ReadSetEnd() error {
352 return nil
353}
354
355func (p *TBinaryProtocol) ReadBool() (bool, error) {
356 b, e := p.ReadByte()
357 v := true
358 if b != 1 {
359 v = false
360 }
361 return v, e
362}
363
364func (p *TBinaryProtocol) ReadByte() (value byte, err error) {
Jens Geyer7d952462013-07-26 01:01:11 +0200365 buf := p.buffer[0:1]
Jens Geyer0e87c462013-06-18 22:25:07 +0200366 err = p.readAll(buf)
367 return buf[0], err
368}
369
370func (p *TBinaryProtocol) ReadI16() (value int16, err error) {
Jens Geyer7d952462013-07-26 01:01:11 +0200371 buf := p.buffer[0:2]
Jens Geyer0e87c462013-06-18 22:25:07 +0200372 err = p.readAll(buf)
373 value = int16(binary.BigEndian.Uint16(buf))
374 return value, err
375}
376
377func (p *TBinaryProtocol) ReadI32() (value int32, err error) {
Jens Geyer7d952462013-07-26 01:01:11 +0200378 buf := p.buffer[0:4]
Jens Geyer0e87c462013-06-18 22:25:07 +0200379 err = p.readAll(buf)
380 value = int32(binary.BigEndian.Uint32(buf))
381 return value, err
382}
383
384func (p *TBinaryProtocol) ReadI64() (value int64, err error) {
Jens Geyer7d952462013-07-26 01:01:11 +0200385 buf := p.buffer[0:8]
Jens Geyer0e87c462013-06-18 22:25:07 +0200386 err = p.readAll(buf)
387 value = int64(binary.BigEndian.Uint64(buf))
388 return value, err
389}
390
391func (p *TBinaryProtocol) ReadDouble() (value float64, err error) {
Jens Geyer7d952462013-07-26 01:01:11 +0200392 buf := p.buffer[0:8]
Jens Geyer0e87c462013-06-18 22:25:07 +0200393 err = p.readAll(buf)
394 value = math.Float64frombits(binary.BigEndian.Uint64(buf))
395 return value, err
396}
397
398func (p *TBinaryProtocol) ReadString() (value string, err error) {
399 size, e := p.ReadI32()
400 if e != nil {
401 return "", e
402 }
403 return p.readStringBody(int(size))
404}
405
406func (p *TBinaryProtocol) ReadBinary() ([]byte, error) {
407 size, e := p.ReadI32()
408 if e != nil {
409 return nil, e
410 }
411 isize := int(size)
Jens Geyer0e87c462013-06-18 22:25:07 +0200412 buf := make([]byte, isize)
413 _, err := io.ReadFull(p.trans, buf)
414 return buf, NewTProtocolException(err)
415}
416
417func (p *TBinaryProtocol) Flush() (err error) {
418 return NewTProtocolException(p.trans.Flush())
419}
420
421func (p *TBinaryProtocol) Skip(fieldType TType) (err error) {
422 return SkipDefaultDepth(p, fieldType)
423}
424
425func (p *TBinaryProtocol) Transport() TTransport {
426 return p.trans
427}
428
429func (p *TBinaryProtocol) readAll(buf []byte) error {
Jens Geyer0e87c462013-06-18 22:25:07 +0200430 _, err := io.ReadFull(p.trans, buf)
431 return NewTProtocolException(err)
432}
433
Jens Geyer0e87c462013-06-18 22:25:07 +0200434func (p *TBinaryProtocol) readStringBody(size int) (value string, err error) {
435 if size < 0 {
436 return "", nil
437 }
Jens Geyer0e87c462013-06-18 22:25:07 +0200438 isize := int(size)
439 buf := make([]byte, isize)
440 _, e := io.ReadFull(p.trans, buf)
441 return string(buf), NewTProtocolException(e)
442}