2014-04-04 22:45:42 +00:00
|
|
|
--
|
|
|
|
-- 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)
|
2015-06-21 12:38:31 +00:00
|
|
|
if self.strictWrite then
|
2014-04-04 22:45:42 +00:00
|
|
|
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
|