Search in sources :

Example 1 with Index

use of org.bytedeco.javacpp.annotation.Index 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(")");
    }
}
Also used : ByVal(org.bytedeco.javacpp.annotation.ByVal) ByRef(org.bytedeco.javacpp.annotation.ByRef) Index(org.bytedeco.javacpp.annotation.Index) 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)

Example 2 with Index

use of org.bytedeco.javacpp.annotation.Index 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;
}
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) 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)

Aggregations

Annotation (java.lang.annotation.Annotation)2 ByVal (org.bytedeco.javacpp.annotation.ByVal)2 Index (org.bytedeco.javacpp.annotation.Index)2 Method (java.lang.reflect.Method)1 BoolPointer (org.bytedeco.javacpp.BoolPointer)1 BytePointer (org.bytedeco.javacpp.BytePointer)1 CLongPointer (org.bytedeco.javacpp.CLongPointer)1 CharPointer (org.bytedeco.javacpp.CharPointer)1 DoublePointer (org.bytedeco.javacpp.DoublePointer)1 FloatPointer (org.bytedeco.javacpp.FloatPointer)1 FunctionPointer (org.bytedeco.javacpp.FunctionPointer)1 IntPointer (org.bytedeco.javacpp.IntPointer)1 LongPointer (org.bytedeco.javacpp.LongPointer)1 Pointer (org.bytedeco.javacpp.Pointer)1 PointerPointer (org.bytedeco.javacpp.PointerPointer)1 ShortPointer (org.bytedeco.javacpp.ShortPointer)1 SizeTPointer (org.bytedeco.javacpp.SizeTPointer)1 Allocator (org.bytedeco.javacpp.annotation.Allocator)1 ArrayAllocator (org.bytedeco.javacpp.annotation.ArrayAllocator)1 ByPtrPtr (org.bytedeco.javacpp.annotation.ByPtrPtr)1