Ejemplo n.º 1
0
static Arg * minc_list_to_arglist(const char *funcname, const MincValue *inList, const int inListLen, Arg *inArgs, int *pNumArgs)
{
	int oldNumArgs = *pNumArgs;
	int n = 0, newNumArgs = oldNumArgs + inListLen;
	// Create expanded array
	Arg *newArgs = new Arg[newNumArgs];
	if (newArgs == NULL)
		return NULL;
	if (inArgs != NULL) {
		// Copy existing args to new array
		for (; n < oldNumArgs; ++n) {
			newArgs[n] = inArgs[n];
		}
	}
	for (int i = 0; n < newNumArgs; ++i, ++n) {
		switch (inList[i].dataType()) {
			case MincVoidType:
				minc_die("call_external_function: %s(): invalid argument type", funcname);
				delete [] newArgs;
				return NULL;
			case MincFloatType:
				newArgs[n] = (MincFloat) inList[i];
				break;
			case MincStringType:
				newArgs[n] = (MincString)inList[i];
				break;
			case MincHandleType:
				newArgs[n] = (Handle) (MincHandle)inList[i];
				break;
			case MincListType:
				if ((MincList *)inList[i] == NULL) {
					minc_die("can't pass a null list (arg %d) to RTcmix function %s()", n, funcname);
					return NULL;
				}
				if (((MincList *)inList[i])->len <= 0) {
					minc_die("can't pass an empty list (arg %d) to RTcmix function %s()", n, funcname);
					delete [] newArgs;
					return NULL;
				}
				else {
					minc_die("for now, no nested lists can be passed to RTcmix function %s()", funcname);
					delete [] newArgs;
					return NULL;
				}
		}
	}
	*pNumArgs = newNumArgs;
	return newArgs;
}
Ejemplo n.º 2
0
int
call_external_function(const char *funcname, const MincValue arglist[],
	const int nargs, MincValue *return_value)
{
	int result, numArgs = nargs;
	Arg retval;

	Arg *rtcmixargs = new Arg[nargs];
	if (rtcmixargs == NULL)
		return MEMORY_ERROR;

	// Convert arglist for passing to RTcmix function.
	for (int i = 0; i < nargs; i++) {
		switch (arglist[i].dataType()) {
		case MincFloatType:
			rtcmixargs[i] = (MincFloat)arglist[i];
			break;
		case MincStringType:
			rtcmixargs[i] = (MincString)arglist[i];
			break;
		case MincHandleType:
			rtcmixargs[i] = (Handle) (MincHandle)arglist[i];
#ifdef EMBEDDED
			if ((Handle)rtcmixargs[i] == NULL) {
				minc_die("can't pass a null handle (arg %d) to RTcmix function %s()", i, funcname);
				return PARAM_ERROR;
			}
#endif
			break;
		case MincListType:
			{
			MincList *list = (MincList *)arglist[i];
			if (list == NULL) {
				minc_die("can't pass a null list (arg %d) to RTcmix function %s()", i, funcname);
				return PARAM_ERROR;
			}
			if (list->len <= 0) {
				minc_die("can't pass an empty list (arg %d) to RTcmix function %s()", i, funcname);
				return PARAM_ERROR;
			}
			// If list is final argument to function, treat its contents as additional function arguments
			if (i == nargs-1) {
				int argCount = i;
				Arg *newargs = minc_list_to_arglist(funcname, list->data, list->len, rtcmixargs, &argCount);
				delete [] rtcmixargs;
				if (newargs == NULL)
					return -1;
				rtcmixargs = newargs;
				numArgs = argCount;
			}
			// If list contains only floats, convert and pass it along.
			else {
				Array *newarray = (Array *) emalloc(sizeof(Array));
				if (newarray == NULL)
					return MEMORY_ERROR;
				assert(sizeof(*newarray->data) == sizeof(double));	// because we cast MincFloat to double here
				newarray->data = (double *) float_list_to_array(list);
				if (newarray->data != NULL) {
					newarray->len = list->len;
					rtcmixargs[i] = newarray;
				}
				else {
					minc_die("can't pass a mixed-type list (arg %d) to RTcmix function %s()", i, funcname);
					free(newarray);
					return PARAM_ERROR;
				}
			}
			}
			break;
		default:
			minc_die("call_external_function: %s(): arg %d: invalid argument type",
					 funcname, i);
			return PARAM_ERROR;
			break;
		}
	}

	result = RTcmix::dispatch(funcname, rtcmixargs, numArgs, &retval);
   
	// Convert return value from RTcmix function.
	switch (retval.type()) {
	case DoubleType:
		*return_value = (MincFloat) retval;
		break;
	case StringType:
		*return_value = (MincString) retval;
		break;
	case HandleType:
		*return_value = (MincHandle) (Handle) retval;
		break;
	case ArrayType:
#ifdef NOMORE
// don't think functions will return non-opaque arrays to Minc, but if they do,
// these should be converted to MincListType
		return_value->type = MincArrayType;
		{
			Array *array = (Array *) retval;
			return_value->val.array.len = array->len;
			return_value->val.array.data = array->data;
		}
#endif
		break;
	default:
		break;
	}

	delete [] rtcmixargs;

	return result;
}
Ejemplo n.º 3
0
int
call_external_function(const char *funcname, const MincListElem arglist[],
	const int nargs, MincListElem *return_value)
{
	int i, result;
	Arg retval;

	Arg *rtcmixargs = new Arg[nargs];
	if (rtcmixargs == NULL)
		return -1;

	// Convert arglist for passing to RTcmix function.
	for (i = 0; i < nargs; i++) {
		switch (arglist[i].type) {
		case MincFloatType:
			rtcmixargs[i] = arglist[i].val.number;
			break;
		case MincStringType:
			rtcmixargs[i] = arglist[i].val.string;
			break;
		case MincHandleType:
			rtcmixargs[i] = (Handle) arglist[i].val.handle;
			break;
		case MincListType:
			// If list contains only floats, convert and pass it along.
			// Otherwise, it's an error.
			{
				Array *newarray = (Array *) emalloc(sizeof(Array));
				if (newarray == NULL)
					return -1;
				assert(sizeof(*newarray->data) == sizeof(double));	// because we cast MincFloat to double here
				newarray->data = (double *) float_list_to_array(arglist[i].val.list);
				if (newarray->data != NULL) {
					newarray->len = arglist[i].val.list->len;
					rtcmixargs[i] = newarray;
				}
				else {
					minc_die("can't pass an empty or mixed-type list to RTcmix function %s()", funcname);
					free(newarray);
					return -1;
				}
			}
			break;
		default:
			minc_die("call_external_function: %s(): invalid argument type",
					 funcname);
			return -1;
			break;
		}
	}

	result = RTcmix::dispatch(funcname, rtcmixargs, nargs, &retval);
   
	// Convert return value from RTcmix function.
	switch (retval.type()) {
	case DoubleType:
		return_value->type = MincFloatType;
		return_value->val.number = (MincFloat) retval;
		break;
	case StringType:
		return_value->type = MincStringType;
		return_value->val.string = (MincString) retval;
		break;
	case HandleType:
		return_value->type = MincHandleType;
		return_value->val.handle = (MincHandle) (Handle) retval;
		if (return_value->val.handle) {
			ref_handle(return_value->val.handle);
		}
		break;
	case ArrayType:
#ifdef NOMORE
// don't think functions will return non-opaque arrays to Minc, but if they do,
// these should be converted to MincListType
		return_value->type = MincArrayType;
		{
			Array *array = (Array *) retval;
			return_value->val.array.len = array->len;
			return_value->val.array.data = array->data;
		}
#endif
		break;
	default:
		break;
	}

	delete [] rtcmixargs;

	return result;
}