/*
* call-seq:
* multicast(message, groups, service_type, [msg_type], [self_discard]) -> nil
*
* Broadcast +message+ to +groups+, using the service type
* +service_type+. +groups+ is either a String specifying a single
* group name, or an Array of Strings specifying the list of group
* names. +service_type+ specifies the desired ordering guarantee for
* the message (which are available as constants in the Spread
* module). For more information on the delivery guarantees provided
* by Spread, see the Spread documentation.
*
* +msg_type+ is the "message type" of the message; this is an
* arbitrary application-defined value. If not specified, it defaults
* to 0. The message type of a received data message can be accessed
* via Spread::DataMessage#msg_type.
*
* If +self_discard+ is +true+, the message will not be delivered to
* the sending node. Otherwise, the message will be delivered if the
* sending node belongs to the group it is sending the message to.
*
* rb_spread imposes no upper limit on message size. By default,
* Spread itself will reject messages larger than about 144,000 bytes;
* this limit can be raised by recompiling Spread. If a message is
* larger than Spread's maximum message size,
* Spread::Error::MessageTooLong will be raised.
*/
static VALUE
spconn_multicast(int argc, VALUE *argv, VALUE obj)
{
VALUE message, group, st, mtype, self_discard;
struct SpreadConnection *sp;
int n;
int service_type;
Data_Get_Struct(obj, struct SpreadConnection, sp);
rb_scan_args(argc, argv, "32", &message, &group, &st, &mtype, &self_discard);
if (NIL_P(mtype))
mtype = INT2FIX(0);
service_type = NUM2INT(st);
if (RTEST(self_discard))
service_type |= SELF_DISCARD;
SafeStringValue(message);
if (TYPE(group) == T_ARRAY)
{
char groupnames[MAX_GROUPS][MAX_GROUP_NAME];
int i;
if (RARRAY(group)->len == 0)
return Qnil;
if (RARRAY(group)->len >= MAX_GROUPS)
rb_raise(rb_eArgError, "too many groups for multicast");
for (i = 0; i < RARRAY(group)->len; i++)
{
VALUE tmp = RARRAY(group)->ptr[i];
snprintf(groupnames[i], MAX_GROUP_NAME, "%s",
StringValuePtr(tmp));
}
if ((n = SP_multigroup_multicast(sp->mbox, service_type,
RARRAY(group)->len,
(const char (*)[]) groupnames,
NUM2INT(mtype),
RSTRING(message)->len,
RSTRING(message)->ptr)) < 0)
raise_sp_error(n);
}
else
{
/* `group' must be a string or equivalent, raise type error if not */
if ((n = SP_multicast(sp->mbox,
service_type,
StringValuePtr(group),
NUM2INT(mtype),
RSTRING(message)->len,
RSTRING(message)->ptr)) < 0)
raise_sp_error(n);
}
return Qnil;
}