luat_lib_protobuf.c 69 KB

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