Search in sources :

Example 1 with Name

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

the class Generator method cppScopeName.

static String cppScopeName(Class<?> type) {
    String scopeName = "";
    while (type != null) {
        Namespace namespace = type.getAnnotation(Namespace.class);
        String spaceName = namespace == null ? "" : namespace.value();
        if (Pointer.class.isAssignableFrom(type) && (!baseClasses.contains(type) || type.isAnnotationPresent(Name.class))) {
            Name name = type.getAnnotation(Name.class);
            String s;
            if (name == null) {
                s = type.getName();
                int i = s.lastIndexOf("$");
                if (i < 0) {
                    i = s.lastIndexOf(".");
                }
                s = s.substring(i + 1);
            } else {
                s = name.value()[0];
            }
            if (spaceName.length() > 0 && !spaceName.endsWith("::")) {
                spaceName += "::";
            }
            spaceName += s;
        }
        if (scopeName.length() > 0 && !spaceName.endsWith("::")) {
            spaceName += "::";
        }
        scopeName = spaceName + scopeName;
        if ((namespace != null && namespace.value().length() == 0) || spaceName.startsWith("::")) {
            // user wants to reset namespace here
            break;
        }
        type = type.getDeclaringClass();
    }
    return scopeName;
}
Also used : 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) Namespace(org.bytedeco.javacpp.annotation.Namespace) Name(org.bytedeco.javacpp.annotation.Name)

Example 2 with Name

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

the class Generator method methods.

