protobuf.lua 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. local c = require "protobuf.c"
  2. local setmetatable = setmetatable
  3. local type = type
  4. local table = table
  5. local assert = assert
  6. local pairs = pairs
  7. local ipairs = ipairs
  8. local string = string
  9. local print = print
  10. local io = io
  11. local tinsert = table.insert
  12. local rawget = rawget
  13. local rawset = rawset
  14. module "protobuf"
  15. local _pattern_cache = {}
  16. -- skynet clear
  17. local P = c._env_new()
  18. local GC = c._gc(P)
  19. function lasterror()
  20. return c._last_error(P)
  21. end
  22. local decode_type_cache = {}
  23. local _R_meta = {}
  24. function _R_meta:__index(key)
  25. local v = decode_type_cache[self._CType][key](self, key)
  26. self[key] = v
  27. return v
  28. end
  29. local _reader = {}
  30. function _reader:int(key)
  31. return c._rmessage_integer(self._CObj , key , 0)
  32. end
  33. function _reader:real(key)
  34. return c._rmessage_real(self._CObj , key , 0)
  35. end
  36. function _reader:string(key)
  37. return c._rmessage_string(self._CObj , key , 0)
  38. end
  39. function _reader:bool(key)
  40. return c._rmessage_integer(self._CObj , key , 0) ~= 0
  41. end
  42. function _reader:message(key, message_type)
  43. local rmessage = c._rmessage_message(self._CObj , key , 0)
  44. if rmessage then
  45. local v = {
  46. _CObj = rmessage,
  47. _CType = message_type,
  48. _Parent = self,
  49. }
  50. return setmetatable( v , _R_meta )
  51. end
  52. end
  53. function _reader:int32(key)
  54. return c._rmessage_int32(self._CObj , key , 0)
  55. end
  56. function _reader:int64(key)
  57. return c._rmessage_int64(self._CObj , key , 0)
  58. end
  59. function _reader:int52(key)
  60. return c._rmessage_int52(self._CObj , key , 0)
  61. end
  62. function _reader:uint52(key)
  63. return c._rmessage_uint52(self._CObj , key , 0)
  64. end
  65. function _reader:int_repeated(key)
  66. local cobj = self._CObj
  67. local n = c._rmessage_size(cobj , key)
  68. local ret = {}
  69. for i=0,n-1 do
  70. tinsert(ret, c._rmessage_integer(cobj , key , i))
  71. end
  72. return ret
  73. end
  74. function _reader:real_repeated(key)
  75. local cobj = self._CObj
  76. local n = c._rmessage_size(cobj , key)
  77. local ret = {}
  78. for i=0,n-1 do
  79. tinsert(ret, c._rmessage_real(cobj , key , i))
  80. end
  81. return ret
  82. end
  83. function _reader:string_repeated(key)
  84. local cobj = self._CObj
  85. local n = c._rmessage_size(cobj , key)
  86. local ret = {}
  87. for i=0,n-1 do
  88. tinsert(ret, c._rmessage_string(cobj , key , i))
  89. end
  90. return ret
  91. end
  92. function _reader:bool_repeated(key)
  93. local cobj = self._CObj
  94. local n = c._rmessage_size(cobj , key)
  95. local ret = {}
  96. for i=0,n-1 do
  97. tinsert(ret, c._rmessage_integer(cobj , key , i) ~= 0)
  98. end
  99. return ret
  100. end
  101. function _reader:message_repeated(key, message_type)
  102. local cobj = self._CObj
  103. local n = c._rmessage_size(cobj , key)
  104. local ret = {}
  105. for i=0,n-1 do
  106. local m = {
  107. _CObj = c._rmessage_message(cobj , key , i),
  108. _CType = message_type,
  109. _Parent = self,
  110. }
  111. tinsert(ret, setmetatable( m , _R_meta ))
  112. end
  113. return ret
  114. end
  115. function _reader:int32_repeated(key)
  116. local cobj = self._CObj
  117. local n = c._rmessage_size(cobj , key)
  118. local ret = {}
  119. for i=0,n-1 do
  120. tinsert(ret, c._rmessage_int32(cobj , key , i))
  121. end
  122. return ret
  123. end
  124. function _reader:int64_repeated(key)
  125. local cobj = self._CObj
  126. local n = c._rmessage_size(cobj , key)
  127. local ret = {}
  128. for i=0,n-1 do
  129. tinsert(ret, c._rmessage_int64(cobj , key , i))
  130. end
  131. return ret
  132. end
  133. function _reader:int52_repeated(key)
  134. local cobj = self._CObj
  135. local n = c._rmessage_size(cobj , key)
  136. local ret = {}
  137. for i=0,n-1 do
  138. tinsert(ret, c._rmessage_int52(cobj , key , i))
  139. end
  140. return ret
  141. end
  142. function _reader:uint52_repeated(key)
  143. local cobj = self._CObj
  144. local n = c._rmessage_size(cobj , key)
  145. local ret = {}
  146. for i=0,n-1 do
  147. tinsert(ret, c._rmessage_uint52(cobj , key , i))
  148. end
  149. return ret
  150. end
  151. _reader[1] = function(msg) return _reader.int end
  152. _reader[2] = function(msg) return _reader.real end
  153. _reader[3] = function(msg) return _reader.bool end
  154. _reader[4] = function(msg) return _reader.string end
  155. _reader[5] = function(msg) return _reader.string end
  156. _reader[6] = function(msg)
  157. local message = _reader.message
  158. return function(self,key)
  159. return message(self, key, msg)
  160. end
  161. end
  162. _reader[7] = function(msg) return _reader.int64 end
  163. _reader[8] = function(msg) return _reader.int32 end
  164. _reader[9] = _reader[5]
  165. _reader[10] = function(msg) return _reader.int52 end
  166. _reader[11] = function(msg) return _reader.uint52 end
  167. _reader[128+1] = function(msg) return _reader.int_repeated end
  168. _reader[128+2] = function(msg) return _reader.real_repeated end
  169. _reader[128+3] = function(msg) return _reader.bool_repeated end
  170. _reader[128+4] = function(msg) return _reader.string_repeated end
  171. _reader[128+5] = function(msg) return _reader.string_repeated end
  172. _reader[128+6] = function(msg)
  173. local message = _reader.message_repeated
  174. return function(self,key)
  175. return message(self, key, msg)
  176. end
  177. end
  178. _reader[128+7] = function(msg) return _reader.int64_repeated end
  179. _reader[128+8] = function(msg) return _reader.int32_repeated end
  180. _reader[128+9] = _reader[128+5]
  181. _reader[128+10] = function(msg) return _reader.int52_repeated end
  182. _reader[128+11] = function(msg) return _reader.uint52_repeated end
  183. local _decode_type_meta = {}
  184. function _decode_type_meta:__index(key)
  185. local t, msg = c._env_type(P, self._CType, key)
  186. local func = assert(_reader[t],key)(msg)
  187. self[key] = func
  188. return func
  189. end
  190. setmetatable(decode_type_cache , {
  191. __index = function(self, key)
  192. local v = setmetatable({ _CType = key } , _decode_type_meta)
  193. self[key] = v
  194. return v
  195. end
  196. })
  197. local function decode_message( message , buffer, length)
  198. local rmessage = c._rmessage_new(P, message, buffer, length)
  199. if rmessage then
  200. local self = {
  201. _CObj = rmessage,
  202. _CType = message,
  203. }
  204. c._add_rmessage(GC,rmessage)
  205. return setmetatable( self , _R_meta )
  206. end
  207. end
  208. ----------- encode ----------------
  209. local encode_type_cache = {}
  210. local function encode_message(CObj, message_type, t)
  211. local type = encode_type_cache[message_type]
  212. for k,v in pairs(t) do
  213. local func = type[k]
  214. func(CObj, k , v)
  215. end
  216. end
  217. local _writer = {
  218. int = c._wmessage_integer,
  219. real = c._wmessage_real,
  220. enum = c._wmessage_string,
  221. string = c._wmessage_string,
  222. int64 = c._wmessage_int64,
  223. int32 = c._wmessage_int32,
  224. int52 = c._wmessage_int52,
  225. uint52 = c._wmessage_uint52,
  226. }
  227. function _writer:bool(k,v)
  228. c._wmessage_integer(self, k, v and 1 or 0)
  229. end
  230. function _writer:message(k, v , message_type)
  231. local submessage = c._wmessage_message(self, k)
  232. encode_message(submessage, message_type, v)
  233. end
  234. function _writer:int_repeated(k,v)
  235. for _,v in ipairs(v) do
  236. c._wmessage_integer(self,k,v)
  237. end
  238. end
  239. function _writer:real_repeated(k,v)
  240. for _,v in ipairs(v) do
  241. c._wmessage_real(self,k,v)
  242. end
  243. end
  244. function _writer:bool_repeated(k,v)
  245. for _,v in ipairs(v) do
  246. c._wmessage_integer(self, k, v and 1 or 0)
  247. end
  248. end
  249. function _writer:string_repeated(k,v)
  250. for _,v in ipairs(v) do
  251. c._wmessage_string(self,k,v)
  252. end
  253. end
  254. function _writer:message_repeated(k,v, message_type)
  255. for _,v in ipairs(v) do
  256. local submessage = c._wmessage_message(self, k)
  257. encode_message(submessage, message_type, v)
  258. end
  259. end
  260. function _writer:int32_repeated(k,v)
  261. for _,v in ipairs(v) do
  262. c._wmessage_int32(self,k,v)
  263. end
  264. end
  265. function _writer:int64_repeated(k,v)
  266. for _,v in ipairs(v) do
  267. c._wmessage_int64(self,k,v)
  268. end
  269. end
  270. function _writer:int52_repeated(k,v)
  271. for _,v in ipairs(v) do
  272. c._wmessage_int52(self,k,v)
  273. end
  274. end
  275. function _writer:uint52_repeated(k,v)
  276. for _,v in ipairs(v) do
  277. c._wmessage_uint52(self,k,v)
  278. end
  279. end
  280. _writer[1] = function(msg) return _writer.int end
  281. _writer[2] = function(msg) return _writer.real end
  282. _writer[3] = function(msg) return _writer.bool end
  283. _writer[4] = function(msg) return _writer.string end
  284. _writer[5] = function(msg) return _writer.string end
  285. _writer[6] = function(msg)
  286. local message = _writer.message
  287. return function(self,key , v)
  288. return message(self, key, v, msg)
  289. end
  290. end
  291. _writer[7] = function(msg) return _writer.int64 end
  292. _writer[8] = function(msg) return _writer.int32 end
  293. _writer[9] = _writer[5]
  294. _writer[10] = function(msg) return _writer.int52 end
  295. _writer[11] = function(msg) return _writer.uint52 end
  296. _writer[128+1] = function(msg) return _writer.int_repeated end
  297. _writer[128+2] = function(msg) return _writer.real_repeated end
  298. _writer[128+3] = function(msg) return _writer.bool_repeated end
  299. _writer[128+4] = function(msg) return _writer.string_repeated end
  300. _writer[128+5] = function(msg) return _writer.string_repeated end
  301. _writer[128+6] = function(msg)
  302. local message = _writer.message_repeated
  303. return function(self,key, v)
  304. return message(self, key, v, msg)
  305. end
  306. end
  307. _writer[128+7] = function(msg) return _writer.int64_repeated end
  308. _writer[128+8] = function(msg) return _writer.int32_repeated end
  309. _writer[128+9] = _writer[128+5]
  310. _writer[128+10] = function(msg) return _writer.int52_repeated end
  311. _writer[128+11] = function(msg) return _writer.uint52_repeated end
  312. local _encode_type_meta = {}
  313. function _encode_type_meta:__index(key)
  314. local t, msg = c._env_type(P, self._CType, key)
  315. local func = assert(_writer[t],key)(msg)
  316. self[key] = func
  317. return func
  318. end
  319. setmetatable(encode_type_cache , {
  320. __index = function(self, key)
  321. local v = setmetatable({ _CType = key } , _encode_type_meta)
  322. self[key] = v
  323. return v
  324. end
  325. })
  326. function encode( message, t , func , ...)
  327. local encoder = c._wmessage_new(P, message)
  328. assert(encoder , message)
  329. encode_message(encoder, message, t)
  330. if func then
  331. local buffer, len = c._wmessage_buffer(encoder)
  332. local ret = func(buffer, len, ...)
  333. c._wmessage_delete(encoder)
  334. return ret
  335. else
  336. local s = c._wmessage_buffer_string(encoder)
  337. c._wmessage_delete(encoder)
  338. return s
  339. end
  340. end
  341. --------- unpack ----------
  342. local _pattern_type = {
  343. [1] = {"%d","i"},
  344. [2] = {"%F","r"},
  345. [3] = {"%d","b"},
  346. [4] = {"%d","i"},
  347. [5] = {"%s","s"},
  348. [6] = {"%s","m"},
  349. [7] = {"%D","x"},
  350. [8] = {"%d","p"},
  351. [10] = {"%D","d"},
  352. [11] = {"%D","u"},
  353. [128+1] = {"%a","I"},
  354. [128+2] = {"%a","R"},
  355. [128+3] = {"%a","B"},
  356. [128+4] = {"%a","I"},
  357. [128+5] = {"%a","S"},
  358. [128+6] = {"%a","M"},
  359. [128+7] = {"%a","X"},
  360. [128+8] = {"%a","P"},
  361. [128+10] = {"%a", "D" },
  362. [128+11] = {"%a", "U" },
  363. }
  364. _pattern_type[9] = _pattern_type[5]
  365. _pattern_type[128+9] = _pattern_type[128+5]
  366. local function _pattern_create(pattern)
  367. local iter = string.gmatch(pattern,"[^ ]+")
  368. local message = iter()
  369. local cpat = {}
  370. local lua = {}
  371. for v in iter do
  372. local tidx = c._env_type(P, message, v)
  373. local t = _pattern_type[tidx]
  374. assert(t,tidx)
  375. tinsert(cpat,v .. " " .. t[1])
  376. tinsert(lua,t[2])
  377. end
  378. local cobj = c._pattern_new(P, message , "@" .. table.concat(cpat," "))
  379. if cobj == nil then
  380. return
  381. end
  382. c._add_pattern(GC, cobj)
  383. local pat = {
  384. CObj = cobj,
  385. format = table.concat(lua),
  386. size = 0
  387. }
  388. pat.size = c._pattern_size(pat.format)
  389. return pat
  390. end
  391. setmetatable(_pattern_cache, {
  392. __index = function(t, key)
  393. local v = _pattern_create(key)
  394. t[key] = v
  395. return v
  396. end
  397. })
  398. function unpack(pattern, buffer, length)
  399. local pat = _pattern_cache[pattern]
  400. return c._pattern_unpack(pat.CObj , pat.format, pat.size, buffer, length)
  401. end
  402. function pack(pattern, ...)
  403. local pat = _pattern_cache[pattern]
  404. return c._pattern_pack(pat.CObj, pat.format, pat.size , ...)
  405. end
  406. function check(typename , field)
  407. if field == nil then
  408. return c._env_type(P,typename)
  409. else
  410. return c._env_type(P,typename,field) ~=0
  411. end
  412. end
  413. --------------
  414. local default_cache = {}
  415. -- todo : clear default_cache, v._CObj
  416. local function default_table(typename)
  417. local v = default_cache[typename]
  418. if v then
  419. return v
  420. end
  421. local default_inst = assert(decode_message(typename , ""))
  422. v = {
  423. __index = function(tb, key)
  424. local ret = default_inst[key]
  425. if 'table' ~= type(ret) then
  426. return ret
  427. end
  428. ret = setmetatable({}, { __index = ret })
  429. rawset(tb, key, ret)
  430. return ret
  431. end
  432. }
  433. default_cache[typename] = v
  434. return v
  435. end
  436. local decode_message_mt = {}
  437. local function decode_message_cb(typename, buffer)
  438. return setmetatable ( { typename, buffer } , decode_message_mt)
  439. end
  440. function decode(typename, buffer, length)
  441. local ret = {}
  442. local ok = c._decode(P, decode_message_cb , ret , typename, buffer, length)
  443. if ok then
  444. return setmetatable(ret , default_table(typename))
  445. else
  446. return false , c._last_error(P)
  447. end
  448. end
  449. local function expand(tbl)
  450. local typename = rawget(tbl , 1)
  451. local buffer = rawget(tbl , 2)
  452. tbl[1] , tbl[2] = nil , nil
  453. assert(c._decode(P, decode_message_cb , tbl , typename, buffer), typename)
  454. setmetatable(tbl , default_table(typename))
  455. end
  456. function decode_message_mt.__index(tbl, key)
  457. expand(tbl)
  458. return tbl[key]
  459. end
  460. function decode_message_mt.__pairs(tbl)
  461. expand(tbl)
  462. return pairs(tbl)
  463. end
  464. local function set_default(typename, tbl)
  465. for k,v in pairs(tbl) do
  466. if type(v) == "table" then
  467. local t, msg = c._env_type(P, typename, k)
  468. if t == 6 then
  469. set_default(msg, v)
  470. elseif t == 128+6 then
  471. for _,v in ipairs(v) do
  472. set_default(msg, v)
  473. end
  474. end
  475. end
  476. end
  477. return setmetatable(tbl , default_table(typename))
  478. end
  479. function register( buffer)
  480. c._env_register(P, buffer)
  481. end
  482. function register_file(filename)
  483. local f = assert(io.open(filename , "rb"))
  484. local buffer = f:read "*a"
  485. c._env_register(P, buffer)
  486. f:close()
  487. end
  488. function enum_id(enum_type, enum_name)
  489. return c._env_enum_id(P, enum_type, enum_name)
  490. end
  491. function extract(tbl)
  492. local typename = rawget(tbl , 1)
  493. local buffer = rawget(tbl , 2)
  494. if type(typename) == "string" and type(buffer) == "string" then
  495. if check(typename) then
  496. expand(tbl)
  497. end
  498. end
  499. for k, v in pairs(tbl) do
  500. if type(v) == "table" then
  501. extract(v)
  502. end
  503. end
  504. end
  505. default=set_default