27
27
#include " ecma-try-catch-macro.h"
28
28
#include " jrt.h"
29
29
#include " jrt-libc-includes.h"
30
+ #include " lit-char-helpers.h"
30
31
31
32
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_STRING_BUILTIN
32
33
@@ -507,6 +508,156 @@ ecma_builtin_string_prototype_object_substring (ecma_value_t this_arg, /**< this
507
508
return ret_value;
508
509
} /* ecma_builtin_string_prototype_object_substring */
509
510
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)
520
+ * or upper (false) case */
521
+ {
522
+ ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
523
+
524
+ /* 1. */
525
+ ECMA_TRY_CATCH (check_coercible_val,
526
+ ecma_op_check_object_coercible (this_arg),
527
+ ret_value);
528
+
529
+ /* 2. */
530
+ ECMA_TRY_CATCH (to_string_val,
531
+ ecma_op_to_string (this_arg),
532
+ ret_value);
533
+
534
+ /* 3. */
535
+ ecma_string_t *input_string_p = ecma_get_string_from_value (to_string_val);
536
+ lit_utf8_size_t input_size = ecma_string_get_size (input_string_p);
537
+
538
+ MEM_DEFINE_LOCAL_ARRAY (input_start_p,
539
+ input_size,
540
+ lit_utf8_byte_t );
541
+
542
+ ecma_string_to_utf8_string (input_string_p,
543
+ input_start_p,
544
+ (ssize_t ) (input_size));
545
+
546
+ /*
547
+ * The URI encoding has two major phases: first we compute
548
+ * the length of the lower case string, then we encode it.
549
+ */
550
+
551
+ lit_utf8_size_t output_length = 0 ;
552
+ lit_utf8_iterator_t input_iterator = lit_utf8_iterator_create (input_start_p, input_size);
553
+
554
+ while (!lit_utf8_iterator_is_eos (&input_iterator))
555
+ {
556
+ ecma_char_t character = lit_utf8_iterator_read_next (&input_iterator);
557
+ ecma_char_t character_buffer[LIT_MAXIMUM_OTHER_CASE_LENGTH];
558
+ lit_utf8_byte_t utf8_byte_buffer[LIT_UTF8_MAX_BYTES_IN_CODE_POINT];
559
+ lit_utf8_size_t character_length;
560
+
561
+ /*
562
+ * We need to keep surrogate pairs. Surrogates are never converted,
563
+ * regardless they form a valid pair or not.
564
+ */
565
+ if (lit_is_code_unit_high_surrogate (character))
566
+ {
567
+ ecma_char_t next_character = lit_utf8_iterator_peek_next (&input_iterator);
568
+
569
+ if (lit_is_code_unit_low_surrogate (next_character))
570
+ {
571
+ lit_code_point_t surrogate_code_point = lit_convert_surrogate_pair_to_code_point (character, next_character);
572
+ output_length += lit_code_point_to_utf8 (surrogate_code_point, utf8_byte_buffer);
573
+ lit_utf8_iterator_incr (&input_iterator);
574
+ continue ;
575
+ }
576
+ }
577
+
578
+ if (lower_case)
579
+ {
580
+ character_length = lit_char_to_lower_case (character, character_buffer);
581
+ }
582
+ else
583
+ {
584
+ character_length = lit_char_to_upper_case (character, character_buffer);
585
+ }
586
+
587
+ JERRY_ASSERT (character_length >= 1 && character_length <= LIT_MAXIMUM_OTHER_CASE_LENGTH);
588
+
589
+ for (lit_utf8_size_t i = 0 ; i < character_length; i++)
590
+ {
591
+ output_length += lit_code_unit_to_utf8 (character_buffer[i], utf8_byte_buffer);
592
+ }
593
+ }
594
+
595
+ /* Second phase. */
596
+
597
+ MEM_DEFINE_LOCAL_ARRAY (output_start_p,
598
+ output_length,
599
+ lit_utf8_byte_t );
600
+
601
+ lit_utf8_byte_t *output_char_p = output_start_p;
602
+
603
+ /* Encoding the output. */
604
+ lit_utf8_iterator_seek_bos (&input_iterator);
605
+
606
+ while (!lit_utf8_iterator_is_eos (&input_iterator))
607
+ {
608
+ ecma_char_t character = lit_utf8_iterator_read_next (&input_iterator);
609
+ ecma_char_t character_buffer[LIT_MAXIMUM_OTHER_CASE_LENGTH];
610
+ lit_utf8_size_t character_length;
611
+
612
+ /*
613
+ * We need to keep surrogate pairs. Surrogates are never converted,
614
+ * regardless they form a valid pair or not.
615
+ */
616
+ if (lit_is_code_unit_high_surrogate (character))
617
+ {
618
+ ecma_char_t next_character = lit_utf8_iterator_peek_next (&input_iterator);
619
+
620
+ if (lit_is_code_unit_low_surrogate (next_character))
621
+ {
622
+ lit_code_point_t surrogate_code_point = lit_convert_surrogate_pair_to_code_point (character, next_character);
623
+ output_char_p += lit_code_point_to_utf8 (surrogate_code_point, output_char_p);
624
+ lit_utf8_iterator_incr (&input_iterator);
625
+ continue ;
626
+ }
627
+ }
628
+
629
+ if (lower_case)
630
+ {
631
+ character_length = lit_char_to_lower_case (character, character_buffer);
632
+ }
633
+ else
634
+ {
635
+ character_length = lit_char_to_upper_case (character, character_buffer);
636
+ }
637
+
638
+ JERRY_ASSERT (character_length >= 1 && character_length <= LIT_MAXIMUM_OTHER_CASE_LENGTH);
639
+
640
+ for (lit_utf8_size_t i = 0 ; i < character_length; i++)
641
+ {
642
+ output_char_p += lit_code_point_to_utf8 (character_buffer[i], output_char_p);
643
+ }
644
+ }
645
+
646
+ JERRY_ASSERT (output_start_p + output_length == output_char_p);
647
+
648
+ ecma_string_t *output_string_p = ecma_new_ecma_string_from_utf8 (output_start_p, output_length);
649
+
650
+ ret_value = ecma_make_normal_completion_value (ecma_make_string_value (output_string_p));
651
+
652
+ MEM_FINALIZE_LOCAL_ARRAY (output_start_p);
653
+ MEM_FINALIZE_LOCAL_ARRAY (input_start_p);
654
+
655
+ ECMA_FINALIZE (to_string_val);
656
+ ECMA_FINALIZE (check_coercible_val);
657
+
658
+ return ret_value;
659
+ } /* ecma_builtin_string_prototype_object_conversion_helper */
660
+
510
661
/* *
511
662
* The String.prototype object's 'toLowerCase' routine
512
663
*
@@ -519,7 +670,7 @@ ecma_builtin_string_prototype_object_substring (ecma_value_t this_arg, /**< this
519
670
static ecma_completion_value_t
520
671
ecma_builtin_string_prototype_object_to_lower_case (ecma_value_t this_arg) /* *< this argument */
521
672
{
522
- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
673
+ return ecma_builtin_string_prototype_object_conversion_helper (this_arg, true );
523
674
} /* ecma_builtin_string_prototype_object_to_lower_case */
524
675
525
676
/* *
@@ -534,7 +685,7 @@ ecma_builtin_string_prototype_object_to_lower_case (ecma_value_t this_arg) /**<
534
685
static ecma_completion_value_t
535
686
ecma_builtin_string_prototype_object_to_locale_lower_case (ecma_value_t this_arg) /* *< this argument */
536
687
{
537
- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
688
+ return ecma_builtin_string_prototype_object_conversion_helper (this_arg, true );
538
689
} /* ecma_builtin_string_prototype_object_to_locale_lower_case */
539
690
540
691
/* *
@@ -549,7 +700,7 @@ ecma_builtin_string_prototype_object_to_locale_lower_case (ecma_value_t this_arg
549
700
static ecma_completion_value_t
550
701
ecma_builtin_string_prototype_object_to_upper_case (ecma_value_t this_arg) /* *< this argument */
551
702
{
552
- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
703
+ return ecma_builtin_string_prototype_object_conversion_helper (this_arg, false );
553
704
} /* ecma_builtin_string_prototype_object_to_upper_case */
554
705
555
706
/* *
@@ -564,7 +715,7 @@ ecma_builtin_string_prototype_object_to_upper_case (ecma_value_t this_arg) /**<
564
715
static ecma_completion_value_t
565
716
ecma_builtin_string_prototype_object_to_locale_upper_case (ecma_value_t this_arg) /* *< this argument */
566
717
{
567
- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
718
+ return ecma_builtin_string_prototype_object_conversion_helper (this_arg, false );
568
719
} /* ecma_builtin_string_prototype_object_to_locale_upper_case */
569
720
570
721
/* *
0 commit comments