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,155 @@ 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) 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
+
510
660
/* *
511
661
* The String.prototype object's 'toLowerCase' routine
512
662
*
@@ -519,7 +669,7 @@ ecma_builtin_string_prototype_object_substring (ecma_value_t this_arg, /**< this
519
669
static ecma_completion_value_t
520
670
ecma_builtin_string_prototype_object_to_lower_case (ecma_value_t this_arg) /* *< this argument */
521
671
{
522
- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
672
+ return ecma_builtin_string_prototype_object_conversion_helper (this_arg, true );
523
673
} /* ecma_builtin_string_prototype_object_to_lower_case */
524
674
525
675
/* *
@@ -534,7 +684,7 @@ ecma_builtin_string_prototype_object_to_lower_case (ecma_value_t this_arg) /**<
534
684
static ecma_completion_value_t
535
685
ecma_builtin_string_prototype_object_to_locale_lower_case (ecma_value_t this_arg) /* *< this argument */
536
686
{
537
- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
687
+ return ecma_builtin_string_prototype_object_conversion_helper (this_arg, true );
538
688
} /* ecma_builtin_string_prototype_object_to_locale_lower_case */
539
689
540
690
/* *
@@ -549,7 +699,7 @@ ecma_builtin_string_prototype_object_to_locale_lower_case (ecma_value_t this_arg
549
699
static ecma_completion_value_t
550
700
ecma_builtin_string_prototype_object_to_upper_case (ecma_value_t this_arg) /* *< this argument */
551
701
{
552
- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
702
+ return ecma_builtin_string_prototype_object_conversion_helper (this_arg, false );
553
703
} /* ecma_builtin_string_prototype_object_to_upper_case */
554
704
555
705
/* *
@@ -564,7 +714,7 @@ ecma_builtin_string_prototype_object_to_upper_case (ecma_value_t this_arg) /**<
564
714
static ecma_completion_value_t
565
715
ecma_builtin_string_prototype_object_to_locale_upper_case (ecma_value_t this_arg) /* *< this argument */
566
716
{
567
- ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
717
+ return ecma_builtin_string_prototype_object_conversion_helper (this_arg, false );
568
718
} /* ecma_builtin_string_prototype_object_to_locale_upper_case */
569
719
570
720
/* *
0 commit comments