boolean methods(Class<?> cls) {
    if (!checkPlatform(cls)) {
        return false;
    }
    Set<String> memberList = members.get(cls);
    if (!cls.isAnnotationPresent(Opaque.class) && !FunctionPointer.class.isAssignableFrom(cls) && cls.getEnclosingClass() != Pointer.class) {
        if (memberList == null) {
            members.put(cls, memberList = new LinkedHashSet<String>());
        }
        if (!memberList.contains("sizeof")) {
            memberList.add("sizeof");
        }
    }
    boolean didSomething = false;
    for (Class<?> c : cls.getDeclaredClasses()) {
        if (Pointer.class.isAssignableFrom(c) || Pointer.class.isAssignableFrom(c.getEnclosingClass())) {
            didSomething |= methods(c);
        }
    }
    Method[] methods = cls.getDeclaredMethods();
    MethodInformation[] methodInfos = new MethodInformation[methods.length];
    for (int i = 0; i < methods.length; i++) {
        methodInfos[i] = methodInformation(methods[i]);
    }
    Class<?> c = cls.getSuperclass();
    while (c != null && c != Object.class) {
        // consider non-duplicate virtual functions from superclasses as well
        for (Method m : c.getDeclaredMethods()) {
            if (m.isAnnotationPresent(Virtual.class)) {
                boolean found = false;
                String name = m.getName();
                Class<?>[] types = m.getParameterTypes();
                for (Method m2 : methods) {
                    if (name.equals(m2.getName()) && Arrays.equals(types, m2.getParameterTypes())) {
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    methods = Arrays.copyOf(methods, methods.length + 1);
                    methods[methods.length - 1] = m;
                    methodInfos = Arrays.copyOf(methodInfos, methodInfos.length + 1);
                    methodInfos[methods.length - 1] = methodInformation(m);
                    methodInfos[methods.length - 1].cls = cls;
                }
            }
        }
        c = c.getSuperclass();
    }
    boolean[] callbackAllocators = new boolean[methods.length];
    Method functionMethod = functionMethod(cls, callbackAllocators);
    boolean firstCallback = true;
    for (int i = 0; i < methods.length; i++) {
        if (!checkPlatform(methods[i].getAnnotation(Platform.class), null)) {
            continue;
        }
        MethodInformation methodInfo = methodInfos[i];
        String nativeName = mangle(cls.getName()) + "_" + mangle(methods[i].getName());
        String callbackName = callbackAllocators[i] && methodInfo.parameterTypes.length > 0 ? null : "JavaCPP_" + nativeName + "_callback";
        if (callbackAllocators[i] && functionMethod == null) {
            logger.warn("No callback method call() or apply() has been not declared in \"" + cls.getCanonicalName() + "\". No code will be generated for callback allocator.");
            continue;
        } else if (callbackAllocators[i] || (methods[i].equals(functionMethod) && !Modifier.isNative(methods[i].getModifiers()))) {
            functions.index(cls);
            Name name = methods[i].getAnnotation(Name.class);
            if (name != null && name.value().length > 0 && name.value()[0].length() > 0) {
                callbackName = name.value()[0];
            }
            callback(cls, functionMethod, callbackName, firstCallback, null);
            firstCallback = false;
            didSomething = true;
        }
        if ((Modifier.isNative(methods[i].getModifiers()) || Modifier.isAbstract(methods[i].getModifiers())) && !methodInfo.valueGetter && !methodInfo.valueSetter && !methodInfo.memberGetter && !methodInfo.memberSetter && !cls.isInterface() && (methods[i].isAnnotationPresent(Virtual.class) || methodInfo.allocator)) {
            callback(cls, methods[i], methodInfo.memberName[0], !methodInfo.allocator, methodInfo);
        }
        if (!Modifier.isNative(methods[i].getModifiers())) {
            continue;
        }
        if ((methodInfo.memberGetter || methodInfo.memberSetter) && !methodInfo.noOffset && memberList != null && !Modifier.isStatic(methodInfo.modifiers)) {
            if (!memberList.contains(methodInfo.memberName[0])) {
                memberList.add(methodInfo.memberName[0]);
            }
        }
        didSomething = true;
        out.print("JNIEXPORT " + jniTypeName(methodInfo.returnType) + " JNICALL Java_" + nativeName);
        if (methodInfo.overloaded) {
            out.print("__" + mangle(signature(methodInfo.parameterTypes)));
        }
        if (Modifier.isStatic(methodInfo.modifiers)) {
            out.print("(JNIEnv* env, jclass cls");
        } else {
            out.print("(JNIEnv* env, jobject obj");
        }
        for (int j = 0; j < methodInfo.parameterTypes.length; j++) {
            out.print(", " + jniTypeName(methodInfo.parameterTypes[j]) + " arg" + j);
        }
        out.println(") {");
        if (callbackAllocators[i]) {
            callbackAllocator(cls, callbackName);
            continue;
        } else if (!Modifier.isStatic(methodInfo.modifiers) && !methodInfo.allocator && !methodInfo.arrayAllocator && !methodInfo.deallocator) {
            // get our "this" pointer
            String[] typeName = cppTypeName(cls);
            if ("void*".equals(typeName[0]) && !cls.isAnnotationPresent(Opaque.class)) {
                typeName[0] = "char*";
            } else if (FunctionPointer.class.isAssignableFrom(cls)) {
                functions.index(cls);
                typeName[0] = functionClassName(cls) + "*";
                typeName[1] = "";
            }
            out.println("    " + typeName[0] + " ptr" + typeName[1] + " = (" + typeName[0] + typeName[1] + ")jlong_to_ptr(env->GetLongField(obj, JavaCPP_addressFID));");
            out.println("    if (ptr == NULL) {");
            out.println("        env->ThrowNew(JavaCPP_getClass(env, " + jclasses.index(NullPointerException.class) + "), \"This pointer address is NULL.\");");
            out.println("        return" + (methodInfo.returnType == void.class ? ";" : " 0;"));
            out.println("    }");
            if (FunctionPointer.class.isAssignableFrom(cls)) {
                out.println("    if (ptr->ptr == NULL) {");
                out.println("        env->ThrowNew(JavaCPP_getClass(env, " + jclasses.index(NullPointerException.class) + "), \"This function pointer address is NULL.\");");
                out.println("        return" + (methodInfo.returnType == void.class ? ";" : " 0;"));
                out.println("    }");
            }
            if (!cls.isAnnotationPresent(Opaque.class)) {
                out.println("    jlong position = env->GetLongField(obj, JavaCPP_positionFID);");
                out.println("    ptr += position;");
                if (methodInfo.bufferGetter) {
                    out.println("    jlong size = env->GetLongField(obj, JavaCPP_limitFID);");
                    out.println("    size -= position;");
                }
            }
        }
        parametersBefore(methodInfo);
        String returnPrefix = returnBefore(methodInfo);
        call(methodInfo, returnPrefix, false);
        returnAfter(methodInfo);
        parametersAfter(methodInfo);
        if (methodInfo.throwsException != null) {
            out.println("    if (exc != NULL) {");
            out.println("        env->Throw(exc);");
            out.println("    }");
        }
        if (methodInfo.returnType != void.class) {
            out.println("    return rarg;");
        }
        out.println("}");
    }
    out.println();
    return didSomething;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) FunctionPointer(org.bytedeco.javacpp.FunctionPointer) 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) Virtual(org.bytedeco.javacpp.annotation.Virtual) Method(java.lang.reflect.Method) Name(org.bytedeco.javacpp.annotation.Name)

Example 3 with Name

use of org.bytedeco.javacpp.annotation.Name 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 4 with Name

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

the class Generator method methods.

