/** * Copyright (c) 2017, Loic Blot * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #include #include #include #include "smsbuffer.h" #include "json.h" #define LOG_TAG "SmsBuffer" const char *SmsBuffer::classPathName = "fr/unix_experience/owncloud_sms/jni/SmsBuffer"; // See https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html JNINativeMethod SmsBuffer::methods[] = { DECL_JNIMETHOD(createNativeObject, "()J") DECL_JNIMETHOD(deleteNativeObject, "()V") DECL_JNIMETHOD(empty, "()Z") DECL_JNIMETHOD(asRawJsonString, "()Ljava/lang/String;") DECL_JNIMETHOD(getLastMessageDate, "()J") DECL_JNIMETHOD(push, "(IIIJLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V") DECL_JNIMETHOD(print, "()V") }; DECL_METHODSIZE(SmsBuffer) #define SMSBUFFER_CAST \ if (!SmsBuffer::gJava_inited) { \ SmsBuffer::gJava_inited = true; \ SmsBuffer::gJava_mHandle = env->GetFieldID(env->GetObjectClass(self), "mHandle", "J"); \ } \ long ptr = env->GetLongField(self, SmsBuffer::gJava_mHandle); \ SmsBuffer *me = reinterpret_cast(ptr); \ if (!me) { \ __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "It's not a SmsBuffer!"); \ assert(false); \ } bool SmsBuffer::gJava_inited = false; jfieldID SmsBuffer::gJava_mHandle{}; jlong SmsBuffer::createNativeObject(JNIEnv *env, jobject self) { return reinterpret_cast(new SmsBuffer()); } void SmsBuffer::deleteNativeObject(JNIEnv *env, jobject self) { SMSBUFFER_CAST __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "deleteNativeObject 0x%li", ptr); delete reinterpret_cast(ptr); } void SmsBuffer::reset_buffer() { m_buffer.clear(); m_buffer_empty = true; m_sms_count = 0; m_last_message_date = 0; } void SmsBuffer::push(JNIEnv *env, jobject self, jint msg_id, jint mailbox_id, jint type, jlong date, jstring address, jstring body, jstring read, jstring seen) { SMSBUFFER_CAST me->_push(msg_id, mailbox_id, type, date, env->GetStringUTFChars(address, NULL), env->GetStringUTFChars(body, NULL), env->GetStringUTFChars(read, NULL), env->GetStringUTFChars(seen, NULL)); } void SmsBuffer::_push(int msg_id, int mailbox_id, int type, long long date, const char *address, const char *body, const char *read, const char *seen) { // If buffer is not empty, we are joining messages if (!m_buffer_empty) { m_buffer << ","; } // Else, we are starting array else { m_buffer << "["; m_buffer_empty = false; } m_buffer << "{\"_id\":" << msg_id << "," << "\"mbox\":" << mailbox_id << "," << "\"type\":" << type << "," << "\"date\":" << date << "," << "\"body\":" << json::escape_string(body) << "," << "\"address\":" << json::escape_string(address) << "," << "\"read\":" << json::escape_string(read) << "," << "\"seen\":" << json::escape_string(seen) << "}"; if (date > m_last_message_date) { m_last_message_date = date; } m_sms_count++; } jboolean SmsBuffer::empty(JNIEnv *env, jobject self) { SMSBUFFER_CAST return (jboolean) (me->_empty() ? 1 : 0); } bool SmsBuffer::_empty() const { return m_buffer_empty; } void SmsBuffer::print(JNIEnv *env, jobject self) { SMSBUFFER_CAST me->_print(); } void SmsBuffer::_print() { __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "SmsBuffer content: '%s'", m_buffer.str().c_str()); } jstring SmsBuffer::asRawJsonString(JNIEnv *env, jobject self) { SMSBUFFER_CAST std::string result; me->as_raw_json_string(result); return env->NewStringUTF(result.c_str()); } void SmsBuffer::as_raw_json_string(std::string &result) { std::stringstream ss; ss << "{\"smsCount\": " << m_sms_count << ", \"smsDatas\": " << m_buffer.str() << "]}"; result = ss.str(); } jlong SmsBuffer::getLastMessageDate(JNIEnv *env, jobject self) { SMSBUFFER_CAST return me->_get_last_message_date(); } long long SmsBuffer::_get_last_message_date() const { return m_last_message_date; }