Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
22fc1e4
implemented support for nested exceptions
Nov 6, 2024
0d068e4
[UNFINISHED] prepared dynamic exceptionMapping
Nov 6, 2024
c72d55a
implemented dynamic exception mapping through the @Platform-annotation
Nov 7, 2024
8689d4a
test commit
Nov 28, 2024
bf11703
Merge pull request #1 from Seclous/feature/nvd-exception-handling
Avdiji Nov 28, 2024
6568ceb
Merge branch 'bytedeco:master' into master
Avdiji Nov 28, 2024
deee6ce
added missing include
Nov 29, 2024
8d0f08e
edited .gitignore
Nov 29, 2024
ac453a9
added include
Nov 29, 2024
c6bef28
enabled custom mapping for single methods
Dec 3, 2024
eee0544
changed default compiler options to use /MT instead of /MD
Dec 5, 2024
6c8a089
enabled dynamicly inserting function name on customMappings
Dec 9, 2024
4a18a9f
added parameternames
Dec 9, 2024
caf19f8
added constMember annotation
Dec 10, 2024
217b080
added CustomMapper flexibility
Dec 12, 2024
f75f244
implemented adding of custom JNI code
Dec 13, 2024
9675848
adjusted CustomMapping annoptation
Dec 19, 2024
ea9e40d
added dynamic pointer initialization
Dec 19, 2024
ac289ba
adjusted CustomMapper
Jan 9, 2025
41c975c
added feature, whichc allows the user to compile the generated source…
Jan 17, 2025
73bb54e
removed logger
Jan 17, 2025
c235041
slight adjustment
Jan 23, 2025
6e41b01
enabled more precise cross language polymorphism, by adjusting the Vi…
Jan 25, 2025
469428b
adjusted @Virutal annotation and Generator
Jan 29, 2025
dfed92c
enabled custom classloading
Jan 30, 2025
353a647
advanced customMapper
Jan 31, 2025
215439b
added include
Feb 24, 2025
fc6d0c1
removed malloc_trim
Jun 8, 2025
a4e128d
added semicolon
Jun 8, 2025
1a41a10
no message
Jun 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 55 additions & 52 deletions src/main/java/org/bytedeco/javacpp/ClassProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,13 @@

package org.bytedeco.javacpp;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.bytedeco.javacpp.annotation.ExceptionMapper;
import org.bytedeco.javacpp.annotation.Platform;
import org.bytedeco.javacpp.tools.Logger;

import java.io.File;
import java.util.*;

