| -- |
| -- Licensed to the Apache Software Foundation (ASF) under one |
| -- or more contributor license agreements. See the NOTICE file |
| -- distributed with this work for additional information |
| -- regarding copyright ownership. The ASF licenses this file |
| -- to you under the Apache License, Version 2.0 (the |
| -- "License"); you may not use this file except in compliance |
| -- with the License. You may obtain a copy of the License at |
| -- |
| -- http://www.apache.org/licenses/LICENSE-2.0 |
| -- |
| -- Unless required by applicable law or agreed to in writing, |
| -- software distributed under the License is distributed on an |
| -- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| -- KIND, either express or implied. See the License for the |
| -- specific language governing permissions and limitations |
| -- under the License. |
| -- |
| |
| require 'TProtocol' |
| require 'libluabpack' |
| require 'libluabitwise' |
| |
| TBinaryProtocol = __TObject.new(TProtocolBase, { |
| __type = 'TBinaryProtocol', |
| VERSION_MASK = -65536, -- 0xffff0000 |
| VERSION_1 = -2147418112, -- 0x80010000 |
| TYPE_MASK = 0x000000ff, |
| strictRead = false, |
| strictWrite = true |
| }) |
| |
| function TBinaryProtocol:writeMessageBegin(name, ttype, seqid) |
| if self.strictWrite then |
| self:writeI32(libluabitwise.bor(TBinaryProtocol.VERSION_1, ttype)) |
| self:writeString(name) |
| self:writeI32(seqid) |
| else |
| self:writeString(name) |
| self:writeByte(ttype) |
| self:writeI32(seqid) |
| end |
| end |
| |
| function TBinaryProtocol:writeMessageEnd() |
| end |
| |
| function TBinaryProtocol:writeStructBegin(name) |
| end |
| |
| function TBinaryProtocol:writeStructEnd() |
| end |
| |
| function TBinaryProtocol:writeFieldBegin(name, ttype, id) |
| self:writeByte(ttype) |
| self:writeI16(id) |
| end |
| |
| function TBinaryProtocol:writeFieldEnd() |
| end |
| |
| function TBinaryProtocol:writeFieldStop() |
| self:writeByte(TType.STOP); |
| end |
| |
| function TBinaryProtocol:writeMapBegin(ktype, vtype, size) |
| self:writeByte(ktype) |
| self:writeByte(vtype) |
| self:writeI32(size) |
| end |
| |
| function TBinaryProtocol:writeMapEnd() |
| end |
| |
| function TBinaryProtocol:writeListBegin(etype, size) |
| self:writeByte(etype) |
| self:writeI32(size) |
| end |
| |
| function TBinaryProtocol:writeListEnd() |
| end |
| |
| function TBinaryProtocol:writeSetBegin(etype, size) |
| self:writeByte(etype) |
| self:writeI32(size) |
| end |
| |
| function TBinaryProtocol:writeSetEnd() |
| end |
| |
| function TBinaryProtocol:writeBool(bool) |
| if bool then |
| self:writeByte(1) |
| else |
| self:writeByte(0) |
| end |
| end |
| |
| function TBinaryProtocol:writeByte(byte) |
| local buff = libluabpack.bpack('c', byte) |
| self.trans:write(buff) |
| end |
| |
| function TBinaryProtocol:writeI16(i16) |
| local buff = libluabpack.bpack('s', i16) |
| self.trans:write(buff) |
| end |
| |
| function TBinaryProtocol:writeI32(i32) |
| local buff = libluabpack.bpack('i', i32) |
| self.trans:write(buff) |
| end |
| |
| function TBinaryProtocol:writeI64(i64) |
| local buff = libluabpack.bpack('l', i64) |
| self.trans:write(buff) |
| end |
| |
| function TBinaryProtocol:writeDouble(dub) |
| local buff = libluabpack.bpack('d', dub) |
| self.trans:write(buff) |
| end |
| |
| function TBinaryProtocol:writeString(str) |
| -- Should be utf-8 |
| self:writeI32(string.len(str)) |
| self.trans:write(str) |
| end |
| |
| function TBinaryProtocol:readMessageBegin() |
| local sz, ttype, name, seqid = self:readI32() |
| if sz < 0 then |
| local version = libluabitwise.band(sz, TBinaryProtocol.VERSION_MASK) |
| if version ~= TBinaryProtocol.VERSION_1 then |
| terror(TProtocolException:new{ |
| message = 'Bad version in readMessageBegin: ' .. sz |
| }) |
| end |
| ttype = libluabitwise.band(sz, TBinaryProtocol.TYPE_MASK) |
| name = self:readString() |
| seqid = self:readI32() |
| else |
| if self.strictRead then |
| terror(TProtocolException:new{message = 'No protocol version header'}) |
| end |
| name = self.trans:readAll(sz) |
| ttype = self:readByte() |
| seqid = self:readI32() |
| end |
| return name, ttype, seqid |
| end |
| |
| function TBinaryProtocol:readMessageEnd() |
| end |
| |
| function TBinaryProtocol:readStructBegin() |
| return nil |
| end |
| |
| function TBinaryProtocol:readStructEnd() |
| end |
| |
| function TBinaryProtocol:readFieldBegin() |
| local ttype = self:readByte() |
| if ttype == TType.STOP then |
| return nil, ttype, 0 |
| end |
| local id = self:readI16() |
| return nil, ttype, id |
| end |
| |
| function TBinaryProtocol:readFieldEnd() |
| end |
| |
| function TBinaryProtocol:readMapBegin() |
| local ktype = self:readByte() |
| local vtype = self:readByte() |
| local size = self:readI32() |
| return ktype, vtype, size |
| end |
| |
| function TBinaryProtocol:readMapEnd() |
| end |
| |
| function TBinaryProtocol:readListBegin() |
| local etype = self:readByte() |
| local size = self:readI32() |
| return etype, size |
| end |
| |
| function TBinaryProtocol:readListEnd() |
| end |
| |
| function TBinaryProtocol:readSetBegin() |
| local etype = self:readByte() |
| local size = self:readI32() |
| return etype, size |
| end |
| |
| function TBinaryProtocol:readSetEnd() |
| end |
| |
| function TBinaryProtocol:readBool() |
| local byte = self:readByte() |
| if byte == 0 then |
| return false |
| end |
| return true |
| end |
| |
| function TBinaryProtocol:readByte() |
| local buff = self.trans:readAll(1) |
| local val = libluabpack.bunpack('c', buff) |
| return val |
| end |
| |
| function TBinaryProtocol:readI16() |
| local buff = self.trans:readAll(2) |
| local val = libluabpack.bunpack('s', buff) |
| return val |
| end |
| |
| function TBinaryProtocol:readI32() |
| local buff = self.trans:readAll(4) |
| local val = libluabpack.bunpack('i', buff) |
| return val |
| end |
| |
| function TBinaryProtocol:readI64() |
| local buff = self.trans:readAll(8) |
| local val = libluabpack.bunpack('l', buff) |
| return val |
| end |
| |
| function TBinaryProtocol:readDouble() |
| local buff = self.trans:readAll(8) |
| local val = libluabpack.bunpack('d', buff) |
| return val |
| end |
| |
| function TBinaryProtocol:readString() |
| local len = self:readI32() |
| local str = self.trans:readAll(len) |
| return str |
| end |
| |
| TBinaryProtocolFactory = TProtocolFactory:new{ |
| __type = 'TBinaryProtocolFactory', |
| strictRead = false |
| } |
| |
| function TBinaryProtocolFactory:getProtocol(trans) |
| -- TODO Enforce that this must be a transport class (ie not a bool) |
| if not trans then |
| terror(TProtocolException:new{ |
| message = 'Must supply a transport to ' .. ttype(self) |
| }) |
| end |
| return TBinaryProtocol:new{ |
| trans = trans, |
| strictRead = self.strictRead, |
| strictWrite = true |
| } |
| end |