X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=jni%2Forg_argeo_api_uuid_libuuid%2Forg_argeo_api_uuid_libuuid_LibuuidFactory.c;fp=jni%2Forg_argeo_api_uuid_libuuid%2Forg_argeo_api_uuid_libuuid_LibuuidFactory.c;h=f97b1f4529499121873e08ce2dc32aaa927519fb;hb=06c84fd58822a899eaaf6a9d19ae62e5c7c72c77;hp=0000000000000000000000000000000000000000;hpb=f14b1ac6aad4b4c9c97fb29cb8cb46fc9092a496;p=gpl%2Fargeo-slc.git diff --git a/jni/org_argeo_api_uuid_libuuid/org_argeo_api_uuid_libuuid_LibuuidFactory.c b/jni/org_argeo_api_uuid_libuuid/org_argeo_api_uuid_libuuid_LibuuidFactory.c new file mode 100644 index 000000000..f97b1f452 --- /dev/null +++ b/jni/org_argeo_api_uuid_libuuid/org_argeo_api_uuid_libuuid_LibuuidFactory.c @@ -0,0 +1,91 @@ +#include +#include +#include "org_argeo_api_uuid_libuuid_LibuuidFactory.h" + +/* + * UTILITIES + */ + +static inline jobject fromBytes(JNIEnv *env, uuid_t out) { + jlong msb = 0; + jlong lsb = 0; + + for (int i = 0; i < 8; i++) + msb = (msb << 8) | (out[i] & 0xff); + for (int i = 8; i < 16; i++) + lsb = (lsb << 8) | (out[i] & 0xff); + + jclass uuidClass = (*env)->FindClass(env, "java/util/UUID"); + jmethodID uuidConstructor = (*env)->GetMethodID(env, uuidClass, "", + "(JJ)V"); + + jobject jUUID = (*env)->AllocObject(env, uuidClass); + (*env)->CallVoidMethod(env, jUUID, uuidConstructor, msb, lsb); + + return jUUID; +} + +static inline void toBytes(JNIEnv *env, jobject jUUID, uuid_t result) { + + jclass uuidClass = (*env)->FindClass(env, "java/util/UUID"); + jmethodID getMostSignificantBits = (*env)->GetMethodID(env, uuidClass, + "getMostSignificantBits", "()J"); + jmethodID getLeastSignificantBits = (*env)->GetMethodID(env, uuidClass, + "getLeastSignificantBits", "()J"); + + jlong msb = (*env)->CallLongMethod(env, jUUID, getMostSignificantBits); + jlong lsb = (*env)->CallLongMethod(env, jUUID, getLeastSignificantBits); + + for (int i = 0; i < 8; i++) + result[i] = (unsigned char) ((msb >> ((7 - i) * 8)) & 0xff); + for (int i = 8; i < 16; i++) + result[i] = (unsigned char) ((lsb >> ((15 - i) * 8)) & 0xff); +} + +/* + * JNI IMPLEMENTATION + */ + +JNIEXPORT jobject JNICALL Java_org_argeo_api_uuid_libuuid_LibuuidFactory_timeUUID( + JNIEnv *env, jobject uuidFactory) { + uuid_t out; + + uuid_generate_time(out); + return fromBytes(env, out); +} + +JNIEXPORT jobject JNICALL Java_org_argeo_api_uuid_libuuid_LibuuidFactory_nameUUIDv5( + JNIEnv *env, jobject uuidFactory, jobject namespaceUuid, + jbyteArray name) { + uuid_t ns; + uuid_t out; + + toBytes(env, namespaceUuid, ns); + jsize length = (*env)->GetArrayLength(env, name); + jbyte *bytes = (*env)->GetByteArrayElements(env, name, 0); + + uuid_generate_sha1(out, ns, bytes, length); + return fromBytes(env, out); +} + +JNIEXPORT jobject JNICALL Java_org_argeo_api_uuid_libuuid_LibuuidFactory_nameUUIDv3( + JNIEnv *env, jobject uuidFactory, jobject namespaceUuid, + jbyteArray name) { + uuid_t ns; + uuid_t out; + + toBytes(env, namespaceUuid, ns); + jsize length = (*env)->GetArrayLength(env, name); + jbyte *bytes = (*env)->GetByteArrayElements(env, name, 0); + + uuid_generate_md5(out, ns, bytes, length); + return fromBytes(env, out); +} + +JNIEXPORT jobject JNICALL Java_org_argeo_api_uuid_libuuid_LibuuidFactory_randomUUIDStrong( + JNIEnv *env, jobject uuidFactory) { + uuid_t out; + + uuid_generate_random(out); + return fromBytes(env, out); +}