93 lines
3.1 KiB
C++
93 lines
3.1 KiB
C++
// Copyright 2020 The Pigweed Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
// use this file except in compliance with the License. You may obtain a copy of
|
|
// the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
// License for the specific language governing permissions and limitations under
|
|
// the License.
|
|
|
|
// This file provides a Java Native Interface (JNI) version of the Detokenizer
|
|
// class. This facilitates using the tokenizer library from Java or other JVM
|
|
// languages. A corresponding Java class is provided in Detokenizer.java.
|
|
|
|
#include <jni.h>
|
|
|
|
#include <cstring>
|
|
#include <span>
|
|
|
|
#include "pw_preprocessor/concat.h"
|
|
#include "pw_tokenizer/detokenize.h"
|
|
#include "pw_tokenizer/token_database.h"
|
|
|
|
#define DETOKENIZER_METHOD(method) \
|
|
JNICALL PW_CONCAT(Java_dev_pigweed_tokenizer_, Detokenizer_, method)
|
|
|
|
namespace pw::tokenizer {
|
|
namespace {
|
|
|
|
Detokenizer* HandleToPointer(jlong handle) {
|
|
Detokenizer* detokenizer = nullptr;
|
|
std::memcpy(&detokenizer, &handle, sizeof(detokenizer));
|
|
static_assert(sizeof(detokenizer) <= sizeof(handle));
|
|
return detokenizer;
|
|
}
|
|
|
|
jlong PointerToHandle(Detokenizer* detokenizer) {
|
|
jlong handle = 0;
|
|
std::memcpy(&handle, &detokenizer, sizeof(detokenizer));
|
|
static_assert(sizeof(handle) >= sizeof(detokenizer));
|
|
return handle;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
extern "C" {
|
|
|
|
static_assert(sizeof(jbyte) == 1u);
|
|
|
|
JNIEXPORT jlong DETOKENIZER_METHOD(newNativeDetokenizer)(JNIEnv* env,
|
|
jclass,
|
|
jbyteArray array) {
|
|
jbyte* const data = env->GetByteArrayElements(array, nullptr);
|
|
const jsize size = env->GetArrayLength(array);
|
|
|
|
TokenDatabase tokens = TokenDatabase::Create(std::span(data, size));
|
|
const jlong handle =
|
|
PointerToHandle(new Detokenizer(tokens.ok() ? tokens : TokenDatabase()));
|
|
|
|
env->ReleaseByteArrayElements(array, data, 0);
|
|
return handle;
|
|
}
|
|
|
|
JNIEXPORT void DETOKENIZER_METHOD(deleteNativeDetokenizer)(JNIEnv*,
|
|
jclass,
|
|
jlong handle) {
|
|
delete HandleToPointer(handle);
|
|
}
|
|
|
|
JNIEXPORT jstring DETOKENIZER_METHOD(detokenizeNative)(JNIEnv* env,
|
|
jobject,
|
|
jlong handle,
|
|
jbyteArray array) {
|
|
jbyte* const data = env->GetByteArrayElements(array, nullptr);
|
|
const jsize size = env->GetArrayLength(array);
|
|
|
|
DetokenizedString result = HandleToPointer(handle)->Detokenize(data, size);
|
|
|
|
env->ReleaseByteArrayElements(array, data, 0);
|
|
|
|
return result.matches().empty()
|
|
? nullptr
|
|
: env->NewStringUTF(result.BestString().c_str());
|
|
}
|
|
|
|
} // extern "C"
|
|
|
|
} // namespace pw::tokenizer
|