Exemple #1
0
// TODO(haberman): discard upb_handlers* objects that do not actually have any
// handlers set and cannot reach any upb_handlers* object that does.  This is
// slightly tricky to do correctly.
static upb_handlers *newformsg(const upb_msgdef *m, const void *owner,
                               dfs_state *s) {
  upb_handlers *h = upb_handlers_new(m, owner);
  if (!h) return NULL;
  if (!upb_inttable_insertptr(&s->tab, m, upb_value_ptr(h))) goto oom;

  s->callback(s->closure, h);

  // For each submessage field, get or create a handlers object and set it as
  // the subhandlers.
  upb_msg_iter i;
  for(upb_msg_begin(&i, m); !upb_msg_done(&i); upb_msg_next(&i)) {
    upb_fielddef *f = upb_msg_iter_field(&i);
    if (!upb_fielddef_issubmsg(f)) continue;

    const upb_msgdef *subdef = upb_downcast_msgdef(upb_fielddef_subdef(f));
    upb_value subm_ent;
    if (upb_inttable_lookupptr(&s->tab, subdef, &subm_ent)) {
      upb_handlers_setsubhandlers(h, f, upb_value_getptr(subm_ent));
    } else {
      upb_handlers *sub_mh = newformsg(subdef, &sub_mh, s);
      if (!sub_mh) goto oom;
      upb_handlers_setsubhandlers(h, f, sub_mh);
      upb_handlers_unref(sub_mh, &sub_mh);
    }
  }
  return h;

oom:
  upb_handlers_unref(h, owner);
  return NULL;
}
Exemple #2
0
upb_sflow_t upb_stdmsg_startsubmsg_r(void *a, upb_value fval) {
  assert(a != NULL);
  const upb_fielddef *f = upb_value_getfielddef(fval);
  void **subm = upb_stdarray_append((upb_stdarray*)a, sizeof(void*));
  upb_stdmsg_recycle(subm, upb_downcast_msgdef(f->def));
  return UPB_CONTINUE_WITH(*subm);
}
Exemple #3
0
static void upb_def_free(upb_def *def) {
  switch (def->type) {
    case UPB_DEF_MSG: upb_msgdef_free(upb_downcast_msgdef(def)); break;
    case UPB_DEF_ENUM: upb_enumdef_free(upb_downcast_enumdef(def)); break;
    case UPB_DEF_UNRESOLVED:
        upb_unresolveddef_free(upb_downcast_unresolveddef(def)); break;
    default:
      assert(false);
  }
}
Exemple #4
0
upb_sflow_t upb_stdmsg_startsubmsg(void *_m, upb_value fval) {
  assert(_m != NULL);
  char *m = _m;
  const upb_fielddef *f = upb_value_getfielddef(fval);
  void **subm = (void*)&m[f->offset];
  if (!upb_stdmsg_has(m, fval)) {
    upb_stdmsg_recycle(subm, upb_downcast_msgdef(f->def));
    upb_stdmsg_sethas(m, fval);
  }
  return UPB_CONTINUE_WITH(*subm);
}
Exemple #5
0
upb_def *upb_def_dup(const upb_def *def, const void *o) {
  switch (def->type) {
    case UPB_DEF_MSG:
      return upb_upcast(upb_msgdef_dup(upb_downcast_msgdef(def), o));
    case UPB_DEF_FIELD:
      return upb_upcast(upb_fielddef_dup(upb_downcast_fielddef(def), o));
    case UPB_DEF_ENUM:
      return upb_upcast(upb_enumdef_dup(upb_downcast_enumdef(def), o));
    default: assert(false); return NULL;
  }
}
Exemple #6
0
const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
  upb_rwlock_rdlock(&s->lock);
  upb_symtab_ent *e = upb_strtable_lookup(&s->symtab, sym);
  upb_msgdef *ret = NULL;
  if(e && e->def->type == UPB_DEF_MSG) {
    ret = upb_downcast_msgdef(e->def);
    upb_def_ref(UPB_UPCAST(ret));
  }
  upb_rwlock_unlock(&s->lock);
  return ret;
}
Exemple #7
0
static upb_flow_t upb_msg_pushval(upb_value val, upb_fielddef *f,
                                  upb_dispatcher *d, upb_fhandlers *hf) {
  if (upb_issubmsg(f)) {
    upb_msg *msg = upb_value_getmsg(val);
    upb_dispatch_startsubmsg(d, hf);
    upb_msg_dispatch(msg, upb_downcast_msgdef(f->def), d);
    upb_dispatch_endsubmsg(d);
  } else {
    upb_dispatch_value(d, hf, val);
  }
  return UPB_CONTINUE;
}
Exemple #8
0
static void test_cycles() {
  bool ok;
  upb_symtab *s = load_test_proto(&s);
  const upb_msgdef *m;
  const upb_fielddef *f;
  const upb_def *def;
  const upb_def *def2;

  /* Test cycle detection by making a cyclic def's main refcount go to zero
   * and then be incremented to one again. */
  def = upb_symtab_lookup(s, "A");
  upb_def_ref(def, &def);
  ASSERT(def);
  ASSERT(upb_def_isfrozen(def));
  upb_symtab_unref(s, &s);

  /* Message A has only one subfield: "optional B b = 1". */
  m = upb_downcast_msgdef(def);
  f = upb_msgdef_itof(m, 1);
  ASSERT(f);
  ASSERT(upb_fielddef_hassubdef(f));
  ASSERT(upb_msgdef_ntofz(m, "b") == f);
  ASSERT(upb_msgdef_ntof(m, "b", 1) == f);
  def2 = upb_fielddef_subdef(f);
  ASSERT(upb_downcast_msgdef(def2));
  ok = strcmp(upb_def_fullname(def2), "B") == 0;
  ASSERT(ok);

  upb_def_ref(def2, &def2);
  upb_def_unref(def, &def);

  /* We know "def" is still alive because it's reachable from def2. */
  ok = strcmp(upb_def_fullname(def), "A") == 0;
  ASSERT(ok);
  upb_def_unref(def2, &def2);
}
Exemple #9
0
void upb_stdseq_free(void *s, upb_fielddef *f) {
  upb_stdarray *a = s;
  if (upb_issubmsg(f) || upb_isstring(f)) {
    void **p = (void**)a->ptr;
    for (uint32_t i = 0; i < a->size; i++) {
      if (upb_issubmsg(f)) {
        upb_stdmsg_free(p[i], upb_downcast_msgdef(f->def));
      } else {
        upb_stdarray *str = p[i];
        free(str->ptr);
        free(str);
      }
    }
  }
  free(a->ptr);
  free(a);
}
Exemple #10
0
void upb_stdmsg_free(void *m, const upb_msgdef *md) {
  if (m == NULL) return;
  upb_msg_iter i;
  for(i = upb_msg_begin(md); !upb_msg_done(i); i = upb_msg_next(md, i)) {
    upb_fielddef *f = upb_msg_iter_field(i);
    if (!upb_isseq(f) && !upb_issubmsg(f) && !upb_isstring(f)) continue;
    void *subp = upb_value_getptr(upb_stdmsg_getptr(m, f->fval));
    if (subp == NULL) continue;
    if (upb_isseq(f)) {
      upb_stdseq_free(subp, f);
    } else if (upb_issubmsg(f)) {
      upb_stdmsg_free(subp, upb_downcast_msgdef(f->def));
    } else {
      upb_stdarray *str = subp;
      free(str->ptr);
      free(str);
    }
  }
  free(m);
}
Exemple #11
0
int main() {
  upb_symtab *symtab = upb_symtab_new();
  upb_symtab_add_descriptorproto(symtab);
  upb_def *fds = upb_symtab_lookup(
      symtab, UPB_STRLIT("google.protobuf.FileDescriptorSet"));

  upb_stdio *in = upb_stdio_new();
  upb_stdio_reset(in, stdin);
  upb_stdio *out = upb_stdio_new();
  upb_stdio_reset(out, stdout);
  upb_decoder d;
  upb_decoder_init(&d, upb_downcast_msgdef(fds));
  upb_decoder_reset(&d, upb_stdio_bytesrc(in));
  upb_textprinter *p = upb_textprinter_new();
  upb_handlers handlers;
  upb_handlers_init(&handlers);
  upb_textprinter_reset(p, &handlers, upb_stdio_bytesink(out), false);
  upb_src *src = upb_decoder_src(&d);
  upb_src_sethandlers(src, &handlers);

  upb_status status = UPB_STATUS_INIT;
  upb_src_run(src, &status);

  assert(upb_ok(&status));

  upb_status_uninit(&status);
  upb_stdio_free(in);
  upb_stdio_free(out);
  upb_decoder_uninit(&d);
  upb_textprinter_free(p);
  upb_def_unref(fds);
  upb_symtab_unref(symtab);

  // Prevent C library from holding buffers open, so Valgrind doesn't see
  // memory leaks.
  fclose(stdin);
  fclose(stdout);
}