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