*/
static void mruby_ruby_to_pair_value(mrb_state *mrb, mrb_value *value, fr_pair_t *vp)
{
- switch (vp->vp_type) {
- case FR_TYPE_STRING:
- *value = mrb_obj_as_string(mrb, *value);
- fr_pair_value_clear(vp);
- fr_pair_value_bstrndup(vp, RSTRING_PTR(*value), RSTRING_LEN(*value), true);
- break;
+ fr_value_box_t *vb = NULL;
- case FR_TYPE_OCTETS:
- *value = mrb_obj_as_string(mrb, *value);
- fr_pair_value_clear(vp);
- fr_pair_value_memdup(vp, (uint8_t *)RSTRING_PTR(*value), RSTRING_LEN(*value), true);
+ /*
+ * Convert the type provided by mRuby to the largest containing FreeRADIUS type
+ */
+ switch (mrb_type(*value)) {
+ case MRB_TT_INTEGER:
+ MEM(vb = fr_value_box_alloc(NULL, FR_TYPE_INT64, NULL));
+ vb->vb_int64 = mrb_integer(*value);
break;
-#define RUBYSETINT(_size) case FR_TYPE_INT ## _size: \
- if (mrb_type(*value) != MRB_TT_INTEGER) mrb_raise(mrb, E_ARGUMENT_ERROR, "Integer value required"); \
- vp->vp_int ## _size = mrb_integer(*value); \
- break;
- RUBYSETINT(8)
- RUBYSETINT(16)
- RUBYSETINT(32)
- RUBYSETINT(64)
-
-#define RUBYSETUINT(_size) case FR_TYPE_UINT ## _size: \
- if (mrb_type(*value) != MRB_TT_INTEGER) mrb_raise(mrb, E_ARGUMENT_ERROR, "Integer value required"); \
- vp->vp_uint ## _size = mrb_integer(*value); \
- break;
- RUBYSETUINT(8)
- RUBYSETUINT(16)
- RUBYSETUINT(32)
- RUBYSETUINT(64)
-
-#define RUBYSETFLOAT(_size) case FR_TYPE_FLOAT ## _size: \
- switch (mrb_type(*value)) { \
- case MRB_TT_FLOAT: \
- vp->vp_float ## _size = mrb_float(*value); \
- break; \
- case MRB_TT_INTEGER: \
- vp->vp_float ## _size = mrb_integer(*value); \
- break; \
- default: \
- mrb_raise(mrb, E_ARGUMENT_ERROR, "Float or integer value required"); \
- } \
- break;
- RUBYSETFLOAT(32)
- RUBYSETFLOAT(64)
-
- case FR_TYPE_SIZE:
- if (mrb_type(*value) != MRB_TT_INTEGER) {
- mrb_raise(mrb, E_ARGUMENT_ERROR, "Integer value required");
- }
- vp->vp_size = mrb_integer(*value);
+ case MRB_TT_FLOAT:
+ MEM(vb = fr_value_box_alloc(NULL, FR_TYPE_FLOAT64, NULL));
+ vb->vb_float64 = mrb_float(*value);
break;
- case FR_TYPE_BOOL:
- if (mrb_type(*value) == MRB_TT_TRUE) {
- vp->vp_bool = true;
- } else if (mrb_type(*value) == MRB_TT_FALSE) {
- vp->vp_bool = false;
- } else {
- mrb_raise(mrb, E_ARGUMENT_ERROR, "Boolean value required");
- }
+ case MRB_TT_STRING:
+ MEM(vb = fr_value_box_alloc(NULL, FR_TYPE_STRING, NULL));
+ fr_value_box_bstrndup_dbuff(vb, vb, NULL,
+ &FR_DBUFF_TMP((uint8_t *)RSTRING_PTR(*value), RSTRING_LEN(*value)),
+ RSTRING_LEN(*value), true);
break;
- case FR_TYPE_ETHERNET:
- case FR_TYPE_IPV4_ADDR:
- case FR_TYPE_IPV6_ADDR:
- case FR_TYPE_IPV4_PREFIX:
- case FR_TYPE_IPV6_PREFIX:
- case FR_TYPE_COMBO_IP_ADDR:
- case FR_TYPE_COMBO_IP_PREFIX:
- case FR_TYPE_IFID:
- case FR_TYPE_TIME_DELTA:
- case FR_TYPE_DATE:
- case FR_TYPE_ATTR:
-
- *value = mrb_obj_as_string(mrb, *value);
- if (fr_pair_value_from_str(vp, RSTRING_PTR(*value), RSTRING_LEN(*value), NULL, false) < 0) {
- mrb_raise(mrb, E_RUNTIME_ERROR, "Failed populating pair");
- }
+ case MRB_TT_TRUE:
+ MEM(vb = fr_value_box_alloc(NULL, FR_TYPE_BOOL, NULL));
+ vb->vb_bool = true;
break;
- case FR_TYPE_NON_LEAF:
- fr_assert(0);
+ case MRB_TT_FALSE:
+ MEM(vb = fr_value_box_alloc(NULL, FR_TYPE_BOOL, NULL));
+ vb->vb_bool = false;
break;
+
+ default:
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "Unsupported value type");
+ }
+
+ /*
+ * Cast the converted value to the required type for the pair
+ */
+ fr_pair_value_clear(vp);
+ if (fr_value_box_cast(vp, &vp->data, vp->vp_type, vp->da, vb) < 0) {
+ talloc_free(vb);
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "Failed casting ruby value to %s", fr_type_to_str(vp->vp_type));
}
+ talloc_free(vb);
}
/** Set a value pair from mruby