Search in sources :

Example 1 with ByVal

use of org.bytedeco.javacpp.annotation.ByVal in project bigbluebutton by bigbluebutton.

the class Generator method returnAfter.

void returnAfter(MethodInformation methodInfo) {
    String indent = methodInfo.throwsException != null ? "        " : "    ";
    String[] typeName = methodInfo.returnRaw ? new String[] { "" } : cppCastTypeName(methodInfo.returnType, methodInfo.annotations);
    Annotation returnBy = by(methodInfo.annotations);
    String valueTypeName = valueTypeName(typeName);
    AdapterInformation adapterInfo = adapterInformation(false, valueTypeName, methodInfo.annotations);
    String suffix = methodInfo.deallocator ? "" : ";";
    if (!methodInfo.returnType.isPrimitive() && adapterInfo != null) {
        suffix = ")" + suffix;
    }
    if ((Pointer.class.isAssignableFrom(methodInfo.returnType) || (methodInfo.returnType.isArray() && methodInfo.returnType.getComponentType().isPrimitive()) || Buffer.class.isAssignableFrom(methodInfo.returnType))) {
        if (returnBy instanceof ByVal && adapterInfo == null) {
            suffix = ")" + suffix;
        } else if (returnBy instanceof ByPtrPtr) {
            out.println(suffix);
            suffix = "";
            out.println(indent + "if (rptrptr == NULL) {");
            out.println(indent + "    env->ThrowNew(JavaCPP_getClass(env, " + jclasses.index(NullPointerException.class) + "), \"Return pointer address is NULL.\");");
            out.println(indent + "} else {");
            out.println(indent + "    rptr = *rptrptr;");
            out.println(indent + "}");
        }
    }
    out.println(suffix);
    if (methodInfo.returnType == void.class) {
        if (methodInfo.allocator || methodInfo.arrayAllocator) {
            out.println(indent + "jlong rcapacity = " + (methodInfo.arrayAllocator ? "arg0;" : "1;"));
            boolean noDeallocator = methodInfo.cls == Pointer.class || methodInfo.cls.isAnnotationPresent(NoDeallocator.class) || methodInfo.method.isAnnotationPresent(NoDeallocator.class);
            out.print(indent + "JavaCPP_initPointer(env, obj, rptr, rcapacity, rptr, ");
            if (noDeallocator) {
                out.println("NULL);");
            } else if (methodInfo.arrayAllocator) {
                out.println("&JavaCPP_" + mangle(methodInfo.cls.getName()) + "_deallocateArray);");
                arrayDeallocators.index(methodInfo.cls);
            } else {
                out.println("&JavaCPP_" + mangle(methodInfo.cls.getName()) + "_deallocate);");
                deallocators.index(methodInfo.cls);
            }
            if (virtualFunctions.containsKey(methodInfo.cls)) {
                typeName = cppTypeName(methodInfo.cls);
                valueTypeName = valueTypeName(typeName);
                String subType = "JavaCPP_" + mangle(valueTypeName);
                out.println(indent + "((" + subType + "*)rptr)->obj = env->NewWeakGlobalRef(obj);");
            }
        }
    } else {
        if (methodInfo.valueSetter || methodInfo.memberSetter || methodInfo.noReturnGetter) {
        // nothing
        } else if (methodInfo.returnType.isPrimitive()) {
            out.println(indent + "rarg = (" + jniTypeName(methodInfo.returnType) + ")rvalue;");
        } else if (methodInfo.returnRaw) {
            out.println(indent + "rarg = rptr;");
        } else {
            boolean needInit = false;
            if (adapterInfo != null) {
                out.println(indent + "rptr = radapter;");
                if (methodInfo.returnType != String.class) {
                    out.println(indent + "jlong rcapacity = (jlong)radapter.size;");
                    if (Pointer.class.isAssignableFrom(methodInfo.returnType)) {
                        out.println(indent + "void* rowner = radapter.owner;");
                    }
                    out.println(indent + "void (*deallocator)(void*) = " + (adapterInfo.constant ? "NULL;" : "&" + adapterInfo.name + "::deallocate;"));
                }
                needInit = true;
            } else if (returnBy instanceof ByVal || FunctionPointer.class.isAssignableFrom(methodInfo.returnType)) {
                out.println(indent + "jlong rcapacity = 1;");
                out.println(indent + "void* rowner = (void*)rptr;");
                out.println(indent + "void (*deallocator)(void*) = &JavaCPP_" + mangle(methodInfo.returnType.getName()) + "_deallocate;");
                deallocators.index(methodInfo.returnType);
                needInit = true;
            }
            if (Pointer.class.isAssignableFrom(methodInfo.returnType)) {
                out.print(indent);
                if (!(returnBy instanceof ByVal)) {
                    // check if we can reuse one of the Pointer objects from the arguments
                    if (Modifier.isStatic(methodInfo.modifiers) && methodInfo.parameterTypes.length > 0) {
                        for (int i = 0; i < methodInfo.parameterTypes.length; i++) {
                            String cast = cast(methodInfo, i);
                            if (Arrays.equals(methodInfo.parameterAnnotations[i], methodInfo.annotations) && methodInfo.parameterTypes[i] == methodInfo.returnType) {
                                out.println("if (rptr == " + cast + "ptr" + i + ") {");
                                out.println(indent + "    rarg = arg" + i + ";");
                                out.print(indent + "} else ");
                            }
                        }
                    } else if (!Modifier.isStatic(methodInfo.modifiers) && methodInfo.cls == methodInfo.returnType) {
                        out.println("if (rptr == ptr) {");
                        out.println(indent + "    rarg = obj;");
                        out.print(indent + "} else ");
                    }
                }
                out.println("if (rptr != NULL) {");
                out.println(indent + "    rarg = JavaCPP_createPointer(env, " + jclasses.index(methodInfo.returnType) + (methodInfo.parameterTypes.length > 0 && methodInfo.parameterTypes[0] == Class.class ? ", arg0);" : ");"));
                out.println(indent + "    if (rarg != NULL) {");
                if (needInit) {
                    out.println(indent + "        JavaCPP_initPointer(env, rarg, rptr, rcapacity, rowner, deallocator);");
                } else {
                    out.println(indent + "        env->SetLongField(rarg, JavaCPP_addressFID, ptr_to_jlong(rptr));");
                }
                out.println(indent + "    }");
                out.println(indent + "}");
            } else if (methodInfo.returnType == String.class) {
                passesStrings = true;
                out.println(indent + "if (rptr != NULL) {");
                out.println(indent + "    rarg = JavaCPP_createString(env, rptr);");
                out.println(indent + "}");
            } else if (methodInfo.returnType.isArray() && methodInfo.returnType.getComponentType().isPrimitive()) {
                if (adapterInfo == null && !(returnBy instanceof ByVal)) {
                    out.println(indent + "jlong rcapacity = rptr != NULL ? 1 : 0;");
                }
                String componentName = methodInfo.returnType.getComponentType().getName();
                String componentNameUpperCase = Character.toUpperCase(componentName.charAt(0)) + componentName.substring(1);
                out.println(indent + "if (rptr != NULL) {");
                out.println(indent + "    rarg = env->New" + componentNameUpperCase + "Array(rcapacity < INT_MAX ? rcapacity : INT_MAX);");
                out.println(indent + "    env->Set" + componentNameUpperCase + "ArrayRegion(rarg, 0, rcapacity < INT_MAX ? rcapacity : INT_MAX, (j" + componentName + "*)rptr);");
                out.println(indent + "}");
                if (adapterInfo != null) {
                    out.println(indent + "if (deallocator != 0 && rptr != NULL) {");
                    out.println(indent + "    (*(void(*)(void*))jlong_to_ptr(deallocator))((void*)rptr);");
                    out.println(indent + "}");
                }
            } else if (Buffer.class.isAssignableFrom(methodInfo.returnType)) {
                if (methodInfo.bufferGetter) {
                    out.println(indent + "jlong rcapacity = size;");
                } else if (adapterInfo == null && !(returnBy instanceof ByVal)) {
                    out.println(indent + "jlong rcapacity = rptr != NULL ? 1 : 0;");
                }
                out.println(indent + "if (rptr != NULL) {");
                out.println(indent + "    jlong rcapacityptr = rcapacity * sizeof(rptr[0]);");
                out.println(indent + "    rarg = env->NewDirectByteBuffer((void*)rptr, rcapacityptr < INT_MAX ? rcapacityptr : INT_MAX);");
                out.println(indent + "}");
            }
        }
    }
}
Also used : ByVal(org.bytedeco.javacpp.annotation.ByVal) FloatBuffer(java.nio.FloatBuffer) ByteBuffer(java.nio.ByteBuffer) IntBuffer(java.nio.IntBuffer) CharBuffer(java.nio.CharBuffer) ShortBuffer(java.nio.ShortBuffer) Buffer(java.nio.Buffer) DoubleBuffer(java.nio.DoubleBuffer) LongBuffer(java.nio.LongBuffer) CLongPointer(org.bytedeco.javacpp.CLongPointer) CharPointer(org.bytedeco.javacpp.CharPointer) IntPointer(org.bytedeco.javacpp.IntPointer) BytePointer(org.bytedeco.javacpp.BytePointer) PointerPointer(org.bytedeco.javacpp.PointerPointer) FunctionPointer(org.bytedeco.javacpp.FunctionPointer) LongPointer(org.bytedeco.javacpp.LongPointer) ShortPointer(org.bytedeco.javacpp.ShortPointer) BoolPointer(org.bytedeco.javacpp.BoolPointer) DoublePointer(org.bytedeco.javacpp.DoublePointer) FloatPointer(org.bytedeco.javacpp.FloatPointer) Pointer(org.bytedeco.javacpp.Pointer) SizeTPointer(org.bytedeco.javacpp.SizeTPointer) ByPtrPtr(org.bytedeco.javacpp.annotation.ByPtrPtr) NoDeallocator(org.bytedeco.javacpp.annotation.NoDeallocator) Annotation(java.lang.annotation.Annotation)