boolean methods(Class<?> cls) {
    if (!Loader.checkPlatform(cls, properties)) {
        return false;
    }
    Set<String> memberList = members.get(cls);
    if (!cls.isAnnotationPresent(Opaque.class) && cls != Loader.class && !FunctionPointer.class.isAssignableFrom(cls) && cls.getEnclosingClass() != Pointer.class) {
        if (memberList == null) {
            members.put(cls, memberList = new LinkedHashSet<String>());
        }
        if (!memberList.contains("sizeof")) {
            memberList.add("sizeof");
        }
    }
    boolean didSomething = false;
    for (Class<?> c : cls.getDeclaredClasses()) {
        if (Pointer.class.isAssignableFrom(c) || Pointer.class.isAssignableFrom(c.getEnclosingClass())) {
            didSomething |= methods(c);
        }
    }
    Method[] methods = cls.getDeclaredMethods();
    MethodInformation[] methodInfos = new MethodInformation[methods.length];
    for (int i = 0; i < methods.length; i++) {
        methodInfos[i] = methodInformation(methods[i]);
    }
    Class<?> c = cls.getSuperclass();
    while (c != null && c != Object.class) {
        // consider non-duplicate virtual functions from superclasses as well
        for (Method m : c.getDeclaredMethods()) {
            if (m.isAnnotationPresent(Virtual.class)) {
                boolean found = false;
                String name = m.getName();
                Class<?>[] types = m.getParameterTypes();
                for (Method m2 : methods) {
                    if (name.equals(m2.getName()) && Arrays.equals(types, m2.getParameterTypes())) {
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    methods = Arrays.copyOf(methods, methods.length + 1);
                    methods[methods.length - 1] = m;
                    methodInfos = Arrays.copyOf(methodInfos, methodInfos.length + 1);
                    methodInfos[methods.length - 1] = methodInformation(m);
                    methodInfos[methods.length - 1].cls = cls;
                }
            }
        }
        c = c.getSuperclass();
    }
    boolean[] callbackAllocators = new boolean[methods.length];
    Method[] functionMethods = functionMethods(cls, callbackAllocators);
    boolean firstCallback = true;
    for (int i = 0; i < methods.length; i++) {
        if (!Loader.checkPlatform(methods[i].getAnnotation(Platform.class), properties)) {
            continue;
        }
        MethodInformation methodInfo = methodInfos[i];
        String nativeName = mangle(cls.getName()) + "_" + mangle(methods[i].getName());
        String callbackName = callbackAllocators[i] && methodInfo.parameterTypes.length > 0 ? null : "JavaCPP_" + nativeName + "_callback";
        if (callbackAllocators[i] && functionMethods == null) {
            logger.warn("No callback method call() or apply() has been not declared in \"" + cls.getCanonicalName() + "\". No code will be generated for callback allocator.");
            continue;
        } else if (functionMethods != null) {
            for (Method functionMethod : functionMethods) {
                if (functionMethod != null && (callbackAllocators[i]) || (methods[i].equals(functionMethod) && !Modifier.isNative(methods[i].getModifiers()))) {
                    functions.index(cls);
                    Name name = methods[i].getAnnotation(Name.class);
                    if (name != null && name.value().length > 0 && name.value()[0].length() > 0) {
                        callbackName = name.value()[0];
                    }
                    callback(cls, functionMethod, callbackName, firstCallback, null);
                    firstCallback = false;
                    didSomething = true;
                }
            }
        }
        if ((Modifier.isNative(methods[i].getModifiers()) || Modifier.isAbstract(methods[i].getModifiers())) && !methodInfo.valueGetter && !methodInfo.valueSetter && !methodInfo.memberGetter && !methodInfo.memberSetter && !cls.isInterface() && (methods[i].isAnnotationPresent(Virtual.class) || methodInfo.allocator)) {
            callback(cls, methods[i], methodInfo.memberName[0], !methodInfo.allocator, methodInfo);
        }
        if (!Modifier.isNative(methods[i].getModifiers())) {
            continue;
        }
        if ((methodInfo.memberGetter || methodInfo.memberSetter) && !methodInfo.noOffset && memberList != null && !Modifier.isStatic(methodInfo.modifiers)) {
            if (!memberList.contains(methodInfo.memberName[0])) {
                memberList.add(methodInfo.memberName[0]);
            }
        }
        didSomething = true;
        out.print("JNIEXPORT " + jniTypeName(methodInfo.returnType) + " JNICALL Java_" + nativeName);
        if (methodInfo.overloaded) {
            out.print("__" + mangle(signature(methodInfo.parameterTypes)));
        }
        if (Modifier.isStatic(methodInfo.modifiers)) {
            out.print("(JNIEnv* env, jclass cls");
        } else {
            out.print("(JNIEnv* env, jobject obj");
        }
        for (int j = 0; j < methodInfo.parameterTypes.length; j++) {
            out.print(", " + jniTypeName(methodInfo.parameterTypes[j]) + " arg" + j);
        }
        out.println(") {");
        if (callbackAllocators[i]) {
            callbackAllocator(cls, callbackName);
            continue;
        } else if (!Modifier.isStatic(methodInfo.modifiers) && Pointer.class.isAssignableFrom(cls) && !methodInfo.allocator && !methodInfo.arrayAllocator && !methodInfo.deallocator) {
            // get our "this" pointer
            String[] typeName = cppTypeName(cls);
            if ("void*".equals(typeName[0]) && !cls.isAnnotationPresent(Opaque.class)) {
                typeName[0] = "char*";
            } else if (FunctionPointer.class.isAssignableFrom(cls)) {
                functions.index(cls);
                typeName[0] = functionClassName(cls) + "*";
                typeName[1] = "";
            }
            out.println("    " + typeName[0] + " ptr" + typeName[1] + " = (" + typeName[0] + typeName[1] + ")jlong_to_ptr(env->GetLongField(obj, JavaCPP_addressFID));");
            out.println("    if (ptr == NULL) {");
            out.println("        env->ThrowNew(JavaCPP_getClass(env, " + jclasses.index(NullPointerException.class) + "), \"This pointer address is NULL.\");");
            out.println("        return" + (methodInfo.returnType == void.class ? ";" : " 0;"));
            out.println("    }");
            if (FunctionPointer.class.isAssignableFrom(cls)) {
                out.println("    if (ptr->ptr == NULL) {");
                out.println("        env->ThrowNew(JavaCPP_getClass(env, " + jclasses.index(NullPointerException.class) + "), \"This function pointer address is NULL.\");");
                out.println("        return" + (methodInfo.returnType == void.class ? ";" : " 0;"));
                out.println("    }");
            }
            if (!cls.isAnnotationPresent(Opaque.class)) {
                out.println("    jlong position = env->GetLongField(obj, JavaCPP_positionFID);");
                out.println("    ptr += position;");
                if (methodInfo.bufferGetter) {
                    out.println("    jlong size = env->GetLongField(obj, JavaCPP_limitFID);");
                    out.println("    size -= position;");
                }
            }
        }
        parametersBefore(methodInfo);
        String returnPrefix = returnBefore(methodInfo);
        call(methodInfo, returnPrefix, false);
        returnAfter(methodInfo);
        parametersAfter(methodInfo);
        if (methodInfo.throwsException != null) {
            out.println("    if (exc != NULL) {");
            out.println("        env->Throw(exc);");
            out.println("    }");
        }
        if (methodInfo.returnType != void.class) {
            out.println("    return rarg;");
        }
        out.println("}");
    }
    out.println();
    return didSomething;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) FunctionPointer(org.bytedeco.javacpp.FunctionPointer) Opaque(org.bytedeco.javacpp.annotation.Opaque) Loader(org.bytedeco.javacpp.Loader) 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) Virtual(org.bytedeco.javacpp.annotation.Virtual) Method(java.lang.reflect.Method) Name(org.bytedeco.javacpp.annotation.Name)

