14static int getArgumentClasses(JNIEnv* env, ArgumentClasses* argumentClasses);
15static void getArgumentClassMethods(JNIEnv* env, ArgumentMethods* argumentMethods);
16static int checkMethods(JNIEnv* env, ArgumentMethods* argumentMethods);
17static int allocateSpaceForArguments(JNIEnv* env,
Arguments* cArgs,
int totalFloatingPoints);
35 object = (*env)->NewObject(env,
class, midInit);
49 JavaObject javaObject;
50 javaObject.class = NULL;
51 javaObject.object = NULL;
54 javaObject.class = (*env)->FindClass(env, clazz);
55 if (!javaObject.class) {
56 char errorString[BUFSIZ];
57 sprintf(errorString,
"Failed to create object of class: %s", clazz);
74 return (
char*)(*env)->GetStringUTFChars(env,
string, NULL);
88 return (*env)->NewStringUTF(env,
string);
102jmethodID
getMethodId(JNIEnv* env, jclass clazz,
char* methodName,
char* methodSignature) {
103 return (*env)->GetMethodID(env, clazz, methodName, methodSignature);
130 ArgumentClasses argumentClasses;
131 if (getArgumentClasses(env, &argumentClasses)) {
136 ArgumentMethods argumentMethods;
137 argumentMethods.argumentClasses = &argumentClasses;
139 getArgumentClassMethods(env, &argumentMethods);
142 if (checkMethods(env, &argumentMethods)) {
147 jobject argumentsList = (*env)->CallObjectMethod(env, jArguments, argumentMethods.argumentsGetArgumentsMethod);
150 cArgs.
argumentCount = (*env)->CallIntMethod(env, argumentsList, argumentMethods.listSizeMethod);
153 jobject jFloatsList = (*env)->CallObjectMethod(env, jArguments, argumentMethods.argumentsGetFloatArgumentsMethod);
154 jobject jDoublesList = (*env)->CallObjectMethod(env, jArguments, argumentMethods.argumentsGetDoubleArgumentsMethod);
157 int floatCount = jFloatsList ? (*env)->CallIntMethod(env, jFloatsList, argumentMethods.listSizeMethod) : 0;
158 int doubleCount = jDoublesList ? (*env)->CallIntMethod(env, jDoublesList, argumentMethods.listSizeMethod) : 0;
159 int totalFloatingPoints = floatCount + doubleCount;
163 if (allocateSpaceForArguments(env, &cArgs, totalFloatingPoints)) {
169 jobject argument = (*env)->CallObjectMethod(env, argumentsList, argumentMethods.listGetMethod, i);
171 (*env)->CallObjectMethod(env, argument, argumentMethods.argumentGetNameMethod));
173 (*env)->CallObjectMethod(env, argument, argumentMethods.argumentGetValueMethod));
178 if (totalFloatingPoints > 0) {
181 jobject floatArgument = (*env)->CallObjectMethod(env, jFloatsList, argumentMethods.listGetMethod, i);
182 jobject name = (*env)->CallObjectMethod(env, floatArgument, argumentMethods.getFloatNameMethod);
183 jfloat value = (*env)->CallFloatMethod(env, floatArgument, argumentMethods.getFloatValueMethod);
192 jobject doubleArgument = (*env)->CallObjectMethod(env, jDoublesList, argumentMethods.listGetMethod, i);
193 jobject name = (*env)->CallObjectMethod(env, doubleArgument, argumentMethods.getDoubleNameMethod);
194 jdouble value = (*env)->CallDoubleMethod(env, doubleArgument, argumentMethods.getDoubleValueMethod);
213static int getArgumentClasses(JNIEnv* env, ArgumentClasses* argumentClasses) {
215 argumentClasses->listClass = (*env)->FindClass(env,
"java/util/List");
216 if (!argumentClasses->listClass) {
222 argumentClasses->floatArgumentClass = (*env)->FindClass(env,
"edu/stanford/slac/aida/lib/model/FloatArgument");
223 if (!argumentClasses->floatArgumentClass) {
229 argumentClasses->doubleArgumentClass = (*env)->FindClass(env,
"edu/stanford/slac/aida/lib/model/DoubleArgument");
230 if (!argumentClasses->doubleArgumentClass) {
236 argumentClasses->aidaArgumentsClass = (*env)->FindClass(env,
"edu/stanford/slac/aida/lib/model/AidaArguments");
237 if (!argumentClasses->aidaArgumentsClass) {
243 argumentClasses->aidaArgumentClass = (*env)->FindClass(env,
"edu/stanford/slac/aida/lib/model/AidaArgument");
244 if (!argumentClasses->aidaArgumentClass) {
257static void getArgumentClassMethods(JNIEnv* env, ArgumentMethods* argumentMethods) {
259 (argumentMethods->listSizeMethod) = (*env)
260 ->GetMethodID(env, argumentMethods->argumentClasses->listClass,
"size",
"()I");
261 (argumentMethods->listGetMethod) = (*env)
262 ->GetMethodID(env, argumentMethods->argumentClasses->listClass,
"get",
"(I)Ljava/lang/Object;");
265 (argumentMethods->argumentGetNameMethod) = (*env)
266 ->GetMethodID(env, argumentMethods->argumentClasses->aidaArgumentClass,
"getName",
"()Ljava/lang/String;");
267 (argumentMethods->argumentGetValueMethod) = (*env)
268 ->GetMethodID(env, argumentMethods->argumentClasses->aidaArgumentClass,
"getValue",
"()Ljava/lang/String;");
271 (argumentMethods->argumentsGetArgumentsMethod) = (*env)
272 ->GetMethodID(env, argumentMethods->argumentClasses->aidaArgumentsClass,
"getArguments",
273 "()Ljava/util/List;");
274 (argumentMethods->argumentsGetFloatArgumentsMethod) = (*env)
275 ->GetMethodID(env, argumentMethods->argumentClasses->aidaArgumentsClass,
"getFloatArguments",
276 "()Ljava/util/List;");
277 (argumentMethods->argumentsGetDoubleArgumentsMethod) = (*env)
278 ->GetMethodID(env, argumentMethods->argumentClasses->aidaArgumentsClass,
"getDoubleArguments",
279 "()Ljava/util/List;");
282 (argumentMethods->getFloatNameMethod) = (*env)
283 ->GetMethodID(env, argumentMethods->argumentClasses->floatArgumentClass,
"getName",
"()Ljava/lang/String;");
284 (argumentMethods->getFloatValueMethod) = (*env)
285 ->GetMethodID(env, argumentMethods->argumentClasses->floatArgumentClass,
"getValue",
"()F");
286 (argumentMethods->getDoubleNameMethod) = (*env)
287 ->GetMethodID(env, argumentMethods->argumentClasses->doubleArgumentClass,
"getName",
288 "()Ljava/lang/String;");
289 (argumentMethods->getDoubleValueMethod) = (*env)
290 ->GetMethodID(env, argumentMethods->argumentClasses->doubleArgumentClass,
"getValue",
"()D");
300static int checkMethods(JNIEnv* env, ArgumentMethods* argumentMethods) {
301 if (!argumentMethods->listSizeMethod) {
303 "Failed to get size(String) method on List object");
306 if (!argumentMethods->listGetMethod) {
310 if (!argumentMethods->argumentGetNameMethod) {
312 "Failed to get getName() method on AidaArgument object");
315 if (!argumentMethods->argumentGetValueMethod) {
317 "Failed to get getValue() method on AidaArgument object");
321 if (!argumentMethods->argumentsGetArgumentsMethod) {
323 "Failed to get getArguments() method on AidaArguments object");
327 if (!argumentMethods->argumentsGetFloatArgumentsMethod) {
329 "Failed to get getFloatArguments() method on AidaArguments object");
333 if (!argumentMethods->argumentsGetDoubleArgumentsMethod) {
335 "Failed to get getDoubleArguments() method on AidaArguments object");
339 if (!argumentMethods->getFloatNameMethod) {
341 "Failed to get getName() method on FloatValue object");
345 if (!argumentMethods->getFloatValueMethod) {
347 "Failed to get getValue() method on FloatValue object");
351 if (!argumentMethods->getDoubleNameMethod) {
353 "Failed to get getName() method on DoubleValue object");
357 if (!argumentMethods->getDoubleValueMethod) {
359 "Failed to get getValue() method on DoubleValue object");
374static int allocateSpaceForArguments(JNIEnv* env,
Arguments* cArgs,
int totalFloatingPoints) {
379 "Failed to allocate memory for arguments");
384 if (totalFloatingPoints > 0) {
390 "Failed to allocate memory for floating point values");
449 jbooleanArray returnValue;
451 returnValue = (*env)->NewBooleanArray(env, array.
count);
453 char errorString[BUFSIZ];
454 sprintf(errorString,
"Failed to create a new Boolean Array with %d elements", array.
count);
460 (*env)->SetBooleanArrayRegion(env, returnValue, 0, array.
count, array.
items);
476 jbyteArray returnValue;
478 returnValue = (*env)->NewByteArray(env, array.
count);
480 char errorString[BUFSIZ];
481 sprintf(errorString,
"Failed to create a new Byte Array with %d elements", array.
count);
487 (*env)->SetByteArrayRegion(env, returnValue, 0, array.
count, array.
items);
504 jshortArray returnValue;
506 returnValue = (*env)->NewShortArray(env, array.
count);
508 char errorString[BUFSIZ];
509 sprintf(errorString,
"Failed to create a new Short Array with %d elements", array.
count);
515 jshort jShortArray[array.
count];
516 for (
int i = 0; i < array.
count; i++) {
517 jShortArray[i] = (jshort)((
short*)array.
items)[i];
519 (*env)->SetShortArrayRegion(env, returnValue, 0, array.
count, jShortArray);
536 jintArray returnValue;
538 returnValue = (*env)->NewIntArray(env, array.
count);
540 char errorString[BUFSIZ];
541 sprintf(errorString,
"Failed to create a new Integer Array with %d elements", array.
count);
547 jint jintArray[array.
count];
548 for (
int i = 0; i < array.
count; i++) {
549 jintArray[i] = (jint)((
int*)array.
items)[i];
551 (*env)->SetIntArrayRegion(env, returnValue, 0, array.
count, jintArray);
568 jlongArray returnValue;
570 returnValue = (*env)->NewLongArray(env, array.
count);
572 char errorString[BUFSIZ];
573 sprintf(errorString,
"Failed to create a new Long Array with %d elements", array.
count);
580 jlong jlongArray[array.
count];
581 for (
int i = 0; i < array.
count; i++) {
582 jlongArray[i] = (jlong)((
long*)array.
items)[i];
584 (*env)->SetLongArrayRegion(env, returnValue, 0, array.
count, jlongArray);
601 jfloatArray returnValue;
603 returnValue = (*env)->NewFloatArray(env, array.
count);
605 char errorString[BUFSIZ];
606 sprintf(errorString,
"Failed to create a new Float Array with %d elements", array.
count);
612 (*env)->SetFloatArrayRegion(env, returnValue, 0, array.
count, array.
items);
629 jdoubleArray returnValue;
632 returnValue = (*env)->NewDoubleArray(env, array.
count);
634 char errorString[BUFSIZ];
635 sprintf(errorString,
"Failed to create a new Double Array with %d elements", array.
count);
641 (*env)->SetDoubleArrayRegion(env, returnValue, 0, array.
count, array.
items);
658 jobjectArray returnValue;
661 jclass classString = (*env)->FindClass(env,
"java/lang/String");
667 returnValue = (*env)->NewObjectArray(env, array.
count, classString, NULL);
670 char errorString[BUFSIZ];
671 sprintf(errorString,
"Failed to create a new String Array with %d elements", array.
count);
677 for (
int i = 0; i < array.
count; i++) {
678 (*env)->SetObjectArrayElement(env, returnValue, i,
toJString(env, array.
items[i]));
703 jobject tableToReturn;
705 JavaObject listObject =
newObject(env,
"edu/stanford/slac/aida/lib/model/AidaTable");
708 tableToReturn = listObject.object;
709 jclass cList = listObject.class;
712 jmethodID mAdd = (*env)->GetMethodID(env, cList,
"add",
"(ILjava/lang/Object;)Z");
715 "Failed to find the add(int, Object) method on AidaTable object");
720 jmethodID mAddField = (*env)->GetMethodID(env, cList,
"addField",
"(Ljava/lang/String;)Z");
723 "Failed to find the addField(String) method on AidaTable object");
728 jmethodID mAddLabel = (*env)->GetMethodID(env, cList,
"addLabel",
"(Ljava/lang/String;)Z");
731 "Failed to find the addLabel(String) method on AidaTable object");
735 if (!tableToReturn) {
747 "Fields overriden but, provider has not supplied enough field names for all table columns");
751 jstring stringValue =
toJString(env, fieldName);
752 (*env)->CallBooleanMethod(env, tableToReturn, mAddField, stringValue);
753 (*env)->DeleteLocalRef(env, stringValue);
764 "Labels overriden but, provider has not supplied enough label names for all table columns");
768 jstring stringValue =
toJString(env, labelName);
769 (*env)->CallBooleanMethod(env, tableToReturn, mAddLabel, stringValue);
770 (*env)->DeleteLocalRef(env, stringValue);
777 for (
int row = 0; row < table.
rowCount; row++) {
778 switch (table.
types[column]) {
780 jboolean data = ((jboolean*)(table.
ppData[column]))[row];
781 jobject dataObject =
toBoolean(env, data);
784 (*env)->CallBooleanMethod(env, tableToReturn, mAdd, column, dataObject);
785 (*env)->DeleteLocalRef(env, dataObject);
789 jbyte data = ((jbyte*)(table.
ppData[column]))[row];
790 jobject dataObject =
toByte(env, data);
793 (*env)->CallBooleanMethod(env, tableToReturn, mAdd, column, dataObject);
794 (*env)->DeleteLocalRef(env, dataObject);
798 jshort data = (jshort)((
short*)(table.
ppData[column]))[row];
799 jobject dataObject =
toShort(env, data);
802 (*env)->CallBooleanMethod(env, tableToReturn, mAdd, column, dataObject);
803 (*env)->DeleteLocalRef(env, dataObject);
807 jint data = (jint)((
int*)(table.
ppData[column]))[row];
808 jobject dataObject =
toInteger(env, data);
811 (*env)->CallBooleanMethod(env, tableToReturn, mAdd, column, dataObject);
812 (*env)->DeleteLocalRef(env, dataObject);
816 jlong data = (jlong)((
long*)(table.
ppData[column]))[row];
817 jobject dataObject =
toLong(env, data);
820 (*env)->CallBooleanMethod(env, tableToReturn, mAdd, column, dataObject);
821 (*env)->DeleteLocalRef(env, dataObject);
825 jfloat data = ((jfloat*)(table.
ppData[column]))[row];
826 jobject dataObject =
toFloat(env, data);
829 (*env)->CallBooleanMethod(env, tableToReturn, mAdd, column, dataObject);
830 (*env)->DeleteLocalRef(env, dataObject);
834 jdouble data = ((jdouble*)(table.
ppData[column]))[row];
835 jobject dataObject =
toDouble(env, data);
838 (*env)->CallBooleanMethod(env, tableToReturn, mAdd, column, dataObject);
839 (*env)->DeleteLocalRef(env, dataObject);
843 char*
string = ((
char**)(table.
ppData[column]))[row];
844 jstring stringValue =
toJString(env,
string);
847 (*env)->CallBooleanMethod(env, tableToReturn, mAdd, column, stringValue);
850 (*env)->DeleteLocalRef(env, stringValue);
856 "Unsupported type found in table. Perhaps you declared a table with n columns but didnt add n columns");
864 return tableToReturn;
874 (*env)->ReleaseStringUTFChars(env, uri, pv);
922 if (table.
ppData[column]) {
923 free(table.
ppData[column]);
924 table.
ppData[column] = NULL;
939 for (
int column = 0; column < table.
_currentField; column++) {
952 for (
int column = 0; column < table.
_currentLabel; column++) {
976 ClassAndMethod classAndMethod;
979 classAndMethod.class = (*env)->FindClass(env, boxedClassSignature);
980 if (!classAndMethod.class) {
981 char errorString[BUFSIZ];
982 sprintf(errorString,
"Failed to get class of: %s", boxedClassSignature);
984 return classAndMethod;
988 classAndMethod.methodId = (*env)->GetStaticMethodID(env, classAndMethod.class,
"valueOf", valueOfMethodSignature);
989 if (!classAndMethod.methodId) {
990 char errorString[BUFSIZ];
991 sprintf(errorString,
"Failed to valueOf method with signature: %s", valueOfMethodSignature);
993 return classAndMethod;
996 return classAndMethod;
1011 jobject dataObject = (*env)->CallStaticObjectMethod(env, classAndMethod.class, classAndMethod.methodId, primitive);
1027jobject
toByte(JNIEnv* env, jbyte primitive) {
1031 jobject dataObject = (*env)->CallStaticObjectMethod(env, classAndMethod.class, classAndMethod.methodId, primitive);
1051 jobject dataObject = (*env)->CallStaticObjectMethod(env, classAndMethod.class, classAndMethod.methodId, primitive);
1071 jobject dataObject = (*env)->CallStaticObjectMethod(env, classAndMethod.class, classAndMethod.methodId, primitive);
1087jobject
toLong(JNIEnv* env, jlong primitive) {
1091 jobject dataObject = (*env)->CallStaticObjectMethod(env, classAndMethod.class, classAndMethod.methodId, primitive);
1111 jobject dataObject = (*env)->CallStaticObjectMethod(env, classAndMethod.class, classAndMethod.methodId, primitive);
1131 jobject dataObject = (*env)->CallStaticObjectMethod(env, classAndMethod.class, classAndMethod.methodId, primitive);
#define ON_EXCEPTION_FREE_STRING_AND_RETURN_(_r)
Check to see if an exception has been raised, free a local variable string, and return the given retu...
#define ON_EXCEPTION_RETURN_(_r)
Check to see if an exception has been raised, and return the given return value.
#define AIDA_INTERNAL_EXCEPTION
Use this string to signal Internal Exceptions in aidaThrow()
#define UNABLE_TO_GET_DATA_EXCEPTION
Use this string to signal Exceptions when trying to Get Data in aidaThrow()
Value getArrayValue(JNIEnv *env, Arguments arguments)
Get value from the VALUE argument, in the provided Arguments structure, when the value is a scalar ar...
jlongArray toLongArray(JNIEnv *env, Array array)
Create a new instance of a java long[], from the Array of long primitives.
jobject toTable(JNIEnv *env, Table table)
Create a new instance of a java List of Lists, from the given Table structure.
jobject newObjectFromClass(JNIEnv *env, jclass class)
Create a new java object.
jbooleanArray toBooleanArray(JNIEnv *env, Array array)
Create a new instance of a java boolean[], from the Array of boolean primitives.
void releaseArray(Array array)
Free up any memory allocated the given scalar array.
jmethodID getConstructorMethodId(JNIEnv *env, jclass clazz)
Get the method ID of the constructor of the given class.
jobject toInteger(JNIEnv *env, jint primitive)
Create a new instance of a java Integer, from the primitive int provided.
jshortArray toShortArray(JNIEnv *env, Array array)
Create a new instance of a java short[], from the Array of short primitives.
JavaObject newObject(JNIEnv *env, char *clazz)
Look up class in the given env, and create a new java object.
jobject toLong(JNIEnv *env, jlong primitive)
Create a new instance of a java Long, from the primitive long provided.
jobjectArray toStringArray(JNIEnv *env, StringArray array)
Create a new instance of a java String[], from the StringArray of C string primitives.
jfloatArray toFloatArray(JNIEnv *env, Array array)
Create a new instance of a java float[], from the Array of float primitives.
jobject toFloat(JNIEnv *env, jfloat primitive)
Create a new instance of a java Float, from the primitive float provided.
jobject toBoolean(JNIEnv *env, jboolean primitive)
Create a new instance of a java Boolean, from the primitive boolean provided.
jobject toShort(JNIEnv *env, jshort primitive)
Create a new instance of a java Short, from the primitive short provided.
Arguments toArguments(JNIEnv *env, jobject jArguments)
Get an Arguments structure, from the given java List<AidaArgument>
jintArray toIntegerArray(JNIEnv *env, Array array)
Create a new instance of a java int[], from the Array of integer primitives.
jobject toDouble(JNIEnv *env, jdouble primitive)
Create a new instance of a java Double, from the primitive double provided.
void releaseValue(Value value)
Release all allocated memory in the given value.
jbyteArray toByteArray(JNIEnv *env, Array array)
Create a new instance of a java byte[], from the Array of byte primitives.
jmethodID getMethodId(JNIEnv *env, jclass clazz, char *methodName, char *methodSignature)
Get the method ID on the given class, with the given method name, and signature.
void releaseTable(Table table)
Free up any memory allocated for the given table.
ClassAndMethod getClassAndValueOfMethod(JNIEnv *env, char *boxedClassSignature, char *valueOfMethodSignature)
Get the class and the valueOf() method for the given signature.
void releaseStringArray(StringArray array)
Free up any memory allocated for string arrays.
Value getValue(JNIEnv *env, Arguments arguments)
Get value from the VALUE request argument, in the provided Arguments structure, when the value is a s...
jdoubleArray toDoubleArray(JNIEnv *env, Array array)
Create a new instance of a java double[], from the Array of double primitives.
jobject toByte(JNIEnv *env, jbyte primitive)
Create a new instance of a java Byte, from the primitive byte provided.
jstring toJString(JNIEnv *env, const char *string)
Convert C string to jstring.
void releasePvAndArguments(JNIEnv *env, jstring uri, const char *pv, Arguments arguments)
Free up any memory allocated for the given pv and arguments.
char * toCString(JNIEnv *env, jstring string)
Convert given jstring to a C string.
The Header File for the JNI helper functions.
Value getNamedArrayValue(JNIEnv *env, Arguments arguments, char *name)
Get value from a named argument in the provided arguments structure.
Value getNamedValue(JNIEnv *env, Arguments arguments, char *name)
Get value from a named argument in the provided arguments structure.
void aidaThrowNonOsException(JNIEnv *env, char *exception, const char *message)
To log any non-OS exceptions and throw back to java.
The Header File for the Native Channel Provider Server Helper functions.
@ AIDA_SHORT_ARRAY_TYPE
Represents a short array.
@ AIDA_FLOAT_ARRAY_TYPE
Represents a float array.
@ AIDA_BOOLEAN_ARRAY_TYPE
Represents a boolean array.
@ AIDA_INTEGER_ARRAY_TYPE
Represents an integer array.
@ AIDA_JSON_TYPE
Argument was provided as JSON text.
@ AIDA_BYTE_ARRAY_TYPE
Represents a byte array.
@ AIDA_LONG_ARRAY_TYPE
Represents a long array.
@ AIDA_STRING_ARRAY_TYPE
Represents a string array.
@ AIDA_NO_TYPE
Used to indicate that no type was provided as an argument.
@ AIDA_DOUBLE_ARRAY_TYPE
Represents a double array.
A single request argument.
char * value
The string value of the argument.
char * name
The name of the argument.
An Arguments structure stores all of the arguments passed from the request to the Native Channel Prov...
int argumentCount
The number of arguments sent with this request.
int floatingPointValuesCount
The number of floating point numbers in the arguments of this request.
Argument * arguments
The array of Arguments.
FloatingPointValue * floatingPointValues
The array of FloatingPointValue.
void * items
The items in this array.
int count
The number of items in this array.
Represents a floating point number.
char * path
The string path from the root of the json structure in which this value is found.
bool isFloat
Determines whether the value is a single or double precision floating point value.
FloatOrDoubleValue value
The floating point value.
int count
The number of items in this array.
char ** items
The items in this array - pointers to the strings you allocate.
int columnCount
number of columns in table
char ** ppLabels
the overridden label names. if null, not overridden. If not null then array of pointers to allocated ...
int _currentLabel
For internal use by addLabel() etc.
char ** ppFields
the overridden field names. if null, not overridden. If not null then array of pointers to allocated ...
Type * types
the scalar type of each column, one of BOOLEAN, BYTE, SHORT, INTEGER, LONG, FLOAT,...
void ** ppData
the data. an array of [rows][columns]
int _currentField
For internal use by addField() etc.
int rowCount
number of rows in table
int _currentColumn
For internal use by addColumn() etc.
This special type represents a Value.
ValueContents value
The value's contents, either a string or parsed json.
Type type
AIDA_STRING_TYPE or AIDA_JSON_TYPE.
double doubleValue
The double precision floating point value.
float floatValue
The single precision floating point value.
json_value * jsonValue
The parsed json_value of this Value if the type is AIDA_JSON_TYPE.