blob: 4b8e98a9d1fb283aa39f5dd5c52d8a15e48213a8 [file] [log] [blame]
Roger Meier6cf0ffc2014-04-05 00:45:42 +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
20require 'TProtocol'
21require 'libluabpack'
22require 'libluabitwise'
23
24TBinaryProtocol = __TObject.new(TProtocolBase, {
25 __type = 'TBinaryProtocol',
26 VERSION_MASK = -65536, -- 0xffff0000
27 VERSION_1 = -2147418112, -- 0x80010000
28 TYPE_MASK = 0x000000ff,
29 strictRead = false,
30 strictWrite = true
31})
32
33function TBinaryProtocol:writeMessageBegin(name, ttype, seqid)
Phillipp Röll42b9be12015-06-21 14:38:31 +020034 if self.strictWrite then
Roger Meier6cf0ffc2014-04-05 00:45:42 +020035 self:writeI32(libluabitwise.bor(TBinaryProtocol.VERSION_1, ttype))
36 self:writeString(name)
37 self:writeI32(seqid)
38 else
39 self:writeString(name)
40 self:writeByte(ttype)
41 self:writeI32(seqid)
42 end
43end
44
45function TBinaryProtocol:writeMessageEnd()
46end
47
48function TBinaryProtocol:writeStructBegin(name)
49end
50
51function TBinaryProtocol:writeStructEnd()
52end
53
54function TBinaryProtocol:writeFieldBegin(name, ttype, id)
55 self:writeByte(ttype)
56 self:writeI16(id)
57end
58
59function TBinaryProtocol:writeFieldEnd()
60end
61
62function TBinaryProtocol:writeFieldStop()
63 self:writeByte(TType.STOP);
64end
65
66function TBinaryProtocol:writeMapBegin(ktype, vtype, size)
67 self:writeByte(ktype)
68 self:writeByte(vtype)
69 self:writeI32(size)
70end
71
72function TBinaryProtocol:writeMapEnd()
73end
74
75function TBinaryProtocol:writeListBegin(etype, size)
76 self:writeByte(etype)
77 self:writeI32(size)
78end
79
80function TBinaryProtocol:writeListEnd()
81end
82
83function TBinaryProtocol:writeSetBegin(etype, size)
84 self:writeByte(etype)
85 self:writeI32(size)
86end
87
88function TBinaryProtocol:writeSetEnd()
89end
90
91function TBinaryProtocol:writeBool(bool)
92 if bool then
93 self:writeByte(1)
94 else
95 self:writeByte(0)
96 end
97end
98
99function TBinaryProtocol:writeByte(byte)
100 local buff = libluabpack.bpack('c', byte)
101 self.trans:write(buff)
102end
103
104function TBinaryProtocol:writeI16(i16)
105 local buff = libluabpack.bpack('s', i16)
106 self.trans:write(buff)
107end
108
109function TBinaryProtocol:writeI32(i32)
110 local buff = libluabpack.bpack('i', i32)
111 self.trans:write(buff)
112end
113
114function TBinaryProtocol:writeI64(i64)
115 local buff = libluabpack.bpack('l', i64)
116 self.trans:write(buff)
117end
118
119function TBinaryProtocol:writeDouble(dub)
120 local buff = libluabpack.bpack('d', dub)
121 self.trans:write(buff)
122end
123
124function TBinaryProtocol:writeString(str)
125 -- Should be utf-8
126 self:writeI32(string.len(str))
127 self.trans:write(str)
128end
129
130function TBinaryProtocol:readMessageBegin()
131 local sz, ttype, name, seqid = self:readI32()
132 if sz < 0 then
133 local version = libluabitwise.band(sz, TBinaryProtocol.VERSION_MASK)
134 if version ~= TBinaryProtocol.VERSION_1 then
135 terror(TProtocolException:new{
136 message = 'Bad version in readMessageBegin: ' .. sz
137 })
138 end
139 ttype = libluabitwise.band(sz, TBinaryProtocol.TYPE_MASK)
140 name = self:readString()
141 seqid = self:readI32()
142 else
143 if self.strictRead then
144 terror(TProtocolException:new{message = 'No protocol version header'})
145 end
146 name = self.trans:readAll(sz)
147 ttype = self:readByte()
148 seqid = self:readI32()
149 end
150 return name, ttype, seqid
151end
152
153function TBinaryProtocol:readMessageEnd()
154end
155
156function TBinaryProtocol:readStructBegin()
157 return nil
158end
159
160function TBinaryProtocol:readStructEnd()
161end
162
163function TBinaryProtocol:readFieldBegin()
164 local ttype = self:readByte()
165 if ttype == TType.STOP then
166 return nil, ttype, 0
167 end
168 local id = self:readI16()
169 return nil, ttype, id
170end
171
172function TBinaryProtocol:readFieldEnd()
173end
174
175function TBinaryProtocol:readMapBegin()
176 local ktype = self:readByte()
177 local vtype = self:readByte()
178 local size = self:readI32()
179 return ktype, vtype, size
180end
181
182function TBinaryProtocol:readMapEnd()
183end
184
185function TBinaryProtocol:readListBegin()
186 local etype = self:readByte()
187 local size = self:readI32()
188 return etype, size
189end
190
191function TBinaryProtocol:readListEnd()
192end
193
194function TBinaryProtocol:readSetBegin()
195 local etype = self:readByte()
196 local size = self:readI32()
197 return etype, size
198end
199
200function TBinaryProtocol:readSetEnd()
201end
202
203function TBinaryProtocol:readBool()
204 local byte = self:readByte()
205 if byte == 0 then
206 return false
207 end
208 return true
209end
210
211function TBinaryProtocol:readByte()
212 local buff = self.trans:readAll(1)
213 local val = libluabpack.bunpack('c', buff)
214 return val
215end
216
217function TBinaryProtocol:readI16()
218 local buff = self.trans:readAll(2)
219 local val = libluabpack.bunpack('s', buff)
220 return val
221end
222
223function TBinaryProtocol:readI32()
224 local buff = self.trans:readAll(4)
225 local val = libluabpack.bunpack('i', buff)
226 return val
227end
228
229function TBinaryProtocol:readI64()
230 local buff = self.trans:readAll(8)
231 local val = libluabpack.bunpack('l', buff)
232 return val
233end
234
235function TBinaryProtocol:readDouble()
236 local buff = self.trans:readAll(8)
237 local val = libluabpack.bunpack('d', buff)
238 return val
239end
240
241function TBinaryProtocol:readString()
242 local len = self:readI32()
243 local str = self.trans:readAll(len)
244 return str
245end
246
247TBinaryProtocolFactory = TProtocolFactory:new{
248 __type = 'TBinaryProtocolFactory',
249 strictRead = false
250}
251
252function TBinaryProtocolFactory:getProtocol(trans)
253 -- TODO Enforce that this must be a transport class (ie not a bool)
254 if not trans then
255 terror(TProtocolException:new{
256 message = 'Must supply a transport to ' .. ttype(self)
257 })
258 end
259 return TBinaryProtocol:new{
260 trans = trans,
261 strictRead = self.strictRead,
262 strictWrite = true
263 }
264end