luat_lib_protobuf.c 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248
  1. /*
  2. @module protobuf
  3. @summary ProtoBuffs编解码
  4. @version 1.0
  5. @date 2022.09.08
  6. @demo protobuf
  7. @tag LUAT_USE_PROTOBUF
  8. @usage
  9. -- 加载 pb 文件, 这个是从pbtxt 转换得到的
  10. -- 转换命令: protoc.exe -operson.pb --cpp_out=cpp person.pbtxt
  11. -- protoc.exe 下载地址: https://github.com/protocolbuffers/protobuf/releases
  12. protobuf.load(io.readFile("/luadb/person.pb"))
  13. local tb = {
  14. name = "wendal",
  15. id = 123,
  16. email = "abc@qq.com"
  17. }
  18. -- 用 protobuf 编码数据
  19. local data = protobuf.encode("Person", tb)
  20. if data then
  21. -- 打印数据长度. 编码后的数据含不可见字符, toHex是方便显示
  22. log.info("protobuf", #data, (data:toHex()))
  23. end
  24. */
  25. #ifdef _MSC_VER
  26. # define _CRT_SECURE_NO_WARNINGS
  27. # define _CRT_NONSTDC_NO_WARNINGS
  28. # pragma warning(disable: 4244) /* int -> char */
  29. # pragma warning(disable: 4706) /* = in if condition */
  30. # pragma warning(disable: 4709) /* comma in array index */
  31. # pragma warning(disable: 4127) /* const in if condition */
  32. #endif
  33. #define PB_STATIC_API
  34. #include "pb.h"
  35. PB_NS_BEGIN
  36. #define LUA_LIB
  37. #include <lua.h>
  38. #include <lauxlib.h>
  39. #include <stdio.h>
  40. #include <errno.h>
  41. /* Lua util routines */
  42. #define PB_STATE "pb.State"
  43. #define PB_BUFFER "pb.Buffer"
  44. #define PB_SLICE "pb.Slice"
  45. #define check_buffer(L,idx) ((pb_Buffer*)luaL_checkudata(L,idx,PB_BUFFER))
  46. #define test_buffer(L,idx) ((pb_Buffer*)luaL_testudata(L,idx,PB_BUFFER))
  47. #define check_slice(L,idx) ((pb_Slice*)luaL_checkudata(L,idx,PB_SLICE))
  48. #define test_slice(L,idx) ((pb_Slice*)luaL_testudata(L,idx,PB_SLICE))
  49. #define push_slice(L,s) lua_pushlstring((L), (s).p, pb_len((s)))
  50. #define return_self(L) { return lua_settop(L, 1), 1; }
  51. static int lpb_relindex(int idx, int offset) {
  52. return idx < 0 && idx > LUA_REGISTRYINDEX ? idx - offset : idx;
  53. }
  54. #if LUA_VERSION_NUM < 502
  55. #include <assert.h>
  56. # define LUA_OK 0
  57. # define lua_rawlen lua_objlen
  58. # define luaL_setfuncs(L,l,n) (assert(n==0), luaL_register(L,NULL,l))
  59. # define luaL_setmetatable(L, name) \
  60. (luaL_getmetatable((L), (name)), lua_setmetatable(L, -2))
  61. static void lua_rawgetp(lua_State *L, int idx, const void *p) {
  62. lua_pushlightuserdata(L, (void*)p);
  63. lua_rawget(L, lpb_relindex(idx, 1));
  64. }
  65. static void lua_rawsetp(lua_State *L, int idx, const void *p) {
  66. lua_pushlightuserdata(L, (void*)p);
  67. lua_insert(L, -2);
  68. lua_rawset(L, lpb_relindex(idx, 1));
  69. }
  70. #ifndef luaL_newlib /* not LuaJIT 2.1 */
  71. #define luaL_newlib(L,l) (lua_newtable(L), luaL_register(L,NULL,l))
  72. static lua_Integer lua_tointegerx(lua_State *L, int idx, int *isint) {
  73. lua_Integer i = lua_tointeger(L, idx);
  74. if (isint) *isint = (i != 0 || lua_type(L, idx) == LUA_TNUMBER);
  75. return i;
  76. }
  77. static lua_Number lua_tonumberx(lua_State *L, int idx, int *isnum) {
  78. lua_Number i = lua_tonumber(L, idx);
  79. if (isnum) *isnum = (i != 0 || lua_type(L, idx) == LUA_TNUMBER);
  80. return i;
  81. }
  82. static void *luaL_testudata(lua_State *L, int idx, const char *type) {
  83. void *p = lua_touserdata(L, idx);
  84. if (p != NULL && lua_getmetatable(L, idx)) {
  85. lua_getfield(L, LUA_REGISTRYINDEX, type);
  86. if (!lua_rawequal(L, -2, -1))
  87. p = NULL;
  88. lua_pop(L, 2);
  89. return p;
  90. }
  91. return NULL;
  92. }
  93. #endif
  94. #ifdef LUAI_BITSINT /* not LuaJIT */
  95. #include <errno.h>
  96. static int luaL_fileresult(lua_State *L, int stat, const char *fname) {
  97. int en = errno;
  98. if (stat) return lua_pushboolean(L, 1), 1;
  99. lua_pushnil(L);
  100. lua_pushfstring(L, "%s: %s", fname, strerror(en));
  101. /*if (fname) lua_pushfstring(L, "%s: %s", fname, strerror(en));
  102. else lua_pushstring(L, strerror(en));*//* NOT USED */
  103. lua_pushinteger(L, en);
  104. return 3;
  105. }
  106. #endif /* not LuaJIT */
  107. #endif
  108. #if LUA_VERSION_NUM >= 503
  109. # define lua53_getfield lua_getfield
  110. # define lua53_rawgeti lua_rawgeti
  111. # define lua53_rawgetp lua_rawgetp
  112. #else /* not Lua 5.3 */
  113. static int lua53_getfield(lua_State *L, int idx, const char *field)
  114. { return lua_getfield(L, idx, field), lua_type(L, -1); }
  115. static int lua53_rawgeti(lua_State *L, int idx, lua_Integer i)
  116. { return lua_rawgeti(L, idx, i), lua_type(L, -1); }
  117. static int lua53_rawgetp(lua_State *L, int idx, const void *p)
  118. { return lua_rawgetp(L, idx, p), lua_type(L, -1); }
  119. #endif
  120. /* protobuf global state */
  121. #define lpbS_state(LS) ((LS)->state)
  122. #define lpb_name(LS,s) pb_name(lpbS_state(LS), (s), &(LS)->cache)
  123. static const pb_State *global_state = NULL;
  124. static const char state_name[] = PB_STATE;
  125. enum lpb_Int64Mode { LPB_NUMBER, LPB_STRING, LPB_HEXSTRING };
  126. enum lpb_EncodeMode { LPB_DEFDEF, LPB_COPYDEF, LPB_METADEF, LPB_NODEF };
  127. typedef struct lpb_State {
  128. const pb_State *state;
  129. pb_State local;
  130. pb_Cache cache;
  131. pb_Buffer buffer;
  132. int defs_index;
  133. int enc_hooks_index;
  134. int dec_hooks_index;
  135. unsigned use_dec_hooks : 1;
  136. unsigned use_enc_hooks : 1;
  137. unsigned enum_as_value : 1;
  138. unsigned encode_mode : 2; /* lpb_EncodeMode */
  139. unsigned int64_mode : 2; /* lpb_Int64Mode */
  140. unsigned encode_default_values : 1;
  141. unsigned decode_default_array : 1;
  142. unsigned decode_default_message : 1;
  143. unsigned encode_order : 1;
  144. } lpb_State;
  145. static int lpb_reftable(lua_State *L, int ref) {
  146. if (ref != LUA_NOREF) {
  147. lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
  148. return ref;
  149. } else {
  150. lua_newtable(L);
  151. lua_pushvalue(L, -1);
  152. return luaL_ref(L, LUA_REGISTRYINDEX);
  153. }
  154. }
  155. static void lpb_pushdeftable(lua_State *L, lpb_State *LS)
  156. { LS->defs_index = lpb_reftable(L, LS->defs_index); }
  157. static void lpb_pushenchooktable(lua_State *L, lpb_State *LS)
  158. { LS->enc_hooks_index = lpb_reftable(L, LS->enc_hooks_index); }
  159. static void lpb_pushdechooktable(lua_State *L, lpb_State *LS)
  160. { LS->dec_hooks_index = lpb_reftable(L, LS->dec_hooks_index); }
  161. #if 0
  162. static int Lpb_delete(lua_State *L) {
  163. lpb_State *LS = (lpb_State*)luaL_testudata(L, 1, PB_STATE);
  164. if (LS != NULL) {
  165. const pb_State *GS = global_state;
  166. pb_free(&LS->local);
  167. if (&LS->local == GS)
  168. global_state = NULL;
  169. LS->state = NULL;
  170. pb_resetbuffer(&LS->buffer);
  171. luaL_unref(L, LUA_REGISTRYINDEX, LS->defs_index);
  172. luaL_unref(L, LUA_REGISTRYINDEX, LS->enc_hooks_index);
  173. luaL_unref(L, LUA_REGISTRYINDEX, LS->dec_hooks_index);
  174. }
  175. return 0;
  176. }
  177. #endif
  178. LUALIB_API lpb_State *lpb_lstate(lua_State *L) {
  179. lpb_State *LS;
  180. if (lua53_rawgetp(L, LUA_REGISTRYINDEX, state_name) == LUA_TUSERDATA) {
  181. LS = (lpb_State*)lua_touserdata(L, -1);
  182. lua_pop(L, 1);
  183. } else {
  184. lua_pop(L, 1);
  185. LS = (lpb_State*)lua_newuserdata(L, sizeof(lpb_State));
  186. memset(LS, 0, sizeof(lpb_State));
  187. LS->defs_index = LUA_NOREF;
  188. LS->enc_hooks_index = LUA_NOREF;
  189. LS->dec_hooks_index = LUA_NOREF;
  190. LS->state = &LS->local;
  191. pb_init(&LS->local);
  192. pb_initbuffer(&LS->buffer);
  193. // luaL_setmetatable(L, PB_STATE);
  194. lua_rawsetp(L, LUA_REGISTRYINDEX, state_name);
  195. }
  196. return LS;
  197. }
  198. #if 0
  199. static int Lpb_state(lua_State *L) {
  200. int top = lua_gettop(L);
  201. lpb_lstate(L);
  202. lua_rawgetp(L, LUA_REGISTRYINDEX, state_name);
  203. if (top != 0) {
  204. if (lua_isnil(L, 1))
  205. lua_pushnil(L);
  206. else {
  207. luaL_checkudata(L, 1, PB_STATE);
  208. lua_pushvalue(L, 1);
  209. }
  210. lua_rawsetp(L, LUA_REGISTRYINDEX, state_name);
  211. }
  212. return 1;
  213. }
  214. #endif
  215. /* protobuf util routines */
  216. static void lpb_addlength(lua_State *L, pb_Buffer *b, size_t len)
  217. { if (pb_addlength(b, len) == 0) luaL_error(L, "encode bytes fail"); }
  218. static int typeerror(lua_State *L, int idx, const char *type) {
  219. lua_pushfstring(L, "%s expected, got %s", type, luaL_typename(L, idx));
  220. return luaL_argerror(L, idx, lua_tostring(L, -1));
  221. }
  222. #if 0
  223. static lua_Integer posrelat(lua_Integer pos, size_t len) {
  224. if (pos >= 0) return pos;
  225. else if (0u - (size_t)pos > len) return 0;
  226. else return (lua_Integer)len + pos + 1;
  227. }
  228. static lua_Integer rangerelat(lua_State *L, int idx, lua_Integer r[2], size_t len) {
  229. r[0] = posrelat(luaL_optinteger(L, idx, 1), len);
  230. r[1] = posrelat(luaL_optinteger(L, idx+1, len), len);
  231. if (r[0] < 1) r[0] = 1;
  232. if (r[1] > (lua_Integer)len) r[1] = len;
  233. return r[0] <= r[1] ? r[1] - r[0] + 1 : 0;
  234. }
  235. #endif
  236. static int argcheck(lua_State *L, int cond, int idx, const char *fmt, ...) {
  237. if (!cond) {
  238. va_list l;
  239. va_start(l, fmt);
  240. lua_pushvfstring(L, fmt, l);
  241. va_end(l);
  242. return luaL_argerror(L, idx, lua_tostring(L, -1));
  243. }
  244. return 1;
  245. }
  246. static pb_Slice lpb_toslice(lua_State *L, int idx) {
  247. int type = lua_type(L, idx);
  248. if (type == LUA_TSTRING) {
  249. size_t len;
  250. const char *s = lua_tolstring(L, idx, &len);
  251. return pb_lslice(s, len);
  252. } else if (type == LUA_TUSERDATA) {
  253. pb_Buffer *buffer;
  254. pb_Slice *s;
  255. if ((buffer = test_buffer(L, idx)) != NULL)
  256. return pb_result(buffer);
  257. else if ((s = test_slice(L, idx)) != NULL)
  258. return *s;
  259. }
  260. return pb_slice(NULL);
  261. }
  262. LUALIB_API pb_Slice lpb_checkslice(lua_State *L, int idx) {
  263. pb_Slice ret = lpb_toslice(L, idx);
  264. if (ret.p == NULL) typeerror(L, idx, "string/buffer/slice");
  265. return ret;
  266. }
  267. static void lpb_readbytes(lua_State *L, pb_Slice *s, pb_Slice *pv) {
  268. uint64_t len = 0;
  269. if (pb_readvarint64(s, &len) == 0 || len > PB_MAX_SIZET)
  270. luaL_error(L, "invalid bytes length: %d (at offset %d)",
  271. (int)len, pb_pos(*s)+1);
  272. if (pb_readslice(s, (size_t)len, pv) == 0 && len != 0)
  273. luaL_error(L, "unfinished bytes (len %d at offset %d)",
  274. (int)len, pb_pos(*s)+1);
  275. }
  276. static int lpb_hexchar(char ch) {
  277. switch (ch) {
  278. case '0': return 0;
  279. case '1': return 1; case '2': return 2; case '3': return 3;
  280. case '4': return 4; case '5': return 5; case '6': return 6;
  281. case '7': return 7; case '8': return 8; case '9': return 9;
  282. case 'a': case 'A': return 10; case 'b': case 'B': return 11;
  283. case 'c': case 'C': return 12; case 'd': case 'D': return 13;
  284. case 'e': case 'E': return 14; case 'f': case 'F': return 15;
  285. }
  286. return -1;
  287. }
  288. static uint64_t lpb_tointegerx(lua_State *L, int idx, int *isint) {
  289. int neg = 0;
  290. const char *s, *os;
  291. #if LUA_VERSION_NUM >= 503
  292. uint64_t v = (uint64_t)lua_tointegerx(L, idx, isint);
  293. if (*isint) return v;
  294. #else
  295. uint64_t v = 0;
  296. lua_Number nv = lua_tonumberx(L, idx, isint);
  297. if (*isint) {
  298. if (nv < (lua_Number)INT64_MIN || nv > (lua_Number)INT64_MAX)
  299. luaL_error(L, "number has no integer representation");
  300. return (uint64_t)(int64_t)nv;
  301. }
  302. #endif
  303. if ((os = s = lua_tostring(L, idx)) == NULL) return 0;
  304. while (*s == '#' || *s == '+' || *s == '-')
  305. neg = (*s == '-') ^ neg, ++s;
  306. if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
  307. for (s += 2; *s != '\0'; ++s) {
  308. int n = lpb_hexchar(*s);
  309. if (n < 0) break;
  310. v = v << 4 | n;
  311. }
  312. } else {
  313. for (; *s != '\0'; ++s) {
  314. int n = lpb_hexchar(*s);
  315. if (n < 0 || n > 10) break;
  316. v = v * 10 + n;
  317. }
  318. }
  319. if (*s != '\0') luaL_error(L, "integer format error: '%s'", os);
  320. *isint = 1;
  321. return neg ? ~v + 1 : v;
  322. }
  323. #if 0
  324. static uint64_t lpb_checkinteger(lua_State *L, int idx) {
  325. int isint;
  326. uint64_t v = lpb_tointegerx(L, idx, &isint);
  327. if (!isint) typeerror(L, idx, "number/string");
  328. return v;
  329. }
  330. #endif
  331. static void lpb_pushinteger(lua_State *L, int64_t n, int mode) {
  332. if (mode != LPB_NUMBER && (n < INT_MIN || n > UINT_MAX)) {
  333. char buff[32], *p = buff + sizeof(buff) - 1;
  334. int neg = n < 0;
  335. uint64_t un = neg ? ~(uint64_t)n + 1 : (uint64_t)n;
  336. if (mode == LPB_STRING) {
  337. for (*p = '\0'; un > 0; un /= 10)
  338. *--p = "0123456789"[un % 10];
  339. } else if (mode == LPB_HEXSTRING) {
  340. for (*p = '\0'; un > 0; un >>= 4)
  341. *--p = "0123456789ABCDEF"[un & 0xF];
  342. *--p = 'x', *--p = '0';
  343. }
  344. if (neg) *--p = '-';
  345. *--p = '#';
  346. lua_pushstring(L, p);
  347. #ifdef LUAT_CONF_VM_64bit
  348. }
  349. else
  350. lua_pushinteger(L, (lua_Integer)n);
  351. #else
  352. } else if (LUA_VERSION_NUM >= 503 && (n >> 32) == 0)
  353. lua_pushinteger(L, (lua_Integer)n);
  354. else
  355. lua_pushnumber(L, (lua_Number)n);
  356. #endif
  357. }
  358. typedef union lpb_Value {
  359. pb_Slice s[1];
  360. uint32_t u32;
  361. uint64_t u64;
  362. lua_Integer lint;
  363. lua_Number lnum;
  364. } lpb_Value;
  365. static int lpb_addtype(lua_State *L, pb_Buffer *b, int idx, int type, size_t *plen) {
  366. int ret = 0, expected = LUA_TNUMBER;
  367. lpb_Value v;
  368. size_t len = 0;
  369. switch (type) {
  370. case PB_Tbool:
  371. len = pb_addvarint32(b, ret = lua_toboolean(L, idx));
  372. if (ret) len = 0;
  373. ret = 1;
  374. break;
  375. case PB_Tdouble:
  376. v.lnum = lua_tonumberx(L, idx, &ret);
  377. if (ret) len = pb_addfixed64(b, pb_encode_double((double)v.lnum));
  378. if (v.lnum != 0.0) len = 0;
  379. break;
  380. case PB_Tfloat:
  381. v.lnum = lua_tonumberx(L, idx, &ret);
  382. if (ret) len = pb_addfixed32(b, pb_encode_float((float)v.lnum));
  383. if (v.lnum != 0.0) len = 0;
  384. break;
  385. case PB_Tfixed32:
  386. v.u64 = lpb_tointegerx(L, idx, &ret);
  387. if (ret) len = pb_addfixed32(b, v.u32);
  388. if (v.u64 != 0) len = 0;
  389. break;
  390. case PB_Tsfixed32:
  391. v.u64 = lpb_tointegerx(L, idx, &ret);
  392. if (ret) len = pb_addfixed32(b, v.u32);
  393. if (v.u64 != 0) len = 0;
  394. break;
  395. case PB_Tint32:
  396. v.u64 = lpb_tointegerx(L, idx, &ret);
  397. if (ret) len = pb_addvarint64(b, pb_expandsig((uint32_t)v.u64));
  398. if (v.u64 != 0) len = 0;
  399. break;
  400. case PB_Tuint32:
  401. v.u64 = lpb_tointegerx(L, idx, &ret);
  402. if (ret) len = pb_addvarint32(b, v.u32);
  403. if (v.u64 != 0) len = 0;
  404. break;
  405. case PB_Tsint32:
  406. v.u64 = lpb_tointegerx(L, idx, &ret);
  407. if (ret) len = pb_addvarint32(b, pb_encode_sint32(v.u32));
  408. if (v.u64 != 0) len = 0;
  409. break;
  410. case PB_Tfixed64:
  411. v.u64 = lpb_tointegerx(L, idx, &ret);
  412. if (ret) len = pb_addfixed64(b, v.u64);
  413. if (v.u64 != 0) len = 0;
  414. break;
  415. case PB_Tsfixed64:
  416. v.u64 = lpb_tointegerx(L, idx, &ret);
  417. if (ret) len = pb_addfixed64(b, v.u64);
  418. if (v.u64 != 0) len = 0;
  419. break;
  420. case PB_Tint64: case PB_Tuint64:
  421. v.u64 = lpb_tointegerx(L, idx, &ret);
  422. if (ret) len = pb_addvarint64(b, v.u64);
  423. if (v.u64 != 0) len = 0;
  424. break;
  425. case PB_Tsint64:
  426. v.u64 = lpb_tointegerx(L, idx, &ret);
  427. if (ret) len = pb_addvarint64(b, pb_encode_sint64(v.u64));
  428. if (v.u64 != 0) len = 0;
  429. break;
  430. case PB_Tbytes: case PB_Tstring:
  431. *v.s = lpb_toslice(L, idx);
  432. if ((ret = (v.s->p != NULL))) len = pb_addbytes(b, *v.s);
  433. if (pb_len(*v.s) != 0) len = 0;
  434. expected = LUA_TSTRING;
  435. break;
  436. default:
  437. lua_pushfstring(L, "unknown type %s", pb_typename(type, "<unknown>"));
  438. if (idx > 0) argcheck(L, 0, idx, lua_tostring(L, -1));
  439. lua_error(L);
  440. }
  441. if (plen) *plen = len;
  442. return ret ? 0 : expected;
  443. }
  444. static void lpb_readtype(lua_State *L, lpb_State *LS, int type, pb_Slice *s) {
  445. lpb_Value v;
  446. switch (type) {
  447. #define pushinteger(n) lpb_pushinteger((L), (n), LS->int64_mode)
  448. case PB_Tbool: case PB_Tenum:
  449. case PB_Tint32: case PB_Tuint32: case PB_Tsint32:
  450. case PB_Tint64: case PB_Tuint64: case PB_Tsint64:
  451. if (pb_readvarint64(s, &v.u64) == 0)
  452. luaL_error(L, "invalid varint value at offset %d", pb_pos(*s)+1);
  453. switch (type) {
  454. case PB_Tbool: lua_pushboolean(L, v.u64 != 0); break;
  455. /*case PB_Tenum: pushinteger(v.u64); break; [> NOT REACHED <]*/
  456. case PB_Tint32: pushinteger((int32_t)v.u64); break;
  457. case PB_Tuint32: pushinteger((uint32_t)v.u64); break;
  458. case PB_Tsint32: pushinteger(pb_decode_sint32((uint32_t)v.u64)); break;
  459. case PB_Tint64: pushinteger((int64_t)v.u64); break;
  460. case PB_Tuint64: pushinteger((uint64_t)v.u64); break;
  461. case PB_Tsint64: pushinteger(pb_decode_sint64(v.u64)); break;
  462. }
  463. break;
  464. case PB_Tfloat:
  465. case PB_Tfixed32:
  466. case PB_Tsfixed32:
  467. if (pb_readfixed32(s, &v.u32) == 0)
  468. luaL_error(L, "invalid fixed32 value at offset %d", pb_pos(*s)+1);
  469. switch (type) {
  470. case PB_Tfloat: lua_pushnumber(L, pb_decode_float(v.u32)); break;
  471. case PB_Tfixed32: pushinteger(v.u32); break;
  472. case PB_Tsfixed32: pushinteger((int32_t)v.u32); break;
  473. }
  474. break;
  475. case PB_Tdouble:
  476. case PB_Tfixed64:
  477. case PB_Tsfixed64:
  478. if (pb_readfixed64(s, &v.u64) == 0)
  479. luaL_error(L, "invalid fixed64 value at offset %d", pb_pos(*s)+1);
  480. switch (type) {
  481. case PB_Tdouble: lua_pushnumber(L, pb_decode_double(v.u64)); break;
  482. case PB_Tfixed64: pushinteger(v.u64); break;
  483. case PB_Tsfixed64: pushinteger((int64_t)v.u64); break;
  484. }
  485. break;
  486. case PB_Tbytes:
  487. case PB_Tstring:
  488. case PB_Tmessage:
  489. lpb_readbytes(L, s, v.s);
  490. push_slice(L, *v.s);
  491. break;
  492. default:
  493. luaL_error(L, "unknown type %s (%d)", pb_typename(type, NULL), type);
  494. }
  495. }
  496. /* io routines */
  497. #if 0
  498. #ifdef _WIN32
  499. # include <io.h>
  500. # include <fcntl.h>
  501. #else
  502. # define setmode(a,b) ((void)0)
  503. #endif
  504. static int io_read(lua_State *L) {
  505. FILE *fp = (FILE*)lua_touserdata(L, 1);
  506. size_t nr;
  507. luaL_Buffer b;
  508. luaL_buffinit(L, &b);
  509. do { /* read file in chunks of LUAL_BUFFERSIZE bytes */
  510. char *p = luaL_prepbuffer(&b);
  511. nr = fread(p, sizeof(char), LUAL_BUFFERSIZE, fp);
  512. luaL_addsize(&b, nr);
  513. } while (nr == LUAL_BUFFERSIZE);
  514. luaL_pushresult(&b); /* close buffer */
  515. return 1;
  516. }
  517. static int io_write(lua_State *L, FILE *f, int idx) {
  518. int nargs = lua_gettop(L) - idx + 1;
  519. int status = 1;
  520. for (; nargs--; idx++) {
  521. pb_Slice s = lpb_checkslice(L, idx);
  522. size_t l = pb_len(s);
  523. status = status && (fwrite(s.p, sizeof(char), l, f) == l);
  524. }
  525. return status ? 1 : luaL_fileresult(L, 0, NULL);
  526. }
  527. static int Lio_read(lua_State *L) {
  528. const char *fname = luaL_optstring(L, 1, NULL);
  529. FILE *fp = stdin;
  530. int ret;
  531. if (fname == NULL)
  532. (void)setmode(fileno(stdin), O_BINARY);
  533. else if ((fp = fopen(fname, "rb")) == NULL)
  534. return luaL_fileresult(L, 0, fname);
  535. lua_pushcfunction(L, io_read);
  536. lua_pushlightuserdata(L, fp);
  537. ret = lua_pcall(L, 1, 1, 0);
  538. if (fp != stdin) fclose(fp);
  539. else (void)setmode(fileno(stdin), O_TEXT);
  540. if (ret != LUA_OK) { lua_pushnil(L); lua_insert(L, -2); return 2; }
  541. return 1;
  542. }
  543. static int Lio_write(lua_State *L) {
  544. int res;
  545. (void)setmode(fileno(stdout), O_BINARY);
  546. res = io_write(L, stdout, 1);
  547. fflush(stdout);
  548. (void)setmode(fileno(stdout), O_TEXT);
  549. return res;
  550. }
  551. static int Lio_dump(lua_State *L) {
  552. int res;
  553. const char *fname = luaL_checkstring(L, 1);
  554. FILE *fp = fopen(fname, "wb");
  555. if (fp == NULL) return luaL_fileresult(L, 0, fname);
  556. res = io_write(L, fp, 2);
  557. fclose(fp);
  558. return res;
  559. }
  560. LUALIB_API int luaopen_pb_io(lua_State *L) {
  561. luaL_Reg libs[] = {
  562. #define ENTRY(name) { #name, Lio_##name }
  563. ENTRY(read),
  564. ENTRY(write),
  565. ENTRY(dump),
  566. #undef ENTRY
  567. { NULL, NULL }
  568. };
  569. luaL_newlib(L, libs);
  570. return 1;
  571. }
  572. /* protobuf integer conversion */
  573. static int Lconv_encode_int32(lua_State *L) {
  574. unsigned mode = lpb_lstate(L)->int64_mode;
  575. uint64_t v = pb_expandsig((int32_t)lpb_checkinteger(L, 1));
  576. lpb_pushinteger(L, v, mode);
  577. return 1;
  578. }
  579. static int Lconv_encode_uint32(lua_State *L) {
  580. unsigned mode = lpb_lstate(L)->int64_mode;
  581. lpb_pushinteger(L, (uint32_t)lpb_checkinteger(L, 1), mode);
  582. return 1;
  583. }
  584. static int Lconv_encode_sint32(lua_State *L) {
  585. unsigned mode = lpb_lstate(L)->int64_mode;
  586. lpb_pushinteger(L, pb_encode_sint32((int32_t)lpb_checkinteger(L, 1)), mode);
  587. return 1;
  588. }
  589. static int Lconv_decode_sint32(lua_State *L) {
  590. unsigned mode = lpb_lstate(L)->int64_mode;
  591. lpb_pushinteger(L, pb_decode_sint32((uint32_t)lpb_checkinteger(L, 1)), mode);
  592. return 1;
  593. }
  594. static int Lconv_encode_sint64(lua_State *L) {
  595. unsigned mode = lpb_lstate(L)->int64_mode;
  596. lpb_pushinteger(L, pb_encode_sint64(lpb_checkinteger(L, 1)), mode);
  597. return 1;
  598. }
  599. static int Lconv_decode_sint64(lua_State *L) {
  600. unsigned mode = lpb_lstate(L)->int64_mode;
  601. lpb_pushinteger(L, pb_decode_sint64(lpb_checkinteger(L, 1)), mode);
  602. return 1;
  603. }
  604. static int Lconv_encode_float(lua_State *L) {
  605. unsigned mode = lpb_lstate(L)->int64_mode;
  606. lpb_pushinteger(L, pb_encode_float((float)luaL_checknumber(L, 1)), mode);
  607. return 1;
  608. }
  609. static int Lconv_decode_float(lua_State *L) {
  610. lua_pushnumber(L, pb_decode_float((uint32_t)lpb_checkinteger(L, 1)));
  611. return 1;
  612. }
  613. static int Lconv_encode_double(lua_State *L) {
  614. unsigned mode = lpb_lstate(L)->int64_mode;
  615. lpb_pushinteger(L, pb_encode_double(luaL_checknumber(L, 1)), mode);
  616. return 1;
  617. }
  618. static int Lconv_decode_double(lua_State *L) {
  619. lua_pushnumber(L, pb_decode_double(lpb_checkinteger(L, 1)));
  620. return 1;
  621. }
  622. LUALIB_API int luaopen_pb_conv(lua_State *L) {
  623. luaL_Reg libs[] = {
  624. { "decode_uint32", Lconv_encode_uint32 },
  625. { "decode_int32", Lconv_encode_int32 },
  626. #define ENTRY(name) { #name, Lconv_##name }
  627. ENTRY(encode_int32),
  628. ENTRY(encode_uint32),
  629. ENTRY(encode_sint32),
  630. ENTRY(encode_sint64),
  631. ENTRY(decode_sint32),
  632. ENTRY(decode_sint64),
  633. ENTRY(decode_float),
  634. ENTRY(decode_double),
  635. ENTRY(encode_float),
  636. ENTRY(encode_double),
  637. #undef ENTRY
  638. { NULL, NULL }
  639. };
  640. luaL_newlib(L, libs);
  641. return 1;
  642. }
  643. /* protobuf encode routine */
  644. static int lpb_typefmt(int fmt) {
  645. switch (fmt) {
  646. #define X(name,type,fmt) case fmt: return PB_T##name;
  647. PB_TYPES(X)
  648. #undef X
  649. }
  650. return -1;
  651. }
  652. static int lpb_packfmt(lua_State *L, int idx, pb_Buffer *b, const char **pfmt, int level) {
  653. const char *fmt = *pfmt;
  654. int type, ltype;
  655. size_t len;
  656. argcheck(L, level <= 100, 1, "format level overflow");
  657. for (; *fmt != '\0'; ++fmt) {
  658. switch (*fmt) {
  659. case 'v': pb_addvarint64(b, (uint64_t)lpb_checkinteger(L, idx++)); break;
  660. case 'd': pb_addfixed32(b, (uint32_t)lpb_checkinteger(L, idx++)); break;
  661. case 'q': pb_addfixed64(b, (uint64_t)lpb_checkinteger(L, idx++)); break;
  662. case 'c': pb_addslice(b, lpb_checkslice(L, idx++)); break;
  663. case 's': pb_addbytes(b, lpb_checkslice(L, idx++)); break;
  664. case '#': lpb_addlength(L, b, (size_t)lpb_checkinteger(L, idx++)); break;
  665. case '(':
  666. len = pb_bufflen(b);
  667. ++fmt;
  668. idx = lpb_packfmt(L, idx, b, &fmt, level+1);
  669. lpb_addlength(L, b, len);
  670. break;
  671. case ')':
  672. if (level == 0) luaL_argerror(L, 1, "unexpected ')' in format");
  673. *pfmt = fmt;
  674. return idx;
  675. case '\0':
  676. default:
  677. argcheck(L, (type = lpb_typefmt(*fmt)) >= 0,
  678. 1, "invalid formater: '%c'", *fmt);
  679. ltype = lpb_addtype(L, b, idx, type, NULL);
  680. argcheck(L, ltype == 0, idx, "%s expected for type '%s', got %s",
  681. lua_typename(L, ltype), pb_typename(type, "<unknown>"),
  682. luaL_typename(L, idx));
  683. ++idx;
  684. }
  685. }
  686. if (level != 0) luaL_argerror(L, 2, "unmatch '(' in format");
  687. *pfmt = fmt;
  688. return idx;
  689. }
  690. static int Lpb_tohex(lua_State *L) {
  691. pb_Slice s = lpb_checkslice(L, 1);
  692. const char *hexa = "0123456789ABCDEF";
  693. char hex[4] = "XX ";
  694. lua_Integer r[2] = { 1, -1 };
  695. luaL_Buffer lb;
  696. rangerelat(L, 2, r, pb_len(s));
  697. luaL_buffinit(L, &lb);
  698. for (; r[0] <= r[1]; ++r[0]) {
  699. unsigned int ch = s.p[r[0]-1];
  700. hex[0] = hexa[(ch>>4)&0xF];
  701. hex[1] = hexa[(ch )&0xF];
  702. if (r[0] == r[1]) hex[2] = '\0';
  703. luaL_addstring(&lb, hex);
  704. }
  705. luaL_pushresult(&lb);
  706. return 1;
  707. }
  708. static int Lpb_fromhex(lua_State *L) {
  709. pb_Slice s = lpb_checkslice(L, 1);
  710. lua_Integer r[2] = { 1, -1 };
  711. luaL_Buffer lb;
  712. int curr = 0, idx = 0, num;
  713. rangerelat(L, 2, r, pb_len(s));
  714. luaL_buffinit(L, &lb);
  715. for (; r[0] <= r[1]; ++r[0]) {
  716. switch (num = s.p[r[0]-1]) {
  717. case '0': case '1': case '2': case '3':
  718. case '4': case '5': case '6': case '7':
  719. case '8': case '9': num -= '0'; break;
  720. case 'A': case 'a': num = 10; break;
  721. case 'B': case 'b': num = 11; break;
  722. case 'C': case 'c': num = 12; break;
  723. case 'D': case 'd': num = 13; break;
  724. case 'E': case 'e': num = 14; break;
  725. case 'F': case 'f': num = 15; break;
  726. default: continue;
  727. }
  728. curr = curr<<4 | num;
  729. if (++idx % 2 == 0) luaL_addchar(&lb, curr), curr = 0;
  730. }
  731. luaL_pushresult(&lb);
  732. return 1;
  733. }
  734. static int Lpb_result(lua_State *L) {
  735. pb_Slice s = lpb_checkslice(L, 1);
  736. lua_Integer r[2] = {1, -1}, range = rangerelat(L, 2, r, pb_len(s));
  737. lua_pushlstring(L, s.p+r[0]-1, (size_t)range);
  738. return 1;
  739. }
  740. static int Lbuf_new(lua_State *L) {
  741. int i, top = lua_gettop(L);
  742. pb_Buffer *buf = (pb_Buffer*)lua_newuserdata(L, sizeof(pb_Buffer));
  743. pb_initbuffer(buf);
  744. luaL_setmetatable(L, PB_BUFFER);
  745. for (i = 1; i <= top; ++i)
  746. pb_addslice(buf, lpb_checkslice(L, i));
  747. return 1;
  748. }
  749. static int Lbuf_delete(lua_State *L) {
  750. pb_Buffer *buf = test_buffer(L, 1);
  751. if (buf) pb_resetbuffer(buf);
  752. return 0;
  753. }
  754. static int Lbuf_libcall(lua_State *L) {
  755. int i, top = lua_gettop(L);
  756. pb_Buffer *buf = (pb_Buffer*)lua_newuserdata(L, sizeof(pb_Buffer));
  757. pb_initbuffer(buf);
  758. luaL_setmetatable(L, PB_BUFFER);
  759. for (i = 2; i <= top; ++i)
  760. pb_addslice(buf, lpb_checkslice(L, i));
  761. return 1;
  762. }
  763. static int Lbuf_tostring(lua_State *L) {
  764. pb_Buffer *buf = check_buffer(L, 1);
  765. lua_pushfstring(L, "pb.Buffer: %p", buf);
  766. return 1;
  767. }
  768. static int Lbuf_reset(lua_State *L) {
  769. pb_Buffer *buf = check_buffer(L, 1);
  770. int i, top = lua_gettop(L);
  771. pb_bufflen(buf) = 0;
  772. for (i = 2; i <= top; ++i)
  773. pb_addslice(buf, lpb_checkslice(L, i));
  774. return_self(L);
  775. }
  776. static int Lbuf_len(lua_State *L) {
  777. pb_Buffer *buf = check_buffer(L, 1);
  778. lua_pushinteger(L, (lua_Integer)buf->size);
  779. return 1;
  780. }
  781. static int Lbuf_pack(lua_State *L) {
  782. pb_Buffer b, *pb = test_buffer(L, 1);
  783. int idx = 1 + (pb != NULL);
  784. const char *fmt = luaL_checkstring(L, idx++);
  785. if (pb == NULL) pb_initbuffer(pb = &b);
  786. lpb_packfmt(L, idx, pb, &fmt, 0);
  787. if (pb != &b)
  788. lua_settop(L, 1);
  789. else {
  790. pb_Slice ret = pb_result(pb);
  791. push_slice(L, ret);
  792. pb_resetbuffer(pb);
  793. }
  794. return 1;
  795. }
  796. LUALIB_API int luaopen_pb_buffer(lua_State *L) {
  797. luaL_Reg libs[] = {
  798. { "__tostring", Lbuf_tostring },
  799. { "__len", Lbuf_len },
  800. { "__gc", Lbuf_delete },
  801. { "delete", Lbuf_delete },
  802. { "tohex", Lpb_tohex },
  803. { "fromhex", Lpb_fromhex },
  804. { "result", Lpb_result },
  805. #define ENTRY(name) { #name, Lbuf_##name }
  806. ENTRY(new),
  807. ENTRY(reset),
  808. ENTRY(pack),
  809. #undef ENTRY
  810. { NULL, NULL }
  811. };
  812. if (luaL_newmetatable(L, PB_BUFFER)) {
  813. luaL_setfuncs(L, libs, 0);
  814. lua_pushvalue(L, -1);
  815. lua_setfield(L, -2, "__index");
  816. lua_createtable(L, 0, 1);
  817. lua_pushcfunction(L, Lbuf_libcall);
  818. lua_setfield(L, -2, "__call");
  819. lua_setmetatable(L, -2);
  820. }
  821. return 1;
  822. }
  823. /* protobuf decode routine */
  824. #define LPB_INITSTACKLEN 2
  825. typedef struct lpb_Slice {
  826. pb_Slice curr;
  827. pb_Slice *buff;
  828. size_t used;
  829. size_t size;
  830. pb_Slice init_buff[LPB_INITSTACKLEN];
  831. } lpb_Slice;
  832. static void lpb_resetslice(lua_State *L, lpb_Slice *s, size_t size) {
  833. if (size == sizeof(lpb_Slice)) {
  834. if (s->buff != s->init_buff) free(s->buff);
  835. memset(s, 0, sizeof(lpb_Slice));
  836. s->buff = s->init_buff;
  837. s->size = LPB_INITSTACKLEN;
  838. }
  839. lua_pushnil(L);
  840. lua_rawsetp(L, LUA_REGISTRYINDEX, s);
  841. }
  842. static pb_Slice lpb_checkview(lua_State *L, int idx, pb_Slice *ps) {
  843. pb_Slice src = lpb_checkslice(L, idx);
  844. lua_Integer r[2] = {1, -1}, range = rangerelat(L, idx+1, r, pb_len(src));
  845. pb_Slice ret;
  846. if (ps) *ps = src, ps->start = src.p;
  847. ret.p = src.p + r[0] - 1;
  848. ret.end = ret.p + range;
  849. ret.start = src.p;
  850. return ret;
  851. }
  852. static void lpb_enterview(lua_State *L, lpb_Slice *s, pb_Slice view) {
  853. if (s->used >= s->size) {
  854. size_t newsize = s->size * 2;
  855. pb_Slice *oldp = s->buff != s->init_buff ? s->buff : NULL;
  856. pb_Slice *newp = (pb_Slice*)realloc(oldp, newsize*sizeof(pb_Slice));
  857. if (newp == NULL) { luaL_error(L, "out of memory"); return; }
  858. if (oldp == NULL) memcpy(newp, s->buff, s->used*sizeof(pb_Slice));
  859. s->buff = newp;
  860. s->size = newsize;
  861. }
  862. s->buff[s->used++] = s->curr;
  863. s->curr = view;
  864. }
  865. static void lpb_initslice(lua_State *L, int idx, lpb_Slice *s, size_t size) {
  866. if (size == sizeof(lpb_Slice)) {
  867. memset(s, 0, sizeof(lpb_Slice));
  868. s->buff = s->init_buff;
  869. s->size = LPB_INITSTACKLEN;
  870. }
  871. if (!lua_isnoneornil(L, idx)) {
  872. pb_Slice base, view = lpb_checkview(L, idx, &base);
  873. s->curr = base;
  874. if (size == sizeof(lpb_Slice)) lpb_enterview(L, s, view);
  875. lua_pushvalue(L, idx);
  876. lua_rawsetp(L, LUA_REGISTRYINDEX, s);
  877. }
  878. }
  879. static int lpb_unpackscalar(lua_State *L, int *pidx, int top, int fmt, pb_Slice *s) {
  880. unsigned mode = lpb_lstate(L)->int64_mode;
  881. lpb_Value v;
  882. switch (fmt) {
  883. case 'v':
  884. if (pb_readvarint64(s, &v.u64) == 0)
  885. luaL_error(L, "invalid varint value at offset %d", pb_pos(*s)+1);
  886. lpb_pushinteger(L, v.u64, mode);
  887. break;
  888. case 'd':
  889. if (pb_readfixed32(s, &v.u32) == 0)
  890. luaL_error(L, "invalid fixed32 value at offset %d", pb_pos(*s)+1);
  891. lpb_pushinteger(L, v.u32, mode);
  892. break;
  893. case 'q':
  894. if (pb_readfixed64(s, &v.u64) == 0)
  895. luaL_error(L, "invalid fixed64 value at offset %d", pb_pos(*s)+1);
  896. lpb_pushinteger(L, v.u64, mode);
  897. break;
  898. case 's':
  899. if (pb_readbytes(s, v.s) == 0)
  900. luaL_error(L, "invalid bytes value at offset %d", pb_pos(*s)+1);
  901. push_slice(L, *v.s);
  902. break;
  903. case 'c':
  904. argcheck(L, *pidx <= top, 1, "format argument exceed");
  905. v.lint = luaL_checkinteger(L, (*pidx)++);
  906. if (pb_readslice(s, (size_t)v.lint, v.s) == 0)
  907. luaL_error(L, "invalid sub string at offset %d", pb_pos(*s)+1);
  908. push_slice(L, *v.s);
  909. break;
  910. default:
  911. return 0;
  912. }
  913. return 1;
  914. }
  915. static int lpb_unpackloc(lua_State *L, int *pidx, int top, int fmt, pb_Slice *s, int *prets) {
  916. lua_Integer li;
  917. size_t len = s->end - s->start;
  918. switch (fmt) {
  919. case '@':
  920. lua_pushinteger(L, pb_pos(*s)+1);
  921. ++*prets;
  922. break;
  923. case '*': case '+':
  924. argcheck(L, *pidx <= top, 1, "format argument exceed");
  925. if (fmt == '*')
  926. li = posrelat(luaL_checkinteger(L, (*pidx)++), len);
  927. else
  928. li = pb_pos(*s) + luaL_checkinteger(L, (*pidx)++) + 1;
  929. if (li == 0) li = 1;
  930. if (li > (lua_Integer)len) li = (lua_Integer)len + 1;
  931. s->p = s->start + li - 1;
  932. break;
  933. default:
  934. return 0;
  935. }
  936. return 1;
  937. }
  938. static int lpb_unpackfmt(lua_State *L, int idx, const char *fmt, pb_Slice *s) {
  939. int rets = 0, top = lua_gettop(L), type;
  940. for (; *fmt != '\0'; ++fmt) {
  941. if (lpb_unpackloc(L, &idx, top, *fmt, s, &rets))
  942. continue;
  943. if (s->p >= s->end) return lua_pushnil(L), rets + 1;
  944. luaL_checkstack(L, 1, "too many values");
  945. if (!lpb_unpackscalar(L, &idx, top, *fmt, s)) {
  946. argcheck(L, (type = lpb_typefmt(*fmt)) >= 0,
  947. 1, "invalid formater: '%c'", *fmt);
  948. lpb_readtype(L, lpb_lstate(L), type, s);
  949. }
  950. ++rets;
  951. }
  952. return rets;
  953. }
  954. static lpb_Slice *check_lslice(lua_State *L, int idx) {
  955. pb_Slice *s = check_slice(L, idx);
  956. argcheck(L, lua_rawlen(L, 1) == sizeof(lpb_Slice),
  957. idx, "unsupport operation for raw mode slice");
  958. return (lpb_Slice*)s;
  959. }
  960. static int Lslice_new(lua_State *L) {
  961. lpb_Slice *s;
  962. lua_settop(L, 3);
  963. s = (lpb_Slice*)lua_newuserdata(L, sizeof(lpb_Slice));
  964. lpb_initslice(L, 1, s, sizeof(lpb_Slice));
  965. if (s->curr.p == NULL) s->curr = pb_lslice("", 0);
  966. luaL_setmetatable(L, PB_SLICE);
  967. return 1;
  968. }
  969. static int Lslice_libcall(lua_State *L) {
  970. lpb_Slice *s;
  971. lua_settop(L, 4);
  972. s = (lpb_Slice*)lua_newuserdata(L, sizeof(lpb_Slice));
  973. lpb_initslice(L, 2, s, sizeof(lpb_Slice));
  974. luaL_setmetatable(L, PB_SLICE);
  975. return 1;
  976. }
  977. static int Lslice_reset(lua_State *L) {
  978. lpb_Slice *s = (lpb_Slice*)check_slice(L, 1);
  979. size_t size = lua_rawlen(L, 1);
  980. lpb_resetslice(L, s, size);
  981. if (!lua_isnoneornil(L, 2))
  982. lpb_initslice(L, 2, s, size);
  983. return_self(L);
  984. }
  985. static int Lslice_tostring(lua_State *L) {
  986. pb_Slice *s = check_slice(L, 1);
  987. lua_pushfstring(L, "pb.Slice: %p%s", s,
  988. lua_rawlen(L, 1) == sizeof(lpb_Slice) ? "" : " (raw)");
  989. return 1;
  990. }
  991. static int Lslice_len(lua_State *L) {
  992. pb_Slice *s = check_slice(L, 1);
  993. lua_pushinteger(L, (lua_Integer)pb_len(*s));
  994. lua_pushinteger(L, (lua_Integer)pb_pos(*s)+1);
  995. return 2;
  996. }
  997. static int Lslice_unpack(lua_State *L) {
  998. pb_Slice view, *s = test_slice(L, 1);
  999. const char *fmt = luaL_checkstring(L, 2);
  1000. if (s == NULL) view = lpb_checkslice(L, 1), s = &view;
  1001. return lpb_unpackfmt(L, 3, fmt, s);
  1002. }
  1003. static int Lslice_level(lua_State *L) {
  1004. lpb_Slice *s = check_lslice(L, 1);
  1005. if (!lua_isnoneornil(L, 2)) {
  1006. pb_Slice *se;
  1007. lua_Integer level = posrelat(luaL_checkinteger(L, 2), s->used);
  1008. if (level > (lua_Integer)s->used)
  1009. return 0;
  1010. else if (level == (lua_Integer)s->used)
  1011. se = &s->curr;
  1012. else
  1013. se = &s->buff[level];
  1014. lua_pushinteger(L, (lua_Integer)(se->p - s->buff[0].start) + 1);
  1015. lua_pushinteger(L, (lua_Integer)(se->start - s->buff[0].start) + 1);
  1016. lua_pushinteger(L, (lua_Integer)(se->end - s->buff[0].start));
  1017. return 3;
  1018. }
  1019. lua_pushinteger(L, s->used);
  1020. return 1;
  1021. }
  1022. static int Lslice_enter(lua_State *L) {
  1023. lpb_Slice *s = check_lslice(L, 1);
  1024. pb_Slice view;
  1025. if (lua_isnoneornil(L, 2)) {
  1026. argcheck(L, pb_readbytes(&s->curr, &view) != 0,
  1027. 1, "bytes wireformat expected at offset %d", pb_pos(s->curr)+1);
  1028. view.start = view.p;
  1029. lpb_enterview(L, s, view);
  1030. } else {
  1031. lua_Integer r[] = {1, -1};
  1032. lua_Integer range = rangerelat(L, 2, r, pb_len(s->curr));
  1033. view.p = s->curr.start + r[0] - 1;
  1034. view.end = view.p + range;
  1035. view.start = s->curr.p;
  1036. lpb_enterview(L, s, view);
  1037. }
  1038. return_self(L);
  1039. }
  1040. static int Lslice_leave(lua_State *L) {
  1041. lpb_Slice *s = check_lslice(L, 1);
  1042. lua_Integer count = posrelat(luaL_optinteger(L, 2, 1), s->used);
  1043. if (count > (lua_Integer)s->used)
  1044. argcheck(L, 0, 2, "level (%d) exceed max level %d",
  1045. (int)count, (int)s->used);
  1046. else if (count == (lua_Integer)s->used) {
  1047. s->curr = s->buff[0];
  1048. s->used = 1;
  1049. } else {
  1050. s->used -= (size_t)count;
  1051. s->curr = s->buff[s->used];
  1052. }
  1053. lua_settop(L, 1);
  1054. lua_pushinteger(L, s->used);
  1055. return 2;
  1056. }
  1057. LUALIB_API int lpb_newslice(lua_State *L, const char *s, size_t len) {
  1058. pb_Slice *ls = (pb_Slice*)lua_newuserdata(L, sizeof(pb_Slice));
  1059. *ls = pb_lslice(s, len);
  1060. luaL_setmetatable(L, PB_SLICE);
  1061. return 1;
  1062. }
  1063. LUALIB_API int luaopen_pb_slice(lua_State *L) {
  1064. luaL_Reg libs[] = {
  1065. { "__tostring", Lslice_tostring },
  1066. { "__len", Lslice_len },
  1067. { "__gc", Lslice_reset },
  1068. { "delete", Lslice_reset },
  1069. { "tohex", Lpb_tohex },
  1070. { "fromhex", Lpb_fromhex },
  1071. { "result", Lpb_result },
  1072. #define ENTRY(name) { #name, Lslice_##name }
  1073. ENTRY(new),
  1074. ENTRY(reset),
  1075. ENTRY(level),
  1076. ENTRY(enter),
  1077. ENTRY(leave),
  1078. ENTRY(unpack),
  1079. #undef ENTRY
  1080. { NULL, NULL }
  1081. };
  1082. if (luaL_newmetatable(L, PB_SLICE)) {
  1083. luaL_setfuncs(L, libs, 0);
  1084. lua_pushvalue(L, -1);
  1085. lua_setfield(L, -2, "__index");
  1086. lua_createtable(L, 0, 1);
  1087. lua_pushcfunction(L, Lslice_libcall);
  1088. lua_setfield(L, -2, "__call");
  1089. lua_setmetatable(L, -2);
  1090. }
  1091. return 1;
  1092. }
  1093. #endif
  1094. /* high level typeinfo/encode/decode routines */
  1095. typedef enum {USE_FIELD = 1, USE_REPEAT = 2, USE_MESSAGE = 4} lpb_DefFlags;
  1096. static void lpb_pushtypetable(lua_State *L, lpb_State *LS, const pb_Type *t);
  1097. static void lpb_newmsgtable(lua_State *L, const pb_Type *t)
  1098. { lua_createtable(L, 0, t->field_count - t->oneof_field + t->oneof_count*2); }
  1099. LUALIB_API const pb_Type *lpb_type(lpb_State *LS, pb_Slice s) {
  1100. const pb_Type *t;
  1101. if (s.p == NULL || *s.p == '.')
  1102. t = pb_type(lpbS_state(LS), lpb_name(LS, s));
  1103. else {
  1104. pb_Buffer b;
  1105. pb_initbuffer(&b);
  1106. *pb_prepbuffsize(&b, 1) = '.';
  1107. pb_addsize(&b, 1);
  1108. pb_addslice(&b, s);
  1109. t = pb_type(lpbS_state(LS), pb_name(lpbS_state(LS),pb_result(&b),NULL));
  1110. pb_resetbuffer(&b);
  1111. }
  1112. return t;
  1113. }
  1114. static const pb_Field *lpb_field(lua_State *L, int idx, const pb_Type *t) {
  1115. lpb_State *LS = lpb_lstate(L);
  1116. int isint, number = (int)lua_tointegerx(L, idx, &isint);
  1117. if (isint) return pb_field(t, number);
  1118. return pb_fname(t, lpb_name(LS, lpb_checkslice(L, idx)));
  1119. }
  1120. /*
  1121. 加载pb二进制定义数据
  1122. @api protobuf.load(pbdata)
  1123. @string 通过protoc.exe程序转换得到的数据,通常从文件读取得到
  1124. @return bool 成功与否
  1125. @return int 读取了多长, 调试用
  1126. @usage
  1127. -- 注意, 同一个文件只需要加载一次, 除非调用过protobuf.clear()
  1128. protobuf.load(io.readFile("/luadb/person.pb"))
  1129. */
  1130. static int Lpb_load(lua_State *L) {
  1131. lpb_State *LS = lpb_lstate(L);
  1132. pb_Slice s = lpb_checkslice(L, 1);
  1133. int r = pb_load(&LS->local, &s);
  1134. if (r == PB_OK) global_state = &LS->local;
  1135. lua_pushboolean(L, r == PB_OK);
  1136. lua_pushinteger(L, pb_pos(s)+1);
  1137. return 2;
  1138. }
  1139. #if 0
  1140. static int Lpb_loadfile(lua_State *L) {
  1141. lpb_State *LS = lpb_lstate(L);
  1142. const char *filename = luaL_checkstring(L, 1);
  1143. size_t size;
  1144. pb_Buffer b;
  1145. pb_Slice s;
  1146. int ret;
  1147. FILE *fp = fopen(filename, "rb");
  1148. if (fp == NULL)
  1149. return luaL_fileresult(L, 0, filename);
  1150. pb_initbuffer(&b);
  1151. do {
  1152. char *d = pb_prepbuffsize(&b, BUFSIZ);
  1153. if (d == NULL) return fclose(fp), luaL_error(L, "out of memory");
  1154. size = fread(d, 1, BUFSIZ, fp);
  1155. pb_addsize(&b, size);
  1156. } while (size == BUFSIZ);
  1157. fclose(fp);
  1158. s = pb_result(&b);
  1159. ret = pb_load(&LS->local, &s);
  1160. if (ret == PB_OK) global_state = &LS->local;
  1161. pb_resetbuffer(&b);
  1162. lua_pushboolean(L, ret == PB_OK);
  1163. lua_pushinteger(L, pb_pos(s)+1);
  1164. return 2;
  1165. }
  1166. static int lpb_pushtype(lua_State *L, const pb_Type *t) {
  1167. if (t == NULL) return 0;
  1168. lua_pushstring(L, (const char*)t->name);
  1169. lua_pushstring(L, (const char*)t->basename);
  1170. lua_pushstring(L, t->is_map ? "map" : t->is_enum ? "enum" : "message");
  1171. return 3;
  1172. }
  1173. static int lpb_pushfield(lua_State *L, const pb_Type *t, const pb_Field *f) {
  1174. if (f == NULL) return 0;
  1175. lua_pushstring(L, (const char*)f->name);
  1176. lua_pushinteger(L, f->number);
  1177. lua_pushstring(L, f->type ?
  1178. (const char*)f->type->name :
  1179. pb_typename(f->type_id, "<unknown>"));
  1180. lua_pushstring(L, (const char*)f->default_value);
  1181. lua_pushstring(L, f->repeated ?
  1182. (f->packed ? "packed" : "repeated") :
  1183. "optional");
  1184. if (f->oneof_idx > 0) {
  1185. lua_pushstring(L, (const char*)pb_oneofname(t, f->oneof_idx));
  1186. lua_pushinteger(L, f->oneof_idx-1);
  1187. return 7;
  1188. }
  1189. return 5;
  1190. }
  1191. static int Lpb_typesiter(lua_State *L) {
  1192. lpb_State *LS = lpb_lstate(L);
  1193. const pb_Type *t = lpb_type(LS, lpb_toslice(L, 2));
  1194. if ((t == NULL && !lua_isnoneornil(L, 2)))
  1195. return 0;
  1196. pb_nexttype(lpbS_state(LS), &t);
  1197. return lpb_pushtype(L, t);
  1198. }
  1199. static int Lpb_types(lua_State *L) {
  1200. lua_pushcfunction(L, Lpb_typesiter);
  1201. lua_pushnil(L);
  1202. lua_pushnil(L);
  1203. return 3;
  1204. }
  1205. #endif
  1206. #if 0
  1207. static int Lpb_fieldsiter(lua_State *L) {
  1208. lpb_State *LS = lpb_lstate(L);
  1209. const pb_Type *t = lpb_type(LS, lpb_checkslice(L, 1));
  1210. const pb_Field *f = pb_fname(t, lpb_name(LS, lpb_toslice(L, 2)));
  1211. if ((f == NULL && !lua_isnoneornil(L, 2)) || !pb_nextfield(t, &f))
  1212. return 0;
  1213. return lpb_pushfield(L, t, f);
  1214. }
  1215. static int Lpb_fields(lua_State *L) {
  1216. lua_pushcfunction(L, Lpb_fieldsiter);
  1217. lua_pushvalue(L, 1);
  1218. lua_pushnil(L);
  1219. return 3;
  1220. }
  1221. static int Lpb_type(lua_State *L) {
  1222. lpb_State *LS = lpb_lstate(L);
  1223. const pb_Type *t = lpb_type(LS, lpb_checkslice(L, 1));
  1224. if (t == NULL || t->is_dead)
  1225. return 0;
  1226. return lpb_pushtype(L, t);
  1227. }
  1228. static int Lpb_field(lua_State *L) {
  1229. lpb_State *LS = lpb_lstate(L);
  1230. const pb_Type *t = lpb_type(LS, lpb_checkslice(L, 1));
  1231. return lpb_pushfield(L, t, lpb_field(L, 2, t));
  1232. }
  1233. static int Lpb_enum(lua_State *L) {
  1234. lpb_State *LS = lpb_lstate(L);
  1235. const pb_Type *t = lpb_type(LS, lpb_checkslice(L, 1));
  1236. const pb_Field *f = lpb_field(L, 2, t);
  1237. if (f == NULL) return 0;
  1238. if (lua_type(L, 2) == LUA_TNUMBER)
  1239. lua_pushstring(L, (const char*)f->name);
  1240. else
  1241. lpb_pushinteger(L, f->number, LS->int64_mode);
  1242. return 1;
  1243. }
  1244. #endif
  1245. static int lpb_pushdeffield(lua_State *L, lpb_State *LS, const pb_Field *f, int is_proto3) {
  1246. int ret = 0;
  1247. const pb_Type *type;
  1248. char *end;
  1249. if (f == NULL) return 0;
  1250. switch (f->type_id) {
  1251. case PB_Tenum:
  1252. if ((type = f ? f->type : NULL) == NULL) return 0;
  1253. if ((f = pb_fname(type, f->default_value)) != NULL)
  1254. ret = LS->enum_as_value ?
  1255. (lpb_pushinteger(L, f->number, LS->int64_mode), 1) :
  1256. (lua_pushstring(L, (const char*)f->name), 1);
  1257. else if (is_proto3)
  1258. ret = (f = pb_field(type, 0)) == NULL || LS->enum_as_value ?
  1259. (lua_pushinteger(L, 0), 1) :
  1260. (lua_pushstring(L, (const char*)f->name), 1);
  1261. break;
  1262. case PB_Tmessage:
  1263. ret = (lpb_pushtypetable(L, LS, f->type), 1);
  1264. break;
  1265. case PB_Tbytes: case PB_Tstring:
  1266. if (f->default_value)
  1267. ret = (lua_pushstring(L, (const char*)f->default_value), 1);
  1268. else if (is_proto3) ret = (lua_pushliteral(L, ""), 1);
  1269. break;
  1270. case PB_Tbool:
  1271. if (f->default_value) {
  1272. if (f->default_value == lpb_name(LS, pb_slice("true")))
  1273. ret = (lua_pushboolean(L, 1), 1);
  1274. else if (f->default_value == lpb_name(LS, pb_slice("false")))
  1275. ret = (lua_pushboolean(L, 0), 1);
  1276. } else if (is_proto3) ret = (lua_pushboolean(L, 0), 1);
  1277. break;
  1278. case PB_Tdouble: case PB_Tfloat:
  1279. if (f->default_value) {
  1280. lua_Number ln = (lua_Number)strtod((const char*)f->default_value, &end);
  1281. if ((const char*)f->default_value == end) return 0;
  1282. ret = (lua_pushnumber(L, ln), 1);
  1283. } else if (is_proto3) ret = (lua_pushnumber(L, 0.0), 1);
  1284. break;
  1285. default:
  1286. if (f->default_value) {
  1287. lua_Integer li = (lua_Integer)strtol((const char*)f->default_value, &end, 10);
  1288. if ((const char*)f->default_value == end) return 0;
  1289. ret = (lpb_pushinteger(L, li, LS->int64_mode), 1);
  1290. } else if (is_proto3) ret = (lua_pushinteger(L, 0), 1);
  1291. }
  1292. return ret;
  1293. }
  1294. static void lpb_setdeffields(lua_State *L, lpb_State *LS, const pb_Type *t, lpb_DefFlags flags) {
  1295. const pb_Field *f = NULL;
  1296. while (pb_nextfield(t, &f)) {
  1297. int has_field = f->repeated ?
  1298. (flags & USE_REPEAT) && (t->is_proto3 || LS->decode_default_array)
  1299. && (lua_newtable(L), 1) :
  1300. !f->oneof_idx && (f->type_id != PB_Tmessage ?
  1301. (flags & USE_FIELD) :
  1302. (flags & USE_MESSAGE) && LS->decode_default_message)
  1303. && lpb_pushdeffield(L, LS, f, t->is_proto3);
  1304. if (has_field) lua_setfield(L, -2, (const char*)f->name);
  1305. }
  1306. }
  1307. static void lpb_pushdefmeta(lua_State *L, lpb_State *LS, const pb_Type *t) {
  1308. lpb_pushdeftable(L, LS);
  1309. if (lua53_rawgetp(L, -1, t) != LUA_TTABLE) {
  1310. lua_pop(L, 1);
  1311. lpb_newmsgtable(L, t);
  1312. lpb_setdeffields(L, LS, t, USE_FIELD);
  1313. lua_pushvalue(L, -1);
  1314. lua_setfield(L, -2, "__index");
  1315. lua_pushvalue(L, -1);
  1316. lua_rawsetp(L, -3, t);
  1317. }
  1318. lua_remove(L, -2);
  1319. }
  1320. static void lpb_cleardefmeta(lua_State *L, lpb_State *LS, const pb_Type *t) {
  1321. lpb_pushdeftable(L, LS);
  1322. lua_pushnil(L);
  1323. lua_rawsetp(L, -2, t);
  1324. lua_pop(L, 1);
  1325. }
  1326. #if 0
  1327. static int Lpb_defaults(lua_State *L) {
  1328. lpb_State *LS = lpb_lstate(L);
  1329. const pb_Type *t = lpb_type(LS, lpb_checkslice(L, 1));
  1330. int clear = lua_toboolean(L, 2);
  1331. if (t == NULL) luaL_argerror(L, 1, "type not found");
  1332. lpb_pushdefmeta(L, LS, t);
  1333. if (clear) lpb_cleardefmeta(L, LS, t);
  1334. return 1;
  1335. }
  1336. static int Lpb_hook(lua_State *L) {
  1337. lpb_State *LS = lpb_lstate(L);
  1338. const pb_Type *t = lpb_type(LS, lpb_checkslice(L, 1));
  1339. int type = lua_type(L, 2);
  1340. if (t == NULL) luaL_argerror(L, 1, "type not found");
  1341. if (type != LUA_TNONE && type != LUA_TNIL && type != LUA_TFUNCTION)
  1342. typeerror(L, 2, "function");
  1343. lua_settop(L, 2);
  1344. lpb_pushdechooktable(L, LS);
  1345. lua_rawgetp(L, 3, t);
  1346. if (type != LUA_TNONE) {
  1347. lua_pushvalue(L, 2);
  1348. lua_rawsetp(L, 3, t);
  1349. }
  1350. return 1;
  1351. }
  1352. static int Lpb_encode_hook(lua_State *L) {
  1353. lpb_State *LS = lpb_lstate(L);
  1354. const pb_Type *t = lpb_type(LS, lpb_checkslice(L, 1));
  1355. int type = lua_type(L, 2);
  1356. if (t == NULL) luaL_argerror(L, 1, "type not found");
  1357. if (type != LUA_TNONE && type != LUA_TNIL && type != LUA_TFUNCTION)
  1358. typeerror(L, 2, "function");
  1359. lua_settop(L, 2);
  1360. lpb_pushenchooktable(L, LS);
  1361. lua_rawgetp(L, 3, t);
  1362. if (type != LUA_TNONE) {
  1363. lua_pushvalue(L, 2);
  1364. lua_rawsetp(L, 3, t);
  1365. }
  1366. return 1;
  1367. }
  1368. #endif
  1369. /*
  1370. 清除已加载的二进制定义数据
  1371. @api protobuf.clear()
  1372. @return nil 无返回值, 总是成功
  1373. @usage
  1374. -- 清除所有已加载的定义数据
  1375. protobuf.clear()
  1376. */
  1377. static int Lpb_clear(lua_State *L) {
  1378. lpb_State *LS = lpb_lstate(L);
  1379. pb_State *S = (pb_State*)LS->state;
  1380. pb_Type *t;
  1381. if (lua_isnoneornil(L, 1)) {
  1382. pb_free(&LS->local), pb_init(&LS->local);
  1383. luaL_unref(L, LUA_REGISTRYINDEX, LS->defs_index);
  1384. LS->defs_index = LUA_NOREF;
  1385. luaL_unref(L, LUA_REGISTRYINDEX, LS->enc_hooks_index);
  1386. LS->enc_hooks_index = LUA_NOREF;
  1387. luaL_unref(L, LUA_REGISTRYINDEX, LS->dec_hooks_index);
  1388. LS->dec_hooks_index = LUA_NOREF;
  1389. return 0;
  1390. }
  1391. LS->state = &LS->local;
  1392. t = (pb_Type*)lpb_type(LS, lpb_checkslice(L, 1));
  1393. if (lua_isnoneornil(L, 2)) pb_deltype(&LS->local, t);
  1394. else pb_delfield(&LS->local, t, (pb_Field*)lpb_field(L, 2, t));
  1395. LS->state = S;
  1396. lpb_cleardefmeta(L, LS, t);
  1397. return 0;
  1398. }
  1399. #if 0
  1400. static int Lpb_typefmt(lua_State *L) {
  1401. pb_Slice s = lpb_checkslice(L, 1);
  1402. const char *r = NULL;
  1403. char buf[2] = {0};
  1404. int type;
  1405. if (pb_len(s) == 1)
  1406. r = pb_typename(type = lpb_typefmt(*s.p), "!");
  1407. else if (lpb_type(lpb_lstate(L), s))
  1408. r = "message", type = PB_TBYTES;
  1409. else if ((type = pb_typebyname(s.p, PB_Tmessage)) != PB_Tmessage) {
  1410. switch (type) {
  1411. #define X(name,type,fmt) case PB_T##name: buf[0] = fmt, r = buf; break;
  1412. PB_TYPES(X)
  1413. #undef X
  1414. }
  1415. type = pb_wtypebytype(type);
  1416. } else if ((type = pb_wtypebyname(s.p, PB_Tmessage)) != PB_Tmessage) {
  1417. switch (type) {
  1418. #define X(id,name,fmt) case PB_T##id: buf[0] = fmt, r = buf; break;
  1419. PB_WIRETYPES(X)
  1420. #undef X
  1421. }
  1422. }
  1423. lua_pushstring(L, r ? r : "!");
  1424. lua_pushinteger(L, type);
  1425. return 2;
  1426. }
  1427. #endif
  1428. /* protobuf encode */
  1429. typedef struct lpb_Env {
  1430. lua_State *L;
  1431. lpb_State *LS;
  1432. pb_Buffer *b;
  1433. pb_Slice *s;
  1434. } lpb_Env;
  1435. static void lpbE_encode (lpb_Env *e, const pb_Type *t, int idx);
  1436. static void lpb_checktable(lua_State *L, const pb_Field *f, int idx) {
  1437. argcheck(L, lua_istable(L, idx),
  1438. 2, "table expected at field '%s', got %s",
  1439. (const char*)f->name, luaL_typename(L, idx));
  1440. }
  1441. static void lpb_useenchooks(lua_State *L, lpb_State *LS, const pb_Type *t) {
  1442. lpb_pushenchooktable(L, LS);
  1443. if (lua53_rawgetp(L, -1, t) != LUA_TNIL) {
  1444. lua_pushvalue(L, -3);
  1445. lua_call(L, 1, 1);
  1446. if (!lua_isnil(L, -1)) {
  1447. lua_pushvalue(L, -1);
  1448. lua_replace(L, -4);
  1449. }
  1450. }
  1451. lua_pop(L, 2);
  1452. }
  1453. static void lpbE_enum(lpb_Env *e, const pb_Field *f, int idx) {
  1454. lua_State *L = e->L;
  1455. pb_Buffer *b = e->b;
  1456. const pb_Field *ev;
  1457. int type = lua_type(L, idx);
  1458. if (type == LUA_TNUMBER)
  1459. pb_addvarint64(b, (uint64_t)lua_tonumber(L, idx));
  1460. else if ((ev = pb_fname(f->type,
  1461. lpb_name(e->LS, lpb_toslice(L, idx)))) != NULL)
  1462. pb_addvarint32(b, ev->number);
  1463. else if (type != LUA_TSTRING)
  1464. argcheck(L, 0, 2, "number/string expected at field '%s', got %s",
  1465. (const char*)f->name, luaL_typename(L, idx));
  1466. else
  1467. argcheck(L, 0, 2, "can not encode unknown enum '%s' at field '%s'",
  1468. lua_tostring(L, -1), (const char*)f->name);
  1469. }
  1470. static void lpbE_field(lpb_Env *e, const pb_Field *f, size_t *plen, int idx) {
  1471. lua_State *L = e->L;
  1472. pb_Buffer *b = e->b;
  1473. size_t len;
  1474. int ltype;
  1475. if (plen) *plen = 0;
  1476. switch (f->type_id) {
  1477. case PB_Tenum:
  1478. if (e->LS->use_enc_hooks) lpb_useenchooks(L, e->LS, f->type);
  1479. lpbE_enum(e, f, idx);
  1480. break;
  1481. case PB_Tmessage:
  1482. if (e->LS->use_enc_hooks) lpb_useenchooks(L, e->LS, f->type);
  1483. lpb_checktable(L, f, idx);
  1484. len = pb_bufflen(b);
  1485. lpbE_encode(e, f->type, idx);
  1486. lpb_addlength(L, b, len);
  1487. break;
  1488. default:
  1489. ltype = lpb_addtype(L, b, idx, f->type_id, plen);
  1490. argcheck(L, ltype == 0,
  1491. 2, "%s expected for field '%s', got %s",
  1492. lua_typename(L, ltype),
  1493. (const char*)f->name, luaL_typename(L, idx));
  1494. }
  1495. }
  1496. static void lpbE_tagfield(lpb_Env *e, const pb_Field *f, int ignorezero, int idx) {
  1497. size_t hlen = pb_addvarint32(e->b,
  1498. pb_pair(f->number, pb_wtypebytype(f->type_id)));
  1499. size_t ignoredlen;
  1500. lpbE_field(e, f, &ignoredlen, idx);
  1501. if (!e->LS->encode_default_values && ignoredlen != 0 && ignorezero)
  1502. e->b->size -= (unsigned)(ignoredlen + hlen);
  1503. }
  1504. static void lpbE_map(lpb_Env *e, const pb_Field *f, int idx) {
  1505. lua_State *L = e->L;
  1506. const pb_Field *kf = pb_field(f->type, 1);
  1507. const pb_Field *vf = pb_field(f->type, 2);
  1508. if (kf == NULL || vf == NULL) return;
  1509. lpb_checktable(L, f, idx);
  1510. lua_pushnil(L);
  1511. while (lua_next(L, lpb_relindex(idx, 1))) {
  1512. size_t len;
  1513. pb_addvarint32(e->b, pb_pair(f->number, PB_TBYTES));
  1514. len = pb_bufflen(e->b);
  1515. lpbE_tagfield(e, kf, 1, -2);
  1516. lpbE_tagfield(e, vf, 1, -1);
  1517. lpb_addlength(L, e->b, len);
  1518. lua_pop(L, 1);
  1519. }
  1520. }
  1521. static void lpbE_repeated(lpb_Env *e, const pb_Field *f, int idx) {
  1522. lua_State *L = e->L;
  1523. pb_Buffer *b = e->b;
  1524. int i;
  1525. lpb_checktable(L, f, idx);
  1526. if (f->packed) {
  1527. unsigned len, bufflen = pb_bufflen(b);
  1528. pb_addvarint32(b, pb_pair(f->number, PB_TBYTES));
  1529. len = pb_bufflen(b);
  1530. for (i = 1; lua53_rawgeti(L, idx, i) != LUA_TNIL; ++i) {
  1531. lpbE_field(e, f, NULL, -1);
  1532. lua_pop(L, 1);
  1533. }
  1534. if (i == 1 && !e->LS->encode_default_values)
  1535. pb_bufflen(b) = bufflen;
  1536. else
  1537. lpb_addlength(L, b, len);
  1538. } else {
  1539. for (i = 1; lua53_rawgeti(L, idx, i) != LUA_TNIL; ++i) {
  1540. lpbE_tagfield(e, f, 0, -1);
  1541. lua_pop(L, 1);
  1542. }
  1543. }
  1544. lua_pop(L, 1);
  1545. }
  1546. static void lpb_encode_onefield(lpb_Env *e, const pb_Type *t, const pb_Field *f, int idx) {
  1547. if (f->type && f->type->is_map)
  1548. lpbE_map(e, f, idx);
  1549. else if (f->repeated)
  1550. lpbE_repeated(e, f, idx);
  1551. else if (!f->type || !f->type->is_dead)
  1552. lpbE_tagfield(e, f, t->is_proto3 && !f->oneof_idx, idx);
  1553. }
  1554. static void lpbE_encode(lpb_Env *e, const pb_Type *t, int idx) {
  1555. lua_State *L = e->L;
  1556. luaL_checkstack(L, 3, "message too many levels");
  1557. if (1) {
  1558. const pb_Field *f = NULL;
  1559. while (pb_nextfield(t, &f)) {
  1560. if (lua53_getfield(L, idx, (const char*)f->name) != LUA_TNIL)
  1561. lpb_encode_onefield(e, t, f, -1);
  1562. lua_pop(L, 1);
  1563. }
  1564. } else {
  1565. lua_pushnil(L);
  1566. while (lua_next(L, lpb_relindex(idx, 1))) {
  1567. if (lua_type(L, -2) == LUA_TSTRING) {
  1568. const pb_Field *f =
  1569. pb_fname(t, lpb_name(e->LS, lpb_toslice(L, -2)));
  1570. if (f != NULL) lpb_encode_onefield(e, t, f, -1);
  1571. }
  1572. lua_pop(L, 1);
  1573. }
  1574. }
  1575. }
  1576. /*
  1577. 编码protobuffs数据包
  1578. @api protobuf.encode(tpname, data)
  1579. @string 数据类型名称, 定义在pb文件中, 由protobuf.load加载
  1580. @table 待编码数据, 必须是table, 内容符合pb文件里的定义
  1581. @return string 编码后的数据,若失败会返回nil
  1582. @usage
  1583. -- 数据编码
  1584. local tb = {
  1585. name = "wendal"
  1586. }
  1587. local pbdata = protobuf.encode("Person", tb)
  1588. if pbdata then
  1589. -- 注意, 编码后的数据通常带不可见字符
  1590. log.info("protobuf", #pbdata, pbdata:toHex())
  1591. end
  1592. */
  1593. static int Lpb_encode(lua_State *L) {
  1594. lpb_State *LS = lpb_lstate(L);
  1595. const pb_Type *t = lpb_type(LS, lpb_checkslice(L, 1));
  1596. lpb_Env e;
  1597. argcheck(L, t!=NULL, 1, "type '%s' does not exists", lua_tostring(L, 1));
  1598. luaL_checktype(L, 2, LUA_TTABLE);
  1599. e.L = L, e.LS = LS, e.b = test_buffer(L, 3);
  1600. if (e.b == NULL) pb_resetbuffer(e.b = &LS->buffer);
  1601. lua_pushvalue(L, 2);
  1602. if (e.LS->use_enc_hooks) lpb_useenchooks(L, e.LS, t);
  1603. lpbE_encode(&e, t, -1);
  1604. if (e.b != &LS->buffer)
  1605. lua_settop(L, 3);
  1606. else {
  1607. lua_pushlstring(L, pb_buffer(e.b), pb_bufflen(e.b));
  1608. pb_resetbuffer(e.b);
  1609. }
  1610. return 1;
  1611. }
  1612. #if 0
  1613. static int lpbE_pack(lpb_Env* e, const pb_Type* t, int idx) {
  1614. unsigned i;
  1615. lua_State* L = e->L;
  1616. pb_Field** f = pb_sortfield((pb_Type*)t);
  1617. for (i = 0; i < t->field_count; i++) {
  1618. int index = idx + i;
  1619. if (!lua_isnoneornil(L, index)) {
  1620. lpb_encode_onefield(e, t, f[i], index);
  1621. }
  1622. }
  1623. return 0;
  1624. }
  1625. static int Lpb_pack(lua_State* L) {
  1626. lpb_State* LS = lpb_lstate(L);
  1627. const pb_Type* t = lpb_type(LS, lpb_checkslice(L, 1));
  1628. lpb_Env e;
  1629. int idx = 3;
  1630. e.L = L, e.LS = LS, e.b = test_buffer(L, 2);
  1631. if (e.b == NULL) {
  1632. idx = 2;
  1633. pb_resetbuffer(e.b = &LS->buffer);
  1634. }
  1635. lpbE_pack(&e, t, idx);
  1636. if (e.b != &LS->buffer)
  1637. lua_settop(L, 3);
  1638. else {
  1639. lua_pushlstring(L, pb_buffer(e.b), pb_bufflen(e.b));
  1640. pb_resetbuffer(e.b);
  1641. }
  1642. return 1;
  1643. }
  1644. #endif
  1645. /* protobuf decode */
  1646. #define lpb_withinput(e,ns,stmt) ((e)->s = (ns), (stmt), (e)->s = s)
  1647. static int lpbD_message(lpb_Env *e, const pb_Type *t);
  1648. static void lpb_usedechooks(lua_State *L, lpb_State *LS, const pb_Type *t) {
  1649. lpb_pushdechooktable(L, LS);
  1650. if (lua53_rawgetp(L, -1, t) != LUA_TNIL) {
  1651. lua_pushvalue(L, -3);
  1652. lua_call(L, 1, 1);
  1653. if (!lua_isnil(L, -1)) {
  1654. lua_pushvalue(L, -1);
  1655. lua_replace(L, -4);
  1656. }
  1657. }
  1658. lua_pop(L, 2);
  1659. }
  1660. static void lpb_pushtypetable(lua_State *L, lpb_State *LS, const pb_Type *t) {
  1661. int mode = LS->encode_mode;
  1662. luaL_checkstack(L, 2, "too many levels");
  1663. lpb_newmsgtable(L, t);
  1664. switch (t->is_proto3 && mode == LPB_DEFDEF ? LPB_COPYDEF : mode) {
  1665. case LPB_COPYDEF:
  1666. lpb_setdeffields(L, LS, t, USE_FIELD|USE_REPEAT|USE_MESSAGE);
  1667. break;
  1668. case LPB_METADEF:
  1669. lpb_setdeffields(L, LS, t, USE_REPEAT|USE_MESSAGE);
  1670. lpb_pushdefmeta(L, LS, t);
  1671. lua_setmetatable(L, -2);
  1672. break;
  1673. default:
  1674. if (LS->decode_default_array || LS->decode_default_message)
  1675. lpb_setdeffields(L, LS, t, USE_REPEAT|USE_MESSAGE);
  1676. break;
  1677. }
  1678. }
  1679. static void lpb_fetchtable(lpb_Env *e, const pb_Field *f) {
  1680. lua_State *L = e->L;
  1681. if (lua53_getfield(L, -1, (const char*)f->name) == LUA_TNIL) {
  1682. lua_pop(L, 1);
  1683. lua_newtable(L);
  1684. lua_pushvalue(L, -1);
  1685. lua_setfield(L, -3, (const char*)f->name);
  1686. }
  1687. }
  1688. static void lpbD_rawfield(lpb_Env *e, const pb_Field *f) {
  1689. lua_State *L = e->L;
  1690. pb_Slice sv, *s = e->s;
  1691. const pb_Field *ev = NULL;
  1692. uint64_t u64;
  1693. switch (f->type_id) {
  1694. case PB_Tenum:
  1695. if (pb_readvarint64(s, &u64) == 0)
  1696. luaL_error(L, "invalid varint value at offset %d", pb_pos(*s)+1);
  1697. if (!lpb_lstate(L)->enum_as_value)
  1698. ev = pb_field(f->type, (int32_t)u64);
  1699. if (ev) lua_pushstring(L, (const char*)ev->name);
  1700. else lpb_pushinteger(L, (lua_Integer)u64, lpb_lstate(L)->int64_mode);
  1701. if (e->LS->use_dec_hooks) lpb_usedechooks(L, e->LS, f->type);
  1702. break;
  1703. case PB_Tmessage:
  1704. lpb_readbytes(L, s, &sv);
  1705. if (f->type == NULL || f->type->is_dead)
  1706. lua_pushnil(L);
  1707. else {
  1708. lpb_pushtypetable(L, e->LS, f->type);
  1709. lpb_withinput(e, &sv, lpbD_message(e, f->type));
  1710. }
  1711. break;
  1712. default:
  1713. lpb_readtype(L, e->LS, f->type_id, s);
  1714. }
  1715. }
  1716. static void lpbD_checktype(lpb_Env *e, const pb_Field *f, uint32_t tag) {
  1717. if (pb_wtypebytype(f->type_id) == (int)pb_gettype(tag)) return;
  1718. luaL_error(e->L,
  1719. "type mismatch for %s%sfield '%s' at offset %d, "
  1720. "%s expected for type %s, got %s",
  1721. f->packed ? "packed " : "", f->repeated ? "repeated " : "",
  1722. (const char*)f->name,
  1723. pb_pos(*e->s)+1,
  1724. pb_wtypename(pb_wtypebytype(f->type_id), NULL),
  1725. pb_typename(f->type_id, NULL),
  1726. pb_wtypename(pb_gettype(tag), NULL));
  1727. }
  1728. static void lpbD_field(lpb_Env *e, const pb_Field *f, uint32_t tag) {
  1729. lpbD_checktype(e, f, tag);
  1730. lpbD_rawfield(e, f);
  1731. }
  1732. static void lpbD_map(lpb_Env *e, const pb_Field *f) {
  1733. lua_State *L = e->L;
  1734. pb_Slice p, *s = e->s;
  1735. int mask = 0, top = lua_gettop(L);
  1736. uint32_t tag;
  1737. lpb_readbytes(L, s, &p);
  1738. if (f->type == NULL) return;
  1739. lua_pushnil(L);
  1740. lua_pushnil(L);
  1741. while (pb_readvarint32(&p, &tag)) {
  1742. int n = pb_gettag(tag);
  1743. if (n == 1 || n == 2) {
  1744. mask |= n;
  1745. lpb_withinput(e, &p, lpbD_field(e, pb_field(f->type, n), tag));
  1746. lua_replace(L, top+n);
  1747. }
  1748. }
  1749. if (!(mask & 1) && lpb_pushdeffield(L, e->LS, pb_field(f->type, 1), 1))
  1750. lua_replace(L, top + 1), mask |= 1;
  1751. if (!(mask & 2) && lpb_pushdeffield(L, e->LS, pb_field(f->type, 2), 1))
  1752. lua_replace(L, top + 2), mask |= 2;
  1753. if (mask == 3) lua_rawset(L, -3);
  1754. else lua_pop(L, 2);
  1755. }
  1756. static void lpbD_repeated(lpb_Env *e, const pb_Field *f, uint32_t tag) {
  1757. lua_State *L = e->L;
  1758. if (pb_gettype(tag) != PB_TBYTES
  1759. || (!f->packed && pb_wtypebytype(f->type_id) == PB_TBYTES)) {
  1760. lpbD_field(e, f, tag);
  1761. lua_rawseti(L, -2, (lua_Integer)lua_rawlen(L, -2) + 1);
  1762. } else {
  1763. int len = (int)lua_rawlen(L, -1);
  1764. pb_Slice p, *s = e->s;
  1765. lpb_readbytes(L, s, &p);
  1766. while (p.p < p.end) {
  1767. lpb_withinput(e, &p, lpbD_rawfield(e, f));
  1768. lua_rawseti(L, -2, ++len);
  1769. }
  1770. }
  1771. }
  1772. static int lpbD_message(lpb_Env *e, const pb_Type *t) {
  1773. lua_State *L = e->L;
  1774. pb_Slice *s = e->s;
  1775. uint32_t tag;
  1776. luaL_checkstack(L, t->field_count * 2, "not enough stack space for fields");
  1777. while (pb_readvarint32(s, &tag)) {
  1778. const pb_Field *f = pb_field(t, pb_gettag(tag));
  1779. if (f == NULL)
  1780. pb_skipvalue(s, tag);
  1781. else if (f->type && f->type->is_map) {
  1782. lpb_fetchtable(e, f);
  1783. lpbD_checktype(e, f, tag);
  1784. lpbD_map(e, f);
  1785. lua_pop(L, 1);
  1786. } else if (f->repeated) {
  1787. lpb_fetchtable(e, f);
  1788. lpbD_repeated(e, f, tag);
  1789. lua_pop(L, 1);
  1790. } else {
  1791. lua_pushstring(L, (const char*)f->name);
  1792. if (f->oneof_idx) {
  1793. lua_pushstring(L, (const char*)pb_oneofname(t, f->oneof_idx));
  1794. lua_pushvalue(L, -2);
  1795. lua_rawset(L, -4);
  1796. }
  1797. lpbD_field(e, f, tag);
  1798. lua_rawset(L, -3);
  1799. }
  1800. }
  1801. if (e->LS->use_dec_hooks) lpb_usedechooks(L, e->LS, t);
  1802. return 1;
  1803. }
  1804. static int lpbD_decode(lua_State *L, pb_Slice s, int start) {
  1805. lpb_State *LS = lpb_lstate(L);
  1806. const pb_Type *t = lpb_type(LS, lpb_checkslice(L, 1));
  1807. lpb_Env e;
  1808. argcheck(L, t!=NULL, 1, "type '%s' does not exists", lua_tostring(L, 1));
  1809. lua_settop(L, start);
  1810. if (!lua_istable(L, start)) {
  1811. lua_pop(L, 1);
  1812. lpb_pushtypetable(L, LS, t);
  1813. }
  1814. e.L = L, e.LS = LS, e.s = &s;
  1815. return lpbD_message(&e, t);
  1816. }
  1817. /*
  1818. 解码protobuffs数据包
  1819. @api protobuf.decode(tpname, data)
  1820. @string 数据类型名称, 定义在pb文件中, 由protobuf.load加载
  1821. @string 待编码数据
  1822. @return table 解码后的数据
  1823. @usage
  1824. -- 数据编码
  1825. local tb = {
  1826. name = "wendal"
  1827. }
  1828. local pbdata = protobuf.encode("Person", tb)
  1829. if pbdata then
  1830. -- 注意, 编码后的数据通常带不可见字符
  1831. log.info("protobuf", #pbdata, pbdata:toHex())
  1832. end
  1833. */
  1834. static int Lpb_decode(lua_State *L) {
  1835. return lpbD_decode(L, lua_isnoneornil(L, 2) ?
  1836. pb_lslice(NULL, 0) :
  1837. lpb_checkslice(L, 2), 3);
  1838. }
  1839. #if 0
  1840. void lpb_pushunpackdef(lua_State* L, lpb_State* LS, const pb_Type* t, pb_Field** l, int top) {
  1841. unsigned int i;
  1842. int mode = LS->encode_mode;
  1843. mode = t->is_proto3 && mode == LPB_DEFDEF ? LPB_COPYDEF : mode;
  1844. if (mode != LPB_COPYDEF && mode != LPB_METADEF) return;
  1845. for (i = 0; i < t->field_count; i++) {
  1846. int idx = top + i + 1;
  1847. if (lua_isnoneornil(L, idx) && lpb_pushdeffield(L, LS, l[i], t->is_proto3)) {
  1848. lua_replace(L, idx);
  1849. }
  1850. }
  1851. }
  1852. static int lpb_unpackfield(lpb_Env *e, const pb_Field* f, uint32_t tag, int last) {
  1853. if (!f) {
  1854. pb_skipvalue(e->s, tag);
  1855. return 0;
  1856. }
  1857. if (f->type && f->type->is_map) {
  1858. lpbD_checktype(e, f, tag);
  1859. if (!last) lua_newtable(e->L);
  1860. lpbD_map(e, f);
  1861. }
  1862. else if (f->repeated) {
  1863. if (!last) lua_newtable(e->L);
  1864. lpbD_repeated(e, f, tag);
  1865. }
  1866. else {
  1867. lpbD_field(e, f, tag);
  1868. }
  1869. return f->sort_index;
  1870. }
  1871. static int lpbD_unpack(lpb_Env* e, const pb_Type* t) {
  1872. lua_State* L = e->L;
  1873. int top = lua_gettop(L);
  1874. uint32_t tag;
  1875. int last_index = 0;
  1876. unsigned int decode_count = 0;
  1877. pb_Field **list = pb_sortfield((pb_Type*)t);
  1878. lua_settop(L, top + t->field_count);
  1879. luaL_checkstack(L, t->field_count * 2, "not enough stack space for fields");
  1880. while (pb_readvarint32(e->s, &tag)) {
  1881. const pb_Field* f = pb_field(t, pb_gettag(tag));
  1882. if (last_index && (!f || f->sort_index != last_index)) {
  1883. decode_count++;
  1884. lua_replace(L, top + last_index);
  1885. last_index = 0;
  1886. }
  1887. last_index = lpb_unpackfield(e, f, tag, last_index);
  1888. }
  1889. if (last_index) {
  1890. decode_count++;
  1891. lua_replace(L, top + last_index);
  1892. }
  1893. if (decode_count != t->field_count) lpb_pushunpackdef(L, e->LS, t, list, top);
  1894. return t->field_count;
  1895. }
  1896. static int Lpb_unpack(lua_State* L) {
  1897. lpb_State* LS = lpb_lstate(L);
  1898. const pb_Type* t = lpb_type(LS, lpb_checkslice(L, 1));
  1899. pb_Slice s = lpb_checkslice(L, 2);
  1900. lpb_Env e;
  1901. e.L = L, e.LS = LS, e.s = &s;
  1902. argcheck(L, t != NULL, 1, "type '%s' does not exists", lua_tostring(L, 1));
  1903. return lpbD_unpack(&e, t);
  1904. }
  1905. /* pb module interface */
  1906. static int Lpb_option(lua_State *L) {
  1907. #define OPTS(X) \
  1908. X(0, enum_as_name, LS->enum_as_value = 0) \
  1909. X(1, enum_as_value, LS->enum_as_value = 1) \
  1910. X(2, int64_as_number, LS->int64_mode = LPB_NUMBER) \
  1911. X(3, int64_as_string, LS->int64_mode = LPB_STRING) \
  1912. X(4, int64_as_hexstring, LS->int64_mode = LPB_HEXSTRING) \
  1913. X(5, encode_order, LS->encode_order = 1) \
  1914. X(6, no_encode_order, LS->encode_order = 0) \
  1915. X(7, encode_default_values, LS->encode_default_values = 1) \
  1916. X(8, no_encode_default_values, LS->encode_default_values = 0) \
  1917. X(9, auto_default_values, LS->encode_mode = LPB_DEFDEF) \
  1918. X(10, no_default_values, LS->encode_mode = LPB_NODEF) \
  1919. X(11, use_default_values, LS->encode_mode = LPB_COPYDEF) \
  1920. X(12, use_default_metatable, LS->encode_mode = LPB_METADEF) \
  1921. X(13, decode_default_array, LS->decode_default_array = 1) \
  1922. X(14, no_decode_default_array, LS->decode_default_array = 0) \
  1923. X(15, decode_default_message, LS->decode_default_message = 1) \
  1924. X(16, no_decode_default_message, LS->decode_default_message = 0) \
  1925. X(17, enable_hooks, LS->use_dec_hooks = 1) \
  1926. X(18, disable_hooks, LS->use_dec_hooks = 0) \
  1927. X(19, enable_enchooks, LS->use_enc_hooks = 1) \
  1928. X(20, disable_enchooks, LS->use_enc_hooks = 0) \
  1929. static const char *opts[] = {
  1930. #define X(ID,NAME,CODE) #NAME,
  1931. OPTS(X)
  1932. #undef X
  1933. NULL
  1934. };
  1935. lpb_State *LS = lpb_lstate(L);
  1936. switch (luaL_checkoption(L, 1, NULL, opts)) {
  1937. #define X(ID,NAME,CODE) case ID: CODE; break;
  1938. OPTS(X)
  1939. #undef X
  1940. }
  1941. return 0;
  1942. #undef OPTS
  1943. }
  1944. LUALIB_API int luaopen_pb(lua_State *L) {
  1945. luaL_Reg libs[] = {
  1946. #define ENTRY(name) { #name, Lpb_##name }
  1947. ENTRY(clear),
  1948. ENTRY(load),
  1949. ENTRY(loadfile),
  1950. ENTRY(encode),
  1951. ENTRY(decode),
  1952. ENTRY(types),
  1953. ENTRY(fields),
  1954. ENTRY(type),
  1955. ENTRY(field),
  1956. ENTRY(typefmt),
  1957. ENTRY(enum),
  1958. ENTRY(defaults),
  1959. ENTRY(hook),
  1960. ENTRY(encode_hook),
  1961. ENTRY(tohex),
  1962. ENTRY(fromhex),
  1963. ENTRY(result),
  1964. ENTRY(option),
  1965. ENTRY(state),
  1966. ENTRY(pack),
  1967. ENTRY(unpack),
  1968. #undef ENTRY
  1969. { NULL, NULL }
  1970. };
  1971. luaL_Reg meta[] = {
  1972. { "__gc", Lpb_delete },
  1973. { "setdefault", Lpb_state },
  1974. { NULL, NULL }
  1975. };
  1976. if (luaL_newmetatable(L, PB_STATE)) {
  1977. luaL_setfuncs(L, meta, 0);
  1978. lua_pushvalue(L, -1);
  1979. lua_setfield(L, -2, "__index");
  1980. }
  1981. luaL_newlib(L, libs);
  1982. return 1;
  1983. }
  1984. // static int Lpb_decode_unsafe(lua_State *L) {
  1985. // const char *data = (const char *)lua_touserdata(L, 2);
  1986. // size_t size = (size_t)luaL_checkinteger(L, 3);
  1987. // if (data == NULL) typeerror(L, 2, "userdata");
  1988. // return lpbD_decode(L, pb_lslice(data, size), 4);
  1989. // }
  1990. // static int Lpb_slice_unsafe(lua_State *L) {
  1991. // const char *data = (const char *)lua_touserdata(L, 1);
  1992. // size_t size = (size_t)luaL_checkinteger(L, 2);
  1993. // if (data == NULL) typeerror(L, 1, "userdata");
  1994. // return lpb_newslice(L, data, size);
  1995. // }
  1996. // static int Lpb_touserdata(lua_State *L) {
  1997. // pb_Slice s = lpb_toslice(L, 1);
  1998. // lua_pushlightuserdata(L, (void*)s.p);
  1999. // lua_pushinteger(L, pb_len(s));
  2000. // return 2;
  2001. // }
  2002. // static int Lpb_use(lua_State *L) {
  2003. // const char *opts[] = { "global", "local", NULL };
  2004. // lpb_State *LS = lpb_lstate(L);
  2005. // const pb_State *GS = global_state;
  2006. // switch (luaL_checkoption(L, 1, NULL, opts)) {
  2007. // case 0: if (GS) LS->state = GS; break;
  2008. // case 1: LS->state = &LS->local; break;
  2009. // }
  2010. // lua_pushboolean(L, GS != NULL);
  2011. // return 1;
  2012. // }
  2013. // LUALIB_API int luaopen_pb_unsafe(lua_State *L) {
  2014. // luaL_Reg libs[] = {
  2015. // { "decode", Lpb_decode_unsafe },
  2016. // { "slice", Lpb_slice_unsafe },
  2017. // { "touserdata", Lpb_touserdata },
  2018. // { "use", Lpb_use },
  2019. // { NULL, NULL }
  2020. // };
  2021. // luaL_newlib(L, libs);
  2022. // return 1;
  2023. // }
  2024. #endif
  2025. #include "luat_base.h"
  2026. #include "rotable2.h"
  2027. static const rotable_Reg_t reg_protobuf[] = {
  2028. #define ENTRY(name) { #name, ROREG_FUNC(Lpb_##name) }
  2029. ENTRY(clear),
  2030. ENTRY(load),
  2031. // ENTRY(loadfile), // 暂不支持loadfile, 通过io.readFile中转一下吧
  2032. ENTRY(encode),
  2033. ENTRY(decode),
  2034. // ENTRY(types),
  2035. // ENTRY(fields),
  2036. // ENTRY(type),
  2037. // ENTRY(field),
  2038. // ENTRY(typefmt),
  2039. // ENTRY(enum),
  2040. // ENTRY(defaults),
  2041. // ENTRY(hook),
  2042. // ENTRY(encode_hook),
  2043. // ENTRY(tohex),
  2044. // ENTRY(fromhex),
  2045. // ENTRY(result),
  2046. // ENTRY(option),
  2047. // ENTRY(state),
  2048. // ENTRY(pack),
  2049. // ENTRY(unpack),
  2050. #undef ENTRY
  2051. { NULL, ROREG_INT(0) }
  2052. };
  2053. LUALIB_API int luaopen_protobuf(lua_State *L) {
  2054. rotable2_newlib(L, reg_protobuf);
  2055. return 1;
  2056. }
  2057. void luat_heap_free(void* ptr);
  2058. void luat_heap_free_pb(void* ptr) {
  2059. if (ptr) {
  2060. luat_heap_free(ptr);
  2061. }
  2062. }
  2063. PB_NS_END
  2064. /* cc: flags+='-O3 -ggdb -pedantic -std=c90 -Wall -Wextra --coverage'
  2065. * maccc: flags+='-ggdb -shared -undefined dynamic_lookup' output='pb.so'
  2066. * win32cc: flags+='-s -mdll -DLUA_BUILD_AS_DLL ' output='pb.dll' libs+='-llua54' */