|
|
- -- --
- -- --------------------------------------------------------------------------------
- -- -- FILE: decoder.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分51秒 CST
- -- --------------------------------------------------------------------------------
- -- --
- -- local string = string
- -- local table = table
- -- local assert = assert
- -- local ipairs = ipairs
- -- local error = error
- -- local print = print
-
- -- local pb = require "pb"
- -- local encoder = require "protobuf.encoder"
- -- local wire_format = require "protobuf.wire_format"
- -- module "protobuf.decoder"
-
- -- local _DecodeVarint = pb.varint_decoder
- -- local _DecodeSignedVarint = pb.signed_varint_decoder
-
- -- local _DecodeVarint32 = pb.varint_decoder
- -- local _DecodeSignedVarint32 = pb.signed_varint_decoder
-
- -- local _DecodeVarint64 = pb.varint_decoder64
- -- local _DecodeSignedVarint64 = pb.signed_varint_decoder64
-
- -- ReadTag = pb.read_tag
-
- -- local function _SimpleDecoder(wire_type, decode_value)
- -- return function(field_number, is_repeated, is_packed, key, new_default)
- -- if is_packed then
- -- local DecodeVarint = _DecodeVarint
- -- return function (buffer, pos, pend, message, field_dict)
- -- local value = field_dict[key]
- -- if value == nil then
- -- value = new_default(message)
- -- field_dict[key] = value
- -- end
- -- local endpoint
- -- endpoint, pos = DecodeVarint(buffer, pos)
- -- endpoint = endpoint + pos
- -- if endpoint > pend then
- -- LogError('Truncated message.')
- -- end
- -- local element
- -- while pos < endpoint do
- -- element, pos = decode_value(buffer, pos)
- -- value[#value + 1] = element
- -- end
- -- if pos > endpoint then
- -- value:remove(#value)
- -- LogError('Packed element was truncated.')
- -- end
- -- return pos
- -- end
- -- elseif is_repeated then
- -- local tag_bytes = encoder.TagBytes(field_number, wire_type)
- -- local tag_len = #tag_bytes
- -- local sub = string.sub
- -- return function(buffer, pos, pend, message, field_dict)
- -- local value = field_dict[key]
- -- if value == nil then
- -- value = new_default(message)
- -- field_dict[key] = value
- -- end
- -- while 1 do
- -- local element, new_pos = decode_value(buffer, pos)
- -- value:append(element)
- -- pos = new_pos + tag_len
- -- if sub(buffer, new_pos+1, pos) ~= tag_bytes or new_pos >= pend then
- -- if new_pos > pend then
- -- LogError('Truncated message.')
- -- end
- -- return new_pos
- -- end
- -- end
- -- end
- -- else
- -- return function (buffer, pos, pend, message, field_dict)
- -- field_dict[key], pos = decode_value(buffer, pos)
- -- if pos > pend then
- -- field_dict[key] = nil
- -- LogError('Truncated message.')
- -- end
- -- return pos
- -- end
- -- end
- -- end
- -- end
-
- -- local function _ModifiedDecoder(wire_type, decode_value, modify_value)
- -- local InnerDecode = function (buffer, pos)
- -- local result, new_pos = decode_value(buffer, pos)
- -- return modify_value(result), new_pos
- -- end
- -- return _SimpleDecoder(wire_type, InnerDecode)
- -- end
-
- -- local function _StructPackDecoder(wire_type, value_size, format)
- -- local struct_unpack = pb.struct_unpack
-
- -- function InnerDecode(buffer, pos)
- -- local new_pos = pos + value_size
- -- local result = struct_unpack(format, buffer, pos)
- -- return result, new_pos
- -- end
- -- return _SimpleDecoder(wire_type, InnerDecode)
- -- end
-
- -- local function _Boolean(value)
- -- return value ~= 0
- -- end
-
- -- Int32Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeSignedVarint32)
- -- EnumDecoder = Int32Decoder
-
- -- Int64Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeSignedVarint64)
-
- -- UInt32Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint32)
- -- UInt64Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint64)
-
- -- SInt32Decoder = _ModifiedDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint32, wire_format.ZigZagDecode32)
- -- SInt64Decoder = _ModifiedDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint64, wire_format.ZigZagDecode64)
-
- -- Fixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('I'))
- -- Fixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('Q'))
- -- SFixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('i'))
- -- SFixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('q'))
- -- FloatDecoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('f'))
- -- DoubleDecoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('d'))
-
-
- -- BoolDecoder = _ModifiedDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint, _Boolean)
-
-
- -- function StringDecoder(field_number, is_repeated, is_packed, key, new_default)
- -- local DecodeVarint = _DecodeVarint
- -- local sub = string.sub
- -- -- local unicode = unicode
- -- assert(not is_packed)
- -- if is_repeated then
- -- local tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
- -- local tag_len = #tag_bytes
- -- return function (buffer, pos, pend, message, field_dict)
- -- local value = field_dict[key]
- -- if value == nil then
- -- value = new_default(message)
- -- field_dict[key] = value
- -- end
- -- while 1 do
- -- local size, new_pos
- -- size, pos = DecodeVarint(buffer, pos)
- -- new_pos = pos + size
- -- if new_pos > pend then
- -- LogError('Truncated string.')
- -- end
- -- value:append(sub(buffer, pos+1, new_pos))
- -- pos = new_pos + tag_len
- -- if sub(buffer, new_pos + 1, pos) ~= tag_bytes or new_pos == pend then
- -- return new_pos
- -- end
- -- end
- -- end
- -- else
- -- return function (buffer, pos, pend, message, field_dict)
- -- local size, new_pos
- -- size, pos = DecodeVarint(buffer, pos)
- -- new_pos = pos + size
- -- if new_pos > pend then
- -- LogError('Truncated string.')
- -- end
- -- field_dict[key] = sub(buffer, pos + 1, new_pos)
- -- return new_pos
- -- end
- -- end
- -- end
-
- -- function BytesDecoder(field_number, is_repeated, is_packed, key, new_default)
- -- local DecodeVarint = _DecodeVarint
- -- local sub = string.sub
- -- assert(not is_packed)
- -- if is_repeated then
- -- local tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
- -- local tag_len = #tag_bytes
- -- return function (buffer, pos, pend, message, field_dict)
- -- local value = field_dict[key]
- -- if value == nil then
- -- value = new_default(message)
- -- field_dict[key] = value
- -- end
- -- while 1 do
- -- local size, new_pos
- -- size, pos = DecodeVarint(buffer, pos)
- -- new_pos = pos + size
- -- if new_pos > pend then
- -- LogError('Truncated string.')
- -- end
- -- value:append(sub(buffer, pos + 1, new_pos))
- -- pos = new_pos + tag_len
- -- if sub(buffer, new_pos + 1, pos) ~= tag_bytes or new_pos == pend then
- -- return new_pos
- -- end
- -- end
- -- end
- -- else
- -- return function(buffer, pos, pend, message, field_dict)
- -- local size, new_pos
- -- size, pos = DecodeVarint(buffer, pos)
- -- new_pos = pos + size
- -- if new_pos > pend then
- -- LogError('Truncated string.')
- -- end
- -- field_dict[key] = sub(buffer, pos + 1, new_pos)
- -- return new_pos
- -- end
- -- end
- -- end
-
- -- function MessageDecoder(field_number, is_repeated, is_packed, key, new_default)
- -- local DecodeVarint = _DecodeVarint
- -- local sub = string.sub
-
- -- assert(not is_packed)
- -- if is_repeated then
- -- local tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
- -- local tag_len = #tag_bytes
- -- return function (buffer, pos, pend, message, field_dict)
- -- local value = field_dict[key]
- -- if value == nil then
- -- value = new_default(message)
- -- field_dict[key] = value
- -- end
- -- while 1 do
- -- local size, new_pos
- -- size, pos = DecodeVarint(buffer, pos)
- -- new_pos = pos + size
- -- if new_pos > pend then
- -- LogError('Truncated message.')
- -- end
- -- if value:add():_InternalParse(buffer, pos, new_pos) ~= new_pos then
- -- LogError('Unexpected end-group tag.')
- -- end
- -- pos = new_pos + tag_len
- -- if sub(buffer, new_pos + 1, pos) ~= tag_bytes or new_pos == pend then
- -- return new_pos
- -- end
- -- end
- -- end
- -- else
- -- return function (buffer, pos, pend, message, field_dict)
- -- local value = field_dict[key]
- -- if value == nil then
- -- value = new_default(message)
- -- field_dict[key] = value
- -- end
- -- local size, new_pos
- -- size, pos = DecodeVarint(buffer, pos)
- -- new_pos = pos + size
- -- if new_pos > pend then
- -- LogError('Truncated message.')
- -- end
- -- if value:_InternalParse(buffer, pos, new_pos) ~= new_pos then
- -- LogError('Unexpected end-group tag.')
- -- end
- -- return new_pos
- -- end
- -- end
- -- end
-
- -- function _SkipVarint(buffer, pos, pend)
- -- local value
- -- value, pos = _DecodeVarint(buffer, pos)
- -- return pos
- -- end
-
- -- function _SkipFixed64(buffer, pos, pend)
- -- pos = pos + 8
- -- if pos > pend then
- -- LogError('Truncated message.')
- -- end
- -- return pos
- -- end
-
- -- function _SkipLengthDelimited(buffer, pos, pend)
- -- local size
- -- size, pos = _DecodeVarint(buffer, pos)
- -- pos = pos + size
- -- if pos > pend then
- -- LogError('Truncated message.')
- -- end
- -- return pos
- -- end
-
- -- function _SkipFixed32(buffer, pos, pend)
- -- pos = pos + 4
- -- if pos > pend then
- -- LogError('Truncated message.')
- -- end
- -- return pos
- -- end
-
- -- function _RaiseInvalidWireType(buffer, pos, pend)
- -- LogError('Tag had invalid wire type.')
- -- end
-
- -- function _FieldSkipper()
- -- WIRETYPE_TO_SKIPPER = {
- -- _SkipVarint,
- -- _SkipFixed64,
- -- _SkipLengthDelimited,
- -- _SkipGroup,
- -- _EndGroup,
- -- _SkipFixed32,
- -- _RaiseInvalidWireType,
- -- _RaiseInvalidWireType,
- -- }
-
- -- -- wiretype_mask = wire_format.TAG_TYPE_MASK
- -- local ord = string.byte
- -- local sub = string.sub
-
- -- return function (buffer, pos, pend, tag_bytes)
- -- local wire_type = ord(sub(tag_bytes, 1, 1)) % 8 + 1
- -- return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, pend)
- -- end
- -- end
-
- -- SkipField = _FieldSkipper()
|