protobuf.lua 12 KB

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