/**
* Does the heavy lifting of collecting values off Properties annotations found
* on enclosing classes. Operates for the desired "platform" value specified
Expand All @@ -41,14 +37,15 @@
*
* @see Loader#loadProperties(Class, java.util.Properties, boolean)
*/
public class ClassProperties extends HashMap<String,List<String>> {
public class ClassProperties extends HashMap<String, List<String>> {
private static final Logger logger = Logger.create(ClassProperties.class);

public ClassProperties() { }

public ClassProperties(Properties properties) {
platform = properties.getProperty("platform");
platform = properties.getProperty("platform");
platformExtension = properties.getProperty("platform.extension");
platformRoot = properties.getProperty("platform.root");
platformRoot = properties.getProperty("platform.root");
pathSeparator = properties.getProperty("platform.path.separator");
if (platformRoot == null || platformRoot.length() == 0) {
platformRoot = ".";
Expand All @@ -57,17 +54,11 @@ public ClassProperties(Properties properties) {
platformRoot += File.separator;
}
for (Map.Entry e : properties.entrySet()) {
String k = (String)e.getKey(), v = (String)e.getValue();
String k = (String) e.getKey(), v = (String) e.getValue();
if (v == null || v.length() == 0) {
continue;
}
if (k.equals("platform.includepath") || k.equals("platform.includeresource") || k.equals("platform.include")
|| k.equals("platform.linkpath") || k.equals("platform.linkresource") || k.equals("platform.link")
|| k.equals("platform.preloadpath") || k.equals("platform.preloadresource") || k.equals("platform.preload")
|| k.equals("platform.resourcepath") || k.equals("platform.resource")
|| k.equals("platform.frameworkpath") || k.equals("platform.framework")
|| k.equals("platform.executablepath") || k.equals("platform.executable")
|| k.equals("platform.compiler.*") || k.equals("platform.library.suffix") || k.equals("platform.extension")) {
if (k.equals("platform.includepath") || k.equals("platform.includeresource") || k.equals("platform.include") || k.equals("platform.linkpath") || k.equals("platform.linkresource") || k.equals("platform.link") || k.equals("platform.preloadpath") || k.equals("platform.preloadresource") || k.equals("platform.preload") || k.equals("platform.resourcepath") || k.equals("platform.resource") || k.equals("platform.frameworkpath") || k.equals("platform.framework") || k.equals("platform.executablepath") || k.equals("platform.executable") || k.equals("platform.compiler.*") || k.equals("platform.library.suffix") || k.equals("platform.extension")) {
addAll(k, v.split(pathSeparator));
} else {
setProperty(k, v);
Expand All @@ -84,21 +75,21 @@ public ClassProperties(Properties properties) {
public List<String> get(String key) {
List<String> list = super.get(key);
if (list == null) {
put((String)key, list = new ArrayList<String>());
put((String) key, list = new ArrayList<String>());
}
return list;
}

public void addAll(String key, String ... values) {
public void addAll(String key, String... values) {
if (values != null) {
addAll(key, Arrays.asList(values));
}
}

public void addAll(String key, Collection<String> values) {
if (values != null) {
String root = null;
if (key.equals("platform.compiler") || key.equals("platform.sysroot") || key.equals("platform.toolchain") ||
key.equals("platform.includepath") || key.equals("platform.linkpath")) {
if (key.equals("platform.compiler") || key.equals("platform.sysroot") || key.equals("platform.toolchain") || key.equals("platform.includepath") || key.equals("platform.linkpath")) {
root = platformRoot;
}

Expand All @@ -107,8 +98,7 @@ public void addAll(String key, Collection<String> values) {
if (value == null) {
continue;
}
if (root != null && !new File(value).isAbsolute() &&
new File(root + value).exists()) {
if (root != null && !new File(value).isAbsolute() && new File(root + value).exists()) {
value = root + value;
}
if (!values2.contains(value)) {
Expand All @@ -121,10 +111,12 @@ public void addAll(String key, Collection<String> values) {
public String getProperty(String key) {
return getProperty(key, null);
}

public String getProperty(String key, String defaultValue) {
List<String> values = get(key);
return values.isEmpty() ? defaultValue : values.get(0);
}

public String setProperty(String key, String value) {
List<String> values = get(key);
String oldValue = values.isEmpty() ? null : values.get(0);
Expand All @@ -137,17 +129,14 @@ public void load(Class cls, boolean inherit) {
Class<?> c = Loader.getEnclosingClass(cls);
List<Class> classList = new ArrayList<Class>();
classList.add(0, c);
while (!c.isAnnotationPresent(org.bytedeco.javacpp.annotation.Properties.class)
&& !c.isAnnotationPresent(Platform.class) && c.getSuperclass() != null
&& c.getSuperclass() != Object.class && c.getSuperclass() != Pointer.class) {
while (!c.isAnnotationPresent(org.bytedeco.javacpp.annotation.Properties.class) && !c.isAnnotationPresent(Platform.class) && c.getSuperclass() != null && c.getSuperclass() != Object.class && c.getSuperclass() != Pointer.class) {
// accumulate superclasses to process native methods from those as well
classList.add(0, c = c.getSuperclass());
}
if (effectiveClasses == null) {
effectiveClasses = classList;
}
org.bytedeco.javacpp.annotation.Properties classProperties =
c.getAnnotation(org.bytedeco.javacpp.annotation.Properties.class);
org.bytedeco.javacpp.annotation.Properties classProperties = c.getAnnotation(org.bytedeco.javacpp.annotation.Properties.class);
Platform classPlatform = c.getAnnotation(Platform.class);
Platform[] platforms = null;
String ourTarget = null;
Expand Down Expand Up @@ -195,17 +184,15 @@ public void load(Class cls, boolean inherit) {
}
if (classPlatform != null) {
if (platforms == null) {
platforms = new Platform[] { classPlatform };
platforms = new Platform[]{classPlatform};
} else {
platforms = Arrays.copyOf(platforms, platforms.length + 1);
platforms[platforms.length - 1] = classPlatform;
}
}
boolean hasPlatformProperties = platforms != null && platforms.length > (classProperties != null && classPlatform != null ? 1 : 0);

String[] pragma = {}, define = {}, exclude = {}, include = {}, cinclude = {}, includepath = {}, includeresource = {}, compiler = {},
linkpath = {}, linkresource = {}, link = {}, frameworkpath = {}, framework = {}, preloadpath = {}, preloadresource = {}, preload = {},
resourcepath = {}, resource = {}, extension = {}, executablepath = {}, executable = {};
String[] addCustomJNIFrom = {}, exceptionMappings = {}, pragma = {}, define = {}, exclude = {}, include = {}, cinclude = {}, includepath = {}, includeresource = {}, compiler = {}, linkpath = {}, linkresource = {}, link = {}, frameworkpath = {}, framework = {}, preloadpath = {}, preloadresource = {}, preload = {}, resourcepath = {}, resource = {}, extension = {}, executablepath = {}, executable = {};
String library = "jni" + c.getSimpleName();
if (hasPlatformProperties) {
if (ourTarget != null && ourTarget.length() > 0) {
Expand All @@ -219,8 +206,8 @@ public void load(Class cls, boolean inherit) {
}
}
for (Platform p : platforms != null ? platforms : new Platform[0]) {
String[][] names = { p.value().length > 0 ? p.value() : defaultNames, p.not(), p.pattern() };
boolean[] matches = { false, false, false };
String[][] names = {p.value().length > 0 ? p.value() : defaultNames, p.not(), p.pattern()};
boolean[] matches = {false, false, false};
for (int i = 0; i < names.length; i++) {
for (String s : names[i]) {
if ((i < 2 && platform.startsWith(s)) || (s.length() > 0 && platform.matches(s))) {
Expand All @@ -241,28 +228,41 @@ public void load(Class cls, boolean inherit) {
if (!match) {
continue;
}
if (p.pragma() .length > 0) { pragma = p.pragma(); }
if (p.define() .length > 0) { define = p.define(); }
if (p.exclude() .length > 0) { exclude = p.exclude(); }
if (p.include() .length > 0) { include = p.include(); }
if (p.cinclude() .length > 0) { cinclude = p.cinclude(); }

if (p.exceptionMappings().length > 0) {
List<String> exceptionMappingsList = new LinkedList<>();
for (ExceptionMapper mapper : p.exceptionMappings()) {
final String cppException = mapper.cppException();
final String javaException = mapper.javaExceptionClass().getName().replace('.', '/');

exceptionMappingsList.add(cppException);
exceptionMappingsList.add(javaException);
}
exceptionMappings = exceptionMappingsList.toArray(new String[0]);
}
if (p.addCustomJNIFrom().length > 0) { addCustomJNIFrom = p.addCustomJNIFrom(); }
if (p.pragma().length > 0) { pragma = p.pragma(); }
if (p.define().length > 0) { define = p.define(); }
if (p.exclude().length > 0) { exclude = p.exclude(); }
if (p.include().length > 0) { include = p.include(); }
if (p.cinclude().length > 0) { cinclude = p.cinclude(); }
if (p.includepath().length > 0) { includepath = p.includepath(); }
if (p.includeresource().length > 0) { includeresource = p.includeresource(); }
if (p.compiler() .length > 0) { compiler = p.compiler(); }
if (p.linkpath() .length > 0) { linkpath = p.linkpath(); }
if (p.linkresource() .length > 0) { linkresource = p.linkresource(); }
if (p.link() .length > 0) { link = p.link(); }
if (p.compiler().length > 0) { compiler = p.compiler(); }
if (p.linkpath().length > 0) { linkpath = p.linkpath(); }
if (p.linkresource().length > 0) { linkresource = p.linkresource(); }
if (p.link().length > 0) { link = p.link(); }
if (p.frameworkpath().length > 0) { frameworkpath = p.frameworkpath(); }
if (p.framework() .length > 0) { framework = p.framework(); }
if (p.framework().length > 0) { framework = p.framework(); }
if (p.preloadresource().length > 0) { preloadresource = p.preloadresource(); }
if (p.preloadpath().length > 0) { preloadpath = p.preloadpath(); }
if (p.preload() .length > 0) { preload = p.preload(); }
if (p.preload().length > 0) { preload = p.preload(); }
if (p.resourcepath().length > 0) { resourcepath = p.resourcepath(); }
if (p.resource() .length > 0) { resource = p.resource(); }
if (p.extension() .length > 0) { extension = p.extension(); }
if (p.resource().length > 0) { resource = p.resource(); }
if (p.extension().length > 0) { extension = p.extension(); }
if (p.executablepath().length > 0) { executablepath = p.executablepath(); }
if (p.executable() .length > 0) { executable = p.executable(); }
if (p.library().length() > 0) { library = p.library(); }
if (p.executable().length > 0) { executable = p.executable(); }
if (p.library().length() > 0) { library = p.library(); }
}
}
for (int i = 0; i < includeresource.length; i++) {
Expand All @@ -289,6 +289,9 @@ public void load(Class cls, boolean inherit) {
linkresource[i] = "/" + name;
}
}

addAll("platform.exceptionMappings", exceptionMappings);
addAll("platform.addCustomJNIFrom", addCustomJNIFrom);
addAll("platform.pragma", pragma);
addAll("platform.define", define);
addAll("platform.exclude", exclude);
Expand Down Expand Up @@ -319,7 +322,7 @@ public void load(Class cls, boolean inherit) {

if (LoadEnabled.class.isAssignableFrom(c)) {
try {
((LoadEnabled)c.newInstance()).init(this);
((LoadEnabled) c.newInstance()).init(this);
} catch (ClassCastException | InstantiationException | IllegalAccessException e) {
logger.warn("Could not create an instance of " + c + ": " + e);
}
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/org/bytedeco/javacpp/annotation/ConstMember.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.bytedeco.javacpp.annotation;

import java.lang.annotation.*;

/**
* Annotation allows to map (mainly virtual) functions, which are const members (e.g.: void func() const)
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface ConstMember {
}
51 changes: 51 additions & 0 deletions src/main/java/org/bytedeco/javacpp/annotation/CustomMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.bytedeco.javacpp.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Annotation allows to implement custom jni-mappings for specific methods.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CustomMapper {

/**
* Custom mapping logic, used only when filePath is not set.
*
* @return A String which will be directly used for the mapping.
*/
String customMapping() default "";

/**
* FilePath of the file, which contains the mapping.
*
* @return The filePath of the file, which contains the mapping.
*/
String[] filePaths() default {};

/**
* Set the name of the function to be called
*/
String functionCall() default "";

/**
* @return True if the CType of the parameters shall be used instead of the jType, to feed the calling function.
*/
boolean passCTypeParams() default false;

/**
*
* @return True if the parameter of the function shall be dereferenced.
*/
boolean dereferenceParams() default false;

/**
* @return The values which should be replaced with (replaces index 0 with 1, 2 with 3...)
*/
String[] replacements() default {};

String typename() default "";
}
29 changes: 29 additions & 0 deletions src/main/java/org/bytedeco/javacpp/annotation/ExceptionMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.bytedeco.javacpp.annotation;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Exception Mapper maps a C/C++ exception to the given java exception.
* Will overwrite any existing exception-mappings.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface ExceptionMapper {

/**
* The C/C++ exception to be mapped (e.g.: std::runtime_error).
*
* @return A String representation of the C/C++ exception to be mapped.
*/
String cppException();

/**
* The corresponding java-exception.
*
* @return The corresponding java-exception.
*/
Class<? extends Throwable> javaExceptionClass();
}

Loading