147 lines
4.7 KiB
C++
147 lines
4.7 KiB
C++
#include <jni.h>
|
|
#include <string>
|
|
#include <android/log.h>
|
|
#include <memory>
|
|
#include <vector>
|
|
#include "../include/cpp/add.h"
|
|
#include "../include/cpp/data_praser.h"
|
|
|
|
using core::math::add;
|
|
|
|
extern "C" JNIEXPORT jstring JNICALL
|
|
Java_com_example_cmake_1project_1test_MainActivity_stringFromJNI(
|
|
JNIEnv* env,
|
|
jobject /* this */) {
|
|
std::string hello = "Hello from C++ (multi-file)";
|
|
return env->NewStringUTF(hello.c_str());
|
|
}
|
|
|
|
extern "C" JNIEXPORT jint JNICALL
|
|
Java_com_example_cmake_1project_1test_MainActivity_addFromJNI(
|
|
JNIEnv* env,
|
|
jobject /* this */,
|
|
jint a,
|
|
jint b) {
|
|
(void)env;
|
|
return static_cast<jint>(add(static_cast<int>(a), static_cast<int>(b)));
|
|
}
|
|
|
|
extern "C" JNIEXPORT jobject JNICALL
|
|
Java_com_example_cmake_1project_1test_MainActivity_parseDeviceDataFromJNI(
|
|
JNIEnv* env,
|
|
jobject /* this */,
|
|
jbyteArray fileData) {
|
|
|
|
try {
|
|
// 将Java的byte数组转换为C++的vector
|
|
std::vector<uint8_t> cppFileData = convertJavaByteArrayToVector(env, fileData);
|
|
|
|
if (cppFileData.empty()) {
|
|
__android_log_print(ANDROID_LOG_WARN, "DataParser", "Empty file data received");
|
|
return nullptr;
|
|
}
|
|
|
|
// 调用C++的解析函数
|
|
std::vector<SensorData> result = parse_device_data(cppFileData);
|
|
|
|
// 将结果转换为Java对象
|
|
jobject javaResult = convertSensorDataVectorToJavaList(env, result);
|
|
|
|
if (javaResult == nullptr) {
|
|
__android_log_print(ANDROID_LOG_ERROR, "DataParser", "Failed to convert result to Java object");
|
|
} else {
|
|
__android_log_print(ANDROID_LOG_INFO, "DataParser", "Successfully parsed %zu data packets", result.size());
|
|
}
|
|
|
|
return javaResult;
|
|
|
|
} catch (const std::exception& e) {
|
|
__android_log_print(ANDROID_LOG_ERROR, "DataParser", "Exception during parsing: %s", e.what());
|
|
return nullptr;
|
|
} catch (...) {
|
|
__android_log_print(ANDROID_LOG_ERROR, "DataParser", "Unknown exception during parsing");
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
|
|
// ================= 流式解析 JNI 接口 =================
|
|
|
|
// 创建解析器实例,返回 native 句柄
|
|
extern "C" JNIEXPORT jlong JNICALL
|
|
Java_com_example_cmake_1project_1test_MainActivity_createStreamParser(
|
|
JNIEnv* env,
|
|
jobject /* this */) {
|
|
(void)env;
|
|
try {
|
|
auto* parser = new StreamParser();
|
|
return reinterpret_cast<jlong>(parser);
|
|
} catch (...) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// 释放解析器实例
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Java_com_example_cmake_1project_1test_MainActivity_destroyStreamParser(
|
|
JNIEnv* env,
|
|
jobject /* this */,
|
|
jlong handle) {
|
|
(void)env;
|
|
auto* parser = reinterpret_cast<StreamParser*>(handle);
|
|
delete parser;
|
|
}
|
|
|
|
// 追加一段字节流数据
|
|
extern "C" JNIEXPORT void JNICALL
|
|
Java_com_example_cmake_1project_1test_MainActivity_streamParserAppend(
|
|
JNIEnv* env,
|
|
jobject /* this */,
|
|
jlong handle,
|
|
jbyteArray chunk) {
|
|
auto* parser = reinterpret_cast<StreamParser*>(handle);
|
|
if (!parser || !chunk) return;
|
|
|
|
jsize len = env->GetArrayLength(chunk);
|
|
if (len <= 0) return;
|
|
std::vector<uint8_t> buf(static_cast<size_t>(len));
|
|
env->GetByteArrayRegion(chunk, 0, len, reinterpret_cast<jbyte*>(buf.data()));
|
|
parser->appendData(buf.data(), buf.size());
|
|
}
|
|
|
|
// 拉取已完成的所有数据包,转换为 Java List<SensorData>
|
|
extern "C" JNIEXPORT jobject JNICALL
|
|
Java_com_example_cmake_1project_1test_MainActivity_streamParserDrainPackets(
|
|
JNIEnv* env,
|
|
jobject /* this */,
|
|
jlong handle) {
|
|
auto* parser = reinterpret_cast<StreamParser*>(handle);
|
|
if (!parser) return nullptr;
|
|
std::vector<SensorData> packets = parser->getAllPackets();
|
|
return convertSensorDataVectorToJavaList(env, packets);
|
|
}
|
|
|
|
// 便捷方法:从整块数据按固定块大小模拟流式解析,返回解析到的所有包
|
|
extern "C" JNIEXPORT jobject JNICALL
|
|
Java_com_example_cmake_1project_1test_MainActivity_parseStreamFromBytes(
|
|
JNIEnv* env,
|
|
jobject /* this */,
|
|
jbyteArray data,
|
|
jint chunkSize) {
|
|
if (data == nullptr || chunkSize <= 0) return nullptr;
|
|
|
|
std::vector<uint8_t> src = convertJavaByteArrayToVector(env, data);
|
|
auto* parser = new StreamParser();
|
|
size_t offset = 0;
|
|
while (offset < src.size()) {
|
|
size_t n = std::min(static_cast<size_t>(chunkSize), src.size() - offset);
|
|
parser->appendData(src.data() + offset, n);
|
|
offset += n;
|
|
}
|
|
std::vector<SensorData> packets = parser->getAllPackets();
|
|
delete parser;
|
|
return convertSensorDataVectorToJavaList(env, packets);
|
|
}
|
|
|
|
|