Example 2 with ByVal

use of org.bytedeco.javacpp.annotation.ByVal in project bigbluebutton by bigbluebutton.

the class Generator method callback.

void callback(Class<?> cls, Method callbackMethod, String callbackName, boolean needDefinition, MethodInformation methodInfo) {
    Class<?> callbackReturnType = callbackMethod.getReturnType();
    Class<?>[] callbackParameterTypes = callbackMethod.getParameterTypes();
    Annotation[] callbackAnnotations = callbackMethod.getAnnotations();
    Annotation[][] callbackParameterAnnotations = callbackMethod.getParameterAnnotations();
    String instanceTypeName = functionClassName(cls);
    String[] callbackTypeName = cppFunctionTypeName(callbackMethod);
    String[] returnConvention = callbackTypeName[0].split("\\(");
    returnConvention[1] = constValueTypeName(returnConvention[1]);
    String parameterDeclaration = callbackTypeName[1].substring(1);
    String fieldName = mangle(callbackMethod.getName()) + "__" + mangle(signature(callbackMethod.getParameterTypes()));
    String firstLine = "";
    if (methodInfo != null) {
        // stuff from a virtualized class
        String nonconstParamDeclaration = parameterDeclaration.endsWith(" const") ? parameterDeclaration.substring(0, parameterDeclaration.length() - 6) : parameterDeclaration;
        String[] typeName = methodInfo.returnRaw ? new String[] { "" } : cppTypeName(methodInfo.cls);
        String valueTypeName = valueTypeName(typeName);
        String subType = "JavaCPP_" + mangle(valueTypeName);
        Set<String> memberList = virtualMembers.get(cls);
        if (memberList == null) {
            virtualMembers.put(cls, memberList = new LinkedHashSet<String>());
        }
        String member = "    ";
        if (methodInfo.arrayAllocator) {
            return;
        } else if (methodInfo.allocator) {
            member += subType + nonconstParamDeclaration + " : " + valueTypeName + "(";
            for (int j = 0; j < callbackParameterTypes.length; j++) {
                member += "arg" + j;
                if (j < callbackParameterTypes.length - 1) {
                    member += ", ";
                }
            }
            member += "), obj(NULL) { }";
        } else {
            Set<String> functionList = virtualFunctions.get(cls);
            if (functionList == null) {
                virtualFunctions.put(cls, functionList = new LinkedHashSet<String>());
            }
            member += "using " + valueTypeName + "::" + methodInfo.memberName[0] + ";\n    " + "virtual " + returnConvention[0] + (returnConvention.length > 1 ? returnConvention[1] : "") + methodInfo.memberName[0] + parameterDeclaration + ";\n    " + returnConvention[0] + "super_" + methodInfo.memberName[0] + nonconstParamDeclaration + " { ";
            if (methodInfo.method.getAnnotation(Virtual.class).value()) {
                member += "throw JavaCPP_exception(\"Cannot call a pure virtual function.\"); }";
            } else {
                member += (callbackReturnType != void.class ? "return " : "") + valueTypeName + "::" + methodInfo.memberName[0] + "(";
                for (int j = 0; j < callbackParameterTypes.length; j++) {
                    member += "arg" + j;
                    if (j < callbackParameterTypes.length - 1) {
                        member += ", ";
                    }
                }
                member += "); }";
            }
            firstLine = returnConvention[0] + (returnConvention.length > 1 ? returnConvention[1] : "") + subType + "::" + methodInfo.memberName[0] + parameterDeclaration + " {";
            functionList.add(fieldName);
        }
        memberList.add(member);
    } else if (callbackName != null) {
        callbacks.index("static " + instanceTypeName + " " + callbackName + "_instance;");
        Convention convention = cls.getAnnotation(Convention.class);
        if (convention != null && !convention.extern().equals("C")) {
            out.println("extern \"" + convention.extern() + "\" {");
            if (out2 != null) {
                out2.println("extern \"" + convention.extern() + "\" {");
            }
        }
        if (out2 != null) {
            out2.println("JNIIMPORT " + returnConvention[0] + (returnConvention.length > 1 ? returnConvention[1] : "") + callbackName + parameterDeclaration + ";");
        }
        out.println("JNIEXPORT " + returnConvention[0] + (returnConvention.length > 1 ? returnConvention[1] : "") + callbackName + parameterDeclaration + " {");
        out.print((callbackReturnType != void.class ? "    return " : "    ") + callbackName + "_instance(");
        for (int j = 0; j < callbackParameterTypes.length; j++) {
            out.print("arg" + j);
            if (j < callbackParameterTypes.length - 1) {
                out.print(", ");
            }
        }
        out.println(");");
        out.println("}");
        if (convention != null && !convention.extern().equals("C")) {
            out.println("}");
            if (out2 != null) {
                out2.println("}");
            }
        }
        firstLine = returnConvention[0] + instanceTypeName + "::operator()" + parameterDeclaration + " {";
    }
    if (!needDefinition) {
        return;
    }
    out.println(firstLine);
    String returnPrefix = "";
    if (callbackReturnType != void.class) {
        out.println("    " + jniTypeName(callbackReturnType) + " rarg = 0;");
        returnPrefix = "rarg = ";
        if (callbackReturnType == String.class) {
            returnPrefix += "(jstring)";
        }
    }
    String callbackReturnCast = cast(callbackReturnType, callbackAnnotations);
    Annotation returnBy = by(callbackAnnotations);
    String[] returnTypeName = cppTypeName(callbackReturnType);
    String returnValueTypeName = valueTypeName(returnTypeName);
    AdapterInformation returnAdapterInfo = adapterInformation(false, returnValueTypeName, callbackAnnotations);
    out.println("    jthrowable exc = NULL;");
    out.println("    JNIEnv* env;");
    out.println("    bool attached = JavaCPP_getEnv(&env);");
    out.println("    if (env == NULL) {");
    out.println("        goto end;");
    out.println("    }");
    out.println("{");
    if (callbackParameterTypes.length > 0) {
        out.println("    jvalue args[" + callbackParameterTypes.length + "];");
        for (int j = 0; j < callbackParameterTypes.length; j++) {
            if (callbackParameterTypes[j].isPrimitive()) {
                out.println("    args[" + j + "]." + signature(callbackParameterTypes[j]).toLowerCase() + " = (" + jniTypeName(callbackParameterTypes[j]) + ")arg" + j + ";");
            } else {
                Annotation passBy = by(callbackParameterAnnotations[j]);
                String[] typeName = cppTypeName(callbackParameterTypes[j]);
                String valueTypeName = valueTypeName(typeName);
                AdapterInformation adapterInfo = adapterInformation(false, valueTypeName, callbackParameterAnnotations[j]);
                if (adapterInfo != null) {
                    usesAdapters = true;
                    out.println("    " + adapterInfo.name + " adapter" + j + "(arg" + j + ");");
                }
                if (Pointer.class.isAssignableFrom(callbackParameterTypes[j]) || Buffer.class.isAssignableFrom(callbackParameterTypes[j]) || (callbackParameterTypes[j].isArray() && callbackParameterTypes[j].getComponentType().isPrimitive())) {
                    String cast = "(" + typeName[0] + typeName[1] + ")";
                    if (FunctionPointer.class.isAssignableFrom(callbackParameterTypes[j])) {
                        functions.index(callbackParameterTypes[j]);
                        typeName[0] = functionClassName(callbackParameterTypes[j]) + "*";
                        typeName[1] = "";
                        valueTypeName = valueTypeName(typeName);
                    } else if (virtualFunctions.containsKey(callbackParameterTypes[j])) {
                        String subType = "JavaCPP_" + mangle(valueTypeName);
                        valueTypeName = subType;
                    }
                    out.println("    " + jniTypeName(callbackParameterTypes[j]) + " obj" + j + " = NULL;");
                    out.println("    " + typeName[0] + " ptr" + j + typeName[1] + " = NULL;");
                    if (FunctionPointer.class.isAssignableFrom(callbackParameterTypes[j])) {
                        out.println("    ptr" + j + " = new (std::nothrow) " + valueTypeName + ";");
                        out.println("    if (ptr" + j + " != NULL) {");
                        out.println("        ptr" + j + "->ptr = " + cast + "&arg" + j + ";");
                        out.println("    }");
                    } else if (adapterInfo != null) {
                        out.println("    ptr" + j + " = adapter" + j + ";");
                    } else if (passBy instanceof ByVal && callbackParameterTypes[j] != Pointer.class) {
                        out.println("    ptr" + j + (noException(callbackParameterTypes[j], callbackMethod) ? " = new (std::nothrow) " : " = new ") + valueTypeName + typeName[1] + "(*" + cast + "&arg" + j + ");");
                    } else if (passBy instanceof ByVal || passBy instanceof ByRef) {
                        out.println("    ptr" + j + " = " + cast + "&arg" + j + ";");
                    } else if (passBy instanceof ByPtrPtr) {
                        out.println("    if (arg" + j + " == NULL) {");
                        out.println("        JavaCPP_log(\"Pointer address of argument " + j + " is NULL in callback for " + cls.getCanonicalName() + ".\");");
                        out.println("    } else {");
                        out.println("        ptr" + j + " = " + cast + "*arg" + j + ";");
                        out.println("    }");
                    } else {
                        // ByPtr || ByPtrRef
                        out.println("    ptr" + j + " = " + cast + "arg" + j + ";");
                    }
                }
                boolean needInit = false;
                if (adapterInfo != null) {
                    if (callbackParameterTypes[j] != String.class) {
                        out.println("    jlong size" + j + " = (jlong)adapter" + j + ".size;");
                        out.println("    void* owner" + j + " = adapter" + j + ".owner;");
                        out.println("    void (*deallocator" + j + ")(void*) = &" + adapterInfo.name + "::deallocate;");
                    }
                    needInit = true;
                } else if ((passBy instanceof ByVal && callbackParameterTypes[j] != Pointer.class) || FunctionPointer.class.isAssignableFrom(callbackParameterTypes[j])) {
                    out.println("    jlong size" + j + " = 1;");
                    out.println("    void* owner" + j + " = ptr" + j + ";");
                    out.println("    void (*deallocator" + j + ")(void*) = &JavaCPP_" + mangle(callbackParameterTypes[j].getName()) + "_deallocate;");
                    deallocators.index(callbackParameterTypes[j]);
                    needInit = true;
                }
                if (Pointer.class.isAssignableFrom(callbackParameterTypes[j])) {
                    String s = "    obj" + j + " = JavaCPP_createPointer(env, " + jclasses.index(callbackParameterTypes[j]) + ");";
                    adapterInfo = adapterInformation(true, valueTypeName, callbackParameterAnnotations[j]);
                    if (adapterInfo != null || passBy instanceof ByPtrPtr || passBy instanceof ByPtrRef) {
                        out.println(s);
                    } else {
                        out.println("    if (ptr" + j + " != NULL) { ");
                        out.println("    " + s);
                        out.println("    }");
                    }
                    out.println("    if (obj" + j + " != NULL) { ");
                    if (needInit) {
                        out.println("        JavaCPP_initPointer(env, obj" + j + ", ptr" + j + ", size" + j + ", owner" + j + ", deallocator" + j + ");");
                    } else {
                        out.println("        env->SetLongField(obj" + j + ", JavaCPP_addressFID, ptr_to_jlong(ptr" + j + "));");
                    }
                    out.println("    }");
                    out.println("    args[" + j + "].l = obj" + j + ";");
                } else if (callbackParameterTypes[j] == String.class) {
                    passesStrings = true;
                    out.println("    jstring obj" + j + " = JavaCPP_createString(env, (const char*)" + (adapterInfo != null ? "adapter" : "arg") + j + ");");
                    out.println("    args[" + j + "].l = obj" + j + ";");
                } else if (callbackParameterTypes[j].isArray() && callbackParameterTypes[j].getComponentType().isPrimitive()) {
                    if (adapterInfo == null) {
                        out.println("    jlong size" + j + " = ptr" + j + " != NULL ? 1 : 0;");
                    }
                    String componentType = callbackParameterTypes[j].getComponentType().getName();
                    String S = Character.toUpperCase(componentType.charAt(0)) + componentType.substring(1);
                    out.println("    if (ptr" + j + " != NULL) {");
                    out.println("        obj" + j + " = env->New" + S + "Array(size" + j + " < INT_MAX ? size" + j + " : INT_MAX);");
                    out.println("        env->Set" + S + "ArrayRegion(obj" + j + ", 0, size" + j + " < INT_MAX ? size" + j + " : INT_MAX, (j" + componentType + "*)ptr" + j + ");");
                    out.println("    }");
                    if (adapterInfo != null) {
                        out.println("    if (deallocator" + j + " != 0 && ptr" + j + " != NULL) {");
                        out.println("        (*(void(*)(void*))jlong_to_ptr(deallocator" + j + "))((void*)ptr" + j + ");");
                        out.println("    }");
                    }
                } else if (Buffer.class.isAssignableFrom(callbackParameterTypes[j])) {
                    if (adapterInfo == null) {
                        out.println("    jlong size" + j + " = ptr" + j + " != NULL ? 1 : 0;");
                    }
                    out.println("    if (ptr" + j + " != NULL) {");
                    out.println("        jlong sizeptr = size" + j + " * sizeof(ptr" + j + "[0]);");
                    out.println("        obj" + j + " = env->NewDirectByteBuffer((void*)ptr" + j + ", sizeptr < INT_MAX ? sizeptr : INT_MAX);");
                    out.println("    }");
                } else {
                    logger.warn("Callback \"" + callbackMethod + "\" has unsupported parameter type \"" + callbackParameterTypes[j].getCanonicalName() + "\". Compilation will most likely fail.");
                }
            }
        }
    }
    if (methodInfo != null) {
        out.println("    if (" + fieldName + " == NULL) {");
        out.println("        " + fieldName + " = JavaCPP_getMethodID(env, " + jclasses.index(cls) + ", \"" + methodInfo.method.getName() + "\", \"(" + signature(methodInfo.method.getParameterTypes()) + ")" + signature(methodInfo.method.getReturnType()) + "\");");
        out.println("    }");
        out.println("    jmethodID mid = " + fieldName + ";");
    } else if (callbackName != null) {
        out.println("    if (obj == NULL) {");
        out.println("        obj = JavaCPP_createPointer(env, " + jclasses.index(cls) + ");");
        out.println("        obj = obj == NULL ? NULL : env->NewGlobalRef(obj);");
        out.println("        if (obj == NULL) {");
        out.println("            JavaCPP_log(\"Error creating global reference of " + cls.getCanonicalName() + " instance for callback.\");");
        out.println("        } else {");
        out.println("            env->SetLongField(obj, JavaCPP_addressFID, ptr_to_jlong(this));");
        out.println("        }");
        out.println("        ptr = &" + callbackName + ";");
        out.println("    }");
        out.println("    if (mid == NULL) {");
        out.println("        mid = JavaCPP_getMethodID(env, " + jclasses.index(cls) + ", \"" + callbackMethod.getName() + "\", \"(" + signature(callbackMethod.getParameterTypes()) + ")" + signature(callbackMethod.getReturnType()) + "\");");
        out.println("    }");
    }
    out.println("    if (env->IsSameObject(obj, NULL)) {");
    out.println("        JavaCPP_log(\"Function pointer object is NULL in callback for " + cls.getCanonicalName() + ".\");");
    out.println("    } else if (mid == NULL) {");
    out.println("        JavaCPP_log(\"Error getting method ID of function caller \\\"" + callbackMethod + "\\\" for callback.\");");
    out.println("    } else {");
    String s = "Object";
    if (callbackReturnType.isPrimitive()) {
        s = callbackReturnType.getName();
        s = Character.toUpperCase(s.charAt(0)) + s.substring(1);
    }
    out.println("        " + returnPrefix + "env->Call" + s + "MethodA(obj, mid, " + (callbackParameterTypes.length == 0 ? "NULL);" : "args);"));
    out.println("        if ((exc = env->ExceptionOccurred()) != NULL) {");
    out.println("            env->ExceptionClear();");
    out.println("        }");
    out.println("    }");
    for (int j = 0; j < callbackParameterTypes.length; j++) {
        if (Pointer.class.isAssignableFrom(callbackParameterTypes[j])) {
            String[] typeName = cppTypeName(callbackParameterTypes[j]);
            Annotation passBy = by(callbackParameterAnnotations[j]);
            String cast = cast(callbackParameterTypes[j], callbackParameterAnnotations[j]);
            String valueTypeName = valueTypeName(typeName);
            AdapterInformation adapterInfo = adapterInformation(true, valueTypeName, callbackParameterAnnotations[j]);
            if ("void*".equals(typeName[0]) && !callbackParameterTypes[j].isAnnotationPresent(Opaque.class)) {
                typeName[0] = "char*";
            }
            if (adapterInfo != null || passBy instanceof ByPtrPtr || passBy instanceof ByPtrRef) {
                out.println("    " + typeName[0] + " rptr" + j + typeName[1] + " = (" + typeName[0] + typeName[1] + ")jlong_to_ptr(env->GetLongField(obj" + j + ", JavaCPP_addressFID));");
                if (adapterInfo != null) {
                    out.println("    jlong rsize" + j + " = env->GetLongField(obj" + j + ", JavaCPP_limitFID);");
                    out.println("    void* rowner" + j + " = JavaCPP_getPointerOwner(env, obj" + j + ");");
                }
                if (!callbackParameterTypes[j].isAnnotationPresent(Opaque.class)) {
                    out.println("    jlong rposition" + j + " = env->GetLongField(obj" + j + ", JavaCPP_positionFID);");
                    out.println("    rptr" + j + " += rposition" + j + ";");
                    if (adapterInfo != null) {
                        out.println("    rsize" + j + " -= rposition" + j + ";");
                    }
                }
                if (adapterInfo != null) {
                    out.println("    adapter" + j + ".assign(rptr" + j + ", rsize" + j + ", rowner" + j + ");");
                } else if (passBy instanceof ByPtrPtr) {
                    out.println("    if (arg" + j + " != NULL) {");
                    out.println("        *arg" + j + " = *" + cast + "&rptr" + j + ";");
                    out.println("    }");
                } else if (passBy instanceof ByPtrRef) {
                    out.println("    arg" + j + " = " + cast + "rptr" + j + ";");
                }
            }
        }
        if (!callbackParameterTypes[j].isPrimitive()) {
            out.println("    env->DeleteLocalRef(obj" + j + ");");
        }
    }
    out.println("}");
    out.println("end:");
    if (callbackReturnType != void.class) {
        if ("void*".equals(returnTypeName[0]) && !callbackReturnType.isAnnotationPresent(Opaque.class)) {
            returnTypeName[0] = "char*";
        }
        if (Pointer.class.isAssignableFrom(callbackReturnType)) {
            out.println("    " + returnTypeName[0] + " rptr" + returnTypeName[1] + " = rarg == NULL ? NULL : (" + returnTypeName[0] + returnTypeName[1] + ")jlong_to_ptr(env->GetLongField(rarg, JavaCPP_addressFID));");
            if (returnAdapterInfo != null) {
                out.println("    jlong rsize = rarg == NULL ? 0 : env->GetLongField(rarg, JavaCPP_limitFID);");
                out.println("    void* rowner = JavaCPP_getPointerOwner(env, rarg);");
            }
            if (!callbackReturnType.isAnnotationPresent(Opaque.class)) {
                out.println("    jlong rposition = rarg == NULL ? 0 : env->GetLongField(rarg, JavaCPP_positionFID);");
                out.println("    rptr += rposition;");
                if (returnAdapterInfo != null) {
                    out.println("    rsize -= rposition;");
                }
            }
        } else if (callbackReturnType == String.class) {
            passesStrings = true;
            out.println("    " + returnTypeName[0] + " rptr" + returnTypeName[1] + " = JavaCPP_getStringBytes(env, rarg);");
            if (returnAdapterInfo != null) {
                out.println("    jlong rsize = 0;");
                out.println("    void* rowner = (void*)rptr");
            }
        } else if (Buffer.class.isAssignableFrom(callbackReturnType)) {
            out.println("    " + returnTypeName[0] + " rptr" + returnTypeName[1] + " = rarg == NULL ? NULL : env->GetDirectBufferAddress(rarg);");
            if (returnAdapterInfo != null) {
                out.println("    jlong rsize = rarg == NULL ? 0 : env->GetDirectBufferCapacity(rarg);");
                out.println("    void* rowner = (void*)rptr;");
            }
        } else if (!callbackReturnType.isPrimitive()) {
            logger.warn("Callback \"" + callbackMethod + "\" has unsupported return type \"" + callbackReturnType.getCanonicalName() + "\". Compilation will most likely fail.");
        }
    }
    out.println("    if (exc != NULL) {");
    out.println("        jstring str = (jstring)env->CallObjectMethod(exc, JavaCPP_toStringMID);");
    out.println("        env->DeleteLocalRef(exc);");
    out.println("        const char *msg = JavaCPP_getStringBytes(env, str);");
    out.println("        JavaCPP_exception e(msg);");
    out.println("        JavaCPP_releaseStringBytes(env, str, msg);");
    out.println("        env->DeleteLocalRef(str);");
    out.println("        JavaCPP_detach(attached);");
    out.println("        throw e;");
    out.println("    } else {");
    out.println("        JavaCPP_detach(attached);");
    out.println("    }");
    if (callbackReturnType != void.class) {
        if (callbackReturnType.isPrimitive()) {
            out.println("    return " + callbackReturnCast + "rarg;");
        } else if (returnAdapterInfo != null) {
            usesAdapters = true;
            out.println("    return " + returnAdapterInfo.name + "(" + callbackReturnCast + "rptr, rsize, rowner);");
        } else if (FunctionPointer.class.isAssignableFrom(callbackReturnType)) {
            functions.index(callbackReturnType);
            out.println("    return " + callbackReturnCast + "(rptr == NULL ? NULL : rptr->ptr);");
        } else if (returnBy instanceof ByVal || returnBy instanceof ByRef) {
            out.println("    if (rptr == NULL) {");
            out.println("        JavaCPP_log(\"Return pointer address is NULL in callback for " + cls.getCanonicalName() + ".\");");
            out.println("        static " + returnConvention[0] + " empty" + returnTypeName[1] + ";");
            out.println("        return empty;");
            out.println("    } else {");
            out.println("        return *" + callbackReturnCast + "rptr;");
            out.println("    }");
        } else if (returnBy instanceof ByPtrPtr) {
            out.println("    return " + callbackReturnCast + "&rptr;");
        } else {
            // ByPtr || ByPtrRef
            out.println("    return " + callbackReturnCast + "rptr;");
        }
    }
    out.println("}");
}
Also used : LinkedHashSet(java.util.LinkedHashSet) FloatBuffer(java.nio.FloatBuffer) ByteBuffer(java.nio.ByteBuffer) IntBuffer(java.nio.IntBuffer) CharBuffer(java.nio.CharBuffer) ShortBuffer(java.nio.ShortBuffer) Buffer(java.nio.Buffer) DoubleBuffer(java.nio.DoubleBuffer) LongBuffer(java.nio.LongBuffer) Set(java.util.Set) LinkedHashSet(java.util.LinkedHashSet) ByRef(org.bytedeco.javacpp.annotation.ByRef) ByPtrRef(org.bytedeco.javacpp.annotation.ByPtrRef) Opaque(org.bytedeco.javacpp.annotation.Opaque) CLongPointer(org.bytedeco.javacpp.CLongPointer) CharPointer(org.bytedeco.javacpp.CharPointer) IntPointer(org.bytedeco.javacpp.IntPointer) BytePointer(org.bytedeco.javacpp.BytePointer) PointerPointer(org.bytedeco.javacpp.PointerPointer) FunctionPointer(org.bytedeco.javacpp.FunctionPointer) LongPointer(org.bytedeco.javacpp.LongPointer) ShortPointer(org.bytedeco.javacpp.ShortPointer) BoolPointer(org.bytedeco.javacpp.BoolPointer) DoublePointer(org.bytedeco.javacpp.DoublePointer) FloatPointer(org.bytedeco.javacpp.FloatPointer) Pointer(org.bytedeco.javacpp.Pointer) SizeTPointer(org.bytedeco.javacpp.SizeTPointer) ByPtrPtr(org.bytedeco.javacpp.annotation.ByPtrPtr) Annotation(java.lang.annotation.Annotation) ByVal(org.bytedeco.javacpp.annotation.ByVal) Convention(org.bytedeco.javacpp.annotation.Convention)

