forked from pEp.foundation/pEpJNIAdapter
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
373 lines
13 KiB
Plaintext
373 lines
13 KiB
Plaintext
include yslt.yml2
|
|
include yslt.yml2
|
|
|
|
tstylesheet {
|
|
include ./textutils.ysl2
|
|
include ./types_c.ysl2
|
|
|
|
template "/namespace[@name='pEp']" {
|
|
apply "struct", 0;
|
|
document("../../build/marker/gen_cpp_Message.marker", "text") > ""
|
|
}
|
|
|
|
template "struct" {
|
|
const "jname" call "CamelCase" with "text", "@name";
|
|
|
|
document("../cxx/foundation_pEp_jniadapter_{$jname}.cc", "text") {
|
|
||
|
|
#include <cassert>
|
|
#include <pEp/mime.h>
|
|
#include <pEp/map_asn1.h>
|
|
#include <pEp/message_codec.h>
|
|
#include <pEp/pEpLog.hh>
|
|
#include "jniutils.hh"
|
|
#include "throw_pEp_exception.hh"
|
|
#include "foundation_pEp_jniadapter_«$jname».h"
|
|
|
|
using namespace std;
|
|
|
|
namespace pEp {
|
|
namespace JNIAdapter {
|
|
static ::«@name» *«@name»_ptr(JNIEnv *env, jobject me) {
|
|
jfieldID handle;
|
|
handle = getFieldID(env, "foundation/pEp/jniadapter/«$jname»", "handle", "J");
|
|
if(!handle) {
|
|
throw runtime_error("field not found: handle");
|
|
}
|
|
|
|
long handle_val = static_cast<long>(env->GetLongField(me, handle));
|
|
if(!handle_val) {
|
|
throw runtime_error("invalid handle (0)");
|
|
}
|
|
|
|
return reinterpret_cast<::«@name» *>(handle_val);
|
|
}
|
|
|
|
};
|
|
};
|
|
|
|
extern "C" {
|
|
|
|
using namespace pEp::JNIAdapter;
|
|
|
|
JNIEXPORT jlong JNICALL Java_foundation_pEp_jniadapter_«$jname»_init(JNIEnv *env,
|
|
jobject obj)
|
|
{
|
|
pEpLog("called");
|
|
::«@name» * _obj = ::new_«@name»(PEP_dir_incoming);
|
|
if (!_obj) {
|
|
outOfMemory(env);
|
|
return 0;
|
|
}
|
|
return reinterpret_cast<jlong>(_obj);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_«$jname»_release(JNIEnv *env,
|
|
jobject obj,
|
|
jlong value)
|
|
{
|
|
pEpLog("called");
|
|
if (value) {
|
|
::«@name» *_obj = reinterpret_cast<::«@name» *>(value);
|
|
::free_«@name»(_obj);
|
|
}
|
|
}
|
|
|
|
JNIEXPORT jlong JNICALL Java_foundation_pEp_jniadapter_«$jname»__1«$jname»(JNIEnv *env,
|
|
jobject msg,
|
|
jbyteArray mime_text)
|
|
{
|
|
pEpLog("called");
|
|
char *_mime_text = to_string(env, mime_text);
|
|
size_t _size = env->GetArrayLength(mime_text);
|
|
|
|
::«@name» *_msg = nullptr;
|
|
PEP_STATUS status = mime_decode_«@name»(_mime_text, _size, &_msg, NULL);
|
|
if (status) {
|
|
throw_pEp_Exception(env, status);
|
|
}
|
|
|
|
return reinterpret_cast<jlong>(_msg);
|
|
}
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_foundation_pEp_jniadapter_«$jname»__1encodeMIME(JNIEnv *env,
|
|
jobject obj)
|
|
{
|
|
pEpLog("called");
|
|
«@name»* _obj = nullptr;
|
|
try {
|
|
_obj = «@name»_ptr(env, obj);
|
|
} catch(...) {
|
|
jclass ex = env->FindClass("java/lang/IllegalStateException");
|
|
assert(ex);
|
|
env->ThrowNew(ex, nullptr);
|
|
return static_cast<jbyteArray>(NULL);
|
|
}
|
|
|
|
char *mime_text = nullptr;
|
|
PEP_STATUS status = ::mime_encode_«@name»(_obj, false, &mime_text, false);
|
|
if (status) {
|
|
throw_pEp_Exception(env, status);
|
|
}
|
|
jbyteArray result = from_string(env, mime_text);
|
|
free(mime_text);
|
|
|
|
return result;
|
|
}
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_foundation_pEp_jniadapter_Message__1encodeASN1XER(JNIEnv *env,
|
|
jclass clazz,
|
|
jobject _msg)
|
|
{
|
|
pEpLog("called");
|
|
message* msg = nullptr;
|
|
try {
|
|
msg = message_ptr(env, _msg);
|
|
} catch(...) {
|
|
jclass ex = env->FindClass("java/lang/IllegalStateException");
|
|
assert(ex);
|
|
env->ThrowNew(ex, nullptr);
|
|
return NULL;
|
|
}
|
|
|
|
// create ASN1Message
|
|
ASN1Message_t *msg_asn1 = ::ASN1Message_from_message(msg, NULL, true, 0);
|
|
if (msg_asn1 == nullptr) {
|
|
jclass ex = env->FindClass("java/lang/IllegalStateException");
|
|
assert(ex);
|
|
env->ThrowNew(ex, nullptr);
|
|
return NULL;
|
|
}
|
|
|
|
// encode PER
|
|
char *msg_per = nullptr;
|
|
size_t data_size_per = 0;
|
|
PEP_STATUS status = ::encode_ASN1Message_message(msg_asn1, &msg_per, &data_size_per);
|
|
free(msg_asn1);
|
|
if (status) {
|
|
throw_pEp_Exception(env, status);
|
|
return NULL;
|
|
}
|
|
if (msg_per == nullptr) {
|
|
jclass ex = env->FindClass("java/lang/IllegalStateException");
|
|
assert(ex);
|
|
env->ThrowNew(ex, nullptr);
|
|
return NULL;
|
|
}
|
|
|
|
// encode PER to XER
|
|
char *msg_xer = nullptr;
|
|
status = ::PER_to_XER_ASN1Message_msg(msg_per, data_size_per, &msg_xer);
|
|
free(msg_per);
|
|
if (status) {
|
|
throw_pEp_Exception(env, status);
|
|
return NULL;
|
|
}
|
|
if (msg_xer == nullptr) {
|
|
jclass ex = env->FindClass("java/lang/IllegalStateException");
|
|
assert(ex);
|
|
env->ThrowNew(ex, nullptr);
|
|
return NULL;
|
|
}
|
|
|
|
jbyteArray result = from_string(env, msg_xer);
|
|
return result;
|
|
}
|
|
|
|
JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Message__1decodeASN1XER(JNIEnv *env,
|
|
jclass clazz,
|
|
jbyteArray _msg_xer)
|
|
{
|
|
pEpLog("called");
|
|
char *msg_xer = nullptr;
|
|
if(_msg_xer) {
|
|
msg_xer = to_string(env, _msg_xer);
|
|
}
|
|
// validate param msg_xer
|
|
if (msg_xer == nullptr) {
|
|
jclass ex = env->FindClass("java/lang/IllegalStateException");
|
|
assert(ex);
|
|
env->ThrowNew(ex, nullptr);
|
|
return NULL;
|
|
}
|
|
|
|
// convert XER to PER
|
|
char *msg_per = nullptr;
|
|
size_t msg_per_size = 0;
|
|
PEP_STATUS status = ::XER_to_PER_ASN1Message_msg(msg_xer, &msg_per, &msg_per_size);
|
|
free(msg_xer);
|
|
if (status) {
|
|
throw_pEp_Exception(env, status);
|
|
return NULL;
|
|
}
|
|
if (msg_per == nullptr) {
|
|
jclass ex = env->FindClass("java/lang/IllegalStateException");
|
|
assert(ex);
|
|
env->ThrowNew(ex, nullptr);
|
|
return NULL;
|
|
}
|
|
|
|
// decode PER to ASN1Message
|
|
ASN1Message *msg_asn1 = nullptr;
|
|
status = ::decode_ASN1Message_message(msg_per, msg_per_size, &msg_asn1);
|
|
free(msg_per);
|
|
if (status) {
|
|
throw_pEp_Exception(env, status);
|
|
return NULL;
|
|
}
|
|
if (msg_asn1 == nullptr) {
|
|
jclass ex = env->FindClass("java/lang/IllegalStateException");
|
|
assert(ex);
|
|
env->ThrowNew(ex, nullptr);
|
|
return NULL;
|
|
}
|
|
|
|
// convert ASN1Message to message
|
|
message *msg_out = nullptr;
|
|
msg_out = ::ASN1Message_to_message(msg_asn1, NULL, false, 0);
|
|
// msg_asn1 gets moved, so dont free it
|
|
if (msg_out == nullptr) {
|
|
jclass ex = env->FindClass("java/lang/IllegalStateException");
|
|
assert(ex);
|
|
env->ThrowNew(ex, nullptr);
|
|
return NULL;
|
|
}
|
|
|
|
// Convert message to java class Message
|
|
jobject msg_ = nullptr;
|
|
jclass clazz_dst_ = findClass(env, "foundation/pEp/jniadapter/Message");
|
|
assert(clazz_dst_);
|
|
jmethodID constructor_dst_ = env->GetMethodID(clazz_dst_, "<init>", "(J)V");
|
|
assert(constructor_dst_);
|
|
msg_ = env->NewObject(clazz_dst_, constructor_dst_, reinterpret_cast<jlong>(msg_out));
|
|
|
|
// msg_ will point to msg_out, so dont free it
|
|
if (msg_ == nullptr) {
|
|
jclass ex = env->FindClass("java/lang/IllegalStateException");
|
|
assert(ex);
|
|
env->ThrowNew(ex, nullptr);
|
|
return NULL;
|
|
}
|
|
|
|
return msg_;
|
|
}
|
|
|
|
||
|
|
apply "*[name(.)!='enum']", 0, mode=entry {
|
|
with "name", "@name";
|
|
with "class" call "CamelCase" with "text", "@name";
|
|
}
|
|
||
|
|
} // extern "C"
|
|
|
|
||
|
|
}
|
|
}
|
|
|
|
function "mangle" {
|
|
param "type";
|
|
param "name";
|
|
param "classname" call "CamelCase" with "text", "../@name";
|
|
|
|
> «concat('Java_foundation_pEp_jniadapter_', $classname, '__1', str:replace($name, '_', '_1'))»
|
|
}
|
|
|
|
template "*", mode=entry {
|
|
param "name";
|
|
param "class";
|
|
const "ctype" call "toC" with "type", "name(.)";
|
|
const "jname" call "CamelCase" with "text", "name(*[1])";
|
|
const "cname" call "lcase" with "text", "name(*[1])";
|
|
const "type", "name(.)";
|
|
const "getname" call "mangle" {
|
|
with "type", "$type";
|
|
with "name", "concat('get', $jname)";
|
|
}
|
|
const "setname" call "mangle" {
|
|
with "type", "$type";
|
|
with "name", "concat('set', $jname)";
|
|
}
|
|
const "type_ret" call "jni_type" with "type", "name(.)";
|
|
|
|
||
|
|
// CodeGen: Getter
|
|
JNIEXPORT «$type_ret» JNICALL «$getname»(JNIEnv *env,
|
|
jobject obj)
|
|
{
|
|
pEpLog("called");
|
|
«$name»* _obj = nullptr;
|
|
try {
|
|
_obj = «$name»_ptr(env, obj);
|
|
} catch(...) {
|
|
jclass ex = env->FindClass("java/lang/IllegalStateException");
|
|
assert(ex);
|
|
env->ThrowNew(ex, nullptr);
|
|
return static_cast<«$type_ret»>(NULL);
|
|
}
|
|
|
|
||
|
|
choose {
|
|
when "../enum[@name=$type]"
|
|
|> return _obj->«$cname»;
|
|
otherwise
|
|
|> return from_«$type»(env, _obj->«$cname»);
|
|
}
|
|
||
|
|
}
|
|
// CodeGen: Setter
|
|
JNIEXPORT void JNICALL «$setname»(JNIEnv *env,
|
|
jobject obj,
|
|
`call "jni_type" with "type", "name(.)"`
|
|
value)
|
|
{
|
|
pEpLog("called");
|
|
«$name»* _obj = nullptr;
|
|
try {
|
|
_obj = «$name»_ptr(env, obj);
|
|
} catch(...) {
|
|
jclass ex = env->FindClass("java/lang/IllegalStateException");
|
|
assert(ex);
|
|
env->ThrowNew(ex, nullptr);
|
|
return;
|
|
}
|
|
||
|
|
choose {
|
|
when "../enum[@name=$type]"
|
|
|> _obj->«$cname» = static_cast<«$ctype»>(value);
|
|
otherwise {
|
|
choose {
|
|
when "$type = 'string'" {
|
|
|> free(_obj->«$cname»);
|
|
}
|
|
otherwise {
|
|
const "free" choose {
|
|
when "$ctype = 'pEp_identity'" > identity
|
|
when "contains($ctype, '_t')" value "substring-before($ctype, '_t')";
|
|
otherwise value "$ctype";
|
|
}
|
|
|
|
|> free_«$free»(_obj->«$cname»);
|
|
}
|
|
}
|
|
|> if(value) {
|
|
choose {
|
|
when "$type = 'string'" {
|
|
|>> _obj->«$cname» = to_«$type»(env, value);
|
|
}
|
|
otherwise {
|
|
|>> _obj->«$cname» = to_«$type»(env, value);
|
|
}
|
|
}
|
|
|> } else {
|
|
|> _obj->«$cname» = NULL;
|
|
|> }
|
|
}
|
|
}
|
|
||
|
|
}
|
|
|
|
||
|
|
}
|
|
}
|
|
|