コード例 #1
0
ファイル: def.c プロジェクト: Phuehvk/upb
bool upb_msgdef_addfields(upb_msgdef *m, upb_fielddef *const *fields, int n,
                          const void *ref_donor, upb_status *s) {
  // Check constraints for all fields before performing any action.
  for (int i = 0; i < n; i++) {
    upb_fielddef *f = fields[i];
    // TODO(haberman): handle the case where two fields of the input duplicate
    // name or number.
    if (f->msgdef != NULL) {
      upb_status_seterrliteral(s, "fielddef already belongs to a message");
      return false;
    } else if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
      upb_status_seterrliteral(s, "field name or number were not set");
      return false;
    } else if(upb_msgdef_itof(m, upb_fielddef_number(f)) ||
              upb_msgdef_ntof(m, upb_fielddef_name(f))) {
      upb_status_seterrliteral(s, "duplicate field name or number");
      return false;
    }
  }

  // Constraint checks ok, perform the action.
  for (int i = 0; i < n; i++) {
    upb_fielddef *f = fields[i];
    f->msgdef = m;
    upb_inttable_insert(&m->itof, upb_fielddef_number(f), upb_value_ptr(f));
    upb_strtable_insert(&m->ntof, upb_fielddef_name(f), upb_value_ptr(f));
    upb_ref2(f, m);
    upb_ref2(m, f);
    if (ref_donor) upb_fielddef_unref(f, ref_donor);
  }
  return true;
}
コード例 #2
0
ファイル: def.c プロジェクト: imageoptimiser/upb
bool upb_msgdef_addfields(upb_msgdef *m, upb_fielddef *const *fields, int n,
                          const void *ref_donor) {
  // Check constraints for all fields before performing any action.
  for (int i = 0; i < n; i++) {
    upb_fielddef *f = fields[i];
    // TODO(haberman): handle the case where two fields of the input duplicate
    // name or number.
    if (f->msgdef != NULL ||
        upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0 ||
        upb_msgdef_itof(m, upb_fielddef_number(f)) ||
        upb_msgdef_ntof(m, upb_fielddef_name(f)))
      return false;
  }

  // Constraint checks ok, perform the action.
  for (int i = 0; i < n; i++) {
    upb_fielddef *f = fields[i];
    f->msgdef = m;
    upb_inttable_insert(&m->itof, upb_fielddef_number(f), upb_value_ptr(f));
    upb_strtable_insert(&m->ntof, upb_fielddef_name(f), upb_value_ptr(f));
    upb_ref2(f, m);
    upb_ref2(m, f);
    if (ref_donor) upb_fielddef_unref(f, ref_donor);
  }
  return true;
}
コード例 #3
0
ファイル: def.c プロジェクト: imageoptimiser/upb
static bool upb_validate_field(upb_fielddef *f, upb_status *s) {
  if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
    upb_status_seterrliteral(s, "fielddef must have name and number set");
    return false;
  }
  if (upb_fielddef_hassubdef(f)) {
    if (f->subdef_is_symbolic) {
      upb_status_seterrf(s,
          "field '%s' has not been resolved", upb_fielddef_name(f));
      return false;
    }

    const upb_def *subdef = upb_fielddef_subdef(f);
    if (subdef == NULL) {
      upb_status_seterrf(s,
          "field %s.%s is missing required subdef",
          msgdef_name(f->msgdef), upb_fielddef_name(f));
      return false;
    } else if (!upb_def_isfrozen(subdef) && !subdef->came_from_user) {
      upb_status_seterrf(s,
          "subdef of field %s.%s is not frozen or being frozen",
          msgdef_name(f->msgdef), upb_fielddef_name(f));
      return false;
    } else if (upb_fielddef_default_is_symbolic(f)) {
      upb_status_seterrf(s,
          "enum field %s.%s has not been resolved",
          msgdef_name(f->msgdef), upb_fielddef_name(f));
      return false;
    }
  }
  return true;
}
コード例 #4
0
ファイル: storage.c プロジェクト: acozzette/protobuf
void layout_set(MessageLayout* layout,
                void* storage,
                const upb_fielddef* field,
                VALUE val) {
  void* memory = slot_memory(layout, storage, field);
  uint32_t* oneof_case = slot_oneof_case(layout, storage, field);

  if (upb_fielddef_containingoneof(field)) {
    if (val == Qnil) {
      // Assigning nil to a oneof field clears the oneof completely.
      *oneof_case = ONEOF_CASE_NONE;
      memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
    } else {
      // The transition between field types for a single oneof (union) slot is
      // somewhat complex because we need to ensure that a GC triggered at any
      // point by a call into the Ruby VM sees a valid state for this field and
      // does not either go off into the weeds (following what it thinks is a
      // VALUE but is actually a different field type) or miss an object (seeing
      // what it thinks is a primitive field but is actually a VALUE for the new
      // field type).
      //
      // In order for the transition to be safe, the oneof case slot must be in
      // sync with the value slot whenever the Ruby VM has been called. Thus, we
      // use native_slot_set_value_and_case(), which ensures that both the value
      // and case number are altered atomically (w.r.t. the Ruby VM).
      native_slot_set_value_and_case(
          upb_fielddef_name(field),
          upb_fielddef_type(field), field_type_class(field),
          memory, val,
          oneof_case, upb_fielddef_number(field));
    }
  } else if (is_map_field(field)) {
    check_map_field_type(val, field);
    DEREF(memory, VALUE) = val;
  } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
    check_repeated_field_type(val, field);
    DEREF(memory, VALUE) = val;
  } else {
    native_slot_set(upb_fielddef_name(field),
                    upb_fielddef_type(field), field_type_class(field),
                    memory, val);
  }

  if (layout->fields[upb_fielddef_index(field)].hasbit !=
      MESSAGE_FIELD_NO_HASBIT) {
    slot_set_hasbit(layout, storage, field);
  }
}
コード例 #5
0
ファイル: reader.c プロジェクト: imageoptimiser/upb
static void field_endmsg(void *_r, upb_status *status) {
  upb_descreader *r = _r;
  upb_fielddef *f = r->f;
  // TODO: verify that all required fields were present.
  assert(upb_fielddef_number(f) != 0 && upb_fielddef_name(f) != NULL);
  assert((upb_fielddef_subdefname(f) != NULL) == upb_fielddef_hassubdef(f));

  if (r->default_string) {
    if (upb_fielddef_issubmsg(f)) {
      upb_status_seterrliteral(status, "Submessages cannot have defaults.");
      return;
    }
    if (upb_fielddef_isstring(f) || upb_fielddef_type(f) == UPB_TYPE(ENUM)) {
      upb_fielddef_setdefaultcstr(f, r->default_string);
    } else {
      upb_value val;
      upb_value_setptr(&val, NULL);  // Silence inaccurate compiler warnings.
      if (!parse_default(r->default_string, &val, upb_fielddef_type(f))) {
        // We don't worry too much about giving a great error message since the
        // compiler should have ensured this was correct.
        upb_status_seterrliteral(status, "Error converting default value.");
        return;
      }
      upb_fielddef_setdefault(f, val);
    }
  }
}
コード例 #6
0
ファイル: upb.c プロジェクト: chenbk85/upb
static PyObject *PyUpb_FieldDef_getattro(PyObject *obj, PyObject *attr_name) {
  upb_fielddef *f = Check_FieldDef(obj, NULL);
  if (!upb_fielddef_ismutable(f)) {
    PyErr_SetString(PyExc_TypeError, "fielddef is not mutable.");
    return NULL;
  }
  const char *name = PyString_AsString(attr_name);
  if (streql(name, "name")) {
    const char *name = upb_fielddef_name(f);
    return name == NULL ? Py_None : PyString_FromString(name);
  } else if (streql(name, "number")) {
    uint32_t num = upb_fielddef_number(f);
    return num == 0 ? Py_None : PyInt_FromLong(num);
  } else if (streql(name, "type")) {
    uint8_t type = upb_fielddef_type(f);
    return type == 0 ? Py_None : PyInt_FromLong(type);
  } else if (streql(name, "label")) {
    return PyInt_FromLong(upb_fielddef_label(f));
  } else if (streql(name, "type_name")) {
    const char *name = upb_fielddef_typename(f);
    return name == NULL ? Py_None : PyString_FromString(name);
  } else if (streql(name, "subdef")) {
    // NYI;
    return NULL;
  } else if (streql(name, "msgdef")) {
    // NYI;
    return NULL;
  } else {
    return PyUpb_Error("Invalid fielddef member.");
  }
}
コード例 #7
0
ファイル: reader.c プロジェクト: YauzZ/upb
static bool field_endmsg(void *closure, const void *hd, upb_status *status) {
  UPB_UNUSED(hd);
  upb_descreader *r = closure;
  upb_fielddef *f = r->f;
  // TODO: verify that all required fields were present.
  assert(upb_fielddef_number(f) != 0);
  assert(upb_fielddef_name(f) != NULL);
  assert((upb_fielddef_subdefname(f) != NULL) == upb_fielddef_hassubdef(f));

  if (r->default_string) {
    if (upb_fielddef_issubmsg(f)) {
      upb_status_seterrmsg(status, "Submessages cannot have defaults.");
      return false;
    }
    if (upb_fielddef_isstring(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM) {
      upb_fielddef_setdefaultcstr(f, r->default_string, NULL);
    } else {
      if (r->default_string && !parse_default(r->default_string, f)) {
        // We don't worry too much about giving a great error message since the
        // compiler should have ensured this was correct.
        upb_status_seterrmsg(status, "Error converting default value.");
        return false;
      }
    }
  }
  return true;
}
コード例 #8
0
ファイル: message.c プロジェクト: goodleon/protobuf
static VALUE which_oneof_field(MessageHeader* self, const upb_oneofdef* o) {
  // If no fields in the oneof, always nil.
  if (upb_oneofdef_numfields(o) == 0) {
    return Qnil;
  }
  // Grab the first field in the oneof so we can get its layout info to find the
  // oneof_case field.
  upb_oneof_iter it;
  upb_oneof_begin(&it, o);
  assert(!upb_oneof_done(&it));
  const upb_fielddef* first_field = upb_oneof_iter_field(&it);
  assert(upb_fielddef_containingoneof(first_field) != NULL);

  size_t case_ofs =
      self->descriptor->layout->
      fields[upb_fielddef_index(first_field)].case_offset;
  uint32_t oneof_case = *((uint32_t*)(Message_data(self) + case_ofs));

  if (oneof_case == ONEOF_CASE_NONE) {
    return Qnil;
  }

  // oneof_case is a field index, so find that field.
  const upb_fielddef* f = upb_oneofdef_itof(o, oneof_case);
  assert(f != NULL);

  return ID2SYM(rb_intern(upb_fielddef_name(f)));
}
コード例 #9
0
ファイル: def.c プロジェクト: Phuehvk/upb
upb_fielddef *upb_fielddef_dup(const upb_fielddef *f, const void *owner) {
  upb_fielddef *newf = upb_fielddef_new(owner);
  if (!newf) return NULL;
  upb_fielddef_settype(newf, upb_fielddef_type(f));
  upb_fielddef_setlabel(newf, upb_fielddef_label(f));
  upb_fielddef_setnumber(newf, upb_fielddef_number(f), NULL);
  upb_fielddef_setname(newf, upb_fielddef_name(f), NULL);
  if (f->default_is_string) {
    str_t *s = upb_value_getptr(upb_fielddef_default(f));
    upb_fielddef_setdefaultstr(newf, s->str, s->len, NULL);
  } else {
    upb_fielddef_setdefault(newf, upb_fielddef_default(f));
  }

  const char *srcname;
  if (f->subdef_is_symbolic) {
    srcname = f->sub.name;  // Might be NULL.
  } else {
    srcname = f->sub.def ? upb_def_fullname(f->sub.def) : NULL;
  }
  if (srcname) {
    char *newname = malloc(strlen(f->sub.def->fullname) + 2);
    if (!newname) {
      upb_fielddef_unref(newf, owner);
      return NULL;
    }
    strcpy(newname, ".");
    strcat(newname, f->sub.def->fullname);
    upb_fielddef_setsubdefname(newf, newname, NULL);
    free(newname);
  }

  return newf;
}
コード例 #10
0
ファイル: storage.c プロジェクト: acozzette/protobuf
void layout_clear(MessageLayout* layout,
                 const void* storage,
                 const upb_fielddef* field) {
  void* memory = slot_memory(layout, storage, field);
  uint32_t* oneof_case = slot_oneof_case(layout, storage, field);

  if (field_contains_hasbit(layout, field)) {
    slot_clear_hasbit(layout, storage, field);
  }

  if (upb_fielddef_containingoneof(field)) {
    memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
    *oneof_case = ONEOF_CASE_NONE;
  } else if (is_map_field(field)) {
    VALUE map = Qnil;

    const upb_fielddef* key_field = map_field_key(field);
    const upb_fielddef* value_field = map_field_value(field);
    VALUE type_class = field_type_class(value_field);

    if (type_class != Qnil) {
      VALUE args[3] = {
        fieldtype_to_ruby(upb_fielddef_type(key_field)),
        fieldtype_to_ruby(upb_fielddef_type(value_field)),
        type_class,
      };
      map = rb_class_new_instance(3, args, cMap);
    } else {
      VALUE args[2] = {
        fieldtype_to_ruby(upb_fielddef_type(key_field)),
        fieldtype_to_ruby(upb_fielddef_type(value_field)),
      };
      map = rb_class_new_instance(2, args, cMap);
    }

    DEREF(memory, VALUE) = map;
  } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
    VALUE ary = Qnil;

    VALUE type_class = field_type_class(field);

    if (type_class != Qnil) {
      VALUE args[2] = {
        fieldtype_to_ruby(upb_fielddef_type(field)),
        type_class,
      };
      ary = rb_class_new_instance(2, args, cRepeatedField);
    } else {
      VALUE args[1] = { fieldtype_to_ruby(upb_fielddef_type(field)) };
      ary = rb_class_new_instance(1, args, cRepeatedField);
    }

    DEREF(memory, VALUE) = ary;
  } else {
    native_slot_set(upb_fielddef_name(field),
                    upb_fielddef_type(field), field_type_class(field),
                    memory, layout_get_default(field));
  }
}
コード例 #11
0
ファイル: textprinter.c プロジェクト: atdt/upb
static void onmreg(const void *c, upb_handlers *h) {
  const upb_msgdef *m = upb_handlers_msgdef(h);
  upb_msg_field_iter i;
  UPB_UNUSED(c);

  upb_handlers_setstartmsg(h, textprinter_startmsg, NULL);
  upb_handlers_setendmsg(h, textprinter_endmsg, NULL);

  for(upb_msg_field_begin(&i, m);
      !upb_msg_field_done(&i);
      upb_msg_field_next(&i)) {
    upb_fielddef *f = upb_msg_iter_field(&i);
    upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
    upb_handlerattr_sethandlerdata(&attr, f);
    switch (upb_fielddef_type(f)) {
      case UPB_TYPE_INT32:
        upb_handlers_setint32(h, f, textprinter_putint32, &attr);
        break;
      case UPB_TYPE_INT64:
        upb_handlers_setint64(h, f, textprinter_putint64, &attr);
        break;
      case UPB_TYPE_UINT32:
        upb_handlers_setuint32(h, f, textprinter_putuint32, &attr);
        break;
      case UPB_TYPE_UINT64:
        upb_handlers_setuint64(h, f, textprinter_putuint64, &attr);
        break;
      case UPB_TYPE_FLOAT:
        upb_handlers_setfloat(h, f, textprinter_putfloat, &attr);
        break;
      case UPB_TYPE_DOUBLE:
        upb_handlers_setdouble(h, f, textprinter_putdouble, &attr);
        break;
      case UPB_TYPE_BOOL:
        upb_handlers_setbool(h, f, textprinter_putbool, &attr);
        break;
      case UPB_TYPE_STRING:
      case UPB_TYPE_BYTES:
        upb_handlers_setstartstr(h, f, textprinter_startstr, &attr);
        upb_handlers_setstring(h, f, textprinter_putstr, &attr);
        upb_handlers_setendstr(h, f, textprinter_endstr, &attr);
        break;
      case UPB_TYPE_MESSAGE: {
        const char *name =
            upb_fielddef_istagdelim(f)
                ? shortname(upb_msgdef_fullname(upb_fielddef_msgsubdef(f)))
                : upb_fielddef_name(f);
        upb_handlerattr_sethandlerdata(&attr, name);
        upb_handlers_setstartsubmsg(h, f, textprinter_startsubmsg, &attr);
        upb_handlers_setendsubmsg(h, f, textprinter_endsubmsg, &attr);
        break;
      }
      case UPB_TYPE_ENUM:
        upb_handlers_setint32(h, f, textprinter_putenum, &attr);
        break;
    }
  }
}
コード例 #12
0
ファイル: def.c プロジェクト: YauzZ/upb
bool upb_msgdef_addfields(upb_msgdef *m, upb_fielddef *const *fields, int n,
                          const void *ref_donor, upb_status *s) {
  // TODO: extensions need to have a separate namespace, because proto2 allows a
  // top-level extension (ie. one not in any package) to have the same name as a
  // field from the message.
  //
  // This also implies that there needs to be a separate lookup-by-name method
  // for extensions.  It seems desirable for iteration to return both extensions
  // and non-extensions though.
  //
  // We also need to validate that the field number is in an extension range iff
  // it is an extension.

  // Check constraints for all fields before performing any action.
  for (int i = 0; i < n; i++) {
    upb_fielddef *f = fields[i];
    // TODO(haberman): handle the case where two fields of the input duplicate
    // name or number.
    if (upb_fielddef_containingtype(f) != NULL) {
      upb_status_seterrmsg(s, "fielddef already belongs to a message");
      return false;
    } else if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
      upb_status_seterrmsg(s, "field name or number were not set");
      return false;
    } else if(upb_msgdef_itof(m, upb_fielddef_number(f)) ||
              upb_msgdef_ntof(m, upb_fielddef_name(f))) {
      upb_status_seterrmsg(s, "duplicate field name or number");
      return false;
    }
  }

  // Constraint checks ok, perform the action.
  for (int i = 0; i < n; i++) {
    upb_fielddef *f = fields[i];
    release_containingtype(f);
    f->msg.def = m;
    f->msg_is_symbolic = false;
    upb_inttable_insert(&m->itof, upb_fielddef_number(f), upb_value_ptr(f));
    upb_strtable_insert(&m->ntof, upb_fielddef_name(f), upb_value_ptr(f));
    upb_ref2(f, m);
    upb_ref2(m, f);
    if (ref_donor) upb_fielddef_unref(f, ref_donor);
  }
  return true;
}
コード例 #13
0
ファイル: textprinter.c プロジェクト: atdt/upb
static void *textprinter_startstr(void *closure, const void *handler_data,
                      size_t size_hint) {
  upb_textprinter *p = closure;
  const upb_fielddef *f = handler_data;
  UPB_UNUSED(size_hint);
  indent(p);
  putf(p, "%s: \"", upb_fielddef_name(f));
  return p;
}
コード例 #14
0
ファイル: handlers.c プロジェクト: YauzZ/upb
static int32_t trygetsel(upb_handlers *h, const upb_fielddef *f,
                         upb_handlertype_t type) {
  upb_selector_t sel;
  assert(!upb_handlers_isfrozen(h));
  if (upb_handlers_msgdef(h) != upb_fielddef_containingtype(f)) {
    upb_status_seterrf(
        &h->status_, "type mismatch: field %s does not belong to message %s",
        upb_fielddef_name(f), upb_msgdef_fullname(upb_handlers_msgdef(h)));
    return -1;
  }
  if (!upb_handlers_getselector(f, type, &sel)) {
    upb_status_seterrf(
        &h->status_,
        "type mismatch: cannot register handler type %d for field %s",
        type, upb_fielddef_name(f));
    return -1;
  }
  return sel;
}
コード例 #15
0
ファイル: def.c プロジェクト: YauzZ/upb
static bool upb_validate_field(upb_fielddef *f, upb_status *s) {
  if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
    upb_status_seterrmsg(s, "fielddef must have name and number set");
    return false;
  }
  if (!f->type_is_set_) {
    upb_status_seterrmsg(s, "fielddef type was not initialized");
    return false;
  }
  if (upb_fielddef_lazy(f) &&
      upb_fielddef_descriptortype(f) != UPB_DESCRIPTOR_TYPE_MESSAGE) {
    upb_status_seterrmsg(s,
                         "only length-delimited submessage fields may be lazy");
    return false;
  }
  if (upb_fielddef_hassubdef(f)) {
    if (f->subdef_is_symbolic) {
      upb_status_seterrf(s,
          "field '%s' has not been resolved", upb_fielddef_name(f));
      return false;
    }

    const upb_def *subdef = upb_fielddef_subdef(f);
    if (subdef == NULL) {
      upb_status_seterrf(s,
          "field %s.%s is missing required subdef",
          msgdef_name(f->msg.def), upb_fielddef_name(f));
      return false;
    } else if (!upb_def_isfrozen(subdef) && !subdef->came_from_user) {
      upb_status_seterrf(s,
          "subdef of field %s.%s is not frozen or being frozen",
          msgdef_name(f->msg.def), upb_fielddef_name(f));
      return false;
    } else if (upb_fielddef_default_is_symbolic(f)) {
      upb_status_seterrf(s,
          "enum field %s.%s has not been resolved",
          msgdef_name(f->msg.def), upb_fielddef_name(f));
      return false;
    }
  }
  return true;
}
コード例 #16
0
ファイル: textprinter.c プロジェクト: atdt/upb
static bool textprinter_putbool(void *closure, const void *handler_data,
                                bool val) {
  upb_textprinter *p = closure;
  const upb_fielddef *f = handler_data;
  CHECK(indent(p));
  putf(p, "%s: %s", upb_fielddef_name(f), val ? "true" : "false");
  CHECK(endfield(p));
  return true;
err:
  return false;
}
コード例 #17
0
ファイル: message.c プロジェクト: hack0303/protobuf
/*
 * call-seq:
 *     Message.method_missing(*args)
 *
 * Provides accessors and setters and methods to clear and check for presence of
 * message fields according to their field names.
 *
 * For any field whose name does not conflict with a built-in method, an
 * accessor is provided with the same name as the field, and a setter is
 * provided with the name of the field plus the '=' suffix. Thus, given a
 * message instance 'msg' with field 'foo', the following code is valid:
 *
 *     msg.foo = 42
 *     puts msg.foo
 *
 * This method also provides read-only accessors for oneofs. If a oneof exists
 * with name 'my_oneof', then msg.my_oneof will return a Ruby symbol equal to
 * the name of the field in that oneof that is currently set, or nil if none.
 *
 * It also provides methods of the form 'clear_fieldname' to clear the value
 * of the field 'fieldname'. For basic data types, this will set the default
 * value of the field.
 *
 * Additionally, it provides methods of the form 'has_fieldname?', which returns
 * true if the field 'fieldname' is set in the message object, else false. For
 * 'proto3' syntax, calling this for a basic type field will result in an error.
 */
VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
  MessageHeader* self;
  const upb_oneofdef* o;
  const upb_fielddef* f;

  TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
  if (argc < 1) {
    rb_raise(rb_eArgError, "Expected method name as first argument.");
  }

  int accessor_type = extract_method_call(argv[0], self, &f, &o);
  if (accessor_type == METHOD_UNKNOWN || (o == NULL && f == NULL) ) {
    return rb_call_super(argc, argv);
  } else if (accessor_type == METHOD_SETTER) {
    if (argc != 2) {
      rb_raise(rb_eArgError, "Expected 2 arguments, received %d", argc);
    }
  } else if (argc != 1) {
    rb_raise(rb_eArgError, "Expected 1 argument, received %d", argc);
  }

  // Return which of the oneof fields are set
  if (o != NULL) {
    if (accessor_type == METHOD_SETTER) {
      rb_raise(rb_eRuntimeError, "Oneof accessors are read-only.");
    }

    const upb_fielddef* oneof_field = which_oneof_field(self, o);
    if (accessor_type == METHOD_PRESENCE) {
      return oneof_field == NULL ? Qfalse : Qtrue;
    } else if (accessor_type == METHOD_CLEAR) {
      if (oneof_field != NULL) {
	layout_clear(self->descriptor->layout, Message_data(self), oneof_field);
      }
      return Qnil;
    } else {
      // METHOD_ACCESSOR
      return oneof_field == NULL ? Qnil :
	ID2SYM(rb_intern(upb_fielddef_name(oneof_field)));
    }
  // Otherwise we're operating on a single proto field
  } else if (accessor_type == METHOD_SETTER) {
    layout_set(self->descriptor->layout, Message_data(self), f, argv[1]);
    return Qnil;
  } else if (accessor_type == METHOD_CLEAR) {
    layout_clear(self->descriptor->layout, Message_data(self), f);
    return Qnil;
  } else if (accessor_type == METHOD_PRESENCE) {
    return layout_has(self->descriptor->layout, Message_data(self), f);
  } else {
    return layout_get(self->descriptor->layout, Message_data(self), f);
  }
}
コード例 #18
0
ファイル: textprinter.c プロジェクト: atdt/upb
/* Output a symbolic value from the enum if found, else just print as int32. */
static bool textprinter_putenum(void *closure, const void *handler_data,
                                int32_t val) {
  upb_textprinter *p = closure;
  const upb_fielddef *f = handler_data;
  const upb_enumdef *enum_def = upb_downcast_enumdef(upb_fielddef_subdef(f));
  const char *label = upb_enumdef_iton(enum_def, val);
  if (label) {
    indent(p);
    putf(p, "%s: %s", upb_fielddef_name(f), label);
    endfield(p);
  } else {
    if (!textprinter_putint32(closure, handler_data, val))
      return false;
  }
  return true;
}
コード例 #19
0
ファイル: handlers.c プロジェクト: YauzZ/upb
// Checks whether the START* handler specified by f & type is missing even
// though it is required to convert the established type of an outer frame
// ("closure_type") into the established type of an inner frame (represented in
// the return closure type of this handler's attr.
bool checkstart(upb_handlers *h, const upb_fielddef *f, upb_handlertype_t type,
                upb_status *status) {
  upb_selector_t sel = getsel(h, f, type);
  if (h->table[sel].func) return true;
  const void *closure_type = effective_closure_type(h, f, type);
  const upb_handlerattr *attr = &h->table[sel].attr;
  const void *return_closure_type = upb_handlerattr_returnclosuretype(attr);
  if (closure_type && return_closure_type &&
      closure_type != return_closure_type) {
    upb_status_seterrf(status,
                       "expected start handler to return sub type for field %f",
                       upb_fielddef_name(f));
    return false;
  }
  return true;
}
コード例 #20
0
ファイル: message.c プロジェクト: hack0303/protobuf
/*
 * call-seq:
 *     Message.to_h => {}
 *
 * Returns the message as a Ruby Hash object, with keys as symbols.
 */
