4
4
#include " env.h"
5
5
#include " env-inl.h"
6
6
#include " string_bytes.h"
7
+ #include " string_search.h"
7
8
#include " util.h"
8
9
#include " util-inl.h"
9
10
#include " v8-profiler.h"
@@ -854,87 +855,156 @@ void Compare(const FunctionCallbackInfo<Value> &args) {
854
855
}
855
856
856
857
857
- int32_t IndexOf (const char * haystack,
858
- size_t h_length,
859
- const char * needle,
860
- size_t n_length) {
861
- CHECK_GE (h_length, n_length);
862
- // TODO(trevnorris): Implement Boyer-Moore string search algorithm.
863
- for (size_t i = 0 ; i < h_length - n_length + 1 ; i++) {
864
- if (haystack[i] == needle[0 ]) {
865
- if (memcmp (haystack + i, needle, n_length) == 0 )
866
- return i;
867
- }
868
- }
869
- return -1 ;
870
- }
871
-
872
-
873
858
void IndexOfString (const FunctionCallbackInfo<Value>& args) {
874
859
ASSERT (args[1 ]->IsString ());
875
860
ASSERT (args[2 ]->IsNumber ());
876
861
862
+ enum encoding enc = ParseEncoding (args.GetIsolate (),
863
+ args[3 ],
864
+ UTF8);
865
+
877
866
THROW_AND_RETURN_UNLESS_BUFFER (Environment::GetCurrent (args), args[0 ]);
878
867
SPREAD_ARG (args[0 ], ts_obj);
879
868
880
- node::Utf8Value str (args.GetIsolate (), args[1 ]);
881
- int32_t offset_i32 = args[2 ]->Int32Value ();
882
- uint32_t offset;
869
+ Local<String> needle = args[1 ].As <String>();
870
+ const char * haystack = ts_obj_data;
871
+ const size_t haystack_length = ts_obj_length;
872
+ const size_t needle_length = needle->Utf8Length ();
873
+
874
+
875
+ if (needle_length == 0 || haystack_length == 0 ) {
876
+ return args.GetReturnValue ().Set (-1 );
877
+ }
878
+
879
+ int64_t offset_i64 = args[2 ]->IntegerValue ();
880
+ size_t offset = 0 ;
883
881
884
- if (offset_i32 < 0 ) {
885
- if (offset_i32 + static_cast <int32_t >(ts_obj_length ) < 0 )
882
+ if (offset_i64 < 0 ) {
883
+ if (offset_i64 + static_cast <int64_t >(haystack_length ) < 0 ) {
886
884
offset = 0 ;
887
- else
888
- offset = static_cast <uint32_t >(ts_obj_length + offset_i32);
885
+ } else {
886
+ offset = static_cast <size_t >(haystack_length + offset_i64);
887
+ }
889
888
} else {
890
- offset = static_cast <uint32_t >(offset_i32 );
889
+ offset = static_cast <size_t >(offset_i64 );
891
890
}
892
891
893
- if (str.length () == 0 ||
894
- ts_obj_length == 0 ||
895
- (offset != 0 && str.length () + offset <= str.length ()) ||
896
- str.length () + offset > ts_obj_length)
892
+ if (haystack_length < offset || needle_length + offset > haystack_length) {
897
893
return args.GetReturnValue ().Set (-1 );
894
+ }
898
895
899
- int32_t r =
900
- IndexOf (ts_obj_data + offset, ts_obj_length - offset, *str, str.length ());
901
- args.GetReturnValue ().Set (r == -1 ? -1 : static_cast <int32_t >(r + offset));
902
- }
896
+ size_t result = haystack_length;
897
+
898
+ if (enc == UCS2) {
899
+ String::Value needle_value (needle);
900
+ if (*needle_value == nullptr )
901
+ return args.GetReturnValue ().Set (-1 );
902
+
903
+ if (haystack_length < 2 || needle_value.length () < 1 ) {
904
+ return args.GetReturnValue ().Set (-1 );
905
+ }
906
+
907
+ result = SearchString (reinterpret_cast <const uint16_t *>(haystack),
908
+ haystack_length / 2 ,
909
+ reinterpret_cast <const uint16_t *>(*needle_value),
910
+ needle_value.length (),
911
+ offset / 2 );
912
+ result *= 2 ;
913
+ } else if (enc == UTF8) {
914
+ String::Utf8Value needle_value (needle);
915
+ if (*needle_value == nullptr )
916
+ return args.GetReturnValue ().Set (-1 );
917
+
918
+ result = SearchString (reinterpret_cast <const uint8_t *>(haystack),
919
+ haystack_length,
920
+ reinterpret_cast <const uint8_t *>(*needle_value),
921
+ needle_length,
922
+ offset);
923
+ } else if (enc == BINARY) {
924
+ uint8_t * needle_data = static_cast <uint8_t *>(malloc (needle_length));
925
+ if (needle_data == nullptr ) {
926
+ return args.GetReturnValue ().Set (-1 );
927
+ }
928
+ needle->WriteOneByte (
929
+ needle_data, 0 , needle_length, String::NO_NULL_TERMINATION);
930
+
931
+ result = SearchString (reinterpret_cast <const uint8_t *>(haystack),
932
+ haystack_length,
933
+ needle_data,
934
+ needle_length,
935
+ offset);
936
+ free (needle_data);
937
+ }
903
938
939
+ args.GetReturnValue ().Set (
940
+ result == haystack_length ? -1 : static_cast <int >(result));
941
+ }
904
942
905
943
void IndexOfBuffer (const FunctionCallbackInfo<Value>& args) {
906
944
ASSERT (args[1 ]->IsObject ());
907
945
ASSERT (args[2 ]->IsNumber ());
908
946
947
+ enum encoding enc = ParseEncoding (args.GetIsolate (),
948
+ args[3 ],
949
+ UTF8);
950
+
909
951
THROW_AND_RETURN_UNLESS_BUFFER (Environment::GetCurrent (args), args[0 ]);
910
952
SPREAD_ARG (args[0 ], ts_obj);
911
953
SPREAD_ARG (args[1 ], buf);
912
- const int32_t offset_i32 = args[2 ]->Int32Value ();
913
- uint32_t offset;
914
954
915
955
if (buf_length > 0 )
916
956
CHECK_NE (buf_data, nullptr );
917
957
918
- if (offset_i32 < 0 ) {
919
- if (offset_i32 + static_cast <int32_t >(ts_obj_length) < 0 )
958
+ const char * haystack = ts_obj_data;
959
+ const size_t haystack_length = ts_obj_length;
960
+ const char * needle = buf_data;
961
+ const size_t needle_length = buf_length;
962
+
963
+ if (needle_length == 0 || haystack_length == 0 ) {
964
+ return args.GetReturnValue ().Set (-1 );
965
+ }
966
+
967
+ int64_t offset_i64 = args[2 ]->IntegerValue ();
968
+ size_t offset = 0 ;
969
+
970
+ if (offset_i64 < 0 ) {
971
+ if (offset_i64 + static_cast <int64_t >(haystack_length) < 0 )
920
972
offset = 0 ;
921
973
else
922
- offset = static_cast <uint32_t >(ts_obj_length + offset_i32 );
974
+ offset = static_cast <size_t >(haystack_length + offset_i64 );
923
975
} else {
924
- offset = static_cast <uint32_t >(offset_i32 );
976
+ offset = static_cast <size_t >(offset_i64 );
925
977
}
926
978
927
- if (buf_length == 0 ||
928
- ts_obj_length == 0 ||
929
- (offset != 0 && buf_length + offset <= buf_length) ||
930
- buf_length + offset > ts_obj_length)
979
+ if (haystack_length < offset || needle_length + offset > haystack_length) {
931
980
return args.GetReturnValue ().Set (-1 );
981
+ }
932
982
933
- int32_t r =
934
- IndexOf (ts_obj_data + offset, ts_obj_length - offset, buf_data, buf_length);
935
- args.GetReturnValue ().Set (r == -1 ? -1 : static_cast <int32_t >(r + offset));
936
- }
983
+ size_t result = haystack_length;
937
984
985
+ if (enc == UCS2) {
986
+ if (haystack_length < 2 || needle_length < 2 ) {
987
+ return args.GetReturnValue ().Set (-1 );
988
+ }
989
+ result = SearchString (
990
+ reinterpret_cast <const uint16_t *>(haystack),
991
+ haystack_length / 2 ,
992
+ reinterpret_cast <const uint16_t *>(needle),
993
+ needle_length / 2 ,
994
+ offset / 2 );
995
+ result *= 2 ;
996
+ } else {
997
+ result = SearchString (
998
+ reinterpret_cast <const uint8_t *>(haystack),
999
+ haystack_length,
1000
+ reinterpret_cast <const uint8_t *>(needle),
1001
+ needle_length,
1002
+ offset);
1003
+ }
1004
+
1005
+ args.GetReturnValue ().Set (
1006
+ result == haystack_length ? -1 : static_cast <int >(result));
1007
+ }
938
1008
939
1009
void IndexOfNumber (const FunctionCallbackInfo<Value>& args) {
940
1010
ASSERT (args[1 ]->IsNumber ());
@@ -944,25 +1014,25 @@ void IndexOfNumber(const FunctionCallbackInfo<Value>& args) {
944
1014
SPREAD_ARG (args[0 ], ts_obj);
945
1015
946
1016
uint32_t needle = args[1 ]->Uint32Value ();
947
- int32_t offset_i32 = args[2 ]->Int32Value ();
948
- uint32_t offset;
1017
+ int64_t offset_i64 = args[2 ]->IntegerValue ();
1018
+ size_t offset;
949
1019
950
- if (offset_i32 < 0 ) {
951
- if (offset_i32 + static_cast <int32_t >(ts_obj_length) < 0 )
1020
+ if (offset_i64 < 0 ) {
1021
+ if (offset_i64 + static_cast <int64_t >(ts_obj_length) < 0 )
952
1022
offset = 0 ;
953
1023
else
954
- offset = static_cast <uint32_t >(ts_obj_length + offset_i32 );
1024
+ offset = static_cast <size_t >(ts_obj_length + offset_i64 );
955
1025
} else {
956
- offset = static_cast <uint32_t >(offset_i32 );
1026
+ offset = static_cast <size_t >(offset_i64 );
957
1027
}
958
1028
959
1029
if (ts_obj_length == 0 || offset + 1 > ts_obj_length)
960
1030
return args.GetReturnValue ().Set (-1 );
961
1031
962
1032
void * ptr = memchr (ts_obj_data + offset, needle, ts_obj_length - offset);
963
1033
char * ptr_char = static_cast <char *>(ptr);
964
- args.GetReturnValue ().Set (
965
- ptr ? static_cast < int32_t >(ptr_char - ts_obj_data) : -1 );
1034
+ args.GetReturnValue ().Set (ptr ? static_cast < int >(ptr_char - ts_obj_data)
1035
+ : -1 );
966
1036
}
967
1037
968
1038
0 commit comments