/*
* call-seq:
* Mod.new(mod_type, attr, vals) => LDAP::Mod
*
* Create a new LDAP::Mod object of type +mod_type+. This is most commonly
* *LDAP_MOD_ADD*, *LDAP_MOD_REPLACE* or *LDAP_MOD_DELETE*, although some LDAP
* servers may offer extension types.
*
* +attr+ should be the name of the attribute on which to operate, whilst
* +vals+ is an array of values pertaining to +attr+. If +vals+ contains
* binary data, +mod_type+ should be logically OR'ed (|) with
* *LDAP_MOD_BVALUES*.
*
* LDAP::Mod objects can be passed to methods in the LDAP::Conn class, such as
* Conn#add, Conn#add_ext, Conn#modify and Conn#modify_ext.
*/
static VALUE
rb_ldap_mod_initialize (int argc, VALUE argv[], VALUE self)
{
struct berval **bvals;
char **strvals;
int mod_op;
char *mod_type;
int i;
VALUE op, type, vals;
RB_LDAPMOD_DATA *moddata;
rb_scan_args (argc, argv, "3", &op, &type, &vals);
Data_Get_Struct (self, RB_LDAPMOD_DATA, moddata);
if (moddata->mod)
return Qnil;
mod_op = NUM2INT (op);
mod_type = StringValueCStr (type);
Check_Type (vals, T_ARRAY);
if (mod_op & LDAP_MOD_BVALUES)
{
bvals = ALLOC_N (struct berval *, RARRAY (vals)->len + 1);
for (i = 0; i < RARRAY (vals)->len; i++)
{
VALUE str;
struct berval *bval;
str = RARRAY (vals)->ptr[i];
Check_Type (str, T_STRING);
bval = ALLOC_N (struct berval, 1);
bval->bv_len = RSTRING (str)->len;
RB_LDAP_SET_STR (bval->bv_val, str);
bvals[i] = bval;
}
bvals[i] = NULL;
moddata->mod = rb_ldap_new_mod2 (mod_op, mod_type, bvals);
}
else
{
strvals = ALLOC_N (char *, RARRAY (vals)->len + 1);
for (i = 0; i < RARRAY (vals)->len; i++)
{
VALUE str;
char *sval;
str = RARRAY (vals)->ptr[i];
RB_LDAP_SET_STR (sval, str);
strvals[i] = sval;
}
strvals[i] = NULL;
moddata->mod = rb_ldap_new_mod (mod_op, mod_type, strvals);
}
return Qnil;
}