summaryrefslogtreecommitdiffstats
path: root/core/jni/android_pim_EventRecurrence.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/jni/android_pim_EventRecurrence.cpp')
-rw-r--r--core/jni/android_pim_EventRecurrence.cpp199
1 files changed, 199 insertions, 0 deletions
diff --git a/core/jni/android_pim_EventRecurrence.cpp b/core/jni/android_pim_EventRecurrence.cpp
new file mode 100644
index 0000000..cbe99bc
--- /dev/null
+++ b/core/jni/android_pim_EventRecurrence.cpp
@@ -0,0 +1,199 @@
+/* //device/libs/android_runtime/android_pim_EventRecurrence.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** 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
+**
+** http://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.
+*/
+
+#include <pim/EventRecurrence.h>
+#include "jni.h"
+#include "nativehelper/JNIHelp.h"
+#include <utils/String8.h>
+
+namespace android {
+
+struct cached_array_fields_t
+{
+ jfieldID array;
+ jfieldID count;
+};
+
+static jclass clazz;
+static jfieldID freq_field;
+static jfieldID until_field;
+static jfieldID count_field;
+static jfieldID interval_field;
+static jfieldID wkst_field;
+static cached_array_fields_t bysecond_fields;
+static cached_array_fields_t byminute_fields;
+static cached_array_fields_t byhour_fields;
+static cached_array_fields_t byday_fields;
+static cached_array_fields_t bydayNum_fields;
+static cached_array_fields_t bymonthday_fields;
+static cached_array_fields_t byyearday_fields;
+static cached_array_fields_t byweekno_fields;
+static cached_array_fields_t bymonth_fields;
+static cached_array_fields_t bysetpos_fields;
+
+static status_t
+set_array(JNIEnv* env, int inCount, int* inArray,
+ jobject This, const cached_array_fields_t& fields)
+{
+ if (inCount > 0) {
+ jintArray array = (jintArray) env->GetObjectField(This, fields.array);
+ if (array == NULL || env->GetArrayLength(array) < inCount) {
+ // +4 because it's cheap to allocate a little extra here, and
+ // that reduces the chance that we'll come back here again
+ array = env->NewIntArray(inCount+4);
+ env->SetObjectField(This, fields.array, array);
+ }
+ if (array == NULL) {
+ return NO_MEMORY;
+ }
+ env->SetIntArrayRegion(array, 0, inCount, inArray);
+
+ }
+ env->SetIntField(This, fields.count, inCount);
+ return NO_ERROR;
+}
+
+/*
+ * In class android.pim.EventRecurrence
+ * public native int parse(String str);
+ */
+#define SET_ARRAY_AND_CHECK(name) \
+ /*printf("setting " #name " to %d elements\n", er.name##Count);*/ \
+ if (set_array(env, er.name##Count, er.name, This, name##_fields) \
+ != NO_ERROR) { \
+ jniThrowException(env, "java/lang/RuntimeException", \
+ "EventRecurrence.parse error setting field " #name " or " \
+ #name "Count."); \
+ return ; \
+ }
+static void
+EventRecurrence_parse(JNIEnv* env, jobject This, jstring jstr)
+{
+ if (jstr == NULL) {
+ jniThrowException(env, "java/lang/NullPointerException",
+ "EventRecurrence.parse str parameter null");
+ return ;
+ }
+ jboolean isCopy;
+ const jchar* jchars = env->GetStringChars(jstr, &isCopy);
+ jsize len = env->GetStringLength(jstr);
+ String16 str(jchars, len);
+ env->ReleaseStringChars(jstr, jchars);
+
+ //printf("the string was '%s'\n", String8(str).string());
+
+ EventRecurrence er;
+ if (NO_ERROR != er.parse(str)) {
+ String8 msg("Error parsing recurrence: '");
+ msg.append(String8(str));
+ msg.append("'");
+
+ jniThrowException(env,
+ "android/pim/EventRecurrence$InvalidFormatException",
+ msg.string());
+ return ;
+ }
+
+ jstring untilStr;
+ if (er.until.size() > 0) {
+ untilStr = env->NewString(er.until.string(), er.until.size());
+ if (untilStr == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException",
+ "EventRecurrence.parse error setting field 'until'");
+ return ;
+ }
+ } else {
+ untilStr = NULL;
+ }
+ env->SetObjectField(This, until_field, untilStr);
+
+ env->SetIntField(This, freq_field, er.freq);
+ env->SetIntField(This, count_field, er.count);
+ env->SetIntField(This, interval_field, er.interval);
+ env->SetIntField(This, wkst_field, er.wkst);
+
+ SET_ARRAY_AND_CHECK(bysecond)
+ SET_ARRAY_AND_CHECK(byminute)
+ SET_ARRAY_AND_CHECK(byhour)
+ SET_ARRAY_AND_CHECK(byday)
+ // we'll just set the bydayCount field twice, it'll be less code total
+ if (set_array(env, er.bydayCount, er.bydayNum, This, bydayNum_fields)
+ != NO_ERROR) {
+ jniThrowException(env, "java/lang/RuntimeException",
+ "EventRecurrence.parse error setting field bydayNum or "
+ "bydayCount.");
+ return ;
+ }
+ SET_ARRAY_AND_CHECK(bymonthday)
+ SET_ARRAY_AND_CHECK(byyearday)
+ SET_ARRAY_AND_CHECK(byweekno)
+ SET_ARRAY_AND_CHECK(bymonth)
+ SET_ARRAY_AND_CHECK(bysetpos)
+}
+
+/*
+ * JNI registration.
+ */
+static JNINativeMethod METHODS[] = {
+ /* name, signature, funcPtr */
+ { "parse", "(Ljava/lang/String;)V", (void*)EventRecurrence_parse }
+};
+
+static const char*const CLASS_NAME = "android/pim/EventRecurrence";
+
+int register_android_pim_EventRecurrence(JNIEnv* env)
+{
+ clazz = env->FindClass(CLASS_NAME);
+ if (clazz == NULL) {
+ LOGE("Field lookup unable to find class '%s'\n", CLASS_NAME);
+ return -1;
+ }
+
+ freq_field = env->GetFieldID(clazz, "freq", "I");
+ count_field = env->GetFieldID(clazz, "count", "I");
+ interval_field = env->GetFieldID(clazz, "interval", "I");
+ wkst_field = env->GetFieldID(clazz, "wkst", "I");
+
+ until_field = env->GetFieldID(clazz, "until", "Ljava/lang/String;");
+
+ bysecond_fields.array = env->GetFieldID(clazz, "bysecond", "[I");
+ bysecond_fields.count = env->GetFieldID(clazz, "bysecondCount", "I");
+ byminute_fields.array = env->GetFieldID(clazz, "byminute", "[I");
+ byminute_fields.count = env->GetFieldID(clazz, "byminuteCount", "I");
+ byhour_fields.array = env->GetFieldID(clazz, "byhour", "[I");
+ byhour_fields.count = env->GetFieldID(clazz, "byhourCount", "I");
+ byday_fields.array = env->GetFieldID(clazz, "byday", "[I");
+ byday_fields.count = env->GetFieldID(clazz, "bydayCount", "I");
+ bydayNum_fields.array = env->GetFieldID(clazz, "bydayNum", "[I");
+ bydayNum_fields.count = byday_fields.count;
+ bymonthday_fields.array = env->GetFieldID(clazz, "bymonthday", "[I");
+ bymonthday_fields.count = env->GetFieldID(clazz, "bymonthdayCount", "I");
+ byyearday_fields.array = env->GetFieldID(clazz, "byyearday", "[I");
+ byyearday_fields.count = env->GetFieldID(clazz, "byyeardayCount", "I");
+ byweekno_fields.array = env->GetFieldID(clazz, "byweekno", "[I");
+ byweekno_fields.count = env->GetFieldID(clazz, "byweeknoCount", "I");
+ bymonth_fields.array = env->GetFieldID(clazz, "bymonth", "[I");
+ bymonth_fields.count = env->GetFieldID(clazz, "bymonthCount", "I");
+ bysetpos_fields.array = env->GetFieldID(clazz, "bysetpos", "[I");
+ bysetpos_fields.count = env->GetFieldID(clazz, "bysetposCount", "I");
+
+ return jniRegisterNativeMethods(env, CLASS_NAME,
+ METHODS, sizeof(METHODS)/sizeof(METHODS[0]));
+}
+
+}; // namespace android
+