2727#include " ecma-try-catch-macro.h"
2828#include " jrt.h"
2929#include " jrt-libc-includes.h"
30+ #include " lit-char-helpers.h"
3031
3132#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_STRING_BUILTIN
3233
@@ -507,6 +508,155 @@ ecma_builtin_string_prototype_object_substring (ecma_value_t this_arg, /**< this
507508 return ret_value;
508509} /* ecma_builtin_string_prototype_object_substring */
509510
511+ /* *
512+ * Helper function to convert a string to upper or lower case.
513+ *
514+ * @return completion value
515+ * Returned value must be freed with ecma_free_completion_value.
516+ */
517+ static ecma_completion_value_t
518+ ecma_builtin_string_prototype_object_conversion_helper (ecma_value_t this_arg, /* *< this argument */
519+ bool lower_case) /* *< convert to lower (true) or upper (false) case */
520+ {
521+ ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
522+
523+ /* 1. */
524+ ECMA_TRY_CATCH (check_coercible_val,
525+ ecma_op_check_object_coercible (this_arg),
526+ ret_value);
527+
528+ /* 2. */
529+ ECMA_TRY_CATCH (to_string_val,
530+ ecma_op_to_string (this_arg),
531+ ret_value);
532+
533+ /* 3. */
534+ ecma_string_t *input_string_p = ecma_get_string_from_value (to_string_val);
535+ lit_utf8_size_t input_size = ecma_string_get_size (input_string_p);
536+
537+ MEM_DEFINE_LOCAL_ARRAY (input_start_p,
538+ input_size,
539+ lit_utf8_byte_t );
540+
541+ ecma_string_to_utf8_string (input_string_p,
542+ input_start_p,
543+ (ssize_t ) (input_size));
544+
545+ /*
546+ * The URI encoding has two major phases: first we compute
547+ * the length of the lower case string, then we encode it.
548+ */
549+
550+ lit_utf8_size_t output_length = 0 ;
551+ lit_utf8_iterator_t input_iterator = lit_utf8_iterator_create (input_start_p, input_size);
552+
553+ while (!lit_utf8_iterator_is_eos (&input_iterator))
554+ {
555+ ecma_char_t character = lit_utf8_iterator_read_next (&input_iterator);
556+ ecma_char_t character_buffer[LIT_MAXIMUM_OTHERCASE_LENGTH];
557+ lit_utf8_byte_t utf8_byte_buffer[LIT_UTF8_MAX_BYTES_IN_CODE_POINT];
558+ lit_utf8_size_t character_length;
559+
560+ /*
561+ * We need to keep surrogate pairs. Surrogates are never converted,
562+ * regardless they form a valid pair or not.
563+ */
564+ if (lit_is_code_unit_high_surrogate (character))
565+ {
566+ ecma_char_t next_character = lit_utf8_iterator_peek_next (&input_iterator);
567+
568+ if (lit_is_code_unit_low_surrogate (next_character))
569+ {
570+ lit_code_point_t surrogate_code_point = lit_convert_surrogate_pair_to_code_point (character, next_character);
571+ output_length += lit_code_point_to_utf8 (surrogate_code_point, utf8_byte_buffer);
572+ lit_utf8_iterator_incr (&input_iterator);
573+ continue ;
574+ }
575+ }
576+
577+ if (lower_case)
578+ {
579+ character_length = lit_char_to_lower_case (character, character_buffer);
580+ }
581+ else
582+ {
583+ character_length = lit_char_to_upper_case (character, character_buffer);
584+ }
585+
586+ JERRY_ASSERT (character_length >= 1 && character_length <= LIT_MAXIMUM_OTHERCASE_LENGTH);
587+
588+ for (lit_utf8_size_t i = 0 ; i < character_length; i++)
589+ {
590+ output_length += lit_code_unit_to_utf8 (character_buffer[i], utf8_byte_buffer);
591+ }
592+ }
593+
594+ /* Second phase. */
595+
596+ MEM_DEFINE_LOCAL_ARRAY (output_start_p,
597+ output_length,
598+ lit_utf8_byte_t );
599+
600+ lit_utf8_byte_t *output_char_p = output_start_p;
601+
602+ /* Encoding the output. */
603+ lit_utf8_iterator_seek_bos (&input_iterator);
604+
605+ while (!lit_utf8_iterator_is_eos (&input_iterator))
606+ {
607+ ecma_char_t character = lit_utf8_iterator_read_next (&input_iterator);
608+ ecma_char_t character_buffer[LIT_MAXIMUM_OTHERCASE_LENGTH];
609+ lit_utf8_size_t character_length;
610+
611+ /*
612+ * We need to keep surrogate pairs. Surrogates are never converted,
613+ * regardless they form a valid pair or not.
614+ */
615+ if (lit_is_code_unit_high_surrogate (character))
616+ {
617+ ecma_char_t next_character = lit_utf8_iterator_peek_next (&input_iterator);
618+
619+ if (lit_is_code_unit_low_surrogate (next_character))
620+ {
621+ lit_code_point_t surrogate_code_point = lit_convert_surrogate_pair_to_code_point (character, next_character);
622+ output_char_p += lit_code_point_to_utf8 (surrogate_code_point, output_char_p);
623+ lit_utf8_iterator_incr (&input_iterator);
624+ continue ;
625+ }
626+ }
627+
628+ if (lower_case)
629+ {
630+ character_length = lit_char_to_lower_case (character, character_buffer);
631+ }
632+ else
633+ {
634+ character_length = lit_char_to_upper_case (character, character_buffer);
635+ }
636+
637+ JERRY_ASSERT (character_length >= 1 && character_length <= LIT_MAXIMUM_OTHERCASE_LENGTH);
638+
639+ for (lit_utf8_size_t i = 0 ; i < character_length; i++)
640+ {
641+ output_char_p += lit_code_point_to_utf8 (character_buffer[i], output_char_p);
642+ }
643+ }
644+
645+ JERRY_ASSERT (output_start_p + output_length == output_char_p);
646+
647+ ecma_string_t *output_string_p = ecma_new_ecma_string_from_utf8 (output_start_p, output_length);
648+
649+ ret_value = ecma_make_normal_completion_value (ecma_make_string_value (output_string_p));
650+
651+ MEM_FINALIZE_LOCAL_ARRAY (output_start_p);
652+ MEM_FINALIZE_LOCAL_ARRAY (input_start_p);
653+
654+ ECMA_FINALIZE (to_string_val);
655+ ECMA_FINALIZE (check_coercible_val);
656+
657+ return ret_value;
658+ } /* ecma_builtin_string_prototype_object_conversion_helper */
659+
510660/* *
511661 * The String.prototype object's 'toLowerCase' routine
512662 *
@@ -519,7 +669,7 @@ ecma_builtin_string_prototype_object_substring (ecma_value_t this_arg, /**< this
519669static ecma_completion_value_t
520670ecma_builtin_string_prototype_object_to_lower_case (ecma_value_t this_arg) /* *< this argument */
521671{
522- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
672+ return ecma_builtin_string_prototype_object_conversion_helper (this_arg, true );
523673} /* ecma_builtin_string_prototype_object_to_lower_case */
524674
525675/* *
@@ -534,7 +684,7 @@ ecma_builtin_string_prototype_object_to_lower_case (ecma_value_t this_arg) /**<
534684static ecma_completion_value_t
535685ecma_builtin_string_prototype_object_to_locale_lower_case (ecma_value_t this_arg) /* *< this argument */
536686{
537- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
687+ return ecma_builtin_string_prototype_object_conversion_helper (this_arg, true );
538688} /* ecma_builtin_string_prototype_object_to_locale_lower_case */
539689
540690/* *
@@ -549,7 +699,7 @@ ecma_builtin_string_prototype_object_to_locale_lower_case (ecma_value_t this_arg
549699static ecma_completion_value_t
550700ecma_builtin_string_prototype_object_to_upper_case (ecma_value_t this_arg) /* *< this argument */
551701{
552- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
702+ return ecma_builtin_string_prototype_object_conversion_helper (this_arg, false );
553703} /* ecma_builtin_string_prototype_object_to_upper_case */
554704
555705/* *
@@ -564,7 +714,7 @@ ecma_builtin_string_prototype_object_to_upper_case (ecma_value_t this_arg) /**<
564714static ecma_completion_value_t
565715ecma_builtin_string_prototype_object_to_locale_upper_case (ecma_value_t this_arg) /* *< this argument */
566716{
567- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
717+ return ecma_builtin_string_prototype_object_conversion_helper (this_arg, false );
568718} /* ecma_builtin_string_prototype_object_to_locale_upper_case */
569719
570720/* *
0 commit comments