Example #1
0
File: handlers.c Project: YauzZ/upb
// 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;
}
Example #2
0
static bool initialize()
{
  // Initialize upb state, decode descriptor.
  upb_status status = UPB_STATUS_INIT;
  upb_symtab *s = upb_symtab_new();
  upb_load_descriptor_file_into_symtab(s, MESSAGE_DESCRIPTOR_FILE, &status);
  if(!upb_ok(&status)) {
    fprintf(stderr, "Error reading descriptor: %s\n",
            upb_status_getstr(&status));
    return false;
  }

  def = upb_dyncast_msgdef_const(upb_symtab_lookup(s, MESSAGE_NAME));
  if(!def) {
    fprintf(stderr, "Error finding symbol '%s'.\n", MESSAGE_NAME);
    return false;
  }
  upb_symtab_unref(s);

  // Read the message data itself.
  char *str = upb_readfile(MESSAGE_FILE, &len);
  if(str == NULL) {
    fprintf(stderr, "Error reading " MESSAGE_FILE "\n");
    return false;
  }
  upb_status_uninit(&status);
  for (int i = 0; i < NUM_MESSAGES; i++)
    msg[i] = upb_stdmsg_new(def);

  upb_stringsrc_init(&strsrc);
  upb_stringsrc_reset(&strsrc, str, len);
  upb_handlers *h = upb_handlers_new();
  upb_accessors_reghandlers(h, def);
  if (!JIT) h->should_jit = false;
  upb_decoder_init(&d, h);
  upb_handlers_unref(h);

  if (!BYREF) {
    // TODO: use byref/byval accessors.
  }
  return true;
}
Example #3
0
static bool initialize()
{
  // Initialize upb state, decode descriptor.
  upb_status status = UPB_STATUS_INIT;
  upb_symtab *s = upb_symtab_new(&s);
  upb_load_descriptor_file_into_symtab(s, MESSAGE_DESCRIPTOR_FILE, &status);
  if(!upb_ok(&status)) {
    fprintf(stderr, "Error reading descriptor: %s\n",
            upb_status_getstr(&status));
    return false;
  }

  def = upb_dyncast_msgdef_const(upb_symtab_lookup(s, MESSAGE_NAME, &def));
  if(!def) {
    fprintf(stderr, "Error finding symbol '%s'.\n", MESSAGE_NAME);
    return false;
  }
  upb_symtab_unref(s, &s);

  // Read the message data itself.
  input_str = upb_readfile(MESSAGE_FILE, &input_len);
  if(input_str == NULL) {
    fprintf(stderr, "Error reading " MESSAGE_FILE "\n");
    return false;
  }

  upb_handlers *handlers = upb_handlers_new();
  // Cause all messages to be read, but do nothing when they are.
  upb_handlerset hset = {NULL, NULL, value, startsubmsg, NULL, NULL, NULL};
  upb_handlers_reghandlerset(handlers, def, &hset);
  upb_decoder_init(&decoder);
  plan = upb_decoderplan_new(handlers, JIT);
  upb_decoder_resetplan(&decoder, plan, 0);
  upb_handlers_unref(handlers);
  upb_stringsrc_init(&stringsrc);
  return true;
}
Example #4
0
int main(int argc, char *argv[]) {
  if (argc < 3) {
    fprintf(stderr, "Usage: stream_transcode <descfile> <msgname>\n");
    return 1;
  }

  upb_symtab *symtab = upb_symtab_new();
  size_t desc_len;
  const char *desc = upb_readfile(argv[1], &desc_len);
  if (!desc) {
    fprintf(stderr, "Couldn't open descriptor file: %s\n", argv[1]);
    return 1;
  }

  upb_status status = UPB_STATUS_INIT;
  upb_load_descriptor_into_symtab(symtab, desc, desc_len, &status);
  if (!upb_ok(&status)) {
    fprintf(stderr, "Error parsing descriptor: %s", upb_status_getstr(&status));
    return 1;
  }
  free((void*)desc);

  const upb_def *md = upb_symtab_lookup(symtab, argv[2]);
  if (!md) {
    fprintf(stderr, "Descriptor did not contain message: %s\n", argv[2]);
    return 1;
  }

  const upb_msgdef *m = upb_dyncast_msgdef_const(md);
  if (!m) {
    fprintf(stderr, "Def was not a msgdef.\n");
    return 1;
  }

  upb_stdio in, out;
  upb_stdio_init(&in);
  upb_stdio_init(&out);
  upb_stdio_reset(&in, stdin);
  upb_stdio_reset(&out, stdout);

  upb_handlers *handlers = upb_handlers_new();
  upb_textprinter *p = upb_textprinter_new();
  upb_textprinter_reset(p, upb_stdio_bytesink(&out), false);
  upb_textprinter_reghandlers(handlers, m);

  upb_decoder d;
  upb_decoder_init(&d, handlers);
  upb_decoder_reset(&d, upb_stdio_bytesrc(&in), 0, UPB_NONDELIMITED, p);

  upb_status_clear(&status);
  upb_decoder_decode(&d, &status);

  if (!upb_ok(&status)) {
    fprintf(stderr, "Error parsing input: %s", upb_status_getstr(&status));
  }

  upb_status_uninit(&status);
  upb_stdio_uninit(&in);
  upb_stdio_uninit(&out);
  upb_decoder_uninit(&d);
  upb_textprinter_free(p);
  upb_def_unref(UPB_UPCAST(m));
  upb_symtab_unref(symtab);

  // Prevent C library from holding buffers open, so Valgrind doesn't see
  // memory leaks.
  fclose(stdin);
  fclose(stdout);
}
Example #5
0
 // Creates a new Handlers instance.
 static Handlers* New() {
     return static_cast<Handlers*>(upb_handlers_new());
 }
