blob: 9eacc4ae8ab23b1068b5e092dbc59a3e60b6d3d9 [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'
Thomaseb684d32024-07-28 15:32:23 +020021local libluabpack = require 'libluabpack'
22local libluabitwise = require 'libluabitwise'
Roger Meier6cf0ffc2014-04-05 00:45:42 +020023
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
Thomaseb684d32024-07-28 15:32:23 +0200114function TBinaryProtocol:writeUI32(i32)
115 local buff = libluabpack.bpack('I', i32)
116 self.trans:write(buff)
117end
118
Roger Meier6cf0ffc2014-04-05 00:45:42 +0200119function TBinaryProtocol:writeI64(i64)
120 local buff = libluabpack.bpack('l', i64)
121 self.trans:write(buff)
122end
123
124function TBinaryProtocol:writeDouble(dub)
125 local buff = libluabpack.bpack('d', dub)
126 self.trans:write(buff)
127end
128
129function TBinaryProtocol:writeString(str)
130 -- Should be utf-8
131 self:writeI32(string.len(str))
132 self.trans:write(str)
133end
134
Thomaseb684d32024-07-28 15:32:23 +0200135function TBinaryProtocol:writeUuid(uuid)
136 self:writeUI32(uuid.two)
137 self:writeUI32(uuid.three)
138 self:writeUI32(uuid.zero)
139 self:writeUI32(uuid.one)
140end
141
Roger Meier6cf0ffc2014-04-05 00:45:42 +0200142function TBinaryProtocol:readMessageBegin()
143 local sz, ttype, name, seqid = self:readI32()
144 if sz < 0 then
145 local version = libluabitwise.band(sz, TBinaryProtocol.VERSION_MASK)
146 if version ~= TBinaryProtocol.VERSION_1 then
147 terror(TProtocolException:new{
148 message = 'Bad version in readMessageBegin: ' .. sz
149 })
150 end
151 ttype = libluabitwise.band(sz, TBinaryProtocol.TYPE_MASK)
152 name = self:readString()
153 seqid = self:readI32()
154 else
155 if self.strictRead then
156 terror(TProtocolException:new{message = 'No protocol version header'})
157 end
158 name = self.trans:readAll(sz)
159 ttype = self:readByte()
160 seqid = self:readI32()
161 end
162 return name, ttype, seqid
163end
164
165function TBinaryProtocol:readMessageEnd()
166end
167
168function TBinaryProtocol:readStructBegin()
169 return nil
170end
171
172function TBinaryProtocol:readStructEnd()
173end
174
175function TBinaryProtocol:readFieldBegin()
176 local ttype = self:readByte()
177 if ttype == TType.STOP then
178 return nil, ttype, 0
179 end
180 local id = self:readI16()
181 return nil, ttype, id
182end
183
184function TBinaryProtocol:readFieldEnd()
185end
186
187function TBinaryProtocol:readMapBegin()
188 local ktype = self:readByte()
189 local vtype = self:readByte()
190 local size = self:readI32()
191 return ktype, vtype, size
192end
193
194function TBinaryProtocol:readMapEnd()
195end
196
197function TBinaryProtocol:readListBegin()
198 local etype = self:readByte()
199 local size = self:readI32()
200 return etype, size
201end
202
203function TBinaryProtocol:readListEnd()
204end
205
206function TBinaryProtocol:readSetBegin()
207 local etype = self:readByte()
208 local size = self:readI32()
209 return etype, size
210end
211
212function TBinaryProtocol:readSetEnd()
213end
214
215function TBinaryProtocol:readBool()
216 local byte = self:readByte()
217 if byte == 0 then
218 return false
219 end
220 return true
221end
222
223function TBinaryProtocol:readByte()
224 local buff = self.trans:readAll(1)
225 local val = libluabpack.bunpack('c', buff)
226 return val
227end
228
229function TBinaryProtocol:readI16()
230 local buff = self.trans:readAll(2)
231 local val = libluabpack.bunpack('s', buff)
232 return val
233end
234
235function TBinaryProtocol:readI32()
236 local buff = self.trans:readAll(4)
237 local val = libluabpack.bunpack('i', buff)
238 return val
239end
240
Thomaseb684d32024-07-28 15:32:23 +0200241function TBinaryProtocol:readUI32()
242 local buff = self.trans:readAll(4)
243 local val = libluabpack.bunpack('I', buff)
244 return val
245end
246
Roger Meier6cf0ffc2014-04-05 00:45:42 +0200247function TBinaryProtocol:readI64()
248 local buff = self.trans:readAll(8)
249 local val = libluabpack.bunpack('l', buff)
250 return val
251end
252
253function TBinaryProtocol:readDouble()
254 local buff = self.trans:readAll(8)
255 local val = libluabpack.bunpack('d', buff)
256 return val
257end
258
259function TBinaryProtocol:readString()
260 local len = self:readI32()
261 local str = self.trans:readAll(len)
262 return str
263end
264
Thomaseb684d32024-07-28 15:32:23 +0200265function TBinaryProtocol:readUuid()
266 local a = self:readUI32()
267 local b = self:readUI32()
268 local c = self:readUI32()
269 local d = self:readUI32()
270 return TUUID:new {
271 zero = c,
272 one = d,
273 two = a,
274 three = b
275 }
276end
277
Roger Meier6cf0ffc2014-04-05 00:45:42 +0200278TBinaryProtocolFactory = TProtocolFactory:new{
279 __type = 'TBinaryProtocolFactory',
280 strictRead = false
281}
282
283function TBinaryProtocolFactory:getProtocol(trans)
284 -- TODO Enforce that this must be a transport class (ie not a bool)
285 if not trans then
286 terror(TProtocolException:new{
287 message = 'Must supply a transport to ' .. ttype(self)
288 })
289 end
290 return TBinaryProtocol:new{
291 trans = trans,
292 strictRead = self.strictRead,
293 strictWrite = true
294 }
295end