1 /*
2 ** TODO(haberman): it's unclear whether a lot of the consistency checks should
3 ** UPB_ASSERT() or return false.
4 */
5 
6 #include "upb/handlers.h"
7 
8 #include <string.h>
9 
10 #include "upb/sink.h"
11 
12 #include "upb/port_def.inc"
13 
14 struct upb_handlers {
15   upb_handlercache *cache;
16   const upb_msgdef *msg;
17   const upb_handlers **sub;
18   const void *top_closure_type;
19   upb_handlers_tabent table[1];  /* Dynamically-sized field handler array. */
20 };
21 
upb_calloc(upb_arena * arena,size_t size)22 static void *upb_calloc(upb_arena *arena, size_t size) {
23   void *mem = upb_malloc(upb_arena_alloc(arena), size);
24   if (mem) {
25     memset(mem, 0, size);
26   }
27   return mem;
28 }
29 
30 /* Defined for the sole purpose of having a unique pointer value for
31  * UPB_NO_CLOSURE. */
32 char _upb_noclosure;
33 
34 /* Given a selector for a STARTSUBMSG handler, resolves to a pointer to the
35  * subhandlers for this submessage field. */
36 #define SUBH(h, selector) (h->sub[selector])
37 
38 /* The selector for a submessage field is the field index. */
39 #define SUBH_F(h, f) SUBH(h, upb_fielddef_index(f))
40 
trygetsel(upb_handlers * h,const upb_fielddef * f,upb_handlertype_t type)41 static int32_t trygetsel(upb_handlers *h, const upb_fielddef *f,
42                          upb_handlertype_t type) {
43   upb_selector_t sel;
44   bool ok;
45 
46   ok = upb_handlers_getselector(f, type, &sel);
47 
48   UPB_ASSERT(upb_handlers_msgdef(h) == upb_fielddef_containingtype(f));
49   UPB_ASSERT(ok);
50 
51   return sel;
52 }
53 
handlers_getsel(upb_handlers * h,const upb_fielddef * f,upb_handlertype_t type)54 static upb_selector_t handlers_getsel(upb_handlers *h, const upb_fielddef *f,
55                              upb_handlertype_t type) {
56   int32_t sel = trygetsel(h, f, type);
57   UPB_ASSERT(sel >= 0);
58   return sel;
59 }
60 
returntype(upb_handlers * h,const upb_fielddef * f,upb_handlertype_t type)61 static const void **returntype(upb_handlers *h, const upb_fielddef *f,
62                                upb_handlertype_t type) {
63   return &h->table[handlers_getsel(h, f, type)].attr.return_closure_type;
64 }
65 
doset(upb_handlers * h,int32_t sel,const upb_fielddef * f,upb_handlertype_t type,upb_func * func,const upb_handlerattr * attr)66 static bool doset(upb_handlers *h, int32_t sel, const upb_fielddef *f,
67                   upb_handlertype_t type, upb_func *func,
68                   const upb_handlerattr *attr) {
69   upb_handlerattr set_attr = UPB_HANDLERATTR_INIT;
70   const void *closure_type;
71   const void **context_closure_type;
72 
73   UPB_ASSERT(!h->table[sel].func);
74 
75   if (attr) {
76     set_attr = *attr;
77   }
78 
79   /* Check that the given closure type matches the closure type that has been
80    * established for this context (if any). */
81   closure_type = set_attr.closure_type;
82 
83   if (type == UPB_HANDLER_STRING) {
84     context_closure_type = returntype(h, f, UPB_HANDLER_STARTSTR);
85   } else if (f && upb_fielddef_isseq(f) &&
86              type != UPB_HANDLER_STARTSEQ &&
87              type != UPB_HANDLER_ENDSEQ) {
88     context_closure_type = returntype(h, f, UPB_HANDLER_STARTSEQ);
89   } else {
90     context_closure_type = &h->top_closure_type;
91   }
92 
93   if (closure_type && *context_closure_type &&
94       closure_type != *context_closure_type) {
95     return false;
96   }
97 
98   if (closure_type)
99     *context_closure_type = closure_type;
100 
101   /* If this is a STARTSEQ or STARTSTR handler, check that the returned pointer
102    * matches any pre-existing expectations about what type is expected. */
103   if (type == UPB_HANDLER_STARTSEQ || type == UPB_HANDLER_STARTSTR) {
104     const void *return_type = set_attr.return_closure_type;
105     const void *table_return_type = h->table[sel].attr.return_closure_type;
106     if (return_type && table_return_type && return_type != table_return_type) {
107       return false;
108     }
109 
110     if (table_return_type && !return_type) {
111       set_attr.return_closure_type = table_return_type;
112     }
113   }
114 
115   h->table[sel].func = (upb_func*)func;
116   h->table[sel].attr = set_attr;
117   return true;
118 }
119 
120 /* Returns the effective closure type for this handler (which will propagate
121  * from outer frames if this frame has no START* handler).  Not implemented for
122  * UPB_HANDLER_STRING at the moment since this is not needed.  Returns NULL is
123  * the effective closure type is unspecified (either no handler was registered
124  * to specify it or the handler that was registered did not specify the closure
125  * type). */
effective_closure_type(upb_handlers * h,const upb_fielddef * f,upb_handlertype_t type)126 const void *effective_closure_type(upb_handlers *h, const upb_fielddef *f,
127                                    upb_handlertype_t type) {
128   const void *ret;
129   upb_selector_t sel;
130 
131   UPB_ASSERT(type != UPB_HANDLER_STRING);
132   ret = h->top_closure_type;
133 
134   if (upb_fielddef_isseq(f) &&
135       type != UPB_HANDLER_STARTSEQ &&
136       type != UPB_HANDLER_ENDSEQ &&
137       h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSEQ)].func) {
138     ret = h->table[sel].attr.return_closure_type;
139   }
140 
141   if (type == UPB_HANDLER_STRING &&
142       h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSTR)].func) {
143     ret = h->table[sel].attr.return_closure_type;
144   }
145 
146   /* The effective type of the submessage; not used yet.
147    * if (type == SUBMESSAGE &&
148    *     h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSUBMSG)].func) {
149    *   ret = h->table[sel].attr.return_closure_type;
150    * } */
151 
152   return ret;
153 }
154 
upb_handlers_new(const upb_msgdef * md,upb_handlercache * cache,upb_arena * arena)155 static upb_handlers *upb_handlers_new(const upb_msgdef *md,
156                                       upb_handlercache *cache,
157                                       upb_arena *arena) {
158   int extra;
159   upb_handlers *h;
160 
161   extra =
162       (int)(sizeof(upb_handlers_tabent) * (upb_msgdef_selectorcount(md) - 1));
163   h = upb_calloc(arena, sizeof(*h) + extra);
164   if (!h) return NULL;
165 
166   h->cache = cache;
167   h->msg = md;
168 
169   if (upb_msgdef_submsgfieldcount(md) > 0) {
170     size_t bytes = upb_msgdef_submsgfieldcount(md) * sizeof(*h->sub);
171     h->sub = upb_calloc(arena, bytes);
172     if (!h->sub) return NULL;
173   } else {
174     h->sub = 0;
175   }
176 
177   /* calloc() above initialized all handlers to NULL. */
178   return h;
179 }
180 
181 /* Public interface ***********************************************************/
182 
183 #define SETTER(name, handlerctype, handlertype)                       \
184   bool upb_handlers_set##name(upb_handlers *h, const upb_fielddef *f, \
185                               handlerctype func,                      \
186                               const upb_handlerattr *attr) {          \
187     int32_t sel = trygetsel(h, f, handlertype);                       \
188     return doset(h, sel, f, handlertype, (upb_func *)func, attr);     \
189   }
190 
SETTER(int32,upb_int32_handlerfunc *,UPB_HANDLER_INT32)191 SETTER(int32,       upb_int32_handlerfunc*,       UPB_HANDLER_INT32)
192 SETTER(int64,       upb_int64_handlerfunc*,       UPB_HANDLER_INT64)
193 SETTER(uint32,      upb_uint32_handlerfunc*,      UPB_HANDLER_UINT32)
194 SETTER(uint64,      upb_uint64_handlerfunc*,      UPB_HANDLER_UINT64)
195 SETTER(float,       upb_float_handlerfunc*,       UPB_HANDLER_FLOAT)
196 SETTER(double,      upb_double_handlerfunc*,      UPB_HANDLER_DOUBLE)
197 SETTER(bool,        upb_bool_handlerfunc*,        UPB_HANDLER_BOOL)
198 SETTER(startstr,    upb_startstr_handlerfunc*,    UPB_HANDLER_STARTSTR)
199 SETTER(string,      upb_string_handlerfunc*,      UPB_HANDLER_STRING)
200 SETTER(endstr,      upb_endfield_handlerfunc*,    UPB_HANDLER_ENDSTR)
201 SETTER(startseq,    upb_startfield_handlerfunc*,  UPB_HANDLER_STARTSEQ)
202 SETTER(startsubmsg, upb_startfield_handlerfunc*,  UPB_HANDLER_STARTSUBMSG)
203 SETTER(endsubmsg,   upb_endfield_handlerfunc*,    UPB_HANDLER_ENDSUBMSG)
204 SETTER(endseq,      upb_endfield_handlerfunc*,    UPB_HANDLER_ENDSEQ)
205 
206 #undef SETTER
207 
208 bool upb_handlers_setunknown(upb_handlers *h, upb_unknown_handlerfunc *func,
209                              const upb_handlerattr *attr) {
210   return doset(h, UPB_UNKNOWN_SELECTOR, NULL, UPB_HANDLER_INT32,
211                (upb_func *)func, attr);
212 }
213 
upb_handlers_setstartmsg(upb_handlers * h,upb_startmsg_handlerfunc * func,const upb_handlerattr * attr)214 bool upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handlerfunc *func,
215                               const upb_handlerattr *attr) {
216   return doset(h, UPB_STARTMSG_SELECTOR, NULL, UPB_HANDLER_INT32,
217                (upb_func *)func, attr);
218 }
219 
upb_handlers_setendmsg(upb_handlers * h,upb_endmsg_handlerfunc * func,const upb_handlerattr * attr)220 bool upb_handlers_setendmsg(upb_handlers *h, upb_endmsg_handlerfunc *func,
221                             const upb_handlerattr *attr) {
222   return doset(h, UPB_ENDMSG_SELECTOR, NULL, UPB_HANDLER_INT32,
223                (upb_func *)func, attr);
224 }
225 
upb_handlers_setsubhandlers(upb_handlers * h,const upb_fielddef * f,const upb_handlers * sub)226 bool upb_handlers_setsubhandlers(upb_handlers *h, const upb_fielddef *f,
227                                  const upb_handlers *sub) {
228   UPB_ASSERT(sub);
229   UPB_ASSERT(upb_fielddef_issubmsg(f));
230   if (SUBH_F(h, f)) return false;  /* Can't reset. */
231   if (upb_handlers_msgdef(sub) != upb_fielddef_msgsubdef(f)) {
232     return false;
233   }
234   SUBH_F(h, f) = sub;
235   return true;
236 }
237 
upb_handlers_getsubhandlers(const upb_handlers * h,const upb_fielddef * f)238 const upb_handlers *upb_handlers_getsubhandlers(const upb_handlers *h,
239                                                 const upb_fielddef *f) {
240   UPB_ASSERT(upb_fielddef_issubmsg(f));
241   return SUBH_F(h, f);
242 }
243 
upb_handlers_gethandler(const upb_handlers * h,upb_selector_t s,const void ** handler_data)244 upb_func *upb_handlers_gethandler(const upb_handlers *h, upb_selector_t s,
245                                   const void **handler_data) {
246   upb_func *ret = (upb_func *)h->table[s].func;
247   if (ret && handler_data) {
248     *handler_data = h->table[s].attr.handler_data;
249   }
250   return ret;
251 }
252 
upb_handlers_getattr(const upb_handlers * h,upb_selector_t sel,upb_handlerattr * attr)253 bool upb_handlers_getattr(const upb_handlers *h, upb_selector_t sel,
254                           upb_handlerattr *attr) {
255   if (!upb_handlers_gethandler(h, sel, NULL))
256     return false;
257   *attr = h->table[sel].attr;
258   return true;
259 }
260 
upb_handlers_getsubhandlers_sel(const upb_handlers * h,upb_selector_t sel)261 const upb_handlers *upb_handlers_getsubhandlers_sel(const upb_handlers *h,
262                                                     upb_selector_t sel) {
263   /* STARTSUBMSG selector in sel is the field's selector base. */
264   return SUBH(h, sel - UPB_STATIC_SELECTOR_COUNT);
265 }
266 
upb_handlers_msgdef(const upb_handlers * h)267 const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h) { return h->msg; }
268 
upb_handlers_addcleanup(upb_handlers * h,void * p,upb_handlerfree * func)269 bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *func) {
270   return upb_handlercache_addcleanup(h->cache, p, func);
271 }
272 
upb_handlers_getprimitivehandlertype(const upb_fielddef * f)273 upb_handlertype_t upb_handlers_getprimitivehandlertype(const upb_fielddef *f) {
274   switch (upb_fielddef_type(f)) {
275     case UPB_TYPE_INT32:
276     case UPB_TYPE_ENUM: return UPB_HANDLER_INT32;
277     case UPB_TYPE_INT64: return UPB_HANDLER_INT64;
278     case UPB_TYPE_UINT32: return UPB_HANDLER_UINT32;
279     case UPB_TYPE_UINT64: return UPB_HANDLER_UINT64;
280     case UPB_TYPE_FLOAT: return UPB_HANDLER_FLOAT;
281     case UPB_TYPE_DOUBLE: return UPB_HANDLER_DOUBLE;
282     case UPB_TYPE_BOOL: return UPB_HANDLER_BOOL;
283     default: UPB_ASSERT(false); return -1;  /* Invalid input. */
284   }
285 }
286 
upb_handlers_getselector(const upb_fielddef * f,upb_handlertype_t type,upb_selector_t * s)287 bool upb_handlers_getselector(const upb_fielddef *f, upb_handlertype_t type,
288                               upb_selector_t *s) {
289   uint32_t selector_base = upb_fielddef_selectorbase(f);
290   switch (type) {
291     case UPB_HANDLER_INT32:
292     case UPB_HANDLER_INT64:
293     case UPB_HANDLER_UINT32:
294     case UPB_HANDLER_UINT64:
295     case UPB_HANDLER_FLOAT:
296     case UPB_HANDLER_DOUBLE:
297     case UPB_HANDLER_BOOL:
298       if (!upb_fielddef_isprimitive(f) ||
299           upb_handlers_getprimitivehandlertype(f) != type)
300         return false;
301       *s = selector_base;
302       break;
303     case UPB_HANDLER_STRING:
304       if (upb_fielddef_isstring(f)) {
305         *s = selector_base;
306       } else if (upb_fielddef_lazy(f)) {
307         *s = selector_base + 3;
308       } else {
309         return false;
310       }
311       break;
312     case UPB_HANDLER_STARTSTR:
313       if (upb_fielddef_isstring(f) || upb_fielddef_lazy(f)) {
314         *s = selector_base + 1;
315       } else {
316         return false;
317       }
318       break;
319     case UPB_HANDLER_ENDSTR:
320       if (upb_fielddef_isstring(f) || upb_fielddef_lazy(f)) {
321         *s = selector_base + 2;
322       } else {
323         return false;
324       }
325       break;
326     case UPB_HANDLER_STARTSEQ:
327       if (!upb_fielddef_isseq(f)) return false;
328       *s = selector_base - 2;
329       break;
330     case UPB_HANDLER_ENDSEQ:
331       if (!upb_fielddef_isseq(f)) return false;
332       *s = selector_base - 1;
333       break;
334     case UPB_HANDLER_STARTSUBMSG:
335       if (!upb_fielddef_issubmsg(f)) return false;
336       /* Selectors for STARTSUBMSG are at the beginning of the table so that the
337        * selector can also be used as an index into the "sub" array of
338        * subhandlers.  The indexes for the two into these two tables are the
339        * same, except that in the handler table the static selectors come first. */
340       *s = upb_fielddef_index(f) + UPB_STATIC_SELECTOR_COUNT;
341       break;
342     case UPB_HANDLER_ENDSUBMSG:
343       if (!upb_fielddef_issubmsg(f)) return false;
344       *s = selector_base;
345       break;
346   }
347   UPB_ASSERT((size_t)*s < upb_msgdef_selectorcount(upb_fielddef_containingtype(f)));
348   return true;
349 }
350 
351 /* upb_handlercache ***********************************************************/
352 
353 struct upb_handlercache {
354   upb_arena *arena;
355   upb_inttable tab;  /* maps upb_msgdef* -> upb_handlers*. */
356   upb_handlers_callback *callback;
357   const void *closure;
358 };
359 
upb_handlercache_get(upb_handlercache * c,const upb_msgdef * md)360 const upb_handlers *upb_handlercache_get(upb_handlercache *c,
361                                          const upb_msgdef *md) {
362   int i, n;
363   upb_value v;
364   upb_handlers *h;
365 
366   if (upb_inttable_lookupptr(&c->tab, md, &v)) {
367     return upb_value_getptr(v);
368   }
369 
370   h = upb_handlers_new(md, c, c->arena);
371   v = upb_value_ptr(h);
372 
373   if (!h) return NULL;
374   if (!upb_inttable_insertptr(&c->tab, md, v)) return NULL;
375 
376   c->callback(c->closure, h);
377 
378   /* For each submessage field, get or create a handlers object and set it as
379    * the subhandlers. */
380   n = upb_msgdef_fieldcount(md);
381   for (i = 0; i < n; i++) {
382     const upb_fielddef *f = upb_msgdef_field(md, i);
383 
384     if (upb_fielddef_issubmsg(f)) {
385       const upb_msgdef *subdef = upb_fielddef_msgsubdef(f);
386       const upb_handlers *sub_mh = upb_handlercache_get(c, subdef);
387 
388       if (!sub_mh) return NULL;
389 
390       upb_handlers_setsubhandlers(h, f, sub_mh);
391     }
392   }
393 
394   return h;
395 }
396 
397 
upb_handlercache_new(upb_handlers_callback * callback,const void * closure)398 upb_handlercache *upb_handlercache_new(upb_handlers_callback *callback,
399                                        const void *closure) {
400   upb_handlercache *cache = upb_gmalloc(sizeof(*cache));
401 
402   if (!cache) return NULL;
403 
404   cache->arena = upb_arena_new();
405 
406   cache->callback = callback;
407   cache->closure = closure;
408 
409   if (!upb_inttable_init(&cache->tab, UPB_CTYPE_PTR)) goto oom;
410 
411   return cache;
412 
413 oom:
414   upb_gfree(cache);
415   return NULL;
416 }
417 
upb_handlercache_free(upb_handlercache * cache)418 void upb_handlercache_free(upb_handlercache *cache) {
419   upb_inttable_uninit(&cache->tab);
420   upb_arena_free(cache->arena);
421   upb_gfree(cache);
422 }
423 
upb_handlercache_addcleanup(upb_handlercache * c,void * p,upb_handlerfree * func)424 bool upb_handlercache_addcleanup(upb_handlercache *c, void *p,
425                                  upb_handlerfree *func) {
426   return upb_arena_addcleanup(c->arena, p, func);
427 }
428 
429 /* upb_byteshandler ***********************************************************/
430 
upb_byteshandler_setstartstr(upb_byteshandler * h,upb_startstr_handlerfunc * func,void * d)431 bool upb_byteshandler_setstartstr(upb_byteshandler *h,
432                                   upb_startstr_handlerfunc *func, void *d) {
433   h->table[UPB_STARTSTR_SELECTOR].func = (upb_func*)func;
434   h->table[UPB_STARTSTR_SELECTOR].attr.handler_data = d;
435   return true;
436 }
437 
upb_byteshandler_setstring(upb_byteshandler * h,upb_string_handlerfunc * func,void * d)438 bool upb_byteshandler_setstring(upb_byteshandler *h,
439                                 upb_string_handlerfunc *func, void *d) {
440   h->table[UPB_STRING_SELECTOR].func = (upb_func*)func;
441   h->table[UPB_STRING_SELECTOR].attr.handler_data = d;
442   return true;
443 }
444 
upb_byteshandler_setendstr(upb_byteshandler * h,upb_endfield_handlerfunc * func,void * d)445 bool upb_byteshandler_setendstr(upb_byteshandler *h,
446                                 upb_endfield_handlerfunc *func, void *d) {
447   h->table[UPB_ENDSTR_SELECTOR].func = (upb_func*)func;
448   h->table[UPB_ENDSTR_SELECTOR].attr.handler_data = d;
449   return true;
450 }
451 
452 /** Handlers for upb_msg ******************************************************/
453 
454 typedef struct {
455   size_t offset;
456   int32_t hasbit;
457 } upb_msg_handlerdata;
458 
459 /* Fallback implementation if the handler is not specialized by the producer. */
460 #define MSG_WRITER(type, ctype)                                               \
461   bool upb_msg_set ## type (void *c, const void *hd, ctype val) {             \
462     uint8_t *m = c;                                                           \
463     const upb_msg_handlerdata *d = hd;                                        \
464     if (d->hasbit > 0)                                                        \
465       *(uint8_t*)&m[d->hasbit / 8] |= 1 << (d->hasbit % 8);                   \
466     *(ctype*)&m[d->offset] = val;                                             \
467     return true;                                                              \
468   }                                                                           \
469 
MSG_WRITER(double,double)470 MSG_WRITER(double, double)
471 MSG_WRITER(float,  float)
472 MSG_WRITER(int32,  int32_t)
473 MSG_WRITER(int64,  int64_t)
474 MSG_WRITER(uint32, uint32_t)
475 MSG_WRITER(uint64, uint64_t)
476 MSG_WRITER(bool,   bool)
477 
478 bool upb_msg_setscalarhandler(upb_handlers *h, const upb_fielddef *f,
479                               size_t offset, int32_t hasbit) {
480   upb_handlerattr attr = UPB_HANDLERATTR_INIT;
481   bool ok;
482 
483   upb_msg_handlerdata *d = upb_gmalloc(sizeof(*d));
484   if (!d) return false;
485   d->offset = offset;
486   d->hasbit = hasbit;
487 
488   attr.handler_data = d;
489   attr.alwaysok = true;
490   upb_handlers_addcleanup(h, d, upb_gfree);
491 
492 #define TYPE(u, l) \
493   case UPB_TYPE_##u: \
494     ok = upb_handlers_set##l(h, f, upb_msg_set##l, &attr); break;
495 
496   ok = false;
497 
498   switch (upb_fielddef_type(f)) {
499     TYPE(INT64,  int64);
500     TYPE(INT32,  int32);
501     TYPE(ENUM,   int32);
502     TYPE(UINT64, uint64);
503     TYPE(UINT32, uint32);
504     TYPE(DOUBLE, double);
505     TYPE(FLOAT,  float);
506     TYPE(BOOL,   bool);
507     default: UPB_ASSERT(false); break;
508   }
509 #undef TYPE
510 
511   return ok;
512 }
513 
upb_msg_getscalarhandlerdata(const upb_handlers * h,upb_selector_t s,upb_fieldtype_t * type,size_t * offset,int32_t * hasbit)514 bool upb_msg_getscalarhandlerdata(const upb_handlers *h,
515                                   upb_selector_t s,
516                                   upb_fieldtype_t *type,
517                                   size_t *offset,
518                                   int32_t *hasbit) {
519   const upb_msg_handlerdata *d;
520   const void *p;
521   upb_func *f = upb_handlers_gethandler(h, s, &p);
522 
523   if ((upb_int64_handlerfunc*)f == upb_msg_setint64) {
524     *type = UPB_TYPE_INT64;
525   } else if ((upb_int32_handlerfunc*)f == upb_msg_setint32) {
526     *type = UPB_TYPE_INT32;
527   } else if ((upb_uint64_handlerfunc*)f == upb_msg_setuint64) {
528     *type = UPB_TYPE_UINT64;
529   } else if ((upb_uint32_handlerfunc*)f == upb_msg_setuint32) {
530     *type = UPB_TYPE_UINT32;
531   } else if ((upb_double_handlerfunc*)f == upb_msg_setdouble) {
532     *type = UPB_TYPE_DOUBLE;
533   } else if ((upb_float_handlerfunc*)f == upb_msg_setfloat) {
534     *type = UPB_TYPE_FLOAT;
535   } else if ((upb_bool_handlerfunc*)f == upb_msg_setbool) {
536     *type = UPB_TYPE_BOOL;
537   } else {
538     return false;
539   }
540 
541   d = p;
542   *offset = d->offset;
543   *hasbit = d->hasbit;
544   return true;
545 }
546