2323#include " jni.h"
2424#include " utils/misc.h"
2525#include " android_runtime/AndroidRuntime.h"
26+ #include " ScopedStringChars.h"
2627#include " TimeUtils.h"
2728#include < nativehelper/JNIHelp.h>
2829#include < cutils/tztime.h>
@@ -71,11 +72,10 @@ static inline bool java2time(JNIEnv* env, Time* t, jobject o)
7172 t->t .tm_gmtoff = env->GetLongField (o, g_gmtoffField);
7273 bool allDay = env->GetBooleanField (o, g_allDayField);
7374 if (allDay &&
74- ((t->t .tm_sec !=0 ) || (t->t .tm_min != 0 ) || (t->t .tm_hour != 0 ))) {
75- char msg[100 ];
76- sprintf (msg, " allDay is true but sec, min, hour are not 0." );
77- jniThrowException (env, " java/lang/IllegalArgumentException" , msg);
78- return false ;
75+ ((t->t .tm_sec !=0 ) || (t->t .tm_min != 0 ) || (t->t .tm_hour != 0 ))) {
76+ jniThrowException (env, " java/lang/IllegalArgumentException" ,
77+ " allDay is true but sec, min, hour are not 0." );
78+ return false ;
7979 }
8080 return true ;
8181}
@@ -308,7 +308,7 @@ static jstring android_text_format_Time_format(JNIEnv* env, jobject This,
308308static jstring android_text_format_Time_toString (JNIEnv* env, jobject This)
309309{
310310 Time t;
311- if (!java2time (env, &t, This)) return env->NewStringUTF (" " );;
311+ if (!java2time (env, &t, This)) return env->NewStringUTF (" " );
312312 ACQUIRE_TIMEZONE (This, t)
313313
314314 String8 r = t.toString ();
@@ -360,32 +360,30 @@ static void android_text_format_Time_set(JNIEnv* env, jobject This, jlong millis
360360// ============================================================================
361361// Just do this here because it's not worth recreating the strings
362362
363- static int get_char (JNIEnv* env, const jchar * s, int spos, int mul,
364- bool * thrown)
363+ static int get_char (JNIEnv* env, const ScopedStringChars& s, int spos, int mul,
364+ bool * thrown)
365365{
366366 jchar c = s[spos];
367367 if (c >= ' 0' && c <= ' 9' ) {
368368 return (c - ' 0' ) * mul;
369369 } else {
370370 if (!*thrown) {
371- char msg[100 ];
372- sprintf (msg, " Parse error at pos=%d" , spos);
373- jniThrowException (env, " android/util/TimeFormatException" , msg);
371+ jniThrowExceptionFmt (env, " android/util/TimeFormatException" ,
372+ " Parse error at pos=%d" , spos);
374373 *thrown = true ;
375374 }
376375 return 0 ;
377376 }
378377}
379378
380- static bool check_char (JNIEnv* env, const jchar * s, int spos, jchar expected)
379+ static bool check_char (JNIEnv* env, const ScopedStringChars& s, int spos, jchar expected)
381380{
382381 jchar c = s[spos];
383382 if (c != expected) {
384- char msg[100 ];
385- sprintf (msg, " Unexpected character 0x%02x at pos=%d. Expected %c." , c, spos,
386- expected);
387- jniThrowException (env, " android/util/TimeFormatException" , msg);
388- return false ;
383+ jniThrowExceptionFmt (env, " android/util/TimeFormatException" ,
384+ " Unexpected character 0x%02x at pos=%d. Expected %c." ,
385+ c, spos, expected);
386+ return false ;
389387 }
390388 return true ;
391389}
@@ -394,20 +392,19 @@ static bool check_char(JNIEnv* env, const jchar *s, int spos, jchar expected)
394392static jboolean android_text_format_Time_parse (JNIEnv* env, jobject This, jstring strObj)
395393{
396394 jsize len = env->GetStringLength (strObj);
397- const jchar *s = env->GetStringChars (strObj, NULL );
395+ if (len < 8 ) {
396+ jniThrowException (env, " android/util/TimeFormatException" ,
397+ " String too short -- expected at least 8 characters." );
398+ return false ;
399+ }
398400
399- bool thrown = false ;
400- int n;
401401 jboolean inUtc = false ;
402402
403- if (len < 8 ) {
404- char msg[100 ];
405- sprintf (msg, " String too short -- expected at least 8 characters." );
406- jniThrowException (env, " android/util/TimeFormatException" , msg);
407- return false ;
408- }
403+ ScopedStringChars s (env, strObj);
409404
410405 // year
406+ int n;
407+ bool thrown = false ;
411408 n = get_char (env, s, 0 , 1000 , &thrown);
412409 n += get_char (env, s, 1 , 100 , &thrown);
413410 n += get_char (env, s, 2 , 10 , &thrown);
@@ -454,7 +451,7 @@ static jboolean android_text_format_Time_parse(JNIEnv* env, jobject This, jstrin
454451 if (len > 15 ) {
455452 // Z
456453 if (!check_char (env, s, 15 , ' Z' )) return false ;
457- inUtc = true ;
454+ inUtc = true ;
458455 }
459456 } else {
460457 env->SetBooleanField (This, g_allDayField, JNI_TRUE);
@@ -467,8 +464,7 @@ static jboolean android_text_format_Time_parse(JNIEnv* env, jobject This, jstrin
467464 env->SetIntField (This, g_ydayField, 0 );
468465 env->SetIntField (This, g_isdstField, -1 );
469466 env->SetLongField (This, g_gmtoffField, 0 );
470-
471- env->ReleaseStringChars (strObj, s);
467+
472468 return inUtc;
473469}
474470
@@ -477,19 +473,19 @@ static jboolean android_text_format_Time_parse3339(JNIEnv* env,
477473 jstring strObj)
478474{
479475 jsize len = env->GetStringLength (strObj);
480- const jchar *s = env->GetStringChars (strObj, NULL );
481-
482- bool thrown = false ;
483- int n;
484- jboolean inUtc = false ;
485-
486476 if (len < 10 ) {
487477 jniThrowException (env, " android/util/TimeFormatException" ,
488- " Time input is too short; must be at least 10 characters" );
478+ " String too short --- expected at least 10 characters. " );
489479 return false ;
490480 }
491481
482+ jboolean inUtc = false ;
483+
484+ ScopedStringChars s (env, strObj);
485+
492486 // year
487+ int n;
488+ bool thrown = false ;
493489 n = get_char (env, s, 0 , 1000 , &thrown);
494490 n += get_char (env, s, 1 , 100 , &thrown);
495491 n += get_char (env, s, 2 , 10 , &thrown);
@@ -520,28 +516,28 @@ static jboolean android_text_format_Time_parse3339(JNIEnv* env,
520516 // T
521517 if (!check_char (env, s, 10 , ' T' )) return false ;
522518
523- env->SetBooleanField (This, g_allDayField, JNI_FALSE);
519+ env->SetBooleanField (This, g_allDayField, JNI_FALSE);
524520 // hour
525521 n = get_char (env, s, 11 , 10 , &thrown);
526522 n += get_char (env, s, 12 , 1 , &thrown);
527523 if (thrown) return false ;
528- int hour = n;
524+ int hour = n;
529525 // env->SetIntField(This, g_hourField, n);
530-
531- // :
532- if (!check_char (env, s, 13 , ' :' )) return false ;
533526
534- // minute
527+ // :
528+ if (!check_char (env, s, 13 , ' :' )) return false ;
529+
530+ // minute
535531 n = get_char (env, s, 14 , 10 , &thrown);
536532 n += get_char (env, s, 15 , 1 , &thrown);
537533 if (thrown) return false ;
538- int minute = n;
534+ int minute = n;
539535 // env->SetIntField(This, g_minField, n);
540536
541- // :
542- if (!check_char (env, s, 16 , ' :' )) return false ;
537+ // :
538+ if (!check_char (env, s, 16 , ' :' )) return false ;
543539
544- // second
540+ // second
545541 n = get_char (env, s, 17 , 10 , &thrown);
546542 n += get_char (env, s, 18 , 1 , &thrown);
547543 if (thrown) return false ;
@@ -561,64 +557,63 @@ static jboolean android_text_format_Time_parse3339(JNIEnv* env,
561557 if (len > tz_index) {
562558 char c = s[tz_index];
563559
564- // NOTE: the offset is meant to be subtracted to get from local time
565- // to UTC. we therefore use 1 for '-' and -1 for '+'.
566- switch (c) {
567- case ' Z' :
568- // Zulu time -- UTC
569- offset = 0 ;
570- break ;
571- case ' -' :
560+ // NOTE: the offset is meant to be subtracted to get from local time
561+ // to UTC. we therefore use 1 for '-' and -1 for '+'.
562+ switch (c) {
563+ case ' Z' :
564+ // Zulu time -- UTC
565+ offset = 0 ;
566+ break ;
567+ case ' -' :
572568 offset = 1 ;
573- break ;
574- case ' +' :
569+ break ;
570+ case ' +' :
575571 offset = -1 ;
576- break ;
577- default :
578- char msg[100 ];
579- sprintf (msg, " Unexpected character 0x%02x at position %d. Expected + or -" ,
580- c, tz_index);
581- jniThrowException (env, " android/util/TimeFormatException" , msg);
582- return false ;
583- }
572+ break ;
573+ default :
574+ jniThrowExceptionFmt (env, " android/util/TimeFormatException" ,
575+ " Unexpected character 0x%02x at position %d. Expected + or -" ,
576+ c, tz_index);
577+ return false ;
578+ }
584579 inUtc = true ;
585580
586- if (offset != 0 ) {
587- if (len < tz_index + 6 ) {
588- char msg[ 100 ];
589- sprintf (msg, " Unexpected length; should be %d characters" , tz_index + 6 );
590- jniThrowException (env, " android/util/TimeFormatException " , msg );
591- return false ;
592- }
593-
594- // hour
595- n = get_char (env, s, tz_index + 1 , 10 , &thrown);
596- n += get_char (env, s, tz_index + 2 , 1 , &thrown);
597- if (thrown) return false ;
598- n *= offset;
599- hour += n;
600-
601- // :
602- if (!check_char (env, s, tz_index + 3 , ' :' )) return false ;
603-
604- // minute
605- n = get_char (env, s, tz_index + 4 , 10 , &thrown);
606- n += get_char (env, s, tz_index + 5 , 1 , &thrown);
607- if (thrown) return false ;
608- n *= offset;
609- minute += n;
610- }
611- }
612- env->SetIntField (This, g_hourField, hour);
581+ if (offset != 0 ) {
582+ if (len < tz_index + 6 ) {
583+ jniThrowExceptionFmt (env, " android/util/TimeFormatException " ,
584+ " Unexpected length; should be %d characters" ,
585+ tz_index + 6 );
586+ return false ;
587+ }
588+
589+ // hour
590+ n = get_char (env, s, tz_index + 1 , 10 , &thrown);
591+ n += get_char (env, s, tz_index + 2 , 1 , &thrown);
592+ if (thrown) return false ;
593+ n *= offset;
594+ hour += n;
595+
596+ // :
597+ if (!check_char (env, s, tz_index + 3 , ' :' )) return false ;
598+
599+ // minute
600+ n = get_char (env, s, tz_index + 4 , 10 , &thrown);
601+ n += get_char (env, s, tz_index + 5 , 1 , &thrown);
602+ if (thrown) return false ;
603+ n *= offset;
604+ minute += n;
605+ }
606+ }
607+ env->SetIntField (This, g_hourField, hour);
613608 env->SetIntField (This, g_minField, minute);
614609
615- if (offset != 0 ) {
616- // we need to normalize after applying the hour and minute offsets
617- android_text_format_Time_normalize (env, This, false /* use isdst */ );
618- // The timezone is set to UTC in the calling Java code.
619- }
610+ if (offset != 0 ) {
611+ // we need to normalize after applying the hour and minute offsets
612+ android_text_format_Time_normalize (env, This, false /* use isdst */ );
613+ // The timezone is set to UTC in the calling Java code.
614+ }
620615 } else {
621- env->SetBooleanField (This, g_allDayField, JNI_TRUE);
616+ env->SetBooleanField (This, g_allDayField, JNI_TRUE);
622617 env->SetIntField (This, g_hourField, 0 );
623618 env->SetIntField (This, g_minField, 0 );
624619 env->SetIntField (This, g_secField, 0 );
@@ -628,8 +623,7 @@ static jboolean android_text_format_Time_parse3339(JNIEnv* env,
628623 env->SetIntField (This, g_ydayField, 0 );
629624 env->SetIntField (This, g_isdstField, -1 );
630625 env->SetLongField (This, g_gmtoffField, 0 );
631-
632- env->ReleaseStringChars (strObj, s);
626+
633627 return inUtc;
634628}
635629
0 commit comments