Example #6
0
File: handlers.c Project: YauzZ/upb
bool upb_handlers_freeze(upb_handlers *const*handlers, int n, upb_status *s) {
  // TODO: verify we have a transitive closure.
  for (int i = 0; i < n; i++) {
    upb_handlers *h = handlers[i];

    if (!upb_ok(&h->status_)) {
      upb_status_seterrf(s, "handlers for message %s had error status: %s",
                         upb_msgdef_fullname(upb_handlers_msgdef(h)),
                         upb_status_errmsg(&h->status_));
      return false;
    }

    // Check that there are no closure mismatches due to missing Start* handlers
    // or subhandlers with different type-level types.
    upb_msg_iter j;
    for(upb_msg_begin(&j, h->msg); !upb_msg_done(&j); upb_msg_next(&j)) {

      const upb_fielddef *f = upb_msg_iter_field(&j);
      if (upb_fielddef_isseq(f)) {
        if (!checkstart(h, f, UPB_HANDLER_STARTSEQ, s))
          return false;
      }

      if (upb_fielddef_isstring(f)) {
        if (!checkstart(h, f, UPB_HANDLER_STARTSTR, s))
          return false;
      }

      if (upb_fielddef_issubmsg(f)) {
        bool hashandler = false;
        if (upb_handlers_gethandler(h, getsel(h, f, UPB_HANDLER_STARTSUBMSG)) ||
            upb_handlers_gethandler(h, getsel(h, f, UPB_HANDLER_ENDSUBMSG))) {
          hashandler = true;
        }

        if (upb_fielddef_isseq(f) &&
            (upb_handlers_gethandler(h, getsel(h, f, UPB_HANDLER_STARTSEQ)) ||
             upb_handlers_gethandler(h, getsel(h, f, UPB_HANDLER_ENDSEQ)))) {
          hashandler = true;
        }

        if (hashandler && !upb_handlers_getsubhandlers(h, f)) {
          // For now we add an empty subhandlers in this case.  It makes the
          // decoder code generator simpler, because it only has to handle two
          // cases (submessage has handlers or not) as opposed to three
          // (submessage has handlers in enclosing message but no subhandlers).
          //
          // This makes parsing less efficient in the case that we want to
          // notice a submessage but skip its contents (like if we're testing
          // for submessage presence or counting the number of repeated
          // submessages).  In this case we will end up parsing the submessage
          // field by field and throwing away the results for each, instead of
          // skipping the whole delimited thing at once.  If this is an issue we
          // can revisit it, but do remember that this only arises when you have
          // handlers (startseq/startsubmsg/endsubmsg/endseq) set for the
          // submessage but no subhandlers.  The uses cases for this are
          // limited.
          upb_handlers *sub = upb_handlers_new(upb_fielddef_msgsubdef(f), &sub);
          upb_handlers_setsubhandlers(h, f, sub);
          upb_handlers_unref(sub, &sub);
        }

        // TODO(haberman): check type of submessage.
        // This is slightly tricky; also consider whether we should check that
        // they match at setsubhandlers time.
      }
    }
  }

  if (!upb_refcounted_freeze((upb_refcounted*const*)handlers, n, s,
                             UPB_MAX_HANDLER_DEPTH)) {
    return false;
  }

  return true;
}