blob: 5880f65ca2b3377f3d1f1abc97eab1948a7eefb4 [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"
27 "strings"
28)
29
30type TBinaryProtocol struct {
31 trans TTransport
32 strictRead bool
33 strictWrite bool
34 readLength int
35 checkReadLength bool
36}
37
38type TBinaryProtocolFactory struct {
39 strictRead bool
40 strictWrite bool
41}
42
43func NewTBinaryProtocolTransport(t TTransport) *TBinaryProtocol {
44 return NewTBinaryProtocol(t, false, true)
45}
46
47func NewTBinaryProtocol(t TTransport, strictRead, strictWrite bool) *TBinaryProtocol {
48 //return &TBinaryProtocol{TProtocolBase:TProtocolBase{trans:t}, strictRead:strictRead, strictWrite:strictWrite, readLength:0, checkReadLength:false};
49 return &TBinaryProtocol{trans: t, strictRead: strictRead, strictWrite: strictWrite, readLength: 0, checkReadLength: false}
50}
51
52func NewTBinaryProtocolFactoryDefault() *TBinaryProtocolFactory {
53 return NewTBinaryProtocolFactory(false, true)
54}
55
56func NewTBinaryProtocolFactory(strictRead, strictWrite bool) *TBinaryProtocolFactory {
57 return &TBinaryProtocolFactory{strictRead: strictRead, strictWrite: strictWrite}
58}
59
60func (p *TBinaryProtocolFactory) GetProtocol(t TTransport) TProtocol {
61 return NewTBinaryProtocol(t, p.strictRead, p.strictWrite)
62}
63
64/**
65 * Writing Methods
66 */
67
68func (p *TBinaryProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) error {
69 if p.strictWrite {
70 version := uint32(VERSION_1) | uint32(typeId)
71 e := p.WriteI32(int32(version))
72 if e != nil {
73 return e
74 }
75 e = p.WriteString(name)
76 if e != nil {
77 return e
78 }
79 e = p.WriteI32(seqId)
80 return e
81 } else {
82 e := p.WriteString(name)
83 if e != nil {
84 return e
85 }
86 e = p.WriteByte(byte(typeId))
87 if e != nil {
88 return e
89 }
90 e = p.WriteI32(seqId)
91 return e
92 }
93 return nil
94}
95
96func (p *TBinaryProtocol) WriteMessageEnd() error {
97 return nil
98}
99
100func (p *TBinaryProtocol) WriteStructBegin(name string) error {
101 return nil
102}
103
104func (p *TBinaryProtocol) WriteStructEnd() error {
105 return nil
106}
107
108func (p *TBinaryProtocol) WriteFieldBegin(name string, typeId TType, id int16) error {
109 e := p.WriteByte(byte(typeId))
110 if e != nil {
111 return e
112 }
113 e = p.WriteI16(id)
114 return e
115}
116
117func (p *TBinaryProtocol) WriteFieldEnd() error {
118 return nil
119}
120
121func (p *TBinaryProtocol) WriteFieldStop() error {
122 e := p.WriteByte(STOP)
123 return e
124}
125
126func (p *TBinaryProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error {
127 e := p.WriteByte(byte(keyType))
128 if e != nil {
129 return e
130 }
131 e = p.WriteByte(byte(valueType))
132 if e != nil {
133 return e
134 }
135 e = p.WriteI32(int32(size))
136 return e
137}
138
139func (p *TBinaryProtocol) WriteMapEnd() error {
140 return nil
141}
142
143func (p *TBinaryProtocol) WriteListBegin(elemType TType, size int) error {
144 e := p.WriteByte(byte(elemType))
145 if e != nil {
146 return e
147 }
148 e = p.WriteI32(int32(size))
149 return e
150}
151
152func (p *TBinaryProtocol) WriteListEnd() error {
153 return nil
154}
155
156func (p *TBinaryProtocol) WriteSetBegin(elemType TType, size int) error {
157 e := p.WriteByte(byte(elemType))
158 if e != nil {
159 return e
160 }
161 e = p.WriteI32(int32(size))
162 return e
163}
164
165func (p *TBinaryProtocol) WriteSetEnd() error {
166 return nil
167}
168
169func (p *TBinaryProtocol) WriteBool(value bool) error {
170 if value {
171 return p.WriteByte(1)
172 }
173 return p.WriteByte(0)
174}
175
176func (p *TBinaryProtocol) WriteByte(value byte) error {
177 v := []byte{value}
178 _, e := p.trans.Write(v)
179 return NewTProtocolException(e)
180}
181
182func (p *TBinaryProtocol) WriteI16(value int16) error {
183 h := byte(0xff & (value >> 8))
184 l := byte(0xff & value)
185 v := []byte{h, l}
186 _, e := p.trans.Write(v)
187 return NewTProtocolException(e)
188}
189
190func (p *TBinaryProtocol) WriteI32(value int32) error {
191 a := byte(0xff & (value >> 24))
192 b := byte(0xff & (value >> 16))
193 c := byte(0xff & (value >> 8))
194 d := byte(0xff & value)
195 v := []byte{a, b, c, d}
196 _, e := p.trans.Write(v)
197 return NewTProtocolException(e)
198}
199
200func (p *TBinaryProtocol) WriteI64(value int64) error {
201 a := byte(0xff & (value >> 56))
202 b := byte(0xff & (value >> 48))
203 c := byte(0xff & (value >> 40))
204 d := byte(0xff & (value >> 32))
205 e := byte(0xff & (value >> 24))
206 f := byte(0xff & (value >> 16))
207 g := byte(0xff & (value >> 8))
208 h := byte(0xff & value)
209 v := []byte{a, b, c, d, e, f, g, h}
210 _, err := p.trans.Write(v)
211 return NewTProtocolException(err)
212}
213
214func (p *TBinaryProtocol) WriteDouble(value float64) error {
215 return p.WriteI64(int64(math.Float64bits(value)))
216}
217
218func (p *TBinaryProtocol) WriteString(value string) error {
219 return p.WriteBinaryFromReader(strings.NewReader(value), len(value))
220}
221
222func (p *TBinaryProtocol) WriteBinary(value []byte) error {
223 e := p.WriteI32(int32(len(value)))
224 if e != nil {
225 return e
226 }
227 _, err := p.trans.Write(value)
228 return NewTProtocolException(err)
229}
230
231func (p *TBinaryProtocol) WriteBinaryFromReader(reader io.Reader, size int) error {
232 e := p.WriteI32(int32(size))
233 if e != nil {
234 return e
235 }
236 _, err := io.CopyN(p.trans, reader, int64(size))
237 return NewTProtocolException(err)
238}
239
240/**
241 * Reading methods
242 */
243
244func (p *TBinaryProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) {
245 size, e := p.ReadI32()
246 if e != nil {
247 return "", typeId, 0, NewTProtocolException(e)
248 }
249 if size < 0 {
250 typeId = TMessageType(size & 0x0ff)
251 version := int64(int64(size) & VERSION_MASK)
252 if version != VERSION_1 {
253 return name, typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, fmt.Errorf("Bad version in ReadMessageBegin"))
254 }
255 name, e = p.ReadString()
256 if e != nil {
257 return name, typeId, seqId, NewTProtocolException(e)
258 }
259 seqId, e = p.ReadI32()
260 if e != nil {
261 return name, typeId, seqId, NewTProtocolException(e)
262 }
263 return name, typeId, seqId, nil
264 }
265 if p.strictRead {
266 return name, typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, fmt.Errorf("Missing version in ReadMessageBegin"))
267 }
268 name, e2 := p.readStringBody(int(size))
269 if e2 != nil {
270 return name, typeId, seqId, e2
271 }
272 b, e3 := p.ReadByte()
273 if e3 != nil {
274 return name, typeId, seqId, e3
275 }
276 typeId = TMessageType(b)
277 seqId, e4 := p.ReadI32()
278 if e4 != nil {
279 return name, typeId, seqId, e4
280 }
281 return name, typeId, seqId, nil
282}
283
284func (p *TBinaryProtocol) ReadMessageEnd() error {
285 return nil
286}
287
288func (p *TBinaryProtocol) ReadStructBegin() (name string, err error) {
289 return
290}
291
292func (p *TBinaryProtocol) ReadStructEnd() error {
293 return nil
294}
295
296func (p *TBinaryProtocol) ReadFieldBegin() (name string, typeId TType, seqId int16, err error) {
297 t, err := p.ReadByte()
298 typeId = TType(t)
299 if err != nil {
300 return name, typeId, seqId, err
301 }
302 if t != STOP {
303 seqId, err = p.ReadI16()
304 }
305 return name, typeId, seqId, err
306}
307
308func (p *TBinaryProtocol) ReadFieldEnd() error {
309 return nil
310}
311
312func (p *TBinaryProtocol) ReadMapBegin() (kType, vType TType, size int, err error) {
313 k, e := p.ReadByte()
314 if e != nil {
315 err = NewTProtocolException(e)
316 return
317 }
318 kType = TType(k)
319 v, e := p.ReadByte()
320 if e != nil {
321 err = NewTProtocolException(e)
322 return
323 }
324 vType = TType(v)
325 size32, e := p.ReadI32()
326 size = int(size32)
327 if e != nil {
328 err = NewTProtocolException(e)
329 return
330 }
331 return kType, vType, size, nil
332}
333
334func (p *TBinaryProtocol) ReadMapEnd() error {
335 return nil
336}
337
338func (p *TBinaryProtocol) ReadListBegin() (elemType TType, size int, err error) {
339 b, e := p.ReadByte()
340 if e != nil {
341 err = NewTProtocolException(e)
342 return
343 }
344 elemType = TType(b)
345 size32, e := p.ReadI32()
346 size = int(size32)
347 if e != nil {
348 err = NewTProtocolException(e)
349 return
350 }
351 return elemType, size, nil
352}
353
354func (p *TBinaryProtocol) ReadListEnd() error {
355 return nil
356}
357
358func (p *TBinaryProtocol) ReadSetBegin() (elemType TType, size int, err error) {
359 b, e := p.ReadByte()
360 if e != nil {
361 err = NewTProtocolException(e)
362 return
363 }
364 elemType = TType(b)
365 size32, e := p.ReadI32()
366 size = int(size32)
367 if e != nil {
368 err = NewTProtocolException(e)
369 return
370 }
371 return elemType, size, nil
372}
373
374func (p *TBinaryProtocol) ReadSetEnd() error {
375 return nil
376}
377
378func (p *TBinaryProtocol) ReadBool() (bool, error) {
379 b, e := p.ReadByte()
380 v := true
381 if b != 1 {
382 v = false
383 }
384 return v, e
385}
386
387func (p *TBinaryProtocol) ReadByte() (value byte, err error) {
388 buf := []byte{0}
389 err = p.readAll(buf)
390 return buf[0], err
391}
392
393func (p *TBinaryProtocol) ReadI16() (value int16, err error) {
394 buf := []byte{0, 0}
395 err = p.readAll(buf)
396 value = int16(binary.BigEndian.Uint16(buf))
397 return value, err
398}
399
400func (p *TBinaryProtocol) ReadI32() (value int32, err error) {
401 buf := []byte{0, 0, 0, 0}
402 err = p.readAll(buf)
403 value = int32(binary.BigEndian.Uint32(buf))
404 return value, err
405}
406
407func (p *TBinaryProtocol) ReadI64() (value int64, err error) {
408 buf := []byte{0, 0, 0, 0, 0, 0, 0, 0}
409 err = p.readAll(buf)
410 value = int64(binary.BigEndian.Uint64(buf))
411 return value, err
412}
413
414func (p *TBinaryProtocol) ReadDouble() (value float64, err error) {
415 buf := []byte{0, 0, 0, 0, 0, 0, 0, 0}
416 err = p.readAll(buf)
417 value = math.Float64frombits(binary.BigEndian.Uint64(buf))
418 return value, err
419}
420
421func (p *TBinaryProtocol) ReadString() (value string, err error) {
422 size, e := p.ReadI32()
423 if e != nil {
424 return "", e
425 }
426 return p.readStringBody(int(size))
427}
428
429func (p *TBinaryProtocol) ReadBinary() ([]byte, error) {
430 size, e := p.ReadI32()
431 if e != nil {
432 return nil, e
433 }
434 isize := int(size)
435 if e = p.readLengthOk(isize); e != nil {
436 return nil, e
437 }
438 buf := make([]byte, isize)
439 _, err := io.ReadFull(p.trans, buf)
440 return buf, NewTProtocolException(err)
441}
442
443func (p *TBinaryProtocol) Flush() (err error) {
444 return NewTProtocolException(p.trans.Flush())
445}
446
447func (p *TBinaryProtocol) Skip(fieldType TType) (err error) {
448 return SkipDefaultDepth(p, fieldType)
449}
450
451func (p *TBinaryProtocol) Transport() TTransport {
452 return p.trans
453}
454
455func (p *TBinaryProtocol) readAll(buf []byte) error {
456 if e := p.readLengthOk(len(buf)); e != nil {
457 return e
458 }
459 _, err := io.ReadFull(p.trans, buf)
460 return NewTProtocolException(err)
461}
462
463func (p *TBinaryProtocol) setReadLength(readLength int) {
464 p.readLength = readLength
465 p.checkReadLength = true
466}
467
468func (p *TBinaryProtocol) readLengthOk(length int) error {
469 if p.checkReadLength {
470 p.readLength = p.readLength - length
471 if p.readLength < 0 {
472 return NewTProtocolExceptionWithType(UNKNOWN_PROTOCOL_EXCEPTION, fmt.Errorf("Message length exceeded: %d", length))
473 }
474 }
475 return nil
476}
477
478func (p *TBinaryProtocol) readStringBody(size int) (value string, err error) {
479 if size < 0 {
480 return "", nil
481 }
482 if err := p.readLengthOk(size); err != nil {
483 return "", err
484 }
485 isize := int(size)
486 buf := make([]byte, isize)
487 _, e := io.ReadFull(p.trans, buf)
488 return string(buf), NewTProtocolException(e)
489}