Beispiel #1
0
func Curves(basis string, spans []int,
	wrap string, varargs ...interface{}) {
	pBasis := C.CString(basis)
	defer C.free(unsafe.Pointer(pBasis))
	pWrap := C.CString(wrap)
	defer C.free(unsafe.Pointer(pWrap))
	names, values, ownership := unzipArgs(varargs...)
	defer freeArgs(names, ownership)
	nArgs := C.RtInt(len(varargs) / 2)
	nSpans := C.RtInt(len(spans))
	pSpans := (*C.RtInt)(C.RtPointer(&spans[0]))
	pNames, pVals := safeArgs(names, values)
	C.RiCurvesV(pBasis, nSpans, pSpans,
		pWrap, nArgs, pNames, pVals)
}
Beispiel #2
0
func unzipArgs(varargs ...interface{}) (names rtTokens,
	vals rtPointers, owned rawPointers) {

	if len(varargs)%2 != 0 {
		fmt.Println("odd number of arguments")
		return
	}

	nArgs := len(varargs) / 2
	names = make(rtTokens, nArgs)
	vals = make(rtPointers, nArgs)
	owned = make(rawPointers, nArgs)

	var pname string
	for i, v := range varargs {

		// Even-numbered arguments are parameter names
		if i%2 == 0 {
			if stringified, ok := v.(string); ok {
				pname = stringified
				token := C.CString(pname)
				names[i/2] = token
			} else {
				fmt.Printf("argument %d is not a string\n", i)
				return
			}
			continue
		}

		// Odd-numbered arguments are values
		switch v.(type) {
		case bool:
			boolified := v.(bool)
			var intified int32 = 0
			if boolified {
				intified = 1
			}
			vals[i/2] = C.RtPointer(&intified)
		case int, int32:
			intified := v.(int)
			vals[i/2] = C.RtPointer(&intified)
		case [3]float32:
			floatified := v.([3]float32)
			vals[i/2] = C.RtPointer(&floatified[0])
		case [4]float32:
			floatified := v.([4]float32)
			vals[i/2] = C.RtPointer(&floatified[0])
		case []float32:
			floatified := v.([]float32)
			vals[i/2] = C.RtPointer(&floatified[0])
		case float32:
			floatified := v.(float32)
			vals[i/2] = C.RtPointer(&floatified)
		case float64:
			floatified := float32(v.(float64))
			vals[i/2] = C.RtPointer(&floatified)
		case string:
			stringified := v.(string)
			token := C.CString(stringified)
			vals[i/2] = C.RtPointer(&token)
			owned[i/2] = unsafe.Pointer(token)
		default:
			m := fmt.Sprintf("'%s' has unknown type %T\n", pname, v)
			panic(m)
		}
	}
	return
}