コード例 #1
0
ファイル: sink.c プロジェクト: Phuehvk/upb
bool upb_sink_endsubmsg(upb_sink *s, upb_selector_t sel) {
  upb_endmsg_handler *endmsg = (upb_endmsg_handler *)upb_handlers_gethandler(
      s->top->h, UPB_ENDMSG_SELECTOR);
  if (endmsg) {
    // TODO(haberman): check return value.
    const void *hd =
        upb_handlers_gethandlerdata(s->top->h, UPB_ENDMSG_SELECTOR);
    endmsg(s->top->closure, hd, &s->pipeline_->status_);
  }
  --s->top;

  assert(sel == s->top->selector);
  const upb_handlers *h = s->top->h;
  upb_endfield_handler *endsubmsg =
      (upb_endfield_handler*)upb_handlers_gethandler(h, sel);

  if (endsubmsg) {
    const void *hd = upb_handlers_gethandlerdata(h, sel);
    bool ok = endsubmsg(s->top->closure, hd);
    if (!ok) {
      ++s->top;
      return false;
    }
  }

  return true;
}
コード例 #2
0
ファイル: handlers.c プロジェクト: YauzZ/upb
bool upb_handlers_getattr(const upb_handlers *h, upb_selector_t sel,
                          upb_handlerattr *attr) {
  if (!upb_handlers_gethandler(h, sel))
    return false;
  *attr = h->table[sel].attr;
  return true;
}
コード例 #3
0
ファイル: sink.c プロジェクト: Phuehvk/upb
bool upb_sink_startsubmsg(upb_sink *s, upb_selector_t sel) {
  if (!chkstack(s)) return false;

  void *subc = s->top->closure;
  const upb_handlers *h = s->top->h;
  upb_startfield_handler *startsubmsg =
      (upb_startfield_handler*)upb_handlers_gethandler(h, sel);

  if (startsubmsg) {
    const void *hd = upb_handlers_gethandlerdata(h, sel);
    subc = startsubmsg(s->top->closure, hd);
    if (subc == UPB_BREAK) {
      return false;
    }
  }

  s->top->selector= upb_handlers_getendselector(sel);
  ++s->top;
  s->top->h = upb_handlers_getsubhandlers_sel(h, sel);
  // TODO: should add support for submessages without any handlers
  assert(s->top->h);
  s->top->closure = subc;
  upb_sink_startmsg(s);
  return true;
}
コード例 #4
0
ファイル: sink.c プロジェクト: Phuehvk/upb
bool upb_sink_startmsg(upb_sink *s) {
  const upb_handlers *h = s->top->h;
  upb_startmsg_handler *startmsg =
      (upb_startmsg_handler *)upb_handlers_gethandler(h, UPB_STARTMSG_SELECTOR);
  if (startmsg) {
    const void *hd = upb_handlers_gethandlerdata(h, UPB_STARTMSG_SELECTOR);
    bool ok = startmsg(s->top->closure, hd);
    if (!ok) return false;
  }
  return true;
}
コード例 #5
0
ファイル: sink.c プロジェクト: Phuehvk/upb
bool upb_sink_endmsg(upb_sink *s) {
  assert(s->top == s->stack);
  const upb_handlers *h = s->top->h;
  upb_endmsg_handler *endmsg =
      (upb_endmsg_handler *)upb_handlers_gethandler(h, UPB_ENDMSG_SELECTOR);
  if (endmsg) {
    const void *hd = upb_handlers_gethandlerdata(h, UPB_ENDMSG_SELECTOR);
    bool ok = endmsg(s->top->closure, hd, &s->pipeline_->status_);
    if (!ok) return false;
  }
  return true;
}
コード例 #6
0
ファイル: sink.c プロジェクト: Phuehvk/upb
size_t upb_sink_putstring(upb_sink *s, upb_selector_t sel,
                          const char *buf, size_t n) {
  const upb_handlers *h = s->top->h;
  upb_string_handler *handler =
      (upb_string_handler*)upb_handlers_gethandler(h, sel);

  if (handler) {
    const void *hd = upb_handlers_gethandlerdata(h, sel);;
    n = handler(s->top->closure, hd, buf, n);
  }

  return n;
}
コード例 #7
0
ファイル: sink.c プロジェクト: Phuehvk/upb
bool upb_sink_endstr(upb_sink *s, upb_selector_t sel) {
  --s->top;
  assert(sel == s->top->selector);
  const upb_handlers *h = s->top->h;
  upb_endfield_handler *endstr =
      (upb_endfield_handler*)upb_handlers_gethandler(h, sel);

  if (endstr) {
    const void *hd = upb_handlers_gethandlerdata(h, sel);
    bool ok = endstr(s->top->closure, hd);
    if (!ok) {
      ++s->top;
      return false;
    }
  }

  return true;
}
コード例 #8
0
ファイル: sink.c プロジェクト: Phuehvk/upb
bool upb_sink_startstr(upb_sink *s, upb_selector_t sel, size_t size_hint) {
  if (!chkstack(s)) return false;

  void *subc = s->top->closure;
  const upb_handlers *h = s->top->h;
  upb_startstr_handler *startstr =
      (upb_startstr_handler*)upb_handlers_gethandler(h, sel);

  if (startstr) {
    const void *hd = upb_handlers_gethandlerdata(h, sel);
    subc = startstr(s->top->closure, hd, size_hint);
    if (subc == UPB_BREAK) {
      return false;
    }
  }

  s->top->selector = upb_handlers_getendselector(sel);
  ++s->top;
  s->top->h = h;
  s->top->closure = subc;
  return true;
}
コード例 #9
0
ファイル: shim.c プロジェクト: atdt/upb
const upb_shim_data *upb_shim_getdata(const upb_handlers *h, upb_selector_t s,
                                      upb_fieldtype_t *type) {
  upb_func *f = upb_handlers_gethandler(h, s);

  if ((upb_int64_handlerfunc*)f == upb_shim_setint64) {
    *type = UPB_TYPE_INT64;
  } else if ((upb_int32_handlerfunc*)f == upb_shim_setint32) {
    *type = UPB_TYPE_INT32;
  } else if ((upb_uint64_handlerfunc*)f == upb_shim_setuint64) {
    *type = UPB_TYPE_UINT64;
  } else if ((upb_uint32_handlerfunc*)f == upb_shim_setuint32) {
    *type = UPB_TYPE_UINT32;
  } else if ((upb_double_handlerfunc*)f == upb_shim_setdouble) {
    *type = UPB_TYPE_DOUBLE;
  } else if ((upb_float_handlerfunc*)f == upb_shim_setfloat) {
    *type = UPB_TYPE_FLOAT;
  } else if ((upb_bool_handlerfunc*)f == upb_shim_setbool) {
    *type = UPB_TYPE_BOOL;
  } else {
    return NULL;
  }

  return (const upb_shim_data*)upb_handlers_gethandlerdata(h, s);
}
コード例 #10
0
ファイル: handlers.c プロジェクト: 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;
}