encoder.lua 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. --
  2. --------------------------------------------------------------------------------
  3. -- FILE: encoder.lua
  4. -- DESCRIPTION: protoc-gen-lua
  5. -- Google's Protocol Buffers project, ported to lua.
  6. -- https://code.google.com/p/protoc-gen-lua/
  7. --
  8. -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com
  9. -- All rights reserved.
  10. --
  11. -- Use, modification and distribution are subject to the "New BSD License"
  12. -- as listed at <url: http://www.opensource.org/licenses/bsd-license.php >.
  13. --
  14. -- COMPANY: NetEase
  15. -- CREATED: 2010年07月29日 19时30分46秒 CST
  16. --------------------------------------------------------------------------------
  17. --
  18. local string = string
  19. local table = table
  20. local ipairs = ipairs
  21. local assert =assert
  22. local pb = require "pb"
  23. local wire_format = require "protobuf.wire_format"
  24. module "protobuf.encoder"
  25. function _VarintSize(value)
  26. if value <= 0x7f then return 1 end
  27. if value <= 0x3fff then return 2 end
  28. if value <= 0x1fffff then return 3 end
  29. if value <= 0xfffffff then return 4 end
  30. if value <= 0x7ffffffff then return 5 end
  31. if value <= 0x3ffffffffff then return 6 end
  32. if value <= 0x1ffffffffffff then return 7 end
  33. if value <= 0xffffffffffffff then return 8 end
  34. if value <= 0x7fffffffffffffff then return 9 end
  35. return 10
  36. end
  37. function _SignedVarintSize(value)
  38. if value < 0 then return 10 end
  39. if value <= 0x7f then return 1 end
  40. if value <= 0x3fff then return 2 end
  41. if value <= 0x1fffff then return 3 end
  42. if value <= 0xfffffff then return 4 end
  43. if value <= 0x7ffffffff then return 5 end
  44. if value <= 0x3ffffffffff then return 6 end
  45. if value <= 0x1ffffffffffff then return 7 end
  46. if value <= 0xffffffffffffff then return 8 end
  47. if value <= 0x7fffffffffffffff then return 9 end
  48. return 10
  49. end
  50. function _TagSize(field_number)
  51. return _VarintSize(wire_format.PackTag(field_number, 0))
  52. end
  53. function _SimpleSizer(compute_value_size)
  54. return function(field_number, is_repeated, is_packed)
  55. local tag_size = _TagSize(field_number)
  56. if is_packed then
  57. local VarintSize = _VarintSize
  58. return function(value)
  59. local result = 0
  60. for _, element in ipairs(value) do
  61. result = result + compute_value_size(element)
  62. end
  63. return result + VarintSize(result) + tag_size
  64. end
  65. elseif is_repeated then
  66. return function(value)
  67. local result = tag_size * #value
  68. for _, element in ipairs(value) do
  69. result = result + compute_value_size(element)
  70. end
  71. return result
  72. end
  73. else
  74. return function (value)
  75. return tag_size + compute_value_size(value)
  76. end
  77. end
  78. end
  79. end
  80. function _ModifiedSizer(compute_value_size, modify_value)
  81. return function (field_number, is_repeated, is_packed)
  82. local tag_size = _TagSize(field_number)
  83. if is_packed then
  84. local VarintSize = _VarintSize
  85. return function (value)
  86. local result = 0
  87. for _, element in ipairs(value) do
  88. result = result + compute_value_size(modify_value(element))
  89. end
  90. return result + VarintSize(result) + tag_size
  91. end
  92. elseif is_repeated then
  93. return function (value)
  94. local result = tag_size * #value
  95. for _, element in ipairs(value) do
  96. result = result + compute_value_size(modify_value(element))
  97. end
  98. return result
  99. end
  100. else
  101. return function (value)
  102. return tag_size + compute_value_size(modify_value(value))
  103. end
  104. end
  105. end
  106. end
  107. function _FixedSizer(value_size)
  108. return function (field_number, is_repeated, is_packed)
  109. local tag_size = _TagSize(field_number)
  110. if is_packed then
  111. local VarintSize = _VarintSize
  112. return function (value)
  113. local result = #value * value_size
  114. return result + VarintSize(result) + tag_size
  115. end
  116. elseif is_repeated then
  117. local element_size = value_size + tag_size
  118. return function(value)
  119. return #value * element_size
  120. end
  121. else
  122. local field_size = value_size + tag_size
  123. return function (value)
  124. return field_size
  125. end
  126. end
  127. end
  128. end
  129. Int32Sizer = _SimpleSizer(_SignedVarintSize)
  130. Int64Sizer = _SimpleSizer(pb.signed_varint_size)
  131. EnumSizer = Int32Sizer
  132. UInt32Sizer = _SimpleSizer(_VarintSize)
  133. UInt64Sizer = _SimpleSizer(pb.varint_size)
  134. SInt32Sizer = _ModifiedSizer(_SignedVarintSize, wire_format.ZigZagEncode32)
  135. SInt64Sizer = SInt32Sizer
  136. Fixed32Sizer = _FixedSizer(4)
  137. SFixed32Sizer = Fixed32Sizer
  138. FloatSizer = Fixed32Sizer
  139. Fixed64Sizer = _FixedSizer(8)
  140. SFixed64Sizer = Fixed64Sizer
  141. DoubleSizer = Fixed64Sizer
  142. BoolSizer = _FixedSizer(1)
  143. function StringSizer(field_number, is_repeated, is_packed)
  144. local tag_size = _TagSize(field_number)
  145. local VarintSize = _VarintSize
  146. assert(not is_packed)
  147. if is_repeated then
  148. return function(value)
  149. local result = tag_size * #value
  150. for _, element in ipairs(value) do
  151. local l = #element
  152. result = result + VarintSize(l) + l
  153. end
  154. return result
  155. end
  156. else
  157. return function(value)
  158. local l = #value
  159. return tag_size + VarintSize(l) + l
  160. end
  161. end
  162. end
  163. function BytesSizer(field_number, is_repeated, is_packed)
  164. local tag_size = _TagSize(field_number)
  165. local VarintSize = _VarintSize
  166. assert(not is_packed)
  167. if is_repeated then
  168. return function (value)
  169. local result = tag_size * #value
  170. for _,element in ipairs(value) do
  171. local l = #element
  172. result = result + VarintSize(l) + l
  173. end
  174. return result
  175. end
  176. else
  177. return function (value)
  178. local l = #value
  179. return tag_size + VarintSize(l) + l
  180. end
  181. end
  182. end
  183. function MessageSizer(field_number, is_repeated, is_packed)
  184. local tag_size = _TagSize(field_number)
  185. local VarintSize = _VarintSize
  186. assert(not is_packed)
  187. if is_repeated then
  188. return function(value)
  189. local result = tag_size * #value
  190. for _,element in ipairs(value) do
  191. local l = element:ByteSize()
  192. result = result + VarintSize(l) + l
  193. end
  194. return result
  195. end
  196. else
  197. return function (value)
  198. local l = value:ByteSize()
  199. return tag_size + VarintSize(l) + l
  200. end
  201. end
  202. end
  203. -- ====================================================================
  204. -- Encoders!
  205. local _EncodeVarint = pb.varint_encoder
  206. local _EncodeSignedVarint = pb.signed_varint_encoder
  207. local _EncodeVarint64 = pb.varint_encoder64
  208. local _EncodeSignedVarint64 = pb.signed_varint_encoder64
  209. function _VarintBytes(value)
  210. local out = {}
  211. local write = function(value)
  212. out[#out + 1 ] = value
  213. end
  214. _EncodeSignedVarint(write, value)
  215. return table.concat(out)
  216. end
  217. function TagBytes(field_number, wire_type)
  218. return _VarintBytes(wire_format.PackTag(field_number, wire_type))
  219. end
  220. function _SimpleEncoder(wire_type, encode_value, compute_value_size)
  221. return function(field_number, is_repeated, is_packed)
  222. if is_packed then
  223. local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
  224. local EncodeVarint = _EncodeVarint
  225. return function(write, value)
  226. write(tag_bytes)
  227. local size = 0
  228. for _, element in ipairs(value) do
  229. size = size + compute_value_size(element)
  230. end
  231. EncodeVarint(write, size)
  232. for element in value do
  233. encode_value(write, element)
  234. end
  235. end
  236. elseif is_repeated then
  237. local tag_bytes = TagBytes(field_number, wire_type)
  238. return function(write, value)
  239. for _, element in ipairs(value) do
  240. write(tag_bytes)
  241. encode_value(write, element)
  242. end
  243. end
  244. else
  245. local tag_bytes = TagBytes(field_number, wire_type)
  246. return function(write, value)
  247. write(tag_bytes)
  248. encode_value(write, value)
  249. end
  250. end
  251. end
  252. end
  253. function _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value)
  254. return function (field_number, is_repeated, is_packed)
  255. if is_packed then
  256. local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
  257. local EncodeVarint = _EncodeVarint
  258. return function (write, value)
  259. write(tag_bytes)
  260. local size = 0
  261. for _, element in ipairs(value) do
  262. size = size + compute_value_size(modify_value(element))
  263. end
  264. EncodeVarint(write, size)
  265. for _, element in ipairs(value) do
  266. encode_value(write, modify_value(element))
  267. end
  268. end
  269. elseif is_repeated then
  270. local tag_bytes = TagBytes(field_number, wire_type)
  271. return function (write, value)
  272. for _, element in ipairs(value) do
  273. write(tag_bytes)
  274. encode_value(write, modify_value(element))
  275. end
  276. end
  277. else
  278. local tag_bytes = TagBytes(field_number, wire_type)
  279. return function (write, value)
  280. write(tag_bytes)
  281. encode_value(write, modify_value(value))
  282. end
  283. end
  284. end
  285. end
  286. function _StructPackEncoder(wire_type, value_size, format)
  287. return function(field_number, is_repeated, is_packed)
  288. local struct_pack = pb.struct_pack
  289. if is_packed then
  290. local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
  291. local EncodeVarint = _EncodeVarint
  292. return function (write, value)
  293. write(tag_bytes)
  294. EncodeVarint(write, #value * value_size)
  295. for _, element in ipairs(value) do
  296. struct_pack(write, format, element)
  297. end
  298. end
  299. elseif is_repeated then
  300. local tag_bytes = TagBytes(field_number, wire_type)
  301. return function (write, value)
  302. for _, element in ipairs(value) do
  303. write(tag_bytes)
  304. struct_pack(write, format, element)
  305. end
  306. end
  307. else
  308. local tag_bytes = TagBytes(field_number, wire_type)
  309. return function (write, value)
  310. write(tag_bytes)
  311. struct_pack(write, format, value)
  312. end
  313. end
  314. end
  315. end
  316. Int32Encoder = _SimpleEncoder(wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize)
  317. Int64Encoder = _SimpleEncoder(wire_format.WIRETYPE_VARINT, _EncodeSignedVarint64, _SignedVarintSize)
  318. EnumEncoder = Int32Encoder
  319. UInt32Encoder = _SimpleEncoder(wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize)
  320. UInt64Encoder = _SimpleEncoder(wire_format.WIRETYPE_VARINT, _EncodeVarint64, _VarintSize)
  321. SInt32Encoder = _ModifiedEncoder(
  322. wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize,
  323. wire_format.ZigZagEncode32)
  324. SInt64Encoder = _ModifiedEncoder(
  325. wire_format.WIRETYPE_VARINT, _EncodeVarint64, _VarintSize,
  326. wire_format.ZigZagEncode64)
  327. Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('I'))
  328. Fixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('Q'))
  329. SFixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('i'))
  330. SFixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('q'))
  331. FloatEncoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('f'))
  332. DoubleEncoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('d'))
  333. function BoolEncoder(field_number, is_repeated, is_packed)
  334. local false_byte = '\0'
  335. local true_byte = '\1'
  336. if is_packed then
  337. local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
  338. local EncodeVarint = _EncodeVarint
  339. return function (write, value)
  340. write(tag_bytes)
  341. EncodeVarint(write, #value)
  342. for _, element in ipairs(value) do
  343. if element then
  344. write(true_byte)
  345. else
  346. write(false_byte)
  347. end
  348. end
  349. end
  350. elseif is_repeated then
  351. local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
  352. return function(write, value)
  353. for _, element in ipairs(value) do
  354. write(tag_bytes)
  355. if element then
  356. write(true_byte)
  357. else
  358. write(false_byte)
  359. end
  360. end
  361. end
  362. else
  363. local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
  364. return function (write, value)
  365. write(tag_bytes)
  366. if value then
  367. return write(true_byte)
  368. end
  369. return write(false_byte)
  370. end
  371. end
  372. end
  373. function StringEncoder(field_number, is_repeated, is_packed)
  374. local tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
  375. local EncodeVarint = _EncodeVarint
  376. assert(not is_packed)
  377. if is_repeated then
  378. return function (write, value)
  379. for _, element in ipairs(value) do
  380. -- encoded = element.encode('utf-8')
  381. write(tag)
  382. EncodeVarint(write, #element)
  383. write(element)
  384. end
  385. end
  386. else
  387. return function (write, value)
  388. -- local encoded = value.encode('utf-8')
  389. write(tag)
  390. EncodeVarint(write, #value)
  391. return write(value)
  392. end
  393. end
  394. end
  395. function BytesEncoder(field_number, is_repeated, is_packed)
  396. local tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
  397. local EncodeVarint = _EncodeVarint
  398. assert(not is_packed)
  399. if is_repeated then
  400. return function (write, value)
  401. for _, element in ipairs(value) do
  402. write(tag)
  403. EncodeVarint(write, #element)
  404. write(element)
  405. end
  406. end
  407. else
  408. return function(write, value)
  409. write(tag)
  410. EncodeVarint(write, #value)
  411. return write(value)
  412. end
  413. end
  414. end
  415. function MessageEncoder(field_number, is_repeated, is_packed)
  416. local tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
  417. local EncodeVarint = _EncodeVarint
  418. assert(not is_packed)
  419. if is_repeated then
  420. return function(write, value)
  421. for _, element in ipairs(value) do
  422. write(tag)
  423. EncodeVarint(write, element:ByteSize())
  424. element:_InternalSerialize(write)
  425. end
  426. end
  427. else
  428. return function (write, value)
  429. write(tag)
  430. EncodeVarint(write, value:ByteSize())
  431. return value:_InternalSerialize(write)
  432. end
  433. end
  434. end