| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- --
- --------------------------------------------------------------------------------
- -- FILE: encoder.lua
- -- DESCRIPTION: protoc-gen-lua
- -- Google's Protocol Buffers project, ported to lua.
- -- https://code.google.com/p/protoc-gen-lua/
- --
- -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com
- -- All rights reserved.
- --
- -- Use, modification and distribution are subject to the "New BSD License"
- -- as listed at <url: http://www.opensource.org/licenses/bsd-license.php >.
- --
- -- COMPANY: NetEase
- -- CREATED: 2010年07月29日 19时30分46秒 CST
- --------------------------------------------------------------------------------
- --
- local string = string
- local table = table
- local ipairs = ipairs
- local assert =assert
- local pb = require "pb"
- local wire_format = require "protobuf.wire_format"
- module "protobuf.encoder"
- function _VarintSize(value)
- if value <= 0x7f then return 1 end
- if value <= 0x3fff then return 2 end
- if value <= 0x1fffff then return 3 end
- if value <= 0xfffffff then return 4 end
- if value <= 0x7ffffffff then return 5 end
- if value <= 0x3ffffffffff then return 6 end
- if value <= 0x1ffffffffffff then return 7 end
- if value <= 0xffffffffffffff then return 8 end
- if value <= 0x7fffffffffffffff then return 9 end
- return 10
- end
- function _SignedVarintSize(value)
- if value < 0 then return 10 end
- if value <= 0x7f then return 1 end
- if value <= 0x3fff then return 2 end
- if value <= 0x1fffff then return 3 end
- if value <= 0xfffffff then return 4 end
- if value <= 0x7ffffffff then return 5 end
- if value <= 0x3ffffffffff then return 6 end
- if value <= 0x1ffffffffffff then return 7 end
- if value <= 0xffffffffffffff then return 8 end
- if value <= 0x7fffffffffffffff then return 9 end
- return 10
- end
- function _TagSize(field_number)
- return _VarintSize(wire_format.PackTag(field_number, 0))
- end
- function _SimpleSizer(compute_value_size)
- return function(field_number, is_repeated, is_packed)
- local tag_size = _TagSize(field_number)
- if is_packed then
- local VarintSize = _VarintSize
- return function(value)
- local result = 0
- for _, element in ipairs(value) do
- result = result + compute_value_size(element)
- end
- return result + VarintSize(result) + tag_size
- end
- elseif is_repeated then
- return function(value)
- local result = tag_size * #value
- for _, element in ipairs(value) do
- result = result + compute_value_size(element)
- end
- return result
- end
- else
- return function (value)
- return tag_size + compute_value_size(value)
- end
- end
- end
- end
- function _ModifiedSizer(compute_value_size, modify_value)
- return function (field_number, is_repeated, is_packed)
- local tag_size = _TagSize(field_number)
- if is_packed then
- local VarintSize = _VarintSize
- return function (value)
- local result = 0
- for _, element in ipairs(value) do
- result = result + compute_value_size(modify_value(element))
- end
- return result + VarintSize(result) + tag_size
- end
- elseif is_repeated then
- return function (value)
- local result = tag_size * #value
- for _, element in ipairs(value) do
- result = result + compute_value_size(modify_value(element))
- end
- return result
- end
- else
- return function (value)
- return tag_size + compute_value_size(modify_value(value))
- end
- end
- end
- end
- function _FixedSizer(value_size)
- return function (field_number, is_repeated, is_packed)
- local tag_size = _TagSize(field_number)
- if is_packed then
- local VarintSize = _VarintSize
- return function (value)
- local result = #value * value_size
- return result + VarintSize(result) + tag_size
- end
- elseif is_repeated then
- local element_size = value_size + tag_size
- return function(value)
- return #value * element_size
- end
- else
- local field_size = value_size + tag_size
- return function (value)
- return field_size
- end
- end
- end
- end
- Int32Sizer = _SimpleSizer(_SignedVarintSize)
- Int64Sizer = _SimpleSizer(pb.signed_varint_size)
- EnumSizer = Int32Sizer
- UInt32Sizer = _SimpleSizer(_VarintSize)
- UInt64Sizer = _SimpleSizer(pb.varint_size)
- SInt32Sizer = _ModifiedSizer(_SignedVarintSize, wire_format.ZigZagEncode32)
- SInt64Sizer = SInt32Sizer
- Fixed32Sizer = _FixedSizer(4)
- SFixed32Sizer = Fixed32Sizer
- FloatSizer = Fixed32Sizer
- Fixed64Sizer = _FixedSizer(8)
- SFixed64Sizer = Fixed64Sizer
- DoubleSizer = Fixed64Sizer
- BoolSizer = _FixedSizer(1)
- function StringSizer(field_number, is_repeated, is_packed)
- local tag_size = _TagSize(field_number)
- local VarintSize = _VarintSize
- assert(not is_packed)
- if is_repeated then
- return function(value)
- local result = tag_size * #value
- for _, element in ipairs(value) do
- local l = #element
- result = result + VarintSize(l) + l
- end
- return result
- end
- else
- return function(value)
- local l = #value
- return tag_size + VarintSize(l) + l
- end
- end
- end
- function BytesSizer(field_number, is_repeated, is_packed)
- local tag_size = _TagSize(field_number)
- local VarintSize = _VarintSize
- assert(not is_packed)
- if is_repeated then
- return function (value)
- local result = tag_size * #value
- for _,element in ipairs(value) do
- local l = #element
- result = result + VarintSize(l) + l
- end
- return result
- end
- else
- return function (value)
- local l = #value
- return tag_size + VarintSize(l) + l
- end
- end
- end
- function MessageSizer(field_number, is_repeated, is_packed)
- local tag_size = _TagSize(field_number)
- local VarintSize = _VarintSize
- assert(not is_packed)
- if is_repeated then
- return function(value)
- local result = tag_size * #value
- for _,element in ipairs(value) do
- local l = element:ByteSize()
- result = result + VarintSize(l) + l
- end
- return result
- end
- else
- return function (value)
- local l = value:ByteSize()
- return tag_size + VarintSize(l) + l
- end
- end
- end
- -- ====================================================================
- -- Encoders!
- local _EncodeVarint = pb.varint_encoder
- local _EncodeSignedVarint = pb.signed_varint_encoder
- local _EncodeVarint64 = pb.varint_encoder64
- local _EncodeSignedVarint64 = pb.signed_varint_encoder64
- function _VarintBytes(value)
- local out = {}
- local write = function(value)
- out[#out + 1 ] = value
- end
- _EncodeSignedVarint(write, value)
- return table.concat(out)
- end
- function TagBytes(field_number, wire_type)
- return _VarintBytes(wire_format.PackTag(field_number, wire_type))
- end
- function _SimpleEncoder(wire_type, encode_value, compute_value_size)
- return function(field_number, is_repeated, is_packed)
- if is_packed then
- local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
- local EncodeVarint = _EncodeVarint
- return function(write, value)
- write(tag_bytes)
- local size = 0
- for _, element in ipairs(value) do
- size = size + compute_value_size(element)
- end
- EncodeVarint(write, size)
- for element in value do
- encode_value(write, element)
- end
- end
- elseif is_repeated then
- local tag_bytes = TagBytes(field_number, wire_type)
- return function(write, value)
- for _, element in ipairs(value) do
- write(tag_bytes)
- encode_value(write, element)
- end
- end
- else
- local tag_bytes = TagBytes(field_number, wire_type)
- return function(write, value)
- write(tag_bytes)
- encode_value(write, value)
- end
- end
- end
- end
- function _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value)
- return function (field_number, is_repeated, is_packed)
- if is_packed then
- local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
- local EncodeVarint = _EncodeVarint
- return function (write, value)
- write(tag_bytes)
- local size = 0
- for _, element in ipairs(value) do
- size = size + compute_value_size(modify_value(element))
- end
- EncodeVarint(write, size)
- for _, element in ipairs(value) do
- encode_value(write, modify_value(element))
- end
- end
- elseif is_repeated then
- local tag_bytes = TagBytes(field_number, wire_type)
- return function (write, value)
- for _, element in ipairs(value) do
- write(tag_bytes)
- encode_value(write, modify_value(element))
- end
- end
- else
- local tag_bytes = TagBytes(field_number, wire_type)
- return function (write, value)
- write(tag_bytes)
- encode_value(write, modify_value(value))
- end
- end
- end
- end
- function _StructPackEncoder(wire_type, value_size, format)
- return function(field_number, is_repeated, is_packed)
- local struct_pack = pb.struct_pack
- if is_packed then
- local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
- local EncodeVarint = _EncodeVarint
- return function (write, value)
- write(tag_bytes)
- EncodeVarint(write, #value * value_size)
- for _, element in ipairs(value) do
- struct_pack(write, format, element)
- end
- end
- elseif is_repeated then
- local tag_bytes = TagBytes(field_number, wire_type)
- return function (write, value)
- for _, element in ipairs(value) do
- write(tag_bytes)
- struct_pack(write, format, element)
- end
- end
- else
- local tag_bytes = TagBytes(field_number, wire_type)
- return function (write, value)
- write(tag_bytes)
- struct_pack(write, format, value)
- end
- end
- end
- end
- Int32Encoder = _SimpleEncoder(wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize)
- Int64Encoder = _SimpleEncoder(wire_format.WIRETYPE_VARINT, _EncodeSignedVarint64, _SignedVarintSize)
- EnumEncoder = Int32Encoder
- UInt32Encoder = _SimpleEncoder(wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize)
- UInt64Encoder = _SimpleEncoder(wire_format.WIRETYPE_VARINT, _EncodeVarint64, _VarintSize)
- SInt32Encoder = _ModifiedEncoder(
- wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize,
- wire_format.ZigZagEncode32)
- SInt64Encoder = _ModifiedEncoder(
- wire_format.WIRETYPE_VARINT, _EncodeVarint64, _VarintSize,
- wire_format.ZigZagEncode64)
- Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('I'))
- Fixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('Q'))
- SFixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('i'))
- SFixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('q'))
- FloatEncoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('f'))
- DoubleEncoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('d'))
- function BoolEncoder(field_number, is_repeated, is_packed)
- local false_byte = '\0'
- local true_byte = '\1'
- if is_packed then
- local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
- local EncodeVarint = _EncodeVarint
- return function (write, value)
- write(tag_bytes)
- EncodeVarint(write, #value)
- for _, element in ipairs(value) do
- if element then
- write(true_byte)
- else
- write(false_byte)
- end
- end
- end
- elseif is_repeated then
- local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
- return function(write, value)
- for _, element in ipairs(value) do
- write(tag_bytes)
- if element then
- write(true_byte)
- else
- write(false_byte)
- end
- end
- end
- else
- local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
- return function (write, value)
- write(tag_bytes)
- if value then
- return write(true_byte)
- end
- return write(false_byte)
- end
- end
- end
- function StringEncoder(field_number, is_repeated, is_packed)
- local tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
- local EncodeVarint = _EncodeVarint
- assert(not is_packed)
- if is_repeated then
- return function (write, value)
- for _, element in ipairs(value) do
- -- encoded = element.encode('utf-8')
- write(tag)
- EncodeVarint(write, #element)
- write(element)
- end
- end
- else
- return function (write, value)
- -- local encoded = value.encode('utf-8')
- write(tag)
- EncodeVarint(write, #value)
- return write(value)
- end
- end
- end
- function BytesEncoder(field_number, is_repeated, is_packed)
- local tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
- local EncodeVarint = _EncodeVarint
- assert(not is_packed)
- if is_repeated then
- return function (write, value)
- for _, element in ipairs(value) do
- write(tag)
- EncodeVarint(write, #element)
- write(element)
- end
- end
- else
- return function(write, value)
- write(tag)
- EncodeVarint(write, #value)
- return write(value)
- end
- end
- end
- function MessageEncoder(field_number, is_repeated, is_packed)
- local tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
- local EncodeVarint = _EncodeVarint
- assert(not is_packed)
- if is_repeated then
- return function(write, value)
- for _, element in ipairs(value) do
- write(tag)
- EncodeVarint(write, element:ByteSize())
- element:_InternalSerialize(write)
- end
- end
- else
- return function (write, value)
- write(tag)
- EncodeVarint(write, value:ByteSize())
- return value:_InternalSerialize(write)
- end
- end
- end
|