VALUE Message_to_h(VALUE _self) {
  MessageHeader* self;
  VALUE hash;
  upb_msg_field_iter it;
  TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);

  hash = rb_hash_new();

  for (upb_msg_field_begin(&it, self->descriptor->msgdef);
       !upb_msg_field_done(&it);
       upb_msg_field_next(&it)) {
    const upb_fielddef* field = upb_msg_iter_field(&it);

    // For proto2, do not include fields which are not set.
    if (upb_msgdef_syntax(self->descriptor->msgdef) == UPB_SYNTAX_PROTO2 &&
	field_contains_hasbit(self->descriptor->layout, field) &&
	!layout_has(self->descriptor->layout, Message_data(self), field)) {
      continue;
    }

    VALUE msg_value = layout_get(self->descriptor->layout, Message_data(self),
                                 field);
    VALUE msg_key   = ID2SYM(rb_intern(upb_fielddef_name(field)));
    if (is_map_field(field)) {
      msg_value = Map_to_h(msg_value);
    } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
      msg_value = RepeatedField_to_ary(msg_value);
      if (upb_msgdef_syntax(self->descriptor->msgdef) == UPB_SYNTAX_PROTO2 &&
          RARRAY_LEN(msg_value) == 0) {
        continue;
      }

      if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE) {
        for (int i = 0; i < RARRAY_LEN(msg_value); i++) {
          VALUE elem = rb_ary_entry(msg_value, i);
          rb_ary_store(msg_value, i, Message_to_h(elem));
        }
      }

    } else if (msg_value != Qnil &&
               upb_fielddef_type(field) == UPB_TYPE_MESSAGE) {
      msg_value = Message_to_h(msg_value);
    }
    rb_hash_aset(hash, msg_key, msg_value);
  }
  return hash;
}
コード例 #21
0
ファイル: message.c プロジェクト: goodleon/protobuf
VALUE Message_to_h(VALUE _self) {
  MessageHeader* self;
  TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);

  VALUE hash = rb_hash_new();

  upb_msg_field_iter it;
  for (upb_msg_field_begin(&it, self->descriptor->msgdef);
       !upb_msg_field_done(&it);
       upb_msg_field_next(&it)) {
    const upb_fielddef* field = upb_msg_iter_field(&it);
    VALUE msg_value = layout_get(self->descriptor->layout, Message_data(self), field);
    VALUE msg_key   = ID2SYM(rb_intern(upb_fielddef_name(field)));
    if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
      msg_value = RepeatedField_to_ary(msg_value);
    }
    rb_hash_aset(hash, msg_key, msg_value);
  }
  return hash;
}
コード例 #22
0
ファイル: def.c プロジェクト: imageoptimiser/upb
upb_fielddef *upb_fielddef_dup(const upb_fielddef *f, const void *owner) {
  upb_fielddef *newf = upb_fielddef_new(owner);
  if (!newf) return NULL;
  upb_fielddef_settype(newf, upb_fielddef_type(f));
  upb_fielddef_setlabel(newf, upb_fielddef_label(f));
  upb_fielddef_setnumber(newf, upb_fielddef_number(f));
  upb_fielddef_setname(newf, upb_fielddef_name(f));
  if (f->default_is_string) {
    upb_byteregion *r = upb_value_getbyteregion(upb_fielddef_default(f));
    size_t len;
    const char *ptr = upb_byteregion_getptr(r, 0, &len);
    assert(len == upb_byteregion_len(r));
    upb_fielddef_setdefaultstr(newf, ptr, len);
  } else {
    upb_fielddef_setdefault(newf, upb_fielddef_default(f));
  }

  const char *srcname;
  if (f->subdef_is_symbolic) {
    srcname = f->sub.name;  // Might be NULL.
  } else {
    srcname = f->sub.def ? upb_def_fullname(f->sub.def) : NULL;
  }
  if (srcname) {
    char *newname = malloc(strlen(f->sub.def->fullname) + 2);
    if (!newname) {
      upb_fielddef_unref(newf, owner);
      return NULL;
    }
    strcpy(newname, ".");
    strcat(newname, f->sub.def->fullname);
    upb_fielddef_setsubdefname(newf, newname);
    free(newname);
  }

  return newf;
}
コード例 #23
0
ファイル: storage.c プロジェクト: acozzette/protobuf
VALUE layout_inspect(MessageLayout* layout, void* storage) {
  VALUE str = rb_str_new2("");

  upb_msg_field_iter it;
  bool first = true;
  for (upb_msg_field_begin(&it, layout->msgdef);
       !upb_msg_field_done(&it);
       upb_msg_field_next(&it)) {
    const upb_fielddef* field = upb_msg_iter_field(&it);
    VALUE field_val = layout_get(layout, storage, field);

    if (!first) {
      str = rb_str_cat2(str, ", ");
    } else {
      first = false;
    }
    str = rb_str_cat2(str, upb_fielddef_name(field));
    str = rb_str_cat2(str, ": ");

    str = rb_str_append(str, rb_funcall(field_val, rb_intern("inspect"), 0));
  }

  return str;
}
コード例 #24
0
ファイル: defs.c プロジェクト: Overruler/protobuf
/*
 * call-seq:
 *     FieldDescriptor.name => name
 *
 * Returns the name of this field.
 */
VALUE FieldDescriptor_name(VALUE _self) {
  DEFINE_SELF(FieldDescriptor, self, _self);
  return rb_str_maybe_null(upb_fielddef_name(self->fielddef));
}