Example 5 with Name

use of org.bytedeco.javacpp.annotation.Name 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

Name (org.bytedeco.javacpp.annotation.Name)6 Method (java.lang.reflect.Method)4 BoolPointer (org.bytedeco.javacpp.BoolPointer)4 BytePointer (org.bytedeco.javacpp.BytePointer)4 CLongPointer (org.bytedeco.javacpp.CLongPointer)4 CharPointer (org.bytedeco.javacpp.CharPointer)4 DoublePointer (org.bytedeco.javacpp.DoublePointer)4 FloatPointer (org.bytedeco.javacpp.FloatPointer)4 FunctionPointer (org.bytedeco.javacpp.FunctionPointer)4 IntPointer (org.bytedeco.javacpp.IntPointer)4 LongPointer (org.bytedeco.javacpp.LongPointer)4 Pointer (org.bytedeco.javacpp.Pointer)4 PointerPointer (org.bytedeco.javacpp.PointerPointer)4 ShortPointer (org.bytedeco.javacpp.ShortPointer)4 SizeTPointer (org.bytedeco.javacpp.SizeTPointer)4 Namespace (org.bytedeco.javacpp.annotation.Namespace)3 Annotation (java.lang.annotation.Annotation)2 LinkedHashSet (java.util.LinkedHashSet)2 Allocator (org.bytedeco.javacpp.annotation.Allocator)2 ArrayAllocator (org.bytedeco.javacpp.annotation.ArrayAllocator)2