use of org.bytedeco.javacpp.annotation.ByVal in project javacpp by bytedeco.
the class Generator method parametersBefore.
void parametersBefore(MethodInformation methodInfo) {
String adapterLine = "";
AdapterInformation prevAdapterInfo = null;
int skipParameters = methodInfo.parameterTypes.length > 0 && methodInfo.parameterTypes[0] == Class.class ? 1 : 0;
for (int j = skipParameters; j < methodInfo.parameterTypes.length; j++) {
if (!methodInfo.parameterTypes[j].isPrimitive()) {
Annotation passBy = by(methodInfo, j);
String cast = cast(methodInfo, j);
String[] typeName = methodInfo.parameterRaw[j] ? new String[] { "" } : cppTypeName(methodInfo.parameterTypes[j]);
AdapterInformation adapterInfo = methodInfo.parameterRaw[j] ? null : adapterInformation(false, methodInfo, j);
if (Enum.class.isAssignableFrom(methodInfo.parameterTypes[j])) {
accessesEnums = true;
String s = enumValueType(methodInfo.parameterTypes[j]);
if (s != null) {
String S = Character.toUpperCase(s.charAt(0)) + s.substring(1);
out.println(" if (arg" + j + " == NULL) {");
out.println(" env->ThrowNew(JavaCPP_getClass(env, " + jclasses.index(NullPointerException.class) + "), \"Enum for argument " + j + " is NULL.\");");
out.println(" return" + (methodInfo.returnType == void.class ? ";" : " 0;"));
out.println(" }");
out.println(" " + typeName[0] + " val" + j + typeName[1] + " = (" + typeName[0] + typeName[1] + ")env->Get" + S + "Field(arg" + j + ", JavaCPP_" + s + "ValueFID);");
}
continue;
}
if (FunctionPointer.class.isAssignableFrom(methodInfo.parameterTypes[j])) {
functions.index(methodInfo.parameterTypes[j]);
if (methodInfo.parameterTypes[j] == FunctionPointer.class) {
logger.warn("Method \"" + methodInfo.method + "\" has an abstract FunctionPointer parameter, " + "but a concrete subclass is required. Compilation will most likely fail.");
}
typeName[0] = functionClassName(methodInfo.parameterTypes[j]) + "*";
typeName[1] = "";
}
if (typeName[0].length() == 0 || methodInfo.parameterRaw[j]) {
methodInfo.parameterRaw[j] = true;
typeName[0] = jniTypeName(methodInfo.parameterTypes[j]);
out.println(" " + typeName[0] + " ptr" + j + " = arg" + j + ";");
continue;
}
if ("void*".equals(typeName[0]) && !methodInfo.parameterTypes[j].isAnnotationPresent(Opaque.class)) {
typeName[0] = "char*";
}
out.print(" " + typeName[0] + " ptr" + j + typeName[1] + " = ");
if (Pointer.class.isAssignableFrom(methodInfo.parameterTypes[j])) {
out.println("arg" + j + " == NULL ? NULL : (" + typeName[0] + typeName[1] + ")jlong_to_ptr(env->GetLongField(arg" + j + ", JavaCPP_addressFID));");
if ((j == 0 && FunctionPointer.class.isAssignableFrom(methodInfo.cls) && methodInfo.cls.isAnnotationPresent(Namespace.class)) || (passBy instanceof ByVal && ((ByVal) passBy).nullValue().length() == 0) || (passBy instanceof ByRef && ((ByRef) passBy).nullValue().length() == 0)) {
// in the case of member ptr, ptr0 is our object pointer, which cannot be NULL
out.println(" if (ptr" + j + " == NULL) {");
out.println(" env->ThrowNew(JavaCPP_getClass(env, " + jclasses.index(NullPointerException.class) + "), \"Pointer address of argument " + j + " is NULL.\");");
out.println(" return" + (methodInfo.returnType == void.class ? ";" : " 0;"));
out.println(" }");
}
if (adapterInfo != null || prevAdapterInfo != null) {
out.println(" jlong size" + j + " = arg" + j + " == NULL ? 0 : env->GetLongField(arg" + j + ", JavaCPP_limitFID);");
out.println(" void* owner" + j + " = JavaCPP_getPointerOwner(env, arg" + j + ");");
}
if (!methodInfo.parameterTypes[j].isAnnotationPresent(Opaque.class)) {
out.println(" jlong position" + j + " = arg" + j + " == NULL ? 0 : env->GetLongField(arg" + j + ", JavaCPP_positionFID);");
out.println(" ptr" + j + " += position" + j + ";");
if (adapterInfo != null || prevAdapterInfo != null) {
out.println(" size" + j + " -= position" + j + ";");
}
}
} else if (methodInfo.parameterTypes[j] == String.class) {
passesStrings = true;
out.println("JavaCPP_getStringBytes(env, arg" + j + ");");
if (adapterInfo != null || prevAdapterInfo != null) {
out.println(" jlong size" + j + " = 0;");
out.println(" void* owner" + j + " = (void*)ptr" + j + ";");
}
} else if (methodInfo.parameterTypes[j].isArray() && methodInfo.parameterTypes[j].getComponentType().isPrimitive()) {
out.print("arg" + j + " == NULL ? NULL : ");
String s = methodInfo.parameterTypes[j].getComponentType().getName();
if (methodInfo.valueGetter || methodInfo.valueSetter || methodInfo.memberGetter || methodInfo.memberSetter) {
out.println("(j" + s + "*)env->GetPrimitiveArrayCritical(arg" + j + ", NULL);");
} else {
s = Character.toUpperCase(s.charAt(0)) + s.substring(1);
out.println("env->Get" + s + "ArrayElements(arg" + j + ", NULL);");
}
if (adapterInfo != null || prevAdapterInfo != null) {
out.println(" jlong size" + j + " = arg" + j + " == NULL ? 0 : env->GetArrayLength(arg" + j + ");");
out.println(" void* owner" + j + " = (void*)ptr" + j + ";");
}
} else if (Buffer.class.isAssignableFrom(methodInfo.parameterTypes[j])) {
out.println("arg" + j + " == NULL ? NULL : (" + typeName[0] + typeName[1] + ")env->GetDirectBufferAddress(arg" + j + ");");
if (adapterInfo != null || prevAdapterInfo != null) {
out.println(" jlong size" + j + " = arg" + j + " == NULL ? 0 : env->GetDirectBufferCapacity(arg" + j + ");");
out.println(" void* owner" + j + " = (void*)ptr" + j + ";");
}
if (methodInfo.parameterTypes[j] != Buffer.class) {
// given the component type, we can also fetch the array of non-direct buffers
String paramName = methodInfo.parameterTypes[j].getSimpleName();
paramName = paramName.substring(0, paramName.length() - 6);
String paramNameLowerCase = Character.toLowerCase(paramName.charAt(0)) + paramName.substring(1);
out.println(" j" + paramNameLowerCase + "Array arr" + j + " = NULL;");
out.println(" if (arg" + j + " != NULL && ptr" + j + " == NULL) {");
out.println(" arr" + j + " = (j" + paramNameLowerCase + "Array)env->CallObjectMethod(arg" + j + ", JavaCPP_arrayMID);");
out.println(" if (env->ExceptionOccurred() != NULL) {");
out.println(" env->ExceptionClear();");
out.println(" } else {");
out.println(" ptr" + j + " = arr" + j + " == NULL ? NULL : env->Get" + paramName + "ArrayElements(arr" + j + ", NULL);");
if (adapterInfo != null || prevAdapterInfo != null) {
out.println(" size" + j + " = env->GetArrayLength(arr" + j + ");");
}
out.println(" }");
out.println(" }");
}
} else {
out.println("arg" + j + ";");
logger.warn("Method \"" + methodInfo.method + "\" has an unsupported parameter of type \"" + methodInfo.parameterTypes[j].getCanonicalName() + "\". Compilation will most likely fail.");
}
if (adapterInfo != null) {
usesAdapters = true;
adapterLine = " " + adapterInfo.name + " adapter" + j + "(";
prevAdapterInfo = adapterInfo;
}
if (prevAdapterInfo != null) {
if (!FunctionPointer.class.isAssignableFrom(methodInfo.cls)) {
// sometimes we need to use the Cast annotation for declaring functions only
adapterLine += cast;
}
adapterLine += "ptr" + j + ", size" + j + ", owner" + j;
if (--prevAdapterInfo.argc > 0) {
adapterLine += ", ";
}
}
if (prevAdapterInfo != null && prevAdapterInfo.argc <= 0) {
out.println(adapterLine + ");");
prevAdapterInfo = null;
}
}
}
}
use of org.bytedeco.javacpp.annotation.ByVal in project bigbluebutton by bigbluebutton.
the class Generator method call.
void call(MethodInformation methodInfo, String returnPrefix, boolean secondCall) {
boolean needSecondCall = false;
String indent = secondCall ? "" : methodInfo.throwsException != null ? " " : " ";
String prefix = "(";
String suffix = ")";
int skipParameters = methodInfo.parameterTypes.length > 0 && methodInfo.parameterTypes[0] == Class.class ? 1 : 0;
boolean index = methodInfo.method.isAnnotationPresent(Index.class) || (methodInfo.pairedMethod != null && methodInfo.pairedMethod.isAnnotationPresent(Index.class));
if (methodInfo.deallocator) {
out.println(indent + "void* allocatedAddress = jlong_to_ptr(arg0);");
out.println(indent + "void (*deallocatorAddress)(void*) = (void(*)(void*))jlong_to_ptr(arg1);");
out.println(indent + "if (deallocatorAddress != NULL && allocatedAddress != NULL) {");
out.println(indent + " (*deallocatorAddress)(allocatedAddress);");
out.println(indent + "}");
// nothing else should be appended here for deallocator
return;
} else if (methodInfo.valueGetter || methodInfo.valueSetter || methodInfo.memberGetter || methodInfo.memberSetter) {
boolean wantsPointer = false;
int k = methodInfo.parameterTypes.length - 1;
if ((methodInfo.valueSetter || methodInfo.memberSetter) && !(by(methodInfo, k) instanceof ByRef) && adapterInformation(false, methodInfo, k) == null && methodInfo.parameterTypes[k] == String.class) {
// special considerations for char arrays as strings
out.print(indent + "strcpy((char*)");
wantsPointer = true;
prefix = ", ";
} else if (k >= 1 && methodInfo.parameterTypes[0].isArray() && methodInfo.parameterTypes[0].getComponentType().isPrimitive() && (methodInfo.parameterTypes[1] == int.class || methodInfo.parameterTypes[1] == long.class)) {
// special considerations for primitive arrays
out.print(indent + "memcpy(");
wantsPointer = true;
prefix = ", ";
if (methodInfo.memberGetter || methodInfo.valueGetter) {
out.print("ptr0 + arg1, ");
} else {
// methodInfo.memberSetter || methodInfo.valueSetter
prefix += "ptr0 + arg1, ";
}
skipParameters = 2;
suffix = " * sizeof(*ptr0)" + suffix;
} else {
out.print(indent + returnPrefix);
prefix = methodInfo.valueGetter || methodInfo.memberGetter ? "" : " = ";
suffix = "";
}
if (Modifier.isStatic(methodInfo.modifiers)) {
out.print(cppScopeName(methodInfo));
} else if (methodInfo.memberGetter || methodInfo.memberSetter) {
if (index) {
out.print("(*ptr)");
prefix = "." + methodInfo.memberName[0] + prefix;
} else {
out.print("ptr->" + methodInfo.memberName[0]);
}
} else {
// methodInfo.valueGetter || methodInfo.valueSetter
out.print(index ? "(*ptr)" : methodInfo.dim > 0 || wantsPointer ? "ptr" : "*ptr");
}
} else if (methodInfo.bufferGetter) {
out.print(indent + returnPrefix + "ptr");
prefix = "";
suffix = "";
} else {
// function call
out.print(indent + returnPrefix);
if (FunctionPointer.class.isAssignableFrom(methodInfo.cls)) {
if (methodInfo.cls.isAnnotationPresent(Namespace.class)) {
out.print("(ptr0->*(ptr->ptr))");
skipParameters = 1;
} else {
out.print("(*ptr->ptr)");
}
} else if (methodInfo.allocator) {
String[] typeName = cppTypeName(methodInfo.cls);
String valueTypeName = valueTypeName(typeName);
if (virtualFunctions.containsKey(methodInfo.cls)) {
String subType = "JavaCPP_" + mangle(valueTypeName);
valueTypeName = subType;
}
if (methodInfo.cls == Pointer.class) {
// can't allocate a "void", so simply assign the argument instead
prefix = "";
suffix = "";
} else {
out.print((noException(methodInfo.cls, methodInfo.method) ? "new (std::nothrow) " : "new ") + valueTypeName + typeName[1]);
if (methodInfo.arrayAllocator) {
prefix = "[";
suffix = "]";
}
}
} else if (Modifier.isStatic(methodInfo.modifiers)) {
out.print(cppScopeName(methodInfo));
} else {
String name = methodInfo.memberName[0];
String[] typeName = cppTypeName(methodInfo.cls);
String valueTypeName = valueTypeName(typeName);
if (virtualFunctions.containsKey(methodInfo.cls) && !secondCall) {
String subType = "JavaCPP_" + mangle(valueTypeName);
if (Modifier.isPublic(methodInfo.method.getModifiers())) {
// non-protected method that could be from any subclass, so check for ours
out.print("(dynamic_cast<" + subType + "*>(ptr) != NULL ? ");
needSecondCall = true;
}
if (methodInfo.method.isAnnotationPresent(Virtual.class)) {
name = "super_" + name;
}
out.print("((" + subType + "*)ptr)->" + name);
} else if (index) {
out.print("(*ptr)");
prefix = "." + name + prefix;
} else {
String op = name.startsWith("operator") ? name.substring(8).trim() : "";
if (methodInfo.parameterTypes.length > 0 && (op.equals("=") || op.equals("+") || op.equals("-") || op.equals("*") || op.equals("/") || op.equals("%") || op.equals("==") || op.equals("!=") || op.equals("<") || op.equals(">") || op.equals("<=") || op.equals(">="))) {
out.print("((*ptr)");
prefix = op + prefix;
suffix += ")";
} else {
out.print("ptr->" + name);
}
}
}
}
for (int j = skipParameters; j <= methodInfo.parameterTypes.length; j++) {
if (j == skipParameters + methodInfo.dim) {
if (methodInfo.memberName.length > 1) {
out.print(methodInfo.memberName[1]);
}
out.print(prefix);
if (methodInfo.withEnv) {
out.print(Modifier.isStatic(methodInfo.modifiers) ? "env, cls" : "env, obj");
if (methodInfo.parameterTypes.length - skipParameters - methodInfo.dim > 0) {
out.print(", ");
}
}
}
if (j == methodInfo.parameterTypes.length) {
break;
}
if (j < skipParameters + methodInfo.dim) {
// print array indices to access array members, or whatever
// the C++ operator does with them when the Index annotation is present
out.print("[");
}
Annotation passBy = by(methodInfo, j);
String cast = cast(methodInfo, j);
AdapterInformation adapterInfo = methodInfo.parameterRaw[j] ? null : adapterInformation(false, methodInfo, j);
if (("(void*)".equals(cast) || "(void *)".equals(cast)) && methodInfo.parameterTypes[j] == long.class) {
out.print("jlong_to_ptr(arg" + j + ")");
} else if (methodInfo.parameterTypes[j].isPrimitive()) {
out.print(cast + "arg" + j);
} else if (adapterInfo != null) {
cast = adapterInfo.cast.trim();
if (cast.length() > 0 && !cast.startsWith("(") && !cast.endsWith(")")) {
cast = "(" + cast + ")";
}
out.print(cast + "adapter" + j);
j += adapterInfo.argc - 1;
} else if (FunctionPointer.class.isAssignableFrom(methodInfo.parameterTypes[j]) && !(passBy instanceof ByVal || passBy instanceof ByRef)) {
out.print(cast + "(ptr" + j + " == NULL ? NULL : " + (passBy instanceof ByPtrPtr ? "&ptr" : "ptr") + j + "->ptr)");
} else if (passBy instanceof ByVal || (passBy instanceof ByRef && methodInfo.parameterTypes[j] != String.class)) {
String nullValue = passBy instanceof ByVal ? ((ByVal) passBy).nullValue() : passBy instanceof ByRef ? ((ByRef) passBy).nullValue() : "";
out.print((nullValue.length() > 0 ? "ptr" + j + " == NULL ? " + nullValue + " : " : "") + "*" + cast + "ptr" + j);
} else if (passBy instanceof ByPtrPtr) {
out.print(cast + "(arg" + j + " == NULL ? NULL : &ptr" + j + ")");
} else {
// ByPtr || ByPtrRef || (ByRef && std::string)
out.print(cast + "ptr" + j);
}
if (j < skipParameters + methodInfo.dim) {
out.print("]");
} else if (j < methodInfo.parameterTypes.length - 1) {
out.print(", ");
}
}
out.print(suffix);
if (methodInfo.memberName.length > 2) {
out.print(methodInfo.memberName[2]);
}
if (by(methodInfo.annotations) instanceof ByRef && methodInfo.returnType == String.class) {
// special considerations for std::string
out.print(");\n" + indent + "rptr = rstr.c_str()");
}
if (needSecondCall) {
call(methodInfo, " : ", true);
out.print(")");
}
}
use of org.bytedeco.javacpp.annotation.ByVal in project bigbluebutton by bigbluebutton.
the class Generator method cppAnnotationTypeName.
String[] cppAnnotationTypeName(Class<?> type, Annotation... annotations) {
String[] typeName = cppCastTypeName(type, annotations);
String prefix = typeName[0];
String suffix = typeName[1];
boolean casted = false;
for (Annotation a : annotations) {
if ((a instanceof Cast && ((Cast) a).value()[0].length() > 0) || a instanceof Const) {
casted = true;
break;
}
}
Annotation by = by(annotations);
if (by instanceof ByVal) {
prefix = constValueTypeName(typeName);
} else if (by instanceof ByRef) {
prefix = constValueTypeName(typeName) + "&";
} else if (by instanceof ByPtrPtr && !casted) {
prefix = prefix + "*";
} else if (by instanceof ByPtrRef) {
prefix = prefix + "&";
}
// else ByPtr
typeName[0] = prefix;
typeName[1] = suffix;
return typeName;
}
use of org.bytedeco.javacpp.annotation.ByVal in project bigbluebutton by bigbluebutton.
the class Generator method methodInformation.
MethodInformation methodInformation(Method method) {
MethodInformation info = new MethodInformation();
info.cls = method.getDeclaringClass();
info.method = method;
info.annotations = method.getAnnotations();
info.modifiers = method.getModifiers();
info.returnType = method.getReturnType();
info.name = method.getName();
Name name = method.getAnnotation(Name.class);
info.memberName = name != null ? name.value() : new String[] { info.name };
Index index = method.getAnnotation(Index.class);
info.dim = index != null ? index.value() : 0;
info.parameterTypes = method.getParameterTypes();
info.parameterAnnotations = method.getParameterAnnotations();
info.returnRaw = method.isAnnotationPresent(Raw.class);
info.withEnv = info.returnRaw ? method.getAnnotation(Raw.class).withEnv() : false;
info.parameterRaw = new boolean[info.parameterAnnotations.length];
for (int i = 0; i < info.parameterAnnotations.length; i++) {
for (int j = 0; j < info.parameterAnnotations[i].length; j++) {
if (info.parameterAnnotations[i][j] instanceof Raw) {
info.parameterRaw[i] = true;
info.withEnv |= ((Raw) info.parameterAnnotations[i][j]).withEnv();
}
}
}
boolean canBeGetter = info.returnType != void.class || (info.parameterTypes.length > 0 && info.parameterTypes[0].isArray() && info.parameterTypes[0].getComponentType().isPrimitive());
boolean canBeSetter = (info.returnType == void.class || info.returnType == info.cls) && info.parameterTypes.length > 0;
boolean canBeAllocator = !Modifier.isStatic(info.modifiers) && info.returnType == void.class;
boolean canBeArrayAllocator = canBeAllocator && info.parameterTypes.length == 1 && (info.parameterTypes[0] == int.class || info.parameterTypes[0] == long.class);
boolean valueGetter = false;
boolean valueSetter = false;
boolean memberGetter = false;
boolean memberSetter = false;
boolean noReturnGetter = false;
Method pairedMethod = null;
for (Method method2 : info.cls.getDeclaredMethods()) {
MethodInformation info2 = annotationCache.get(method2);
if (info2 == null) {
annotationCache.put(method2, info2 = new MethodInformation());
info2.modifiers = method2.getModifiers();
info2.returnType = method2.getReturnType();
info2.name = method2.getName();
info2.parameterTypes = method2.getParameterTypes();
info2.annotations = method2.getAnnotations();
info2.parameterAnnotations = method2.getParameterAnnotations();
}
int skipParameters = info.parameterTypes.length > 0 && info.parameterTypes[0] == Class.class ? 1 : 0;
int skipParameters2 = info2.parameterTypes.length > 0 && info2.parameterTypes[0] == Class.class ? 1 : 0;
if (method.equals(method2) || !Modifier.isNative(info2.modifiers)) {
continue;
}
boolean canBeValueGetter = false;
boolean canBeValueSetter = false;
boolean canBeMemberGetter = false;
boolean canBeMemberSetter = false;
if (canBeGetter && "get".equals(info.name) && "put".equals(info2.name)) {
canBeValueGetter = true;
} else if (canBeSetter && "put".equals(info.name) && "get".equals(info2.name)) {
canBeValueSetter = true;
} else if (info2.name.equals(info.name)) {
info.overloaded = true;
canBeMemberGetter = canBeGetter;
canBeMemberSetter = canBeSetter;
for (int j = skipParameters; j < info.parameterTypes.length; j++) {
if (info.parameterTypes[j] != int.class && info.parameterTypes[j] != long.class) {
canBeMemberGetter = false;
if (j < info.parameterTypes.length - 1) {
canBeMemberSetter = false;
}
}
}
} else {
continue;
}
boolean sameIndexParameters = true;
for (int j = 0; j < info.parameterTypes.length - skipParameters && j < info2.parameterTypes.length - skipParameters2; j++) {
if (info.parameterTypes[j + skipParameters] != info2.parameterTypes[j + skipParameters2]) {
sameIndexParameters = false;
}
}
if (!sameIndexParameters) {
continue;
}
boolean parameterAsReturn = canBeValueGetter && info.parameterTypes.length > 0 && info.parameterTypes[0].isArray() && info.parameterTypes[0].getComponentType().isPrimitive();
boolean parameterAsReturn2 = canBeValueSetter && info2.parameterTypes.length > 0 && info2.parameterTypes[0].isArray() && info2.parameterTypes[0].getComponentType().isPrimitive();
if (canBeGetter && info2.parameterTypes.length - (parameterAsReturn ? 0 : 1) == info.parameterTypes.length - skipParameters && (parameterAsReturn ? info.parameterTypes[info.parameterTypes.length - 1] : info.returnType) == info2.parameterTypes[info2.parameterTypes.length - 1] && (info2.returnType == void.class || info2.returnType == info.cls) && (info2.parameterAnnotations[info2.parameterAnnotations.length - 1].length == 0 || (Arrays.equals(info2.parameterAnnotations[info2.parameterAnnotations.length - 1], info.annotations)))) {
pairedMethod = method2;
valueGetter = canBeValueGetter;
memberGetter = canBeMemberGetter;
noReturnGetter = parameterAsReturn;
} else if (canBeSetter && info.parameterTypes.length - (parameterAsReturn2 ? 0 : 1) == info2.parameterTypes.length - skipParameters2 && (parameterAsReturn2 ? info2.parameterTypes[info2.parameterTypes.length - 1] : info2.returnType) == info.parameterTypes[info.parameterTypes.length - 1] && (info.returnType == void.class || info.returnType == info.cls) && (info.parameterAnnotations[info.parameterAnnotations.length - 1].length == 0 || (Arrays.equals(info.parameterAnnotations[info.parameterAnnotations.length - 1], info2.annotations)))) {
pairedMethod = method2;
valueSetter = canBeValueSetter;
memberSetter = canBeMemberSetter;
}
}
Annotation behavior = behavior(info.annotations);
if (canBeGetter && behavior instanceof ValueGetter) {
info.valueGetter = true;
info.noReturnGetter = noReturnGetter;
} else if (canBeSetter && behavior instanceof ValueSetter) {
info.valueSetter = true;
} else if (canBeGetter && behavior instanceof MemberGetter) {
info.memberGetter = true;
info.noReturnGetter = noReturnGetter;
} else if (canBeSetter && behavior instanceof MemberSetter) {
info.memberSetter = true;
} else if (canBeAllocator && behavior instanceof Allocator) {
info.allocator = true;
} else if (canBeArrayAllocator && behavior instanceof ArrayAllocator) {
info.allocator = info.arrayAllocator = true;
} else if (behavior == null) {
// try to guess the behavior of the method
if (info.returnType == void.class && "deallocate".equals(info.name) && !Modifier.isStatic(info.modifiers) && info.parameterTypes.length == 2 && info.parameterTypes[0] == long.class && info.parameterTypes[1] == long.class) {
info.deallocator = true;
} else if (canBeAllocator && "allocate".equals(info.name)) {
info.allocator = true;
} else if (canBeArrayAllocator && "allocateArray".equals(info.name)) {
info.allocator = info.arrayAllocator = true;
} else if (info.returnType.isAssignableFrom(ByteBuffer.class) && "asDirectBuffer".equals(info.name) && !Modifier.isStatic(info.modifiers) && info.parameterTypes.length == 0) {
info.bufferGetter = true;
} else if (valueGetter) {
info.valueGetter = true;
info.noReturnGetter = noReturnGetter;
info.pairedMethod = pairedMethod;
} else if (valueSetter) {
info.valueSetter = true;
info.pairedMethod = pairedMethod;
} else if (memberGetter) {
info.memberGetter = true;
info.noReturnGetter = noReturnGetter;
info.pairedMethod = pairedMethod;
} else if (memberSetter) {
info.memberSetter = true;
info.pairedMethod = pairedMethod;
}
} else if (!(behavior instanceof Function)) {
logger.warn("Method \"" + method + "\" cannot behave like a \"" + behavior.annotationType().getSimpleName() + "\". No code will be generated.");
return null;
}
if (name == null && info.pairedMethod != null) {
name = info.pairedMethod.getAnnotation(Name.class);
if (name != null) {
info.memberName = name.value();
}
}
info.noOffset = info.cls.isAnnotationPresent(NoOffset.class) || method.isAnnotationPresent(NoOffset.class) || method.isAnnotationPresent(Index.class);
if (!info.noOffset && info.pairedMethod != null) {
info.noOffset = info.pairedMethod.isAnnotationPresent(NoOffset.class) || info.pairedMethod.isAnnotationPresent(Index.class);
}
if (info.parameterTypes.length == 0 || !info.parameterTypes[0].isArray()) {
if (info.valueGetter || info.memberGetter) {
info.dim = info.parameterTypes.length;
} else if (info.memberSetter || info.valueSetter) {
info.dim = info.parameterTypes.length - 1;
}
}
info.throwsException = null;
if (!noException(info.cls, method)) {
if ((by(info.annotations) instanceof ByVal && !noException(info.returnType, method)) || !info.deallocator && !info.valueGetter && !info.valueSetter && !info.memberGetter && !info.memberSetter && !info.bufferGetter) {
Class<?>[] exceptions = method.getExceptionTypes();
info.throwsException = exceptions.length > 0 ? exceptions[0] : RuntimeException.class;
}
}
return info;
}
use of org.bytedeco.javacpp.annotation.ByVal in project javacpp by bytedeco.
the class Generator method call.
void call(MethodInformation methodInfo, String returnPrefix, boolean secondCall) {
boolean needSecondCall = false;
String indent = secondCall ? "" : methodInfo.throwsException != null ? " " : " ";
String prefix = "(";
String suffix = ")";
int skipParameters = methodInfo.parameterTypes.length > 0 && methodInfo.parameterTypes[0] == Class.class ? 1 : 0;
Index index = methodInfo.method.getAnnotation(Index.class);
if (index == null && methodInfo.pairedMethod != null) {
index = methodInfo.pairedMethod.getAnnotation(Index.class);
}
if (methodInfo.deallocator) {
out.println(indent + "void* allocatedAddress = jlong_to_ptr(arg0);");
out.println(indent + "void (*deallocatorAddress)(void*) = (void(*)(void*))jlong_to_ptr(arg1);");
out.println(indent + "if (deallocatorAddress != NULL && allocatedAddress != NULL) {");
out.println(indent + " (*deallocatorAddress)(allocatedAddress);");
out.println(indent + "}");
// nothing else should be appended here for deallocator
return;
} else if (!FunctionPointer.class.isAssignableFrom(methodInfo.cls) && (methodInfo.valueGetter || methodInfo.valueSetter || methodInfo.memberGetter || methodInfo.memberSetter)) {
boolean wantsPointer = false;
int k = methodInfo.parameterTypes.length - 1;
if ((methodInfo.valueSetter || methodInfo.memberSetter) && !(by(methodInfo, k) instanceof ByRef) && adapterInformation(false, methodInfo, k) == null && methodInfo.parameterTypes[k] == String.class) {
// special considerations for char arrays as strings
out.print(indent + "strcpy((char*)");
wantsPointer = true;
prefix = ", ";
} else if (k >= 1 && methodInfo.parameterTypes[0].isArray() && methodInfo.parameterTypes[0].getComponentType().isPrimitive() && (methodInfo.parameterTypes[1] == int.class || methodInfo.parameterTypes[1] == long.class)) {
// special considerations for primitive arrays
out.print(indent + "memcpy(");
wantsPointer = true;
prefix = ", ";
if (methodInfo.memberGetter || methodInfo.valueGetter) {
out.print("ptr0 + arg1, ");
} else {
// methodInfo.memberSetter || methodInfo.valueSetter
prefix += "ptr0 + arg1, ";
}
skipParameters = 2;
suffix = " * sizeof(*ptr0)" + suffix;
} else {
out.print(indent + returnPrefix);
prefix = methodInfo.valueGetter || methodInfo.memberGetter ? "" : " = ";
suffix = "";
}
if (Modifier.isStatic(methodInfo.modifiers) || !Pointer.class.isAssignableFrom(methodInfo.cls)) {
out.print(cppScopeName(methodInfo));
} else if (methodInfo.memberGetter || methodInfo.memberSetter) {
if (index != null) {
out.print("(*ptr)");
prefix = "." + methodInfo.memberName[0] + prefix;
} else {
out.print("ptr->" + methodInfo.memberName[0]);
}
} else {
// methodInfo.valueGetter || methodInfo.valueSetter
String cast = cast(methodInfo.returnType, methodInfo.annotations);
if (index == null && cast.length() > 0) {
// make sure to cast the returned pointer and not the value
out.print("*(" + cast.substring(1, cast.length() - 1) + "*)&");
}
out.print(index != null ? "(*ptr)" : methodInfo.dim > 0 || wantsPointer ? "ptr" : "*ptr");
}
} else if (methodInfo.bufferGetter) {
out.print(indent + returnPrefix + "ptr");
prefix = "";
suffix = "";
} else {
// function call
out.print(indent + returnPrefix);
if (FunctionPointer.class.isAssignableFrom(methodInfo.cls)) {
if (methodInfo.cls.isAnnotationPresent(Namespace.class)) {
out.print("(ptr0->*(ptr->ptr))");
skipParameters = 1;
if (methodInfo.valueGetter || methodInfo.valueSetter) {
// this is get/put for a field pointer, not a real function
prefix = methodInfo.valueGetter ? "" : " = ";
suffix = "";
}
} else {
if (methodInfo.valueGetter || methodInfo.valueSetter) {
out.print("ptr->ptr");
prefix = methodInfo.valueGetter ? "" : " = ";
suffix = "";
} else {
out.print("(*ptr->ptr)");
}
}
} else if (methodInfo.allocator) {
String[] typeName = cppTypeName(methodInfo.cls);
String valueTypeName = valueTypeName(typeName);
if (virtualFunctions.containsKey(methodInfo.cls)) {
String subType = "JavaCPP_" + mangle(valueTypeName);
valueTypeName = subType;
}
if (methodInfo.cls == Pointer.class) {
// can't allocate a "void", so simply assign the argument instead
prefix = "";
suffix = "";
} else {
out.print((noException(methodInfo.cls, methodInfo.method) ? "new (std::nothrow) " : "new ") + valueTypeName + typeName[1]);
if (methodInfo.arrayAllocator) {
prefix = "[";
suffix = "]";
}
}
} else if (Modifier.isStatic(methodInfo.modifiers) || !Pointer.class.isAssignableFrom(methodInfo.cls)) {
out.print(cppScopeName(methodInfo));
} else {
String name = methodInfo.memberName[0];
String[] typeName = cppTypeName(methodInfo.cls);
String valueTypeName = valueTypeName(typeName);
if (virtualFunctions.containsKey(methodInfo.cls) && !secondCall) {
String subType = "JavaCPP_" + mangle(valueTypeName);
if (Modifier.isPublic(methodInfo.method.getModifiers())) {
// non-protected method that could be from any subclass, so check for ours
out.print("(dynamic_cast<" + subType + "*>(ptr) != NULL ? ");
needSecondCall = true;
}
if (methodInfo.method.isAnnotationPresent(Virtual.class)) {
name = "super_" + name;
}
out.print("((" + subType + "*)ptr)->" + name);
} else if (index != null) {
out.print("(*ptr)");
prefix = "." + name + prefix;
} else {
String op = name.startsWith("operator") ? name.substring(8).trim() : "";
if (methodInfo.parameterTypes.length > 0 && (op.equals("=") || op.equals("+") || op.equals("-") || op.equals("*") || op.equals("/") || op.equals("%") || op.equals("==") || op.equals("!=") || op.equals("<") || op.equals(">") || op.equals("<=") || op.equals(">="))) {
out.print("((*ptr)");
prefix = op + prefix;
suffix += ")";
} else {
out.print("ptr->" + name);
}
}
}
}
for (int j = skipParameters; j <= methodInfo.parameterTypes.length; j++) {
if (j == skipParameters + methodInfo.dim) {
if (methodInfo.memberName.length > 1) {
out.print(methodInfo.memberName[1]);
}
out.print(prefix);
if (methodInfo.withEnv) {
out.print(Modifier.isStatic(methodInfo.modifiers) ? "env, cls" : "env, obj");
if (methodInfo.parameterTypes.length - skipParameters - methodInfo.dim > 0) {
out.print(", ");
}
}
}
if (j == methodInfo.parameterTypes.length) {
break;
}
if (j < skipParameters + methodInfo.dim) {
// the C++ operator does with them when the Index annotation is present
if (index == null || index.function().length() == 0) {
out.print("[");
} else {
out.print("." + index.function() + "(");
}
}
Annotation passBy = by(methodInfo, j);
String cast = cast(methodInfo, j);
AdapterInformation adapterInfo = methodInfo.parameterRaw[j] ? null : adapterInformation(false, methodInfo, j);
if (FunctionPointer.class.isAssignableFrom(methodInfo.cls) && !methodInfo.cls.isAnnotationPresent(Namespace.class) && methodInfo.valueSetter) {
String[] typeName = cppTypeName(methodInfo.cls);
cast = "(" + typeName[0] + typeName[1] + ")";
}
if (Enum.class.isAssignableFrom(methodInfo.parameterTypes[j])) {
accessesEnums = true;
out.print(cast + "val" + j);
} else if (("(void*)".equals(cast) || "(void *)".equals(cast)) && methodInfo.parameterTypes[j] == long.class) {
out.print("jlong_to_ptr(arg" + j + ")");
} else if (methodInfo.parameterTypes[j].isPrimitive()) {
out.print(cast + "arg" + j);
} else if (adapterInfo != null) {
cast = adapterInfo.cast.trim();
if (cast.length() > 0 && !cast.startsWith("(") && !cast.endsWith(")")) {
cast = "(" + cast + ")";
}
String cast2 = adapterInfo.cast2.trim();
if (cast2.length() > 0 && !cast2.startsWith("(") && !cast2.endsWith(")")) {
cast2 = "(" + cast2 + ")";
}
out.print(cast + cast2 + "adapter" + j);
j += adapterInfo.argc - 1;
} else if (FunctionPointer.class.isAssignableFrom(methodInfo.parameterTypes[j]) && !(passBy instanceof ByVal || passBy instanceof ByRef)) {
if (passBy instanceof ByPtrRef) {
out.print(cast + "(ptr" + j + "->ptr)");
} else {
out.print(cast + "(ptr" + j + " == NULL ? NULL : " + (passBy instanceof ByPtrPtr ? "&ptr" : "ptr") + j + "->ptr)");
}
} else if (passBy instanceof ByVal || (passBy instanceof ByRef && methodInfo.parameterTypes[j] != String.class)) {
String nullValue = passBy instanceof ByVal ? ((ByVal) passBy).nullValue() : passBy instanceof ByRef ? ((ByRef) passBy).nullValue() : "";
out.print((nullValue.length() > 0 ? "ptr" + j + " == NULL ? " + nullValue + " : " : "") + "*" + cast + "ptr" + j);
} else if (passBy instanceof ByPtrPtr) {
out.print(cast + "(arg" + j + " == NULL ? NULL : &ptr" + j + ")");
} else {
// ByPtr || ByPtrRef || (ByRef && std::string)
out.print(cast + "ptr" + j);
}
if (j < skipParameters + methodInfo.dim) {
if (index == null || index.function().length() == 0) {
out.print("]");
} else {
out.print(")");
}
} else if (j < methodInfo.parameterTypes.length - 1) {
out.print(", ");
}
}
out.print(suffix);
if (methodInfo.memberName.length > 2) {
out.print(methodInfo.memberName[2]);
}
if (by(methodInfo.annotations) instanceof ByRef && methodInfo.returnType == String.class) {
// special considerations for std::string
out.print(");\n" + indent + "rptr = rstr.c_str()");
}
if (needSecondCall) {
call(methodInfo, " : ", true);
out.print(")");
}
}
Aggregations