pb.h 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721
  1. #ifndef pb_h
  2. #define pb_h
  3. #ifndef PB_NS_BEGIN
  4. # ifdef __cplusplus
  5. # define PB_NS_BEGIN extern "C" {
  6. # define PB_NS_END }
  7. # else
  8. # define PB_NS_BEGIN
  9. # define PB_NS_END
  10. # endif
  11. #endif /* PB_NS_BEGIN */
  12. #ifndef PB_STATIC
  13. # if __GNUC__
  14. # define PB_STATIC static __attribute((unused))
  15. # else
  16. # define PB_STATIC static
  17. # endif
  18. #endif
  19. #ifdef PB_STATIC_API
  20. # ifndef PB_IMPLEMENTATION
  21. # define PB_IMPLEMENTATION
  22. # endif
  23. # define PB_API PB_STATIC
  24. #endif
  25. #if !defined(PB_API) && defined(_WIN32)
  26. # ifdef PB_IMPLEMENTATION
  27. # define PB_API __declspec(dllexport)
  28. # else
  29. # define PB_API __declspec(dllimport)
  30. # endif
  31. #endif
  32. #ifndef PB_API
  33. # define PB_API extern
  34. #endif
  35. #include "stdint.h"
  36. #include <stddef.h>
  37. #include <limits.h>
  38. void* luat_heap_malloc(size_t len);
  39. void luat_heap_free_pb(void* ptr);
  40. #define os_malloc luat_heap_malloc
  41. #define os_free luat_heap_free_pb
  42. PB_NS_BEGIN
  43. /* types */
  44. #define PB_WIRETYPES(X) /* X(id, name, fmt) */\
  45. X(VARINT, "varint", 'v') X(64BIT, "64bit", 'q') X(BYTES, "bytes", 's') \
  46. X(GSTART, "gstart", '!') X(GEND, "gend", '!') X(32BIT, "32bit", 'd') \
  47. #define PB_TYPES(X) /* X(name, type, fmt) */\
  48. X(double, double, 'F') X(float, float, 'f') \
  49. X(int64, int64_t, 'I') X(uint64, uint64_t, 'U') \
  50. X(int32, int32_t, 'i') X(fixed64, uint64_t, 'X') \
  51. X(fixed32, uint32_t, 'x') X(bool, int, 'b') \
  52. X(string, pb_Slice, 't') X(group, pb_Slice, 'g') \
  53. X(message, pb_Slice, 'S') X(bytes, pb_Slice, 's') \
  54. X(uint32, uint32_t, 'u') X(enum, int32_t, 'v') \
  55. X(sfixed32, int32_t, 'y') X(sfixed64, int64_t, 'Y') \
  56. X(sint32, int32_t, 'j') X(sint64, int64_t, 'J') \
  57. typedef enum pb_WireType {
  58. #define X(id,name,fmt) PB_T##id,
  59. PB_WIRETYPES(X)
  60. #undef X
  61. PB_TWIRECOUNT
  62. } pb_WireType;
  63. typedef enum pb_FieldType {
  64. PB_TNONE,
  65. #define X(name,type,fmt) PB_T##name,
  66. PB_TYPES(X)
  67. #undef X
  68. PB_TYPECOUNT
  69. } pb_FieldType;
  70. /* conversions */
  71. PB_API uint64_t pb_expandsig (uint32_t v);
  72. PB_API uint32_t pb_encode_sint32 ( int32_t v);
  73. PB_API int32_t pb_decode_sint32 (uint32_t v);
  74. PB_API uint64_t pb_encode_sint64 ( int64_t v);
  75. PB_API int64_t pb_decode_sint64 (uint64_t v);
  76. PB_API uint32_t pb_encode_float (float v);
  77. PB_API float pb_decode_float (uint32_t v);
  78. PB_API uint64_t pb_encode_double (double v);
  79. PB_API double pb_decode_double (uint64_t v);
  80. /* decode */
  81. typedef struct pb_Slice { const char *p, *start, *end; } pb_Slice;
  82. #define pb_gettype(v) ((v) & 7)
  83. #define pb_gettag(v) ((v) >> 3)
  84. #define pb_pair(tag,type) ((tag) << 3 | ((type) & 7))
  85. PB_API pb_Slice pb_slice (const char *p);
  86. PB_API pb_Slice pb_lslice (const char *p, size_t len);
  87. PB_API size_t pb_pos (const pb_Slice s);
  88. PB_API size_t pb_len (const pb_Slice s);
  89. PB_API size_t pb_readvarint32 (pb_Slice *s, uint32_t *pv);
  90. PB_API size_t pb_readvarint64 (pb_Slice *s, uint64_t *pv);
  91. PB_API size_t pb_readfixed32 (pb_Slice *s, uint32_t *pv);
  92. PB_API size_t pb_readfixed64 (pb_Slice *s, uint64_t *pv);
  93. PB_API size_t pb_readslice (pb_Slice *s, size_t len, pb_Slice *pv);
  94. PB_API size_t pb_readbytes (pb_Slice *s, pb_Slice *pv);
  95. PB_API size_t pb_readgroup (pb_Slice *s, uint32_t tag, pb_Slice *pv);
  96. PB_API size_t pb_skipvarint (pb_Slice *s);
  97. PB_API size_t pb_skipbytes (pb_Slice *s);
  98. PB_API size_t pb_skipslice (pb_Slice *s, size_t len);
  99. PB_API size_t pb_skipvalue (pb_Slice *s, uint32_t tag);
  100. PB_API const char *pb_wtypename (int wiretype, const char *def);
  101. PB_API const char *pb_typename (int type, const char *def);
  102. PB_API int pb_typebyname (const char *name, int def);
  103. PB_API int pb_wtypebyname (const char *name, int def);
  104. PB_API int pb_wtypebytype (int type);
  105. /* encode */
  106. #define PB_SSO_SIZE (sizeof(pb_HeapBuffer))
  107. typedef struct pb_HeapBuffer {
  108. unsigned capacity;
  109. char *buff;
  110. } pb_HeapBuffer;
  111. typedef struct pb_Buffer {
  112. unsigned size : sizeof(unsigned)*CHAR_BIT - 1;
  113. unsigned heap : 1;
  114. union {
  115. char buff[PB_SSO_SIZE];
  116. pb_HeapBuffer h;
  117. } u;
  118. } pb_Buffer;
  119. #define pb_onheap(b) ((b)->heap)
  120. #define pb_bufflen(b) ((b)->size)
  121. #define pb_buffer(b) (pb_onheap(b) ? (b)->u.h.buff : (b)->u.buff)
  122. #define pb_addsize(b,sz) ((void)((b)->size += (unsigned)(sz)))
  123. PB_API void pb_initbuffer (pb_Buffer *b);
  124. PB_API void pb_resetbuffer (pb_Buffer *b);
  125. PB_API char *pb_prepbuffsize (pb_Buffer *b, size_t len);
  126. PB_API pb_Slice pb_result (const pb_Buffer *b);
  127. PB_API size_t pb_addvarint32 (pb_Buffer *b, uint32_t v);
  128. PB_API size_t pb_addvarint64 (pb_Buffer *b, uint64_t v);
  129. PB_API size_t pb_addfixed32 (pb_Buffer *b, uint32_t v);
  130. PB_API size_t pb_addfixed64 (pb_Buffer *b, uint64_t v);
  131. PB_API size_t pb_addslice (pb_Buffer *b, pb_Slice s);
  132. PB_API size_t pb_addbytes (pb_Buffer *b, pb_Slice s);
  133. PB_API size_t pb_addlength (pb_Buffer *b, size_t len);
  134. /* type info database state and name table */
  135. typedef struct pb_State pb_State;
  136. typedef struct pb_Name pb_Name;
  137. typedef struct pb_Cache pb_Cache;
  138. PB_API void pb_init (pb_State *S);
  139. PB_API void pb_free (pb_State *S);
  140. PB_API pb_Name *pb_newname (pb_State *S, pb_Slice s, pb_Cache *cache);
  141. PB_API void pb_delname (pb_State *S, pb_Name *name);
  142. PB_API pb_Name *pb_usename (pb_Name *name);
  143. PB_API const pb_Name *pb_name (const pb_State *S, pb_Slice s, pb_Cache *cache);
  144. /* type info */
  145. typedef struct pb_Type pb_Type;
  146. typedef struct pb_Field pb_Field;
  147. #define PB_OK 0
  148. #define PB_ERROR 1
  149. #define PB_ENOMEM 2
  150. PB_API int pb_load (pb_State *S, pb_Slice *s);
  151. PB_API pb_Type *pb_newtype (pb_State *S, pb_Name *tname);
  152. PB_API void pb_deltype (pb_State *S, pb_Type *t);
  153. PB_API pb_Field *pb_newfield (pb_State *S, pb_Type *t, pb_Name *fname, int32_t number);
  154. PB_API void pb_delfield (pb_State *S, pb_Type *t, pb_Field *f);
  155. PB_API const pb_Type *pb_type (const pb_State *S, const pb_Name *tname);
  156. PB_API const pb_Field *pb_fname (const pb_Type *t, const pb_Name *tname);
  157. PB_API const pb_Field *pb_field (const pb_Type *t, int32_t number);
  158. PB_API const pb_Name *pb_oneofname (const pb_Type *t, int oneof_index);
  159. PB_API int pb_nexttype (const pb_State *S, const pb_Type **ptype);
  160. PB_API int pb_nextfield (const pb_Type *t, const pb_Field **pfield);
  161. /* util: memory pool */
  162. #define PB_POOLSIZE 4096
  163. typedef struct pb_Pool {
  164. void *pages;
  165. void *freed;
  166. size_t obj_size;
  167. } pb_Pool;
  168. PB_API void pb_initpool (pb_Pool *pool, size_t obj_size);
  169. PB_API void pb_freepool (pb_Pool *pool);
  170. PB_API void *pb_poolalloc (pb_Pool *pool);
  171. PB_API void pb_poolfree (pb_Pool *pool, void *obj);
  172. /* util: hash table */
  173. typedef struct pb_Table pb_Table;
  174. typedef struct pb_Entry pb_Entry;
  175. typedef ptrdiff_t pb_Key;
  176. PB_API void pb_inittable (pb_Table *t, size_t entrysize);
  177. PB_API void pb_freetable (pb_Table *t);
  178. PB_API size_t pb_resizetable (pb_Table *t, size_t size);
  179. PB_API pb_Entry *pb_gettable (const pb_Table *t, pb_Key key);
  180. PB_API pb_Entry *pb_settable (pb_Table *t, pb_Key key);
  181. PB_API int pb_nextentry (const pb_Table *t, const pb_Entry **pentry);
  182. struct pb_Table {
  183. unsigned size;
  184. unsigned lastfree;
  185. unsigned entry_size : sizeof(unsigned)*CHAR_BIT - 1;
  186. unsigned has_zero : 1;
  187. pb_Entry *hash;
  188. };
  189. struct pb_Entry {
  190. ptrdiff_t next;
  191. pb_Key key;
  192. };
  193. /* fields */
  194. #define PB_CACHE_SIZE (53)
  195. typedef struct pb_NameEntry {
  196. struct pb_NameEntry *next;
  197. unsigned hash : 32;
  198. unsigned length : 16;
  199. unsigned refcount : 16;
  200. } pb_NameEntry;
  201. typedef struct pb_NameTable {
  202. size_t size;
  203. size_t count;
  204. pb_NameEntry **hash;
  205. } pb_NameTable;
  206. typedef struct pb_CacheSlot {
  207. const char *name;
  208. unsigned hash;
  209. } pb_CacheSlot;
  210. struct pb_Cache {
  211. pb_CacheSlot slots[PB_CACHE_SIZE][2];
  212. unsigned hash;
  213. };
  214. struct pb_State {
  215. pb_NameTable nametable;
  216. pb_Table types;
  217. pb_Pool typepool;
  218. pb_Pool fieldpool;
  219. };
  220. struct pb_Field {
  221. pb_Name *name;
  222. pb_Type *type;
  223. pb_Name *default_value;
  224. int32_t number;
  225. int32_t sort_index;
  226. unsigned oneof_idx : 24;
  227. unsigned type_id : 5; /* PB_T* enum */
  228. unsigned repeated : 1;
  229. unsigned packed : 1;
  230. unsigned scalar : 1;
  231. };
  232. struct pb_Type {
  233. pb_Name *name;
  234. const char *basename;
  235. pb_Field **field_sort;
  236. pb_Table field_tags;
  237. pb_Table field_names;
  238. pb_Table oneof_index;
  239. unsigned oneof_count; /* extra field count from oneof entries */
  240. unsigned oneof_field; /* extra field in oneof declarations */
  241. unsigned field_count : 28;
  242. unsigned is_enum : 1;
  243. unsigned is_map : 1;
  244. unsigned is_proto3 : 1;
  245. unsigned is_dead : 1;
  246. };
  247. PB_NS_END
  248. #endif /* pb_h */
  249. #if defined(PB_IMPLEMENTATION) && !defined(pb_implemented)
  250. #define pb_implemented
  251. #define PB_MAX_SIZET ((unsigned)~0 - 100)
  252. #define PB_MAX_HASHSIZE ((unsigned)~0 - 100)
  253. #define PB_MIN_STRTABLE_SIZE 16
  254. #define PB_MIN_HASHTABLE_SIZE 8
  255. #define PB_HASHLIMIT 5
  256. #include <assert.h>
  257. #include <stdlib.h>
  258. #include <string.h>
  259. PB_NS_BEGIN
  260. /* conversions */
  261. PB_API uint32_t pb_encode_sint32(int32_t value)
  262. { return ((uint32_t)value << 1) ^ -(value < 0); }
  263. PB_API int32_t pb_decode_sint32(uint32_t value)
  264. { return (value >> 1) ^ -(int32_t)(value & 1); }
  265. PB_API uint64_t pb_encode_sint64(int64_t value)
  266. { return ((uint64_t)value << 1) ^ -(value < 0); }
  267. PB_API int64_t pb_decode_sint64(uint64_t value)
  268. { return (value >> 1) ^ -(int64_t)(value & 1); }
  269. PB_API uint64_t pb_expandsig(uint32_t value)
  270. { uint64_t m = (uint64_t)1U << 31; return (value ^ m) - m; }
  271. PB_API uint32_t pb_encode_float(float value)
  272. { union { uint32_t u32; float f; } u; u.f = value; return u.u32; }
  273. PB_API float pb_decode_float(uint32_t value)
  274. { union { uint32_t u32; float f; } u; u.u32 = value; return u.f; }
  275. PB_API uint64_t pb_encode_double(double value)
  276. { union { uint64_t u64; double d; } u; u.d = value; return u.u64; }
  277. PB_API double pb_decode_double(uint64_t value)
  278. { union { uint64_t u64; double d; } u; u.u64 = value; return u.d; }
  279. /* decode */
  280. PB_API pb_Slice pb_slice(const char *s)
  281. { return s ? pb_lslice(s, strlen(s)) : pb_lslice(NULL, 0); }
  282. PB_API size_t pb_pos(const pb_Slice s) { return s.p - s.start; }
  283. PB_API size_t pb_len(const pb_Slice s) { return s.end - s.p; }
  284. static size_t pb_readvarint_slow(pb_Slice *s, uint64_t *pv) {
  285. const char *p = s->p;
  286. uint64_t n = 0;
  287. int i = 0;
  288. while (s->p < s->end && i < 10) {
  289. int b = *s->p++;
  290. n |= ((uint64_t)b & 0x7F) << (7*i++);
  291. if ((b & 0x80) == 0) {
  292. *pv = n;
  293. return i;
  294. }
  295. }
  296. s->p = p;
  297. return 0;
  298. }
  299. static size_t pb_readvarint32_fallback(pb_Slice *s, uint32_t *pv) {
  300. const uint8_t *p = (const uint8_t*)s->p, *o = p;
  301. uint32_t b, n;
  302. for (;;) {
  303. n = *p++ - 0x80, n += (b = *p++) << 7; if (!(b & 0x80)) break;
  304. n -= 0x80 << 7, n += (b = *p++) << 14; if (!(b & 0x80)) break;
  305. n -= 0x80 << 14, n += (b = *p++) << 21; if (!(b & 0x80)) break;
  306. n -= 0x80 << 21, n += (b = *p++) << 28; if (!(b & 0x80)) break;
  307. /* n -= 0x80 << 28; */
  308. if (!(*p++ & 0x80)) break;
  309. if (!(*p++ & 0x80)) break;
  310. if (!(*p++ & 0x80)) break;
  311. if (!(*p++ & 0x80)) break;
  312. if (!(*p++ & 0x80)) break;
  313. return 0;
  314. }
  315. *pv = n;
  316. s->p = (const char*)p;
  317. return p - o;
  318. }
  319. static size_t pb_readvarint64_fallback(pb_Slice *s, uint64_t *pv) {
  320. const uint8_t *p = (const uint8_t*)s->p, *o = p;
  321. uint32_t b, n1, n2 = 0, n3 = 0;
  322. for (;;) {
  323. n1 = *p++ - 0x80, n1 += (b = *p++) << 7; if (!(b & 0x80)) break;
  324. n1 -= 0x80 << 7, n1 += (b = *p++) << 14; if (!(b & 0x80)) break;
  325. n1 -= 0x80 << 14, n1 += (b = *p++) << 21; if (!(b & 0x80)) break;
  326. n1 -= 0x80 << 21, n2 += (b = *p++) ; if (!(b & 0x80)) break;
  327. n2 -= 0x80 , n2 += (b = *p++) << 7; if (!(b & 0x80)) break;
  328. n2 -= 0x80 << 7, n2 += (b = *p++) << 14; if (!(b & 0x80)) break;
  329. n2 -= 0x80 << 14, n2 += (b = *p++) << 21; if (!(b & 0x80)) break;
  330. n2 -= 0x80 << 21, n3 += (b = *p++) ; if (!(b & 0x80)) break;
  331. n3 -= 0x80 , n3 += (b = *p++) << 7; if (!(b & 0x80)) break;
  332. return 0;
  333. }
  334. *pv = n1 | ((uint64_t)n2 << 28) | ((uint64_t)n3 << 56);
  335. s->p = (const char*)p;
  336. return p - o;
  337. }
  338. PB_API pb_Slice pb_lslice(const char *s, size_t len) {
  339. pb_Slice slice;
  340. slice.start = slice.p = s;
  341. slice.end = s + len;
  342. return slice;
  343. }
  344. PB_API size_t pb_readvarint32(pb_Slice *s, uint32_t *pv) {
  345. uint64_t u64;
  346. size_t ret;
  347. if (s->p >= s->end) return 0;
  348. if (!(*s->p & 0x80)) return *pv = *s->p++, 1;
  349. if (pb_len(*s) >= 10 || !(s->end[-1] & 0x80))
  350. return pb_readvarint32_fallback(s, pv);
  351. if ((ret = pb_readvarint_slow(s, &u64)) != 0)
  352. *pv = (uint32_t)u64;
  353. return ret;
  354. }
  355. PB_API size_t pb_readvarint64(pb_Slice *s, uint64_t *pv) {
  356. if (s->p >= s->end) return 0;
  357. if (!(*s->p & 0x80)) return *pv = *s->p++, 1;
  358. if (pb_len(*s) >= 10 || !(s->end[-1] & 0x80))
  359. return pb_readvarint64_fallback(s, pv);
  360. return pb_readvarint_slow(s, pv);
  361. }
  362. PB_API size_t pb_readfixed32(pb_Slice *s, uint32_t *pv) {
  363. int i;
  364. uint32_t n = 0;
  365. if (s->p + 4 > s->end)
  366. return 0;
  367. for (i = 3; i >= 0; --i) {
  368. n <<= 8;
  369. n |= s->p[i] & 0xFF;
  370. }
  371. s->p += 4;
  372. *pv = n;
  373. return 4;
  374. }
  375. PB_API size_t pb_readfixed64(pb_Slice *s, uint64_t *pv) {
  376. int i;
  377. uint64_t n = 0;
  378. if (s->p + 8 > s->end)
  379. return 0;
  380. for (i = 7; i >= 0; --i) {
  381. n <<= 8;
  382. n |= s->p[i] & 0xFF;
  383. }
  384. s->p += 8;
  385. *pv = n;
  386. return 8;
  387. }
  388. PB_API size_t pb_readslice(pb_Slice *s, size_t len, pb_Slice *pv) {
  389. if (pb_len(*s) < len)
  390. return 0;
  391. pv->start = s->start;
  392. pv->p = s->p;
  393. pv->end = s->p + len;
  394. s->p = pv->end;
  395. return len;
  396. }
  397. PB_API size_t pb_readbytes(pb_Slice *s, pb_Slice *pv) {
  398. const char *p = s->p;
  399. uint64_t len;
  400. if (pb_readvarint64(s, &len) == 0 || pb_len(*s) < len) {
  401. s->p = p;
  402. return 0;
  403. }
  404. pv->start = s->start;
  405. pv->p = s->p;
  406. pv->end = s->p + len;
  407. s->p = pv->end;
  408. return s->p - p;
  409. }
  410. PB_API size_t pb_readgroup(pb_Slice *s, uint32_t tag, pb_Slice *pv) {
  411. const char *p = s->p;
  412. uint32_t newtag = 0;
  413. size_t count;
  414. assert(pb_gettype(tag) == PB_TGSTART);
  415. while ((count = pb_readvarint32(s, &newtag)) != 0) {
  416. if (pb_gettype(newtag) == PB_TGEND) {
  417. if (pb_gettag(newtag) != pb_gettag(tag))
  418. break;
  419. pv->start = s->start;
  420. pv->p = p;
  421. pv->end = s->p - count;
  422. return s->p - p;
  423. }
  424. if (pb_skipvalue(s, newtag) == 0) break;
  425. }
  426. s->p = p;
  427. return 0;
  428. }
  429. PB_API size_t pb_skipvalue(pb_Slice *s, uint32_t tag) {
  430. const char *p = s->p;
  431. size_t ret = 0;
  432. pb_Slice data;
  433. switch (pb_gettype(tag)) {
  434. default: break;
  435. case PB_TVARINT: ret = pb_skipvarint(s); break;
  436. case PB_T64BIT: ret = pb_skipslice(s, 8); break;
  437. case PB_TBYTES: ret = pb_skipbytes(s); break;
  438. case PB_T32BIT: ret = pb_skipslice(s, 4); break;
  439. case PB_TGSTART: ret = pb_readgroup(s, tag, &data); break;
  440. }
  441. if (!ret) s->p = p;
  442. return ret;
  443. }
  444. PB_API size_t pb_skipvarint(pb_Slice *s) {
  445. const char *p = s->p, *op = p;
  446. while (p < s->end && (*p & 0x80) != 0) ++p;
  447. if (p >= s->end) return 0;
  448. s->p = ++p;
  449. return p - op;
  450. }
  451. PB_API size_t pb_skipbytes(pb_Slice *s) {
  452. const char *p = s->p;
  453. uint64_t var;
  454. if (!pb_readvarint64(s, &var)) return 0;
  455. if (pb_len(*s) < var) {
  456. s->p = p;
  457. return 0;
  458. }
  459. s->p += var;
  460. return s->p - p;
  461. }
  462. PB_API size_t pb_skipslice(pb_Slice *s, size_t len) {
  463. if (s->p + len > s->end) return 0;
  464. s->p += len;
  465. return len;
  466. }
  467. PB_API int pb_wtypebytype(int type) {
  468. switch (type) {
  469. case PB_Tdouble: return PB_T64BIT;
  470. case PB_Tfloat: return PB_T32BIT;
  471. case PB_Tint64: return PB_TVARINT;
  472. case PB_Tuint64: return PB_TVARINT;
  473. case PB_Tint32: return PB_TVARINT;
  474. case PB_Tfixed64: return PB_T64BIT;
  475. case PB_Tfixed32: return PB_T32BIT;
  476. case PB_Tbool: return PB_TVARINT;
  477. case PB_Tstring: return PB_TBYTES;
  478. case PB_Tmessage: return PB_TBYTES;
  479. case PB_Tbytes: return PB_TBYTES;
  480. case PB_Tuint32: return PB_TVARINT;
  481. case PB_Tenum: return PB_TVARINT;
  482. case PB_Tsfixed32: return PB_T32BIT;
  483. case PB_Tsfixed64: return PB_T64BIT;
  484. case PB_Tsint32: return PB_TVARINT;
  485. case PB_Tsint64: return PB_TVARINT;
  486. default: return PB_TWIRECOUNT;
  487. }
  488. }
  489. PB_API const char *pb_wtypename(int wiretype, const char *def) {
  490. switch (wiretype) {
  491. #define X(id,name,fmt) case PB_T##id: return name;
  492. PB_WIRETYPES(X)
  493. #undef X
  494. default: return def ? def : "<unknown>";
  495. }
  496. }
  497. PB_API const char *pb_typename(int type, const char *def) {
  498. switch (type) {
  499. #define X(name,type,fmt) case PB_T##name: return #name;
  500. PB_TYPES(X)
  501. #undef X
  502. default: return def ? def : "<unknown>";
  503. }
  504. }
  505. PB_API int pb_typebyname(const char *name, int def) {
  506. static struct entry { const char *name; int value; } names[] = {
  507. #define X(name,type,fmt) { #name, PB_T##name },
  508. PB_TYPES(X)
  509. #undef X
  510. { NULL, 0 }
  511. };
  512. struct entry *p;
  513. for (p = names; p->name != NULL; ++p)
  514. if (strcmp(p->name, name) == 0)
  515. return p->value;
  516. return def;
  517. }
  518. PB_API int pb_wtypebyname(const char *name, int def) {
  519. static struct entry { const char *name; int value; } names[] = {
  520. #define X(id,name,fmt) { name, PB_T##id },
  521. PB_WIRETYPES(X)
  522. #undef X
  523. { NULL, 0 }
  524. };
  525. struct entry *p;
  526. for (p = names; p->name != NULL; ++p)
  527. if (strcmp(p->name, name) == 0)
  528. return p->value;
  529. return def;
  530. }
  531. /* encode */
  532. PB_API pb_Slice pb_result(const pb_Buffer *b)
  533. { pb_Slice slice = pb_lslice(pb_buffer(b), b->size); return slice; }
  534. PB_API void pb_initbuffer(pb_Buffer *b)
  535. { memset(b, 0, sizeof(pb_Buffer)); }
  536. PB_API void pb_resetbuffer(pb_Buffer *b)
  537. { if (pb_onheap(b)) os_free(b->u.h.buff); pb_initbuffer(b); }
  538. static int pb_write32(char *buff, uint32_t n) {
  539. int p, c = 0;
  540. do {
  541. p = n & 0x7F; if ((n >>= 7) == 0) break; *buff++ = p | 0x80, ++c;
  542. p = n & 0x7F; if ((n >>= 7) == 0) break; *buff++ = p | 0x80, ++c;
  543. p = n & 0x7F; if ((n >>= 7) == 0) break; *buff++ = p | 0x80, ++c;
  544. p = n & 0x7F; if ((n >>= 7) == 0) break; *buff++ = p | 0x80, ++c;
  545. p = n;
  546. } while (0);
  547. return *buff++ = p, ++c;
  548. }
  549. static int pb_write64(char *buff, uint64_t n) {
  550. int p, c = 0;
  551. do {
  552. p = n & 0x7F; if ((n >>= 7) == 0) break; *buff++ = p | 0x80, ++c;
  553. p = n & 0x7F; if ((n >>= 7) == 0) break; *buff++ = p | 0x80, ++c;
  554. p = n & 0x7F; if ((n >>= 7) == 0) break; *buff++ = p | 0x80, ++c;
  555. p = n & 0x7F; if ((n >>= 7) == 0) break; *buff++ = p | 0x80, ++c;
  556. p = n & 0x7F; if ((n >>= 7) == 0) break; *buff++ = p | 0x80, ++c;
  557. p = n & 0x7F; if ((n >>= 7) == 0) break; *buff++ = p | 0x80, ++c;
  558. p = n & 0x7F; if ((n >>= 7) == 0) break; *buff++ = p | 0x80, ++c;
  559. p = n & 0x7F; if ((n >>= 7) == 0) break; *buff++ = p | 0x80, ++c;
  560. p = n & 0x7F; if ((n >>= 7) == 0) break; *buff++ = p | 0x80, ++c;
  561. p = n & 0x7F;
  562. } while (0);
  563. return *buff++ = p, ++c;
  564. }
  565. PB_API char *pb_prepbuffsize(pb_Buffer *b, size_t len) {
  566. size_t capacity = pb_onheap(b) ? b->u.h.capacity : PB_SSO_SIZE;
  567. if (b->size + len > capacity) {
  568. char *newp, *oldp = pb_onheap(b) ? b->u.h.buff : NULL;
  569. size_t expected = b->size + len;
  570. size_t newsize = PB_SSO_SIZE;
  571. while (newsize < PB_MAX_SIZET/2 && newsize < expected)
  572. newsize += newsize >> 1;
  573. if (newsize < expected) return NULL;
  574. if ((newp = (char*)realloc(oldp, newsize)) == NULL) return NULL;
  575. if (!pb_onheap(b)) memcpy(newp, pb_buffer(b), b->size);
  576. b->heap = 1;
  577. b->u.h.buff = newp;
  578. b->u.h.capacity = (unsigned)newsize;
  579. }
  580. return &pb_buffer(b)[b->size];
  581. }
  582. PB_API size_t pb_addslice(pb_Buffer *b, pb_Slice s) {
  583. size_t len = pb_len(s);
  584. char *buff = pb_prepbuffsize(b, len);
  585. if (buff == NULL) return 0;
  586. memcpy(buff, s.p, len);
  587. pb_addsize(b, len);
  588. return len;
  589. }
  590. PB_API size_t pb_addlength(pb_Buffer *b, size_t len) {
  591. char buff[10], *s;
  592. size_t bl, ml;
  593. if ((bl = pb_bufflen(b)) < len)
  594. return 0;
  595. ml = pb_write64(buff, bl - len);
  596. if (pb_prepbuffsize(b, ml) == NULL) return 0;
  597. s = pb_buffer(b) + len;
  598. memmove(s+ml, s, bl - len);
  599. memcpy(s, buff, ml);
  600. pb_addsize(b, ml);
  601. return ml;
  602. }
  603. PB_API size_t pb_addbytes(pb_Buffer *b, pb_Slice s) {
  604. size_t ret, len = pb_len(s);
  605. if (pb_prepbuffsize(b, len+5) == NULL) return 0;
  606. ret = pb_addvarint32(b, (uint32_t)len);
  607. return ret + pb_addslice(b, s);
  608. }
  609. PB_API size_t pb_addvarint32(pb_Buffer *b, uint32_t n) {
  610. char *buff = pb_prepbuffsize(b, 5);
  611. size_t l;
  612. if (buff == NULL) return 0;
  613. pb_addsize(b, l = pb_write32(buff, n));
  614. return l;
  615. }
  616. PB_API size_t pb_addvarint64(pb_Buffer *b, uint64_t n) {
  617. char *buff = pb_prepbuffsize(b, 10);
  618. size_t l;
  619. if (buff == NULL) return 0;
  620. pb_addsize(b, l = pb_write64(buff, n));
  621. return l;
  622. }
  623. PB_API size_t pb_addfixed32(pb_Buffer *b, uint32_t n) {
  624. char *ch = pb_prepbuffsize(b, 4);
  625. if (ch == NULL) return 0;
  626. *ch++ = n & 0xFF; n >>= 8;
  627. *ch++ = n & 0xFF; n >>= 8;
  628. *ch++ = n & 0xFF; n >>= 8;
  629. *ch = n & 0xFF;
  630. pb_addsize(b, 4);
  631. return 4;
  632. }
  633. PB_API size_t pb_addfixed64(pb_Buffer *b, uint64_t n) {
  634. char *ch = pb_prepbuffsize(b, 8);
  635. if (ch == NULL) return 0;
  636. *ch++ = n & 0xFF; n >>= 8;
  637. *ch++ = n & 0xFF; n >>= 8;
  638. *ch++ = n & 0xFF; n >>= 8;
  639. *ch++ = n & 0xFF; n >>= 8;
  640. *ch++ = n & 0xFF; n >>= 8;
  641. *ch++ = n & 0xFF; n >>= 8;
  642. *ch++ = n & 0xFF; n >>= 8;
  643. *ch = n & 0xFF;
  644. pb_addsize(b, 8);
  645. return 8;
  646. }
  647. /* memory pool */
  648. PB_API void pb_initpool(pb_Pool *pool, size_t obj_size) {
  649. memset(pool, 0, sizeof(pb_Pool));
  650. pool->obj_size = obj_size;
  651. assert(obj_size > sizeof(void*) && obj_size < PB_POOLSIZE/4);
  652. }
  653. PB_API void pb_freepool(pb_Pool *pool) {
  654. void *page = pool->pages;
  655. while (page) {
  656. void *next = *(void**)((char*)page + PB_POOLSIZE - sizeof(void*));
  657. os_free(page);
  658. page = next;
  659. }
  660. pb_initpool(pool, pool->obj_size);
  661. }
  662. PB_API void *pb_poolalloc(pb_Pool *pool) {
  663. void *obj = pool->freed;
  664. if (obj == NULL) {
  665. size_t objsize = pool->obj_size, offset;
  666. void *newpage = os_malloc(PB_POOLSIZE);
  667. if (newpage == NULL) return NULL;
  668. offset = ((PB_POOLSIZE - sizeof(void*)) / objsize - 1) * objsize;
  669. for (; offset > 0; offset -= objsize) {
  670. void **entry = (void**)((char*)newpage + offset);
  671. *entry = pool->freed, pool->freed = (void*)entry;
  672. }
  673. *(void**)((char*)newpage + PB_POOLSIZE - sizeof(void*)) = pool->pages;
  674. pool->pages = newpage;
  675. return newpage;
  676. }
  677. pool->freed = *(void**)obj;
  678. return obj;
  679. }
  680. PB_API void pb_poolfree(pb_Pool *pool, void *obj)
  681. { *(void**)obj = pool->freed, pool->freed = obj; }
  682. /* hash table */
  683. #define pbT_offset(a,b) ((char*)(a) - (char*)(b))
  684. #define pbT_index(a,b) ((pb_Entry*)((char*)(a) + (b)))
  685. PB_API void pb_inittable(pb_Table *t, size_t entrysize)
  686. { memset(t, 0, sizeof(pb_Table)), t->entry_size = (unsigned)entrysize; }
  687. PB_API void pb_freetable(pb_Table *t)
  688. { os_free(t->hash); pb_inittable(t, t->entry_size); }
  689. static pb_Entry *pbT_hash(const pb_Table *t, pb_Key key) {
  690. size_t h = ((size_t)key*2654435761U)&(t->size-1);
  691. if (key && h == 0) h = 1;
  692. return pbT_index(t->hash, h*t->entry_size);
  693. }
  694. static pb_Entry *pbT_newkey(pb_Table *t, pb_Key key) {
  695. pb_Entry *mp, *on, *next, *f = NULL;
  696. if (t->size == 0 && pb_resizetable(t, (size_t)t->size*2) == 0) return NULL;
  697. if (key == 0) {
  698. mp = t->hash;
  699. t->has_zero = 1;
  700. } else if ((mp = pbT_hash(t, key))->key != 0) {
  701. while (t->lastfree > t->entry_size) {
  702. pb_Entry *cur = pbT_index(t->hash, t->lastfree -= t->entry_size);
  703. if (cur->key == 0 && cur->next == 0) { f = cur; break; }
  704. }
  705. if (f == NULL) return pb_resizetable(t, (size_t)t->size*2u) ?
  706. pbT_newkey(t, key) : NULL;
  707. if ((on = pbT_hash(t, mp->key)) != mp) {
  708. while ((next = pbT_index(on, on->next)) != mp) on = next;
  709. on->next = pbT_offset(f, on);
  710. memcpy(f, mp, t->entry_size);
  711. if (mp->next != 0) f->next += pbT_offset(mp, f), mp->next = 0;
  712. } else {
  713. if (mp->next != 0) f->next = pbT_offset(mp, f) + mp->next;
  714. else assert(f->next == 0);
  715. mp->next = pbT_offset(f, mp);
  716. mp = f;
  717. }
  718. }
  719. mp->key = key;
  720. if (t->entry_size != sizeof(pb_Entry))
  721. memset(mp+1, 0, t->entry_size - sizeof(pb_Entry));
  722. return mp;
  723. }
  724. PB_API size_t pb_resizetable(pb_Table *t, size_t size) {
  725. pb_Table nt = *t;
  726. unsigned i, rawsize = t->size*t->entry_size;
  727. unsigned newsize = PB_MIN_HASHTABLE_SIZE;
  728. while (newsize < PB_MAX_HASHSIZE/t->entry_size && newsize < size)
  729. newsize <<= 1;
  730. if (newsize < size) return 0;
  731. nt.size = newsize;
  732. nt.lastfree = nt.entry_size * newsize;
  733. nt.hash = (pb_Entry*)os_malloc(nt.lastfree);
  734. if (nt.hash == NULL) return 0;
  735. memset(nt.hash, 0, nt.lastfree);
  736. for (i = 0; i < rawsize; i += t->entry_size) {
  737. pb_Entry *olde = (pb_Entry*)((char*)t->hash + i);
  738. pb_Entry *newe = pbT_newkey(&nt, olde->key);
  739. if (nt.entry_size > sizeof(pb_Entry))
  740. memcpy(newe+1, olde+1, nt.entry_size - sizeof(pb_Entry));
  741. }
  742. os_free(t->hash);
  743. *t = nt;
  744. return newsize;
  745. }
  746. PB_API pb_Entry *pb_gettable(const pb_Table *t, pb_Key key) {
  747. pb_Entry *entry;
  748. if (t == NULL || t->size == 0)
  749. return NULL;
  750. if (key == 0)
  751. return t->has_zero ? t->hash : NULL;
  752. for (entry = pbT_hash(t, key);
  753. entry->key != key;
  754. entry = pbT_index(entry, entry->next))
  755. if (entry->next == 0) return NULL;
  756. return entry;
  757. }
  758. PB_API pb_Entry *pb_settable(pb_Table *t, pb_Key key) {
  759. pb_Entry *entry;
  760. if ((entry = pb_gettable(t, key)) != NULL)
  761. return entry;
  762. return pbT_newkey(t, key);
  763. }
  764. PB_API int pb_nextentry(const pb_Table *t, const pb_Entry **pentry) {
  765. size_t i = *pentry ? pbT_offset(*pentry, t->hash) : 0;
  766. size_t size = (size_t)t->size*t->entry_size;
  767. if (*pentry == NULL && t->has_zero) {
  768. *pentry = t->hash;
  769. return 1;
  770. }
  771. while (i += t->entry_size, i < size) {
  772. pb_Entry *entry = pbT_index(t->hash, i);
  773. if (entry->key != 0) {
  774. *pentry = entry;
  775. return 1;
  776. }
  777. }
  778. *pentry = NULL;
  779. return 0;
  780. }
  781. /* name table */
  782. static void pbN_init(pb_State *S)
  783. { memset(&S->nametable, 0, sizeof(pb_NameTable)); }
  784. PB_API pb_Name *pb_usename(pb_Name *name)
  785. { if (name != NULL) ++((pb_NameEntry*)name-1)->refcount; return name; }
  786. static void pbN_free(pb_State *S) {
  787. pb_NameTable *nt = &S->nametable;
  788. size_t i;
  789. for (i = 0; i < nt->size; ++i) {
  790. pb_NameEntry *ne = nt->hash[i];
  791. while (ne != NULL) {
  792. pb_NameEntry *next = ne->next;
  793. os_free(ne);
  794. ne = next;
  795. }
  796. }
  797. os_free(nt->hash);
  798. pbN_init(S);
  799. }
  800. static unsigned pbN_calchash(pb_Slice s) {
  801. size_t len = pb_len(s);
  802. unsigned h = (unsigned)len;
  803. size_t step = (len >> PB_HASHLIMIT) + 1;
  804. for (; len >= step; len -= step)
  805. h ^= ((h<<5) + (h>>2) + (unsigned char)(s.p[len - 1]));
  806. return h;
  807. }
  808. static size_t pbN_resize(pb_State *S, size_t size) {
  809. pb_NameTable *nt = &S->nametable;
  810. pb_NameEntry **hash;
  811. size_t i, newsize = PB_MIN_STRTABLE_SIZE;
  812. while (newsize < PB_MAX_HASHSIZE/sizeof(pb_NameEntry*) && newsize < size)
  813. newsize <<= 1;
  814. if (newsize < size) return 0;
  815. hash = (pb_NameEntry**)os_malloc(newsize * sizeof(pb_NameEntry*));
  816. if (hash == NULL) return 0;
  817. memset(hash, 0, newsize * sizeof(pb_NameEntry*));
  818. for (i = 0; i < nt->size; ++i) {
  819. pb_NameEntry *entry = nt->hash[i];
  820. while (entry != NULL) {
  821. pb_NameEntry *next = entry->next;
  822. pb_NameEntry **newh = &hash[entry->hash & (newsize - 1)];
  823. entry->next = *newh, *newh = entry;
  824. entry = next;
  825. }
  826. }
  827. os_free(nt->hash);
  828. nt->hash = hash;
  829. nt->size = newsize;
  830. return newsize;
  831. }
  832. static pb_NameEntry *pbN_newname(pb_State *S, pb_Slice s, unsigned hash) {
  833. pb_NameTable *nt = &S->nametable;
  834. pb_NameEntry **list, *newobj;
  835. size_t len = pb_len(s);
  836. if (nt->count >= nt->size && !pbN_resize(S, nt->size * 2)) return NULL;
  837. list = &nt->hash[hash & (nt->size - 1)];
  838. newobj = (pb_NameEntry*)os_malloc(sizeof(pb_NameEntry) + len + 1);
  839. if (newobj == NULL) return NULL;
  840. newobj->next = *list;
  841. newobj->length = (unsigned)len;
  842. newobj->refcount = 0;
  843. newobj->hash = hash;
  844. memcpy(newobj+1, s.p, len);
  845. ((char*)(newobj+1))[len] = '\0';
  846. *list = newobj;
  847. ++nt->count;
  848. return newobj;
  849. }
  850. static void pbN_delname(pb_State *S, pb_NameEntry *name) {
  851. pb_NameTable *nt = &S->nametable;
  852. pb_NameEntry **list = &nt->hash[name->hash & (nt->size - 1)];
  853. while (*list != NULL) {
  854. if (*list != name)
  855. list = &(*list)->next;
  856. else {
  857. *list = (*list)->next;
  858. --nt->count;
  859. os_free(name);
  860. break;
  861. }
  862. }
  863. }
  864. static pb_NameEntry *pbN_getname(const pb_State *S, pb_Slice s, unsigned hash) {
  865. const pb_NameTable *nt = &S->nametable;
  866. size_t len = pb_len(s);
  867. if (nt->hash) {
  868. pb_NameEntry *entry = nt->hash[hash & (nt->size - 1)];
  869. for (; entry != NULL; entry = entry->next)
  870. if (entry->hash == hash && entry->length == len
  871. && memcmp(s.p, entry + 1, len) == 0)
  872. return entry;
  873. }
  874. return NULL;
  875. }
  876. PB_API void pb_delname(pb_State *S, pb_Name *name) {
  877. if (name != NULL) {
  878. pb_NameEntry *ne = (pb_NameEntry*)name - 1;
  879. if (ne->refcount <= 1) { pbN_delname(S, ne); return; }
  880. --ne->refcount;
  881. }
  882. }
  883. PB_API pb_Name *pb_newname(pb_State *S, pb_Slice s, pb_Cache *cache) {
  884. pb_NameEntry *entry;
  885. if (s.p == NULL) return NULL;
  886. (void)cache;
  887. assert(cache == NULL);
  888. /* if (cache == NULL) */{
  889. unsigned hash = pbN_calchash(s);
  890. entry = pbN_getname(S, s, hash);
  891. if (entry == NULL) entry = pbN_newname(S, s, hash);
  892. }/* else {
  893. pb_Name *name = (pb_Name*)pb_name(S, s, cache);
  894. if (name) return pb_usename(name);
  895. entry = pbN_newname(S, s, cache->hash);
  896. }*/
  897. return entry ? pb_usename((pb_Name*)(entry + 1)) : NULL;
  898. }
  899. PB_API const pb_Name *pb_name(const pb_State *S, pb_Slice s, pb_Cache *cache) {
  900. pb_NameEntry *entry = NULL;
  901. pb_CacheSlot *slot;
  902. if (s.p == NULL) return NULL;
  903. if (cache == NULL)
  904. entry = pbN_getname(S, s, pbN_calchash(s));
  905. else {
  906. slot = cache->slots[((uintptr_t)s.p*2654435761U)%PB_CACHE_SIZE];
  907. if (slot[0].name == s.p)
  908. entry = pbN_getname(S, s, cache->hash = slot[0].hash);
  909. else if (slot[1].name == s.p)
  910. entry = pbN_getname(S, s, cache->hash = (++slot)[0].hash);
  911. else
  912. slot[1] = slot[0], slot[0].name = s.p;
  913. if (entry == NULL) {
  914. cache->hash = slot[0].hash = pbN_calchash(s);
  915. entry = pbN_getname(S, s, slot[0].hash);
  916. }
  917. }
  918. return entry ? (pb_Name*)(entry + 1) : NULL;
  919. }
  920. /* state */
  921. typedef struct pb_TypeEntry { pb_Entry entry; pb_Type *value; } pb_TypeEntry;
  922. typedef struct pb_FieldEntry { pb_Entry entry; pb_Field *value; } pb_FieldEntry;
  923. typedef struct pb_OneofEntry {
  924. pb_Entry entry;
  925. pb_Name *name;
  926. unsigned index;
  927. } pb_OneofEntry;
  928. PB_API void pb_init(pb_State *S) {
  929. memset(S, 0, sizeof(pb_State));
  930. S->types.entry_size = sizeof(pb_TypeEntry);
  931. pb_initpool(&S->typepool, sizeof(pb_Type));
  932. pb_initpool(&S->fieldpool, sizeof(pb_Field));
  933. }
  934. PB_API void pb_free(pb_State *S) {
  935. const pb_TypeEntry *te = NULL;
  936. if (S == NULL) return;
  937. while (pb_nextentry(&S->types, (const pb_Entry**)&te))
  938. if (te->value != NULL) pb_deltype(S, te->value);
  939. pb_freetable(&S->types);
  940. pb_freepool(&S->typepool);
  941. pb_freepool(&S->fieldpool);
  942. pbN_free(S);
  943. }
  944. PB_API const pb_Type *pb_type(const pb_State *S, const pb_Name *tname) {
  945. pb_TypeEntry *te = NULL;
  946. if (S != NULL && tname != NULL)
  947. te = (pb_TypeEntry*)pb_gettable(&S->types, (pb_Key)tname);
  948. return te && !te->value->is_dead ? te->value : NULL;
  949. }
  950. PB_API const pb_Field *pb_fname(const pb_Type *t, const pb_Name *name) {
  951. pb_FieldEntry *fe = NULL;
  952. if (t != NULL && name != NULL)
  953. fe = (pb_FieldEntry*)pb_gettable(&t->field_names, (pb_Key)name);
  954. return fe ? fe->value : NULL;
  955. }
  956. PB_API const pb_Field *pb_field(const pb_Type *t, int32_t number) {
  957. pb_FieldEntry *fe = NULL;
  958. if (t != NULL) fe = (pb_FieldEntry*)pb_gettable(&t->field_tags, number);
  959. return fe ? fe->value : NULL;
  960. }
  961. static int comp_field(const void* a, const void* b) {
  962. return (*(const pb_Field**)a)->number - (*(const pb_Field**)b)->number;
  963. }
  964. PB_API pb_Field** pb_sortfield(pb_Type* t) {
  965. if (!t->field_sort && t->field_count) {
  966. int index = 0;
  967. unsigned int i = 0;
  968. const pb_Field* f = NULL;
  969. pb_Field** list = os_malloc(sizeof(pb_Field*) * t->field_count);
  970. assert(list);
  971. while (pb_nextfield(t, &f)) {
  972. list[index++] = (pb_Field*)f;
  973. }
  974. qsort(list, index, sizeof(pb_Field*), comp_field);
  975. for (i = 0; i < t->field_count; i++) {
  976. list[i]->sort_index = i + 1;
  977. }
  978. t->field_sort = list;
  979. }
  980. return t->field_sort;
  981. }
  982. PB_API const pb_Name *pb_oneofname(const pb_Type *t, int idx) {
  983. pb_OneofEntry *oe = NULL;
  984. if (t != NULL) oe = (pb_OneofEntry*)pb_gettable(&t->oneof_index, idx);
  985. return oe ? oe->name : NULL;
  986. }
  987. PB_API int pb_nexttype(const pb_State *S, const pb_Type **ptype) {
  988. const pb_TypeEntry *e = NULL;
  989. if (S != NULL) {
  990. if (*ptype != NULL)
  991. e = (pb_TypeEntry*)pb_gettable(&S->types, (pb_Key)(*ptype)->name);
  992. while (pb_nextentry(&S->types, (const pb_Entry**)&e))
  993. if ((*ptype = e->value) != NULL && !(*ptype)->is_dead)
  994. return 1;
  995. }
  996. *ptype = NULL;
  997. return 0;
  998. }
  999. PB_API int pb_nextfield(const pb_Type *t, const pb_Field **pfield) {
  1000. const pb_FieldEntry *e = NULL;
  1001. if (t != NULL) {
  1002. if (*pfield != NULL)
  1003. e = (pb_FieldEntry*)pb_gettable(&t->field_tags, (*pfield)->number);
  1004. while (pb_nextentry(&t->field_tags, (const pb_Entry**)&e))
  1005. if ((*pfield = e->value) != NULL)
  1006. return 1;
  1007. }
  1008. *pfield = NULL;
  1009. return 0;
  1010. }
  1011. /* new type/field */
  1012. static const char *pbT_basename(const char *tname) {
  1013. const char *end = tname + strlen(tname);
  1014. while (tname < end && *--end != '.')
  1015. ;
  1016. return *end != '.' ? end : end + 1;
  1017. }
  1018. static void pbT_inittype(pb_Type *t) {
  1019. memset(t, 0, sizeof(pb_Type));
  1020. pb_inittable(&t->field_names, sizeof(pb_FieldEntry));
  1021. pb_inittable(&t->field_tags, sizeof(pb_FieldEntry));
  1022. pb_inittable(&t->oneof_index, sizeof(pb_OneofEntry));
  1023. }
  1024. static void pbT_freefield(pb_State *S, pb_Field *f) {
  1025. pb_delname(S, f->default_value);
  1026. pb_delname(S, f->name);
  1027. pb_poolfree(&S->fieldpool, f);
  1028. }
  1029. PB_API pb_Type *pb_newtype(pb_State *S, pb_Name *tname) {
  1030. pb_TypeEntry *te;
  1031. pb_Type *t;
  1032. if (tname == NULL) return NULL;
  1033. te = (pb_TypeEntry*)pb_settable(&S->types, (pb_Key)tname);
  1034. if (te == NULL) return NULL;
  1035. if ((t = te->value) != NULL) return t->is_dead = 0, t;
  1036. if (!(t = (pb_Type*)pb_poolalloc(&S->typepool))) return NULL;
  1037. pbT_inittype(t);
  1038. t->name = tname;
  1039. t->basename = pbT_basename((const char*)tname);
  1040. return te->value = t;
  1041. }
  1042. PB_API void pb_delsort(pb_Type *t) {
  1043. if (t->field_sort) {
  1044. os_free(t->field_sort);
  1045. t->field_sort = NULL;
  1046. }
  1047. }
  1048. PB_API void pb_deltype(pb_State *S, pb_Type *t) {
  1049. pb_FieldEntry *nf = NULL;
  1050. pb_OneofEntry *ne = NULL;
  1051. if (S == NULL || t == NULL) return;
  1052. while (pb_nextentry(&t->field_names, (const pb_Entry**)&nf)) {
  1053. if (nf->value != NULL) {
  1054. pb_FieldEntry *of = (pb_FieldEntry*)pb_gettable(
  1055. &t->field_tags, nf->value->number);
  1056. if (of && of->value == nf->value)
  1057. of->entry.key = 0, of->value = NULL;
  1058. pbT_freefield(S, nf->value);
  1059. }
  1060. }
  1061. while (pb_nextentry(&t->field_tags, (const pb_Entry**)&nf))
  1062. if (nf->value != NULL) pbT_freefield(S, nf->value);
  1063. while (pb_nextentry(&t->oneof_index, (const pb_Entry**)&ne))
  1064. pb_delname(S, ne->name);
  1065. pb_freetable(&t->field_tags);
  1066. pb_freetable(&t->field_names);
  1067. pb_freetable(&t->oneof_index);
  1068. t->oneof_field = 0, t->field_count = 0;
  1069. t->is_dead = 1;
  1070. pb_delsort(t);
  1071. /*pb_delname(S, t->name); */
  1072. /*pb_poolfree(&S->typepool, t); */
  1073. }
  1074. PB_API pb_Field *pb_newfield(pb_State *S, pb_Type *t, pb_Name *fname, int32_t number) {
  1075. pb_FieldEntry *nf, *tf;
  1076. pb_Field *f;
  1077. if (fname == NULL) return NULL;
  1078. nf = (pb_FieldEntry*)pb_settable(&t->field_names, (pb_Key)fname);
  1079. tf = (pb_FieldEntry*)pb_settable(&t->field_tags, number);
  1080. if (nf == NULL || tf == NULL) return NULL;
  1081. if ((f = nf->value) != NULL && tf->value == f) {
  1082. pb_delname(S, f->default_value);
  1083. f->default_value = NULL;
  1084. return f;
  1085. }
  1086. if (!(f = (pb_Field*)pb_poolalloc(&S->fieldpool))) return NULL;
  1087. memset(f, 0, sizeof(pb_Field));
  1088. f->name = fname;
  1089. f->type = t;
  1090. f->number = number;
  1091. if (nf->value && pb_field(t, nf->value->number) != nf->value)
  1092. pbT_freefield(S, nf->value), --t->field_count;
  1093. if (tf->value && pb_fname(t, tf->value->name) != tf->value)
  1094. pbT_freefield(S, tf->value), --t->field_count;
  1095. ++t->field_count;
  1096. pb_delsort(t);
  1097. return nf->value = tf->value = f;
  1098. }
  1099. PB_API void pb_delfield(pb_State *S, pb_Type *t, pb_Field *f) {
  1100. pb_FieldEntry *nf, *tf;
  1101. int count = 0;
  1102. if (S == NULL || t == NULL || f == NULL) return;
  1103. nf = (pb_FieldEntry*)pb_gettable(&t->field_names, (pb_Key)f->name);
  1104. tf = (pb_FieldEntry*)pb_gettable(&t->field_tags, (pb_Key)f->number);
  1105. if (nf && nf->value == f) nf->entry.key = 0, nf->value = NULL, ++count;
  1106. if (tf && tf->value == f) tf->entry.key = 0, tf->value = NULL, ++count;
  1107. if (count) pbT_freefield(S, f), --t->field_count;
  1108. pb_delsort(t);
  1109. }
  1110. /* .pb proto loader */
  1111. typedef struct pb_Loader pb_Loader;
  1112. typedef struct pbL_FieldInfo pbL_FieldInfo;
  1113. typedef struct pbL_EnumValueInfo pbL_EnumValueInfo;
  1114. typedef struct pbL_EnumInfo pbL_EnumInfo;
  1115. typedef struct pbL_TypeInfo pbL_TypeInfo;
  1116. typedef struct pbL_FileInfo pbL_FileInfo;
  1117. #define pbC(e) do { int r = (e); if (r != PB_OK) return r; } while (0)
  1118. #define pbCM(e) do { if ((e) == NULL) return PB_ENOMEM; } while (0)
  1119. #define pbCE(e) do { if ((e) == NULL) return PB_ERROR; } while (0)
  1120. typedef struct pb_ArrayHeader {
  1121. unsigned count;
  1122. unsigned capacity;
  1123. } pb_ArrayHeader;
  1124. #define pbL_rawh(A) ((pb_ArrayHeader*)(A) - 1)
  1125. #define pbL_delete(A) ((A) ? (void)os_free(pbL_rawh(A)) : (void)0)
  1126. #define pbL_count(A) ((A) ? pbL_rawh(A)->count : 0)
  1127. #define pbL_add(A) (pbL_grow((void**)&(A),sizeof(*(A)))==PB_OK ?\
  1128. &(A)[pbL_rawh(A)->count++] : NULL)
  1129. struct pb_Loader {
  1130. pb_Slice s;
  1131. pb_Buffer b;
  1132. int is_proto3;
  1133. };
  1134. /* parsers */
  1135. struct pbL_EnumValueInfo {
  1136. pb_Slice name;
  1137. int32_t number;
  1138. };
  1139. struct pbL_EnumInfo {
  1140. pb_Slice name;
  1141. pbL_EnumValueInfo *value;
  1142. };
  1143. struct pbL_FieldInfo {
  1144. pb_Slice name;
  1145. pb_Slice type_name;
  1146. pb_Slice extendee;
  1147. pb_Slice default_value;
  1148. int32_t number;
  1149. int32_t label;
  1150. int32_t type;
  1151. int32_t oneof_index;
  1152. int32_t packed;
  1153. };
  1154. struct pbL_TypeInfo {
  1155. pb_Slice name;
  1156. int32_t is_map;
  1157. pbL_FieldInfo *field;
  1158. pbL_FieldInfo *extension;
  1159. pbL_EnumInfo *enum_type;
  1160. pbL_TypeInfo *nested_type;
  1161. pb_Slice *oneof_decl;
  1162. };
  1163. struct pbL_FileInfo {
  1164. pb_Slice package;
  1165. pb_Slice syntax;
  1166. pbL_EnumInfo *enum_type;
  1167. pbL_TypeInfo *message_type;
  1168. pbL_FieldInfo *extension;
  1169. };
  1170. static int pbL_readbytes(pb_Loader *L, pb_Slice *pv)
  1171. { return pb_readbytes(&L->s, pv) == 0 ? PB_ERROR : PB_OK; }
  1172. static int pbL_beginmsg(pb_Loader *L, pb_Slice *pv)
  1173. { pb_Slice v; pbC(pbL_readbytes(L, &v)); *pv = L->s, L->s = v; return PB_OK; }
  1174. static void pbL_endmsg(pb_Loader *L, pb_Slice *pv)
  1175. { L->s = *pv; }
  1176. static int pbL_grow(void **pp, size_t objs) {
  1177. pb_ArrayHeader *nh, *h = *pp ? pbL_rawh(*pp) : NULL;
  1178. if (h == NULL || h->capacity <= h->count) {
  1179. size_t used = (h ? h->count : 0);
  1180. size_t size = used + 4, nsize = size + (size >> 1);
  1181. nh = nsize < size ? NULL :
  1182. (pb_ArrayHeader*)realloc(h, sizeof(pb_ArrayHeader)+nsize*objs);
  1183. if (nh == NULL) return PB_ENOMEM;
  1184. nh->count = (unsigned)used;
  1185. nh->capacity = (unsigned)nsize;
  1186. *pp = nh + 1;
  1187. memset((char*)*pp + used*objs, 0, (nsize - used)*objs);
  1188. }
  1189. return PB_OK;
  1190. }
  1191. static int pbL_readint32(pb_Loader *L, int32_t *pv) {
  1192. uint32_t v;
  1193. if (pb_readvarint32(&L->s, &v) == 0) return PB_ERROR;
  1194. *pv = (int32_t)v;
  1195. return PB_OK;
  1196. }
  1197. static int pbL_FieldOptions(pb_Loader *L, pbL_FieldInfo *info) {
  1198. pb_Slice s;
  1199. uint32_t tag;
  1200. pbC(pbL_beginmsg(L, &s));
  1201. while (pb_readvarint32(&L->s, &tag)) {
  1202. switch (tag) {
  1203. case pb_pair(2, PB_TVARINT): /* bool packed */
  1204. pbC(pbL_readint32(L, &info->packed)); break;
  1205. default: if (pb_skipvalue(&L->s, tag) == 0) return PB_ERROR;
  1206. }
  1207. }
  1208. pbL_endmsg(L, &s);
  1209. return PB_OK;
  1210. }
  1211. static int pbL_FieldDescriptorProto(pb_Loader *L, pbL_FieldInfo *info) {
  1212. pb_Slice s;
  1213. uint32_t tag;
  1214. pbCM(info); pbC(pbL_beginmsg(L, &s));
  1215. info->packed = -1;
  1216. while (pb_readvarint32(&L->s, &tag)) {
  1217. switch (tag) {
  1218. case pb_pair(1, PB_TBYTES): /* string name */
  1219. pbC(pbL_readbytes(L, &info->name)); break;
  1220. case pb_pair(3, PB_TVARINT): /* int32 number */
  1221. pbC(pbL_readint32(L, &info->number)); break;
  1222. case pb_pair(4, PB_TVARINT): /* Label label */
  1223. pbC(pbL_readint32(L, &info->label)); break;
  1224. case pb_pair(5, PB_TVARINT): /* Type type */
  1225. pbC(pbL_readint32(L, &info->type)); break;
  1226. case pb_pair(6, PB_TBYTES): /* string type_name */
  1227. pbC(pbL_readbytes(L, &info->type_name)); break;
  1228. case pb_pair(2, PB_TBYTES): /* string extendee */
  1229. pbC(pbL_readbytes(L, &info->extendee)); break;
  1230. case pb_pair(7, PB_TBYTES): /* string default_value */
  1231. pbC(pbL_readbytes(L, &info->default_value)); break;
  1232. case pb_pair(8, PB_TBYTES): /* FieldOptions options */
  1233. pbC(pbL_FieldOptions(L, info)); break;
  1234. case pb_pair(9, PB_TVARINT): /* int32 oneof_index */
  1235. pbC(pbL_readint32(L, &info->oneof_index));
  1236. ++info->oneof_index; break;
  1237. default: if (pb_skipvalue(&L->s, tag) == 0) return PB_ERROR;
  1238. }
  1239. }
  1240. pbL_endmsg(L, &s);
  1241. return PB_OK;
  1242. }
  1243. static int pbL_EnumValueDescriptorProto(pb_Loader *L, pbL_EnumValueInfo *info) {
  1244. pb_Slice s;
  1245. uint32_t tag;
  1246. pbCM(info); pbC(pbL_beginmsg(L, &s));
  1247. while (pb_readvarint32(&L->s, &tag)) {
  1248. switch (tag) {
  1249. case pb_pair(1, PB_TBYTES): /* string name */
  1250. pbC(pbL_readbytes(L, &info->name)); break;
  1251. case pb_pair(2, PB_TVARINT): /* int32 number */
  1252. pbC(pbL_readint32(L, &info->number)); break;
  1253. default: if (pb_skipvalue(&L->s, tag) == 0) return PB_ERROR;
  1254. }
  1255. }
  1256. pbL_endmsg(L, &s);
  1257. return PB_OK;
  1258. }
  1259. static int pbL_EnumDescriptorProto(pb_Loader *L, pbL_EnumInfo *info) {
  1260. pb_Slice s;
  1261. uint32_t tag;
  1262. pbCM(info); pbC(pbL_beginmsg(L, &s));
  1263. while (pb_readvarint32(&L->s, &tag)) {
  1264. switch (tag) {
  1265. case pb_pair(1, PB_TBYTES): /* string name */
  1266. pbC(pbL_readbytes(L, &info->name)); break;
  1267. case pb_pair(2, PB_TBYTES): /* EnumValueDescriptorProto value */
  1268. pbC(pbL_EnumValueDescriptorProto(L, pbL_add(info->value))); break;
  1269. default: if (pb_skipvalue(&L->s, tag) == 0) return PB_ERROR;
  1270. }
  1271. }
  1272. pbL_endmsg(L, &s);
  1273. return PB_OK;
  1274. }
  1275. static int pbL_MessageOptions(pb_Loader *L, pbL_TypeInfo *info) {
  1276. pb_Slice s;
  1277. uint32_t tag;
  1278. pbCM(info); pbC(pbL_beginmsg(L, &s));
  1279. while (pb_readvarint32(&L->s, &tag)) {
  1280. switch (tag) {
  1281. case pb_pair(7, PB_TVARINT): /* bool map_entry */
  1282. pbC(pbL_readint32(L, &info->is_map)); break;
  1283. default: if (pb_skipvalue(&L->s, tag) == 0) return PB_ERROR;
  1284. }
  1285. }
  1286. pbL_endmsg(L, &s);
  1287. return PB_OK;
  1288. }
  1289. static int pbL_OneofDescriptorProto(pb_Loader *L, pbL_TypeInfo *info) {
  1290. pb_Slice s;
  1291. uint32_t tag;
  1292. pbCM(info); pbC(pbL_beginmsg(L, &s));
  1293. while (pb_readvarint32(&L->s, &tag)) {
  1294. switch (tag) {
  1295. case pb_pair(1, PB_TBYTES): /* string name */
  1296. pbC(pbL_readbytes(L, pbL_add(info->oneof_decl))); break;
  1297. default: if (pb_skipvalue(&L->s, tag) == 0) return PB_ERROR;
  1298. }
  1299. }
  1300. pbL_endmsg(L, &s);
  1301. return PB_OK;
  1302. }
  1303. static int pbL_DescriptorProto(pb_Loader *L, pbL_TypeInfo *info) {
  1304. pb_Slice s;
  1305. uint32_t tag;
  1306. pbCM(info); pbC(pbL_beginmsg(L, &s));
  1307. while (pb_readvarint32(&L->s, &tag)) {
  1308. switch (tag) {
  1309. case pb_pair(1, PB_TBYTES): /* string name */
  1310. pbC(pbL_readbytes(L, &info->name)); break;
  1311. case pb_pair(2, PB_TBYTES): /* FieldDescriptorProto field */
  1312. pbC(pbL_FieldDescriptorProto(L, pbL_add(info->field))); break;
  1313. case pb_pair(6, PB_TBYTES): /* FieldDescriptorProto extension */
  1314. pbC(pbL_FieldDescriptorProto(L, pbL_add(info->extension))); break;
  1315. case pb_pair(3, PB_TBYTES): /* DescriptorProto nested_type */
  1316. pbC(pbL_DescriptorProto(L, pbL_add(info->nested_type))); break;
  1317. case pb_pair(4, PB_TBYTES): /* EnumDescriptorProto enum_type */
  1318. pbC(pbL_EnumDescriptorProto(L, pbL_add(info->enum_type))); break;
  1319. case pb_pair(8, PB_TBYTES): /* OneofDescriptorProto oneof_decl */
  1320. pbC(pbL_OneofDescriptorProto(L, info)); break;
  1321. case pb_pair(7, PB_TBYTES): /* MessageOptions options */
  1322. pbC(pbL_MessageOptions(L, info)); break;
  1323. default: if (pb_skipvalue(&L->s, tag) == 0) return PB_ERROR;
  1324. }
  1325. }
  1326. pbL_endmsg(L, &s);
  1327. return PB_OK;
  1328. }
  1329. static int pbL_FileDescriptorProto(pb_Loader *L, pbL_FileInfo *info) {
  1330. pb_Slice s;
  1331. uint32_t tag;
  1332. pbCM(info); pbC(pbL_beginmsg(L, &s));
  1333. while (pb_readvarint32(&L->s, &tag)) {
  1334. switch (tag) {
  1335. case pb_pair(2, PB_TBYTES): /* string package */
  1336. pbC(pbL_readbytes(L, &info->package)); break;
  1337. case pb_pair(4, PB_TBYTES): /* DescriptorProto message_type */
  1338. pbC(pbL_DescriptorProto(L, pbL_add(info->message_type))); break;
  1339. case pb_pair(5, PB_TBYTES): /* EnumDescriptorProto enum_type */
  1340. pbC(pbL_EnumDescriptorProto(L, pbL_add(info->enum_type))); break;
  1341. case pb_pair(7, PB_TBYTES): /* FieldDescriptorProto extension */
  1342. pbC(pbL_FieldDescriptorProto(L, pbL_add(info->extension))); break;
  1343. case pb_pair(12, PB_TBYTES): /* string syntax */
  1344. pbC(pbL_readbytes(L, &info->syntax)); break;
  1345. default: if (pb_skipvalue(&L->s, tag) == 0) return PB_ERROR;
  1346. }
  1347. }
  1348. pbL_endmsg(L, &s);
  1349. return PB_OK;
  1350. }
  1351. static int pbL_FileDescriptorSet(pb_Loader *L, pbL_FileInfo **pfiles) {
  1352. uint32_t tag;
  1353. while (pb_readvarint32(&L->s, &tag)) {
  1354. switch (tag) {
  1355. case pb_pair(1, PB_TBYTES): /* FileDescriptorProto file */
  1356. pbC(pbL_FileDescriptorProto(L, pbL_add(*pfiles))); break;
  1357. default: if (pb_skipvalue(&L->s, tag) == 0) return PB_ERROR;
  1358. }
  1359. }
  1360. return PB_OK;
  1361. }
  1362. /* loader */
  1363. static void pbL_delTypeInfo(pbL_TypeInfo *info) {
  1364. size_t i, count;
  1365. for (i = 0, count = pbL_count(info->nested_type); i < count; ++i)
  1366. pbL_delTypeInfo(&info->nested_type[i]);
  1367. for (i = 0, count = pbL_count(info->enum_type); i < count; ++i)
  1368. pbL_delete(info->enum_type[i].value);
  1369. pbL_delete(info->nested_type);
  1370. pbL_delete(info->enum_type);
  1371. pbL_delete(info->field);
  1372. pbL_delete(info->extension);
  1373. pbL_delete(info->oneof_decl);
  1374. }
  1375. static void pbL_delFileInfo(pbL_FileInfo *files) {
  1376. size_t i, count, j, jcount;
  1377. for (i = 0, count = pbL_count(files); i < count; ++i) {
  1378. for (j = 0, jcount = pbL_count(files[i].message_type); j < jcount; ++j)
  1379. pbL_delTypeInfo(&files[i].message_type[j]);
  1380. for (j = 0, jcount = pbL_count(files[i].enum_type); j < jcount; ++j)
  1381. pbL_delete(files[i].enum_type[j].value);
  1382. pbL_delete(files[i].message_type);
  1383. pbL_delete(files[i].enum_type);
  1384. pbL_delete(files[i].extension);
  1385. }
  1386. pbL_delete(files);
  1387. }
  1388. static int pbL_prefixname(pb_State *S, pb_Slice s, size_t *ps, pb_Loader *L, pb_Name **out) {
  1389. char *buff;
  1390. *ps = pb_bufflen(&L->b);
  1391. pbCM(buff = pb_prepbuffsize(&L->b, pb_len(s) + 1));
  1392. *buff = '.'; pb_addsize(&L->b, 1);
  1393. if (pb_addslice(&L->b, s) == 0) return PB_ENOMEM;
  1394. if (out) *out = pb_newname(S, pb_result(&L->b), NULL);
  1395. return PB_OK;
  1396. }
  1397. static int pbL_loadEnum(pb_State *S, pbL_EnumInfo *info, pb_Loader *L) {
  1398. size_t i, count, curr;
  1399. pb_Name *name;
  1400. pb_Type *t;
  1401. pbC(pbL_prefixname(S, info->name, &curr, L, &name));
  1402. pbCM(t = pb_newtype(S, name));
  1403. t->is_enum = 1;
  1404. for (i = 0, count = pbL_count(info->value); i < count; ++i) {
  1405. pbL_EnumValueInfo *ev = &info->value[i];
  1406. pbCE(pb_newfield(S, t, pb_newname(S, ev->name, NULL), ev->number));
  1407. }
  1408. L->b.size = (unsigned)curr;
  1409. return PB_OK;
  1410. }
  1411. static int pbL_loadField(pb_State *S, pbL_FieldInfo *info, pb_Loader *L, pb_Type *t) {
  1412. pb_Type *ft = NULL;
  1413. pb_Field *f;
  1414. if (info->type == PB_Tmessage || info->type == PB_Tenum)
  1415. pbCE(ft = pb_newtype(S, pb_newname(S, info->type_name, NULL)));
  1416. if (t == NULL)
  1417. pbCE(t = pb_newtype(S, pb_newname(S, info->extendee, NULL)));
  1418. pbCE(f = pb_newfield(S, t, pb_newname(S, info->name, NULL), info->number));
  1419. f->default_value = pb_newname(S, info->default_value, NULL);
  1420. f->type = ft;
  1421. if ((f->oneof_idx = info->oneof_index)) ++t->oneof_field;
  1422. f->type_id = info->type;
  1423. f->repeated = info->label == 3; /* repeated */
  1424. f->packed = info->packed >= 0 ? info->packed : L->is_proto3 && f->repeated;
  1425. if (f->type_id >= 9 && f->type_id <= 12) f->packed = 0;
  1426. f->scalar = (f->type == NULL);
  1427. return PB_OK;
  1428. }
  1429. static int pbL_loadType(pb_State *S, pbL_TypeInfo *info, pb_Loader *L) {
  1430. size_t i, count, curr;
  1431. pb_Name *name;
  1432. pb_Type *t;
  1433. pbC(pbL_prefixname(S, info->name, &curr, L, &name));
  1434. pbCM(t = pb_newtype(S, name));
  1435. t->is_map = info->is_map, t->is_proto3 = L->is_proto3;
  1436. for (i = 0, count = pbL_count(info->oneof_decl); i < count; ++i) {
  1437. pb_OneofEntry *e = (pb_OneofEntry*)pb_settable(&t->oneof_index, i+1);
  1438. pbCM(e); pbCE(e->name = pb_newname(S, info->oneof_decl[i], NULL));
  1439. e->index = (int)i+1;
  1440. }
  1441. for (i = 0, count = pbL_count(info->field); i < count; ++i)
  1442. pbC(pbL_loadField(S, &info->field[i], L, t));
  1443. for (i = 0, count = pbL_count(info->extension); i < count; ++i)
  1444. pbC(pbL_loadField(S, &info->extension[i], L, NULL));
  1445. for (i = 0, count = pbL_count(info->enum_type); i < count; ++i)
  1446. pbC(pbL_loadEnum(S, &info->enum_type[i], L));
  1447. for (i = 0, count = pbL_count(info->nested_type); i < count; ++i)
  1448. pbC(pbL_loadType(S, &info->nested_type[i], L));
  1449. t->oneof_count = pbL_count(info->oneof_decl);
  1450. L->b.size = (unsigned)curr;
  1451. return PB_OK;
  1452. }
  1453. static int pbL_loadFile(pb_State *S, pbL_FileInfo *info, pb_Loader *L) {
  1454. size_t i, count, j, jcount, curr = 0;
  1455. pb_Name *syntax;
  1456. pbCM(syntax = pb_newname(S, pb_slice("proto3"), NULL));
  1457. for (i = 0, count = pbL_count(info); i < count; ++i) {
  1458. if (info[i].package.p)
  1459. pbC(pbL_prefixname(S, info[i].package, &curr, L, NULL));
  1460. L->is_proto3 = (pb_name(S, info[i].syntax, NULL) == syntax);
  1461. for (j = 0, jcount = pbL_count(info[i].enum_type); j < jcount; ++j)
  1462. pbC(pbL_loadEnum(S, &info[i].enum_type[j], L));
  1463. for (j = 0, jcount = pbL_count(info[i].message_type); j < jcount; ++j)
  1464. pbC(pbL_loadType(S, &info[i].message_type[j], L));
  1465. for (j = 0, jcount = pbL_count(info[i].extension); j < jcount; ++j)
  1466. pbC(pbL_loadField(S, &info[i].extension[j], L, NULL));
  1467. L->b.size = (unsigned)curr;
  1468. }
  1469. return PB_OK;
  1470. }
  1471. PB_API int pb_load(pb_State *S, pb_Slice *s) {
  1472. pbL_FileInfo *files = NULL;
  1473. pb_Loader L;
  1474. int r;
  1475. pb_initbuffer(&L.b);
  1476. L.s = *s;
  1477. L.is_proto3 = 0;
  1478. if ((r = pbL_FileDescriptorSet(&L, &files)) == PB_OK)
  1479. r = pbL_loadFile(S, files, &L);
  1480. pbL_delFileInfo(files);
  1481. pb_resetbuffer(&L.b);
  1482. s->p = L.s.p;
  1483. return r;
  1484. }
  1485. PB_NS_END
  1486. #endif /* PB_IMPLEMENTATION */
  1487. /* cc: flags+='-shared -DPB_IMPLEMENTATION -xc' output='pb.so' */