blob: 4b8e98a9d1fb283aa39f5dd5c52d8a15e48213a8 [file] [log] [blame]
--
-- 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