Example 3 with ByVal

use of org.bytedeco.javacpp.annotation.ByVal in project bigbluebutton by bigbluebutton.

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 (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;
            }
        }
    }
}
Also used : ByVal(org.bytedeco.javacpp.annotation.ByVal) FloatBuffer(java.nio.FloatBuffer) ByteBuffer(java.nio.ByteBuffer) IntBuffer(java.nio.IntBuffer) CharBuffer(java.nio.CharBuffer) ShortBuffer(java.nio.ShortBuffer) Buffer(java.nio.Buffer) DoubleBuffer(java.nio.DoubleBuffer) LongBuffer(java.nio.LongBuffer) FunctionPointer(org.bytedeco.javacpp.FunctionPointer) ByRef(org.bytedeco.javacpp.annotation.ByRef) Opaque(org.bytedeco.javacpp.annotation.Opaque) Annotation(java.lang.annotation.Annotation)

Example 4 with ByVal

use of org.bytedeco.javacpp.annotation.ByVal in project javacpp by bytedeco.

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;
        } 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;
        }
        if (memberGetter || memberSetter) {
            for (int j = skipParameters; j < info.parameterTypes.length; j++) {
                if (!method.isAnnotationPresent(Index.class) && (pairedMethod == null || !pairedMethod.isAnnotationPresent(Index.class)) && info.parameterTypes[j] != int.class && info.parameterTypes[j] != long.class) {
                    memberGetter = false;
                    if (j < info.parameterTypes.length - 1) {
                        memberSetter = false;
                    }
                }
            }
        }
    }
    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 || (!memberGetter && canBeGetter && "get".equals(info.name) && index != null)) {
            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;
        }
        if ((info.valueGetter || info.valueSetter) && FunctionPointer.class.isAssignableFrom(info.cls) && info.cls.isAnnotationPresent(Namespace.class)) {
            // a member pointer where the first argument is the object
            info.dim--;
        }
    }
    Index index2 = pairedMethod != null ? pairedMethod.getAnnotation(Index.class) : null;
    info.throwsException = null;
    if (!noException(info.cls, method)) {
        if ((by(info.annotations) instanceof ByVal && !noException(info.returnType, method)) || (index != null && index.function().length() > 0) || (index2 != null && index2.function().length() > 0) || !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;
}
Also used : ArrayAllocator(org.bytedeco.javacpp.annotation.ArrayAllocator) Allocator(org.bytedeco.javacpp.annotation.Allocator) Raw(org.bytedeco.javacpp.annotation.Raw) Index(org.bytedeco.javacpp.annotation.Index) Method(java.lang.reflect.Method) Annotation(java.lang.annotation.Annotation) MemberGetter(org.bytedeco.javacpp.annotation.MemberGetter) Namespace(org.bytedeco.javacpp.annotation.Namespace) Name(org.bytedeco.javacpp.annotation.Name) ValueGetter(org.bytedeco.javacpp.annotation.ValueGetter) ByVal(org.bytedeco.javacpp.annotation.ByVal) Function(org.bytedeco.javacpp.annotation.Function) MemberSetter(org.bytedeco.javacpp.annotation.MemberSetter) ValueSetter(org.bytedeco.javacpp.annotation.ValueSetter) ArrayAllocator(org.bytedeco.javacpp.annotation.ArrayAllocator) NoOffset(org.bytedeco.javacpp.annotation.NoOffset)

Example 5 with ByVal

use of org.bytedeco.javacpp.annotation.ByVal in project javacpp by bytedeco.

the class Generator method returnAfter.

void returnAfter(MethodInformation methodInfo) {
    String indent = methodInfo.throwsException != null ? "        " : "    ";
    String[] typeName = methodInfo.returnRaw ? new String[] { "" } : cppCastTypeName(methodInfo.returnType, methodInfo.annotations);
    Annotation returnBy = by(methodInfo.annotations);
    String valueTypeName = valueTypeName(typeName);
    AdapterInformation adapterInfo = adapterInformation(false, valueTypeName, methodInfo.annotations);
    String suffix = methodInfo.deallocator ? "" : ";";
    if (!methodInfo.returnType.isPrimitive() && adapterInfo != null) {
        suffix = ")" + suffix;
    }
    if ((Pointer.class.isAssignableFrom(methodInfo.returnType) || (methodInfo.returnType.isArray() && methodInfo.returnType.getComponentType().isPrimitive()) || Buffer.class.isAssignableFrom(methodInfo.returnType)) || methodInfo.returnType == String.class) {
        if (returnBy instanceof ByVal && adapterInfo == null) {
            suffix = ")" + suffix;
        } else if (returnBy instanceof ByPtrPtr) {
            out.println(suffix);
            suffix = "";
            out.println(indent + "if (rptrptr == NULL) {");
            out.println(indent + "    env->ThrowNew(JavaCPP_getClass(env, " + jclasses.index(NullPointerException.class) + "), \"Return pointer address is NULL.\");");
            out.println(indent + "} else {");
            out.println(indent + "    rptr = *rptrptr;");
            out.println(indent + "}");
        }
    }
    out.println(suffix);
    if (methodInfo.returnType == void.class) {
        if (methodInfo.allocator || methodInfo.arrayAllocator) {
            out.println(indent + "jlong rcapacity = " + (methodInfo.arrayAllocator ? "arg0;" : "1;"));
            boolean noDeallocator = methodInfo.cls == Pointer.class || methodInfo.cls.isAnnotationPresent(NoDeallocator.class) || methodInfo.method.isAnnotationPresent(NoDeallocator.class);
            out.print(indent + "JavaCPP_initPointer(env, obj, rptr, rcapacity, rptr, ");
            if (noDeallocator) {
                out.println("NULL);");
            } else if (methodInfo.arrayAllocator) {
                out.println("&JavaCPP_" + mangle(methodInfo.cls.getName()) + "_deallocateArray);");
                arrayDeallocators.index(methodInfo.cls);
            } else {
                out.println("&JavaCPP_" + mangle(methodInfo.cls.getName()) + "_deallocate);");
                deallocators.index(methodInfo.cls);
            }
            if (virtualFunctions.containsKey(methodInfo.cls)) {
                typeName = cppTypeName(methodInfo.cls);
                valueTypeName = valueTypeName(typeName);
                String subType = "JavaCPP_" + mangle(valueTypeName);
                out.println(indent + "((" + subType + "*)rptr)->obj = env->NewWeakGlobalRef(obj);");
            }
        }
    } else {
        if (methodInfo.valueSetter || methodInfo.memberSetter || methodInfo.noReturnGetter) {
        // nothing
        } else if (methodInfo.returnType.isPrimitive()) {
            out.println(indent + "rarg = (" + jniTypeName(methodInfo.returnType) + ")rval;");
        } else if (methodInfo.returnRaw) {
            out.println(indent + "rarg = rptr;");
        } else if (Enum.class.isAssignableFrom(methodInfo.returnType)) {
            accessesEnums = true;
            String s = enumValueType(methodInfo.returnType);
            if (s != null) {
                String S = Character.toUpperCase(s.charAt(0)) + s.substring(1);
                out.println(indent + "if (rarg != NULL) {");
                out.println(indent + "    env->Set" + S + "Field(rarg, JavaCPP_" + s + "ValueFID, (j" + s + ")rval);");
                out.println(indent + "}");
            }
        } else {
            boolean needInit = false;
            if (adapterInfo != null) {
                out.println(indent + "rptr = radapter;");
                if (methodInfo.returnType != String.class) {
                    out.println(indent + "jlong rcapacity = (jlong)radapter.size;");
                    if (Pointer.class.isAssignableFrom(methodInfo.returnType)) {
                        out.println(indent + "void* rowner = radapter.owner;");
                    }
                    out.println(indent + "void (*deallocator)(void*) = &" + adapterInfo.name + "::deallocate;");
                }
                needInit = true;
            } else if (returnBy instanceof ByVal || FunctionPointer.class.isAssignableFrom(methodInfo.returnType)) {
                out.println(indent + "jlong rcapacity = 1;");
                out.println(indent + "void* rowner = (void*)rptr;");
                out.println(indent + "void (*deallocator)(void*) = &JavaCPP_" + mangle(methodInfo.returnType.getName()) + "_deallocate;");
                deallocators.index(methodInfo.returnType);
                needInit = true;
            }
            if (Pointer.class.isAssignableFrom(methodInfo.returnType)) {
                out.print(indent);
                if (!(returnBy instanceof ByVal)) {
                    // check if we can reuse one of the Pointer objects from the arguments
                    if (Modifier.isStatic(methodInfo.modifiers) && methodInfo.parameterTypes.length > 0) {
                        for (int i = 0; i < methodInfo.parameterTypes.length; i++) {
                            String cast = cast(methodInfo, i);
                            if (Arrays.equals(methodInfo.parameterAnnotations[i], methodInfo.annotations) && methodInfo.parameterTypes[i] == methodInfo.returnType && !(returnBy instanceof ByPtrPtr) && !(returnBy instanceof ByPtrRef)) {
                                out.println("if (rptr == " + cast + "ptr" + i + ") {");
                                out.println(indent + "    rarg = arg" + i + ";");
                                out.print(indent + "} else ");
                            }
                        }
                    } else if (!Modifier.isStatic(methodInfo.modifiers) && methodInfo.cls == methodInfo.returnType) {
                        out.println("if (rptr == ptr) {");
                        out.println(indent + "    rarg = obj;");
                        out.print(indent + "} else ");
                    }
                }
                out.println("if (rptr != NULL) {");
                out.println(indent + "    rarg = JavaCPP_createPointer(env, " + jclasses.index(methodInfo.returnType) + (methodInfo.parameterTypes.length > 0 && methodInfo.parameterTypes[0] == Class.class ? ", arg0);" : ");"));
                out.println(indent + "    if (rarg != NULL) {");
                if (needInit) {
                    out.println(indent + "        JavaCPP_initPointer(env, rarg, rptr, rcapacity, rowner, deallocator);");
                } else {
                    out.println(indent + "        env->SetLongField(rarg, JavaCPP_addressFID, ptr_to_jlong(rptr));");
                }
                out.println(indent + "    }");
                out.println(indent + "}");
            } else if (methodInfo.returnType == String.class) {
                passesStrings = true;
                out.println(indent + "if (rptr != NULL) {");
                out.println(indent + "    rarg = JavaCPP_createString(env, rptr);");
                out.println(indent + "}");
            } else if (methodInfo.returnType.isArray() && methodInfo.returnType.getComponentType().isPrimitive()) {
                if (adapterInfo == null && !(returnBy instanceof ByVal)) {
                    out.println(indent + "jlong rcapacity = rptr != NULL ? 1 : 0;");
                }
                String componentName = methodInfo.returnType.getComponentType().getName();
                String componentNameUpperCase = Character.toUpperCase(componentName.charAt(0)) + componentName.substring(1);
                out.println(indent + "if (rptr != NULL) {");
                out.println(indent + "    rarg = env->New" + componentNameUpperCase + "Array(rcapacity < INT_MAX ? rcapacity : INT_MAX);");
                out.println(indent + "    env->Set" + componentNameUpperCase + "ArrayRegion(rarg, 0, rcapacity < INT_MAX ? rcapacity : INT_MAX, (j" + componentName + "*)rptr);");
                out.println(indent + "}");
                if (adapterInfo != null) {
                    out.println(indent + "if (deallocator != 0 && rptr != NULL) {");
                    out.println(indent + "    (*(void(*)(void*))jlong_to_ptr(deallocator))((void*)rptr);");
                    out.println(indent + "}");
                }
            } else if (Buffer.class.isAssignableFrom(methodInfo.returnType)) {
                if (methodInfo.bufferGetter) {
                    out.println(indent + "jlong rcapacity = size;");
                } else if (adapterInfo == null && !(returnBy instanceof ByVal)) {
                    out.println(indent + "jlong rcapacity = rptr != NULL ? 1 : 0;");
                }
                out.println(indent + "if (rptr != NULL) {");
                out.println(indent + "    jlong rcapacityptr = rcapacity * sizeof(rptr[0]);");
                out.println(indent + "    rarg = env->NewDirectByteBuffer((void*)rptr, rcapacityptr < INT_MAX ? rcapacityptr : INT_MAX);");
                out.println(indent + "}");
            }
        }
    }
}
Also used : FloatBuffer(java.nio.FloatBuffer) ByteBuffer(java.nio.ByteBuffer) IntBuffer(java.nio.IntBuffer) CharBuffer(java.nio.CharBuffer) ShortBuffer(java.nio.ShortBuffer) Buffer(java.nio.Buffer) DoubleBuffer(java.nio.DoubleBuffer) LongBuffer(java.nio.LongBuffer) FunctionPointer(org.bytedeco.javacpp.FunctionPointer) ByPtrRef(org.bytedeco.javacpp.annotation.ByPtrRef) CLongPointer(org.bytedeco.javacpp.CLongPointer) CharPointer(org.bytedeco.javacpp.CharPointer) IntPointer(org.bytedeco.javacpp.IntPointer) BytePointer(org.bytedeco.javacpp.BytePointer) PointerPointer(org.bytedeco.javacpp.PointerPointer) FunctionPointer(org.bytedeco.javacpp.FunctionPointer) LongPointer(org.bytedeco.javacpp.LongPointer) ShortPointer(org.bytedeco.javacpp.ShortPointer) BoolPointer(org.bytedeco.javacpp.BoolPointer) DoublePointer(org.bytedeco.javacpp.DoublePointer) FloatPointer(org.bytedeco.javacpp.FloatPointer) Pointer(org.bytedeco.javacpp.Pointer) SizeTPointer(org.bytedeco.javacpp.SizeTPointer) ByPtrPtr(org.bytedeco.javacpp.annotation.ByPtrPtr) NoDeallocator(org.bytedeco.javacpp.annotation.NoDeallocator) Annotation(java.lang.annotation.Annotation) ByVal(org.bytedeco.javacpp.annotation.ByVal)

Aggregations

Annotation (java.lang.annotation.Annotation)13 ByVal (org.bytedeco.javacpp.annotation.ByVal)13 FunctionPointer (org.bytedeco.javacpp.FunctionPointer)9 ByPtrPtr (org.bytedeco.javacpp.annotation.ByPtrPtr)9 ByRef (org.bytedeco.javacpp.annotation.ByRef)9 Buffer (java.nio.Buffer)7 ByteBuffer (java.nio.ByteBuffer)7 CharBuffer (java.nio.CharBuffer)7 DoubleBuffer (java.nio.DoubleBuffer)7 FloatBuffer (java.nio.FloatBuffer)7 IntBuffer (java.nio.IntBuffer)7 LongBuffer (java.nio.LongBuffer)7 ShortBuffer (java.nio.ShortBuffer)7 BoolPointer (org.bytedeco.javacpp.BoolPointer)7 BytePointer (org.bytedeco.javacpp.BytePointer)7 CLongPointer (org.bytedeco.javacpp.CLongPointer)7 CharPointer (org.bytedeco.javacpp.CharPointer)7 DoublePointer (org.bytedeco.javacpp.DoublePointer)7 FloatPointer (org.bytedeco.javacpp.FloatPointer)7 IntPointer (org.bytedeco.javacpp.IntPointer)7