19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2006, The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "Log_println" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h> 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/String8.h> 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <assert.h> 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h" 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/misc.h" 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_runtime/AndroidRuntime.h" 2668dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes#include "ScopedStringChars.h" 27cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru#include "TimeUtils.h" 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <nativehelper/JNIHelp.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/tztime.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_allDayField = 0; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_secField = 0; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_minField = 0; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_hourField = 0; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_mdayField = 0; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_monField = 0; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_yearField = 0; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_wdayField = 0; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_ydayField = 0; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_isdstField = 0; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_gmtoffField = 0; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_timezoneField = 0; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_shortMonthsField = 0; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_longMonthsField = 0; 48cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Querustatic jfieldID g_longStandaloneMonthsField = 0; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_shortWeekdaysField = 0; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_longWeekdaysField = 0; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_timeOnlyFormatField = 0; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_dateOnlyFormatField = 0; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_dateTimeFormatField = 0; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_amField = 0; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_pmField = 0; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID g_dateCommandField = 0; 574df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Projectstatic jfieldID g_localeField = 0; 584df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 594df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Projectstatic jclass g_timeClass = NULL; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline bool java2time(JNIEnv* env, Time* t, jobject o) 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->t.tm_sec = env->GetIntField(o, g_secField); 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->t.tm_min = env->GetIntField(o, g_minField); 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->t.tm_hour = env->GetIntField(o, g_hourField); 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->t.tm_mday = env->GetIntField(o, g_mdayField); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->t.tm_mon = env->GetIntField(o, g_monField); 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->t.tm_year = (env->GetIntField(o, g_yearField))-1900; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->t.tm_wday = env->GetIntField(o, g_wdayField); 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->t.tm_yday = env->GetIntField(o, g_ydayField); 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->t.tm_isdst = env->GetIntField(o, g_isdstField); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t->t.tm_gmtoff = env->GetLongField(o, g_gmtoffField); 73be414332a11b539b8b7751f31a0ef584f11b48f6Elliott Hughes bool allDay = env->GetBooleanField(o, g_allDayField); 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (allDay && 7568dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes ((t->t.tm_sec !=0) || (t->t.tm_min != 0) || (t->t.tm_hour != 0))) { 7668dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes jniThrowException(env, "java/lang/IllegalArgumentException", 7768dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes "allDay is true but sec, min, hour are not 0."); 7868dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes return false; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline void time2java(JNIEnv* env, jobject o, const Time &t) 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(o, g_secField, t.t.tm_sec); 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(o, g_minField, t.t.tm_min); 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(o, g_hourField, t.t.tm_hour); 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(o, g_mdayField, t.t.tm_mday); 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(o, g_monField, t.t.tm_mon); 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(o, g_yearField, t.t.tm_year+1900); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(o, g_wdayField, t.t.tm_wday); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(o, g_ydayField, t.t.tm_yday); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(o, g_isdstField, t.t.tm_isdst); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetLongField(o, g_gmtoffField, t.t.tm_gmtoff); 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define ACQUIRE_TIMEZONE(This, t) \ 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jstring timezoneString_##This \ 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = (jstring) env->GetObjectField(This, g_timezoneField); \ 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.timezone = env->GetStringUTFChars(timezoneString_##This, NULL); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define RELEASE_TIMEZONE(This, t) \ 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseStringUTFChars(timezoneString_##This, t.timezone); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ============================================================================ 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_text_format_Time_normalize(JNIEnv* env, jobject This, 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jboolean ignoreDst) 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Time t; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!java2time(env, &t, This)) return 0L; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ACQUIRE_TIMEZONE(This, t) 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int64_t result = t.toMillis(ignoreDst != 0); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time2java(env, This, t); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RELEASE_TIMEZONE(This, t) 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_text_format_Time_switchTimezone(JNIEnv* env, jobject This, 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jstring timezoneObject) 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Time t; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!java2time(env, &t, This)) return; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ACQUIRE_TIMEZONE(This, t) 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* timezone = env->GetStringUTFChars(timezoneObject, NULL); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.switchTimezone(timezone); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time2java(env, This, t); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseStringUTFChars(timezoneObject, timezone); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RELEASE_TIMEZONE(This, t) 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we do this here because there's no point in reallocating the string 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetObjectField(This, g_timezoneField, timezoneObject); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_text_format_Time_compare(JNIEnv* env, jobject clazz, 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject aObject, jobject bObject) 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Time a, b; 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!java2time(env, &a, aObject)) return 0; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ACQUIRE_TIMEZONE(aObject, a) 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!java2time(env, &b, bObject)) return 0; 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ACQUIRE_TIMEZONE(bObject, b) 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = Time::compare(a, b); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RELEASE_TIMEZONE(aObject, a) 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RELEASE_TIMEZONE(bObject, b) 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jstring android_text_format_Time_format2445(JNIEnv* env, jobject This) 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Time t; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!java2time(env, &t, This)) return env->NewStringUTF(""); 165be414332a11b539b8b7751f31a0ef584f11b48f6Elliott Hughes bool allDay = env->GetBooleanField(This, g_allDayField); 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allDay) { 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ACQUIRE_TIMEZONE(This, t) 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool inUtc = strcmp("UTC", t.timezone) == 0; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project short buf[16]; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.format2445(buf, true); 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RELEASE_TIMEZONE(This, t) 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inUtc) { 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The letter 'Z' is appended to the end so allow for one 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // more character in the buffer. 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return env->NewString((jchar*)buf, 16); 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return env->NewString((jchar*)buf, 15); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project short buf[8]; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.format2445(buf, false); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return env->NewString((jchar*)buf, 8); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jstring android_text_format_Time_format(JNIEnv* env, jobject This, 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jstring formatObject) 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1904df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // We only teardown and setup our 'locale' struct and other state 1914df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // when the Java-side locale changed. This is safe to do here 1924df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // without locking because we're always called from Java code 1934df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // synchronized on the class instance. 1944df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project static jobject js_locale_previous = NULL; 1954df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project static struct strftime_locale locale; 1964df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project static jstring js_mon[12], js_month[12], js_wday[7], js_weekday[7]; 197cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru static jstring js_standalone_month[12]; 1984df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project static jstring js_X_fmt, js_x_fmt, js_c_fmt, js_am, js_pm, js_date_fmt; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2004df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project Time t; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!java2time(env, &t, This)) return env->NewStringUTF(""); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2034df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project jclass timeClass = g_timeClass; 2044df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project jobject js_locale = (jobject) env->GetStaticObjectField(timeClass, g_localeField); 2054df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (js_locale_previous != js_locale) { 2064df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (js_locale_previous != NULL) { 2074df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // Free the old one. 2084df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project for (int i = 0; i < 12; i++) { 2094df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->ReleaseStringUTFChars(js_mon[i], locale.mon[i]); 2104df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->ReleaseStringUTFChars(js_month[i], locale.month[i]); 211cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru env->ReleaseStringUTFChars(js_standalone_month[i], locale.standalone_month[i]); 2124df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->DeleteGlobalRef(js_mon[i]); 2134df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->DeleteGlobalRef(js_month[i]); 214cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru env->DeleteGlobalRef(js_standalone_month[i]); 2154df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 2164df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 2174df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project for (int i = 0; i < 7; i++) { 2184df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->ReleaseStringUTFChars(js_wday[i], locale.wday[i]); 2194df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->ReleaseStringUTFChars(js_weekday[i], locale.weekday[i]); 2204df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->DeleteGlobalRef(js_wday[i]); 2214df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->DeleteGlobalRef(js_weekday[i]); 2224df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 2234df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 2244df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->ReleaseStringUTFChars(js_X_fmt, locale.X_fmt); 2254df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->ReleaseStringUTFChars(js_x_fmt, locale.x_fmt); 2264df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->ReleaseStringUTFChars(js_c_fmt, locale.c_fmt); 2274df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->ReleaseStringUTFChars(js_am, locale.am); 2284df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->ReleaseStringUTFChars(js_pm, locale.pm); 2294df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->ReleaseStringUTFChars(js_date_fmt, locale.date_fmt); 2304df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->DeleteGlobalRef(js_X_fmt); 2314df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->DeleteGlobalRef(js_x_fmt); 2324df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->DeleteGlobalRef(js_c_fmt); 2334df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->DeleteGlobalRef(js_am); 2344df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->DeleteGlobalRef(js_pm); 2354df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project env->DeleteGlobalRef(js_date_fmt); 2364df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 2374df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project js_locale_previous = js_locale; 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2394df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project jobjectArray ja; 2404df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project ja = (jobjectArray) env->GetStaticObjectField(timeClass, g_shortMonthsField); 2414df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project for (int i = 0; i < 12; i++) { 24299c406e42ba154584070ca7ec100e8be7ff8a800Elliott Hughes // Calendar.JANUARY == 0. 2434df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project js_mon[i] = (jstring) env->NewGlobalRef(env->GetObjectArrayElement(ja, i)); 2444df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project locale.mon[i] = env->GetStringUTFChars(js_mon[i], NULL); 2454df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2474df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project ja = (jobjectArray) env->GetStaticObjectField(timeClass, g_longMonthsField); 2484df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project for (int i = 0; i < 12; i++) { 24999c406e42ba154584070ca7ec100e8be7ff8a800Elliott Hughes // Calendar.JANUARY == 0. 2504df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project js_month[i] = (jstring) env->NewGlobalRef(env->GetObjectArrayElement(ja, i)); 2514df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project locale.month[i] = env->GetStringUTFChars(js_month[i], NULL); 2524df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 254cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru ja = (jobjectArray) env->GetStaticObjectField(timeClass, g_longStandaloneMonthsField); 255cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru for (int i = 0; i < 12; i++) { 25699c406e42ba154584070ca7ec100e8be7ff8a800Elliott Hughes // Calendar.JANUARY == 0. 257cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru js_standalone_month[i] = (jstring) env->NewGlobalRef(env->GetObjectArrayElement(ja, i)); 258cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru locale.standalone_month[i] = env->GetStringUTFChars(js_standalone_month[i], NULL); 259cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru } 260cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru 2614df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project ja = (jobjectArray) env->GetStaticObjectField(timeClass, g_shortWeekdaysField); 2624df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project for (int i = 0; i < 7; i++) { 26399c406e42ba154584070ca7ec100e8be7ff8a800Elliott Hughes // Calendar.SUNDAY == 1, and there's an empty string in element 0. 26499c406e42ba154584070ca7ec100e8be7ff8a800Elliott Hughes js_wday[i] = (jstring) env->NewGlobalRef(env->GetObjectArrayElement(ja, i + 1)); 2654df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project locale.wday[i] = env->GetStringUTFChars(js_wday[i], NULL); 2664df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2684df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project ja = (jobjectArray) env->GetStaticObjectField(timeClass, g_longWeekdaysField); 2694df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project for (int i = 0; i < 7; i++) { 27099c406e42ba154584070ca7ec100e8be7ff8a800Elliott Hughes // Calendar.SUNDAY == 1, and there's an empty string in element 0. 27199c406e42ba154584070ca7ec100e8be7ff8a800Elliott Hughes js_weekday[i] = (jstring) env->NewGlobalRef(env->GetObjectArrayElement(ja, i + 1)); 2724df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project locale.weekday[i] = env->GetStringUTFChars(js_weekday[i], NULL); 2734df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 2744df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 2754df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project js_X_fmt = (jstring) env->NewGlobalRef(env->GetStaticObjectField( 2764df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project timeClass, g_timeOnlyFormatField)); 2774df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project locale.X_fmt = env->GetStringUTFChars(js_X_fmt, NULL); 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2794df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project js_x_fmt = (jstring) env->NewGlobalRef(env->GetStaticObjectField( 2804df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project timeClass, g_dateOnlyFormatField)); 2814df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project locale.x_fmt = env->GetStringUTFChars(js_x_fmt, NULL); 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2834df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project js_c_fmt = (jstring) env->NewGlobalRef(env->GetStaticObjectField( 2844df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project timeClass, g_dateTimeFormatField)); 2854df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project locale.c_fmt = env->GetStringUTFChars(js_c_fmt, NULL); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2874df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project js_am = (jstring) env->NewGlobalRef(env->GetStaticObjectField( 2884df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project timeClass, g_amField)); 2894df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project locale.am = env->GetStringUTFChars(js_am, NULL); 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2914df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project js_pm = (jstring) env->NewGlobalRef(env->GetStaticObjectField( 2924df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project timeClass, g_pmField)); 2934df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project locale.pm = env->GetStringUTFChars(js_pm, NULL); 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2954df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project js_date_fmt = (jstring) env->NewGlobalRef(env->GetStaticObjectField( 2964df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project timeClass, g_dateCommandField)); 2974df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project locale.date_fmt = env->GetStringUTFChars(js_date_fmt, NULL); 2984df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ACQUIRE_TIMEZONE(This, t) 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* format = env->GetStringUTFChars(formatObject, NULL); 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 r = t.format(format, &locale); 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseStringUTFChars(formatObject, format); 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RELEASE_TIMEZONE(This, t) 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return env->NewStringUTF(r.string()); 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jstring android_text_format_Time_toString(JNIEnv* env, jobject This) 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Time t; 31668dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes if (!java2time(env, &t, This)) return env->NewStringUTF(""); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ACQUIRE_TIMEZONE(This, t) 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 r = t.toString(); 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RELEASE_TIMEZONE(This, t) 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return env->NewStringUTF(r.string()); 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_text_format_Time_setToNow(JNIEnv* env, jobject This) 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetBooleanField(This, g_allDayField, JNI_FALSE); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Time t; 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ACQUIRE_TIMEZONE(This, t) 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.setToNow(); 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time2java(env, This, t); 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RELEASE_TIMEZONE(This, t) 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_text_format_Time_toMillis(JNIEnv* env, jobject This, 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jboolean ignoreDst) 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Time t; 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!java2time(env, &t, This)) return 0L; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ACQUIRE_TIMEZONE(This, t) 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int64_t result = t.toMillis(ignoreDst != 0); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RELEASE_TIMEZONE(This, t) 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_text_format_Time_set(JNIEnv* env, jobject This, jlong millis) 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetBooleanField(This, g_allDayField, JNI_FALSE); 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Time t; 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ACQUIRE_TIMEZONE(This, t) 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.set(millis); 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time2java(env, This, t); 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RELEASE_TIMEZONE(This, t) 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ============================================================================ 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Just do this here because it's not worth recreating the strings 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36868dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughesstatic int get_char(JNIEnv* env, const ScopedStringChars& s, int spos, int mul, 36968dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes bool* thrown) 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jchar c = s[spos]; 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c >= '0' && c <= '9') { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (c - '0') * mul; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3759db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru if (!*thrown) { 37668dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes jniThrowExceptionFmt(env, "android/util/TimeFormatException", 37768dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes "Parse error at pos=%d", spos); 3789db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru *thrown = true; 3799db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru } 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38468dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughesstatic bool check_char(JNIEnv* env, const ScopedStringChars& s, int spos, jchar expected) 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jchar c = s[spos]; 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c != expected) { 38868dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes jniThrowExceptionFmt(env, "android/util/TimeFormatException", 38968dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes "Unexpected character 0x%02x at pos=%d. Expected %c.", 39068dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes c, spos, expected); 39168dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes return false; 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_text_format_Time_parse(JNIEnv* env, jobject This, jstring strObj) 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jsize len = env->GetStringLength(strObj); 40068dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes if (len < 8) { 40168dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes jniThrowException(env, "android/util/TimeFormatException", 40268dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes "String too short -- expected at least 8 characters."); 40368dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes return false; 40468dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes } 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jboolean inUtc = false; 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40868dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes ScopedStringChars s(env, strObj); 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // year 41168dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes int n; 41268dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes bool thrown = false; 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = get_char(env, s, 0, 1000, &thrown); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += get_char(env, s, 1, 100, &thrown); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += get_char(env, s, 2, 10, &thrown); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += get_char(env, s, 3, 1, &thrown); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thrown) return false; 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_yearField, n); 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // month 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = get_char(env, s, 4, 10, &thrown); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += get_char(env, s, 5, 1, &thrown); 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n--; 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thrown) return false; 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_monField, n); 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // day of month 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = get_char(env, s, 6, 10, &thrown); 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += get_char(env, s, 7, 1, &thrown); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thrown) return false; 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_mdayField, n); 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len > 8) { 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // T 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!check_char(env, s, 8, 'T')) return false; 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetBooleanField(This, g_allDayField, JNI_FALSE); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // hour 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = get_char(env, s, 9, 10, &thrown); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += get_char(env, s, 10, 1, &thrown); 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thrown) return false; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_hourField, n); 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // min 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = get_char(env, s, 11, 10, &thrown); 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += get_char(env, s, 12, 1, &thrown); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thrown) return false; 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_minField, n); 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // sec 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = get_char(env, s, 13, 10, &thrown); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += get_char(env, s, 14, 1, &thrown); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thrown) return false; 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_secField, n); 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len > 15) { 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Z 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!check_char(env, s, 15, 'Z')) return false; 45968dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes inUtc = true; 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetBooleanField(This, g_allDayField, JNI_TRUE); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_hourField, 0); 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_minField, 0); 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_secField, 0); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_wdayField, 0); 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_ydayField, 0); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_isdstField, -1); 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetLongField(This, g_gmtoffField, 0); 47268dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return inUtc; 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean android_text_format_Time_parse3339(JNIEnv* env, 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject This, 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jstring strObj) 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jsize len = env->GetStringLength(strObj); 4816c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root if (len < 10) { 4826c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root jniThrowException(env, "android/util/TimeFormatException", 48368dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes "String too short --- expected at least 10 characters."); 4846c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root return false; 4856c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root } 4866c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root 48768dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes jboolean inUtc = false; 48868dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes 48968dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes ScopedStringChars s(env, strObj); 49068dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // year 49268dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes int n; 49368dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes bool thrown = false; 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = get_char(env, s, 0, 1000, &thrown); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += get_char(env, s, 1, 100, &thrown); 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += get_char(env, s, 2, 10, &thrown); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += get_char(env, s, 3, 1, &thrown); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thrown) return false; 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_yearField, n); 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // - 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!check_char(env, s, 4, '-')) return false; 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // month 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = get_char(env, s, 5, 10, &thrown); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += get_char(env, s, 6, 1, &thrown); 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project --n; 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thrown) return false; 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_monField, n); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // - 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!check_char(env, s, 7, '-')) return false; 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // day 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = get_char(env, s, 8, 10, &thrown); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += get_char(env, s, 9, 1, &thrown); 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thrown) return false; 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_mdayField, n); 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5206c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root if (len >= 19) { 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // T 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!check_char(env, s, 10, 'T')) return false; 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 52468dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes env->SetBooleanField(This, g_allDayField, JNI_FALSE); 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // hour 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = get_char(env, s, 11, 10, &thrown); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += get_char(env, s, 12, 1, &thrown); 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thrown) return false; 52968dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes int hour = n; 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // env->SetIntField(This, g_hourField, n); 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 53268dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes // : 53368dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes if (!check_char(env, s, 13, ':')) return false; 53468dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes 53568dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes // minute 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = get_char(env, s, 14, 10, &thrown); 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += get_char(env, s, 15, 1, &thrown); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thrown) return false; 53968dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes int minute = n; 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // env->SetIntField(This, g_minField, n); 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 54268dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes // : 54368dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes if (!check_char(env, s, 16, ':')) return false; 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 54568dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes // second 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = get_char(env, s, 17, 10, &thrown); 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += get_char(env, s, 18, 1, &thrown); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (thrown) return false; 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_secField, n); 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5516c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root // skip the '.XYZ' -- we don't care about subsecond precision. 5526c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root int tz_index = 19; 5536c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root if (tz_index < len && s[tz_index] == '.') { 5546c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root do { 5556c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root tz_index++; 5566c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root } while (tz_index < len 5576c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root && s[tz_index] >= '0' 5586c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root && s[tz_index] <= '9'); 5596c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root } 5606c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int offset = 0; 5626c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root if (len > tz_index) { 5636c2d4029f1fecb51e0b002e652fd18e18d059fe0Kenny Root char c = s[tz_index]; 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 56568dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes // NOTE: the offset is meant to be subtracted to get from local time 56668dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes // to UTC. we therefore use 1 for '-' and -1 for '+'. 56768dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes switch (c) { 56868dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes case 'Z': 56968dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes // Zulu time -- UTC 57068dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes offset = 0; 57168dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes break; 57268dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes case '-': 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset = 1; 57468dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes break; 57568dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes case '+': 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset = -1; 57768dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes break; 57868dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes default: 57968dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes jniThrowExceptionFmt(env, "android/util/TimeFormatException", 58068dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes "Unexpected character 0x%02x at position %d. Expected + or -", 58168dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes c, tz_index); 58268dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes return false; 58368dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inUtc = true; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 58668dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes if (offset != 0) { 58768dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes if (len < tz_index + 6) { 58868dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes jniThrowExceptionFmt(env, "android/util/TimeFormatException", 58968dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes "Unexpected length; should be %d characters", 59068dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes tz_index + 6); 59168dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes return false; 59268dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes } 59368dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes 59468dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes // hour 59568dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes n = get_char(env, s, tz_index + 1, 10, &thrown); 59668dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes n += get_char(env, s, tz_index + 2, 1, &thrown); 59768dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes if (thrown) return false; 59868dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes n *= offset; 59968dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes hour += n; 60068dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes 60168dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes // : 60268dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes if (!check_char(env, s, tz_index + 3, ':')) return false; 60368dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes 60468dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes // minute 60568dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes n = get_char(env, s, tz_index + 4, 10, &thrown); 60668dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes n += get_char(env, s, tz_index + 5, 1, &thrown); 60768dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes if (thrown) return false; 60868dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes n *= offset; 60968dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes minute += n; 61068dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes } 61168dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes } 61268dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes env->SetIntField(This, g_hourField, hour); 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_minField, minute); 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 61568dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes if (offset != 0) { 61668dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes // we need to normalize after applying the hour and minute offsets 61768dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes android_text_format_Time_normalize(env, This, false /* use isdst */); 61868dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes // The timezone is set to UTC in the calling Java code. 61968dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes } 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 62168dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes env->SetBooleanField(This, g_allDayField, JNI_TRUE); 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_hourField, 0); 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_minField, 0); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_secField, 0); 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_wdayField, 0); 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_ydayField, 0); 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(This, g_isdstField, -1); 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetLongField(This, g_gmtoffField, 0); 63168dcd1750eea33b6687f54a03b2fb7fbbb9c44c7Elliott Hughes 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return inUtc; 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ============================================================================ 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * JNI registration. 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMethods[] = { 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* name, signature, funcPtr */ 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "normalize", "(Z)J", (void*)android_text_format_Time_normalize }, 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "switchTimezone", "(Ljava/lang/String;)V", (void*)android_text_format_Time_switchTimezone }, 643467cabe879cb58df96f6a84879f5fb226e049aebKenny Root { "nativeCompare", "(Landroid/text/format/Time;Landroid/text/format/Time;)I", (void*)android_text_format_Time_compare }, 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "format1", "(Ljava/lang/String;)Ljava/lang/String;", (void*)android_text_format_Time_format }, 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "format2445", "()Ljava/lang/String;", (void*)android_text_format_Time_format2445 }, 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "toString", "()Ljava/lang/String;", (void*)android_text_format_Time_toString }, 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "nativeParse", "(Ljava/lang/String;)Z", (void*)android_text_format_Time_parse }, 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "nativeParse3339", "(Ljava/lang/String;)Z", (void*)android_text_format_Time_parse3339 }, 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "setToNow", "()V", (void*)android_text_format_Time_setToNow }, 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "toMillis", "(Z)J", (void*)android_text_format_Time_toMillis }, 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "set", "(J)V", (void*)android_text_format_Time_set } 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_text_format_Time(JNIEnv* env) 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass timeClass = env->FindClass("android/text/format/Time"); 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6584df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project g_timeClass = (jclass) env->NewGlobalRef(timeClass); 6594df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_allDayField = env->GetFieldID(timeClass, "allDay", "Z"); 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_secField = env->GetFieldID(timeClass, "second", "I"); 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_minField = env->GetFieldID(timeClass, "minute", "I"); 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_hourField = env->GetFieldID(timeClass, "hour", "I"); 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_mdayField = env->GetFieldID(timeClass, "monthDay", "I"); 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_monField = env->GetFieldID(timeClass, "month", "I"); 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_yearField = env->GetFieldID(timeClass, "year", "I"); 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_wdayField = env->GetFieldID(timeClass, "weekDay", "I"); 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_ydayField = env->GetFieldID(timeClass, "yearDay", "I"); 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_isdstField = env->GetFieldID(timeClass, "isDst", "I"); 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_gmtoffField = env->GetFieldID(timeClass, "gmtoff", "J"); 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_timezoneField = env->GetFieldID(timeClass, "timezone", "Ljava/lang/String;"); 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_shortMonthsField = env->GetStaticFieldID(timeClass, "sShortMonths", "[Ljava/lang/String;"); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_longMonthsField = env->GetStaticFieldID(timeClass, "sLongMonths", "[Ljava/lang/String;"); 675cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru g_longStandaloneMonthsField = env->GetStaticFieldID(timeClass, "sLongStandaloneMonths", "[Ljava/lang/String;"); 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_shortWeekdaysField = env->GetStaticFieldID(timeClass, "sShortWeekdays", "[Ljava/lang/String;"); 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_longWeekdaysField = env->GetStaticFieldID(timeClass, "sLongWeekdays", "[Ljava/lang/String;"); 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_timeOnlyFormatField = env->GetStaticFieldID(timeClass, "sTimeOnlyFormat", "Ljava/lang/String;"); 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_dateOnlyFormatField = env->GetStaticFieldID(timeClass, "sDateOnlyFormat", "Ljava/lang/String;"); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_dateTimeFormatField = env->GetStaticFieldID(timeClass, "sDateTimeFormat", "Ljava/lang/String;"); 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_amField = env->GetStaticFieldID(timeClass, "sAm", "Ljava/lang/String;"); 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_pmField = env->GetStaticFieldID(timeClass, "sPm", "Ljava/lang/String;"); 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project g_dateCommandField = env->GetStaticFieldID(timeClass, "sDateCommand", "Ljava/lang/String;"); 6844df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project g_localeField = env->GetStaticFieldID(timeClass, "sLocale", "Ljava/util/Locale;"); 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AndroidRuntime::registerNativeMethods(env, "android/text/format/Time", gMethods, NELEM(gMethods)); 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 690