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"
@@ -792,87 +793,156 @@ void Compare(const FunctionCallbackInfo<Value> &args) {
792
793
}
793
794
794
795
795
- int32_t IndexOf (const char * haystack,
796
- size_t h_length,
797
- const char * needle,
798
- size_t n_length) {
799
- CHECK_GE (h_length, n_length);
800
- // TODO(trevnorris): Implement Boyer-Moore string search algorithm.
801
- for (size_t i = 0 ; i < h_length - n_length + 1 ; i++) {
802
- if (haystack[i] == needle[0 ]) {
803
- if (memcmp (haystack + i, needle, n_length) == 0 )
804
- return i;
805
- }
806
- }
807
- return -1 ;
808
- }
809
-
810
-
811
796
void IndexOfString (const FunctionCallbackInfo<Value>& args) {
812
797
ASSERT (args[1 ]->IsString ());
813
798
ASSERT (args[2 ]->IsNumber ());
814
799
800
+ enum encoding enc = ParseEncoding (args.GetIsolate (),
801
+ args[3 ],
802
+ UTF8);
803
+
815
804
THROW_AND_RETURN_UNLESS_BUFFER (Environment::GetCurrent (args), args[0 ]);
816
805
SPREAD_ARG (args[0 ], ts_obj);
817
806
818
- node::Utf8Value str (args.GetIsolate (), args[1 ]);
819
- int32_t offset_i32 = args[2 ]->Int32Value ();
820
- uint32_t offset;
807
+ Local<String> needle = args[1 ].As <String>();
808
+ const char * haystack = ts_obj_data;
809
+ const size_t haystack_length = ts_obj_length;
810
+ const size_t needle_length = needle->Utf8Length ();
811
+
812
+
813
+ if (needle_length == 0 || haystack_length == 0 ) {
814
+ return args.GetReturnValue ().Set (-1 );
815
+ }
816
+
817
+ int64_t offset_i64 = args[2 ]->IntegerValue ();
818
+ size_t offset = 0 ;
821
819
822
- if (offset_i32 < 0 ) {
823
- if (offset_i32 + static_cast <int32_t >(ts_obj_length ) < 0 )
820
+ if (offset_i64 < 0 ) {
821
+ if (offset_i64 + static_cast <int64_t >(haystack_length ) < 0 ) {
824
822
offset = 0 ;
825
- else
826
- offset = static_cast <uint32_t >(ts_obj_length + offset_i32);
823
+ } else {
824
+ offset = static_cast <size_t >(haystack_length + offset_i64);
825
+ }
827
826
} else {
828
- offset = static_cast <uint32_t >(offset_i32 );
827
+ offset = static_cast <size_t >(offset_i64 );
829
828
}
830
829
831
- if (str.length () == 0 ||
832
- ts_obj_length == 0 ||
833
- (offset != 0 && str.length () + offset <= str.length ()) ||
834
- str.length () + offset > ts_obj_length)
830
+ if (haystack_length < offset || needle_length + offset > haystack_length) {
835
831
return args.GetReturnValue ().Set (-1 );
832
+ }
836
833
837
- int32_t r =
838
- IndexOf (ts_obj_data + offset, ts_obj_length - offset, *str, str.length ());
839
- args.GetReturnValue ().Set (r == -1 ? -1 : static_cast <int32_t >(r + offset));
840
- }
834
+ size_t result = haystack_length;
835
+
836
+ if (enc == UCS2) {
837
+ String::Value needle_value (needle);
838
+ if (*needle_value == nullptr )
839
+ return args.GetReturnValue ().Set (-1 );
840
+
841
+ if (haystack_length < 2 || needle_value.length () < 1 ) {
842
+ return args.GetReturnValue ().Set (-1 );
843
+ }
844
+
845
+ result = SearchString (reinterpret_cast <const uint16_t *>(haystack),
846
+ haystack_length / 2 ,
847
+ reinterpret_cast <const uint16_t *>(*needle_value),
848
+ needle_value.length (),
849
+ offset / 2 );
850
+ result *= 2 ;
851
+ } else if (enc == UTF8) {
852
+ String::Utf8Value needle_value (needle);
853
+ if (*needle_value == nullptr )
854
+ return args.GetReturnValue ().Set (-1 );
855
+
856
+ result = SearchString (reinterpret_cast <const uint8_t *>(haystack),
857
+ haystack_length,
858
+ reinterpret_cast <const uint8_t *>(*needle_value),
859
+ needle_length,
860
+ offset);
861
+ } else if (enc == BINARY) {
862
+ uint8_t * needle_data = static_cast <uint8_t *>(malloc (needle_length));
863
+ if (needle_data == nullptr ) {
864
+ return args.GetReturnValue ().Set (-1 );
865
+ }
866
+ needle->WriteOneByte (
867
+ needle_data, 0 , needle_length, String::NO_NULL_TERMINATION);
868
+
869
+ result = SearchString (reinterpret_cast <const uint8_t *>(haystack),
870
+ haystack_length,
871
+ needle_data,
872
+ needle_length,
873
+ offset);
874
+ free (needle_data);
875
+ }
841
876
877
+ args.GetReturnValue ().Set (
878
+ result == haystack_length ? -1 : static_cast <int >(result));
879
+ }
842
880
843
881
void IndexOfBuffer (const FunctionCallbackInfo<Value>& args) {
844
882
ASSERT (args[1 ]->IsObject ());
845
883
ASSERT (args[2 ]->IsNumber ());
846
884
885
+ enum encoding enc = ParseEncoding (args.GetIsolate (),
886
+ args[3 ],
887
+ UTF8);
888
+
847
889
THROW_AND_RETURN_UNLESS_BUFFER (Environment::GetCurrent (args), args[0 ]);
848
890
SPREAD_ARG (args[0 ], ts_obj);
849
891
SPREAD_ARG (args[1 ], buf);
850
- const int32_t offset_i32 = args[2 ]->Int32Value ();
851
- uint32_t offset;
852
892
853
893
if (buf_length > 0 )
854
894
CHECK_NE (buf_data, nullptr );
855
895
856
- if (offset_i32 < 0 ) {
857
- if (offset_i32 + static_cast <int32_t >(ts_obj_length) < 0 )
896
+ const char * haystack = ts_obj_data;
897
+ const size_t haystack_length = ts_obj_length;
898
+ const char * needle = buf_data;
899
+ const size_t needle_length = buf_length;
900
+
901
+ if (needle_length == 0 || haystack_length == 0 ) {
902
+ return args.GetReturnValue ().Set (-1 );
903
+ }
904
+
905
+ int64_t offset_i64 = args[2 ]->IntegerValue ();
906
+ size_t offset = 0 ;
907
+
908
+ if (offset_i64 < 0 ) {
909
+ if (offset_i64 + static_cast <int64_t >(haystack_length) < 0 )
858
910
offset = 0 ;
859
911
else
860
- offset = static_cast <uint32_t >(ts_obj_length + offset_i32 );
912
+ offset = static_cast <size_t >(haystack_length + offset_i64 );
861
913
} else {
862
- offset = static_cast <uint32_t >(offset_i32 );
914
+ offset = static_cast <size_t >(offset_i64 );
863
915
}
864
916
865
- if (buf_length == 0 ||
866
- ts_obj_length == 0 ||
867
- (offset != 0 && buf_length + offset <= buf_length) ||
868
- buf_length + offset > ts_obj_length)
917
+ if (haystack_length < offset || needle_length + offset > haystack_length) {
869
918
return args.GetReturnValue ().Set (-1 );
919
+ }
870
920
871
- int32_t r =
872
- IndexOf (ts_obj_data + offset, ts_obj_length - offset, buf_data, buf_length);
873
- args.GetReturnValue ().Set (r == -1 ? -1 : static_cast <int32_t >(r + offset));
874
- }
921
+ size_t result = haystack_length;
875
922
923
+ if (enc == UCS2) {
924
+ if (haystack_length < 2 || needle_length < 2 ) {
925
+ return args.GetReturnValue ().Set (-1 );
926
+ }
927
+ result = SearchString (
928
+ reinterpret_cast <const uint16_t *>(haystack),
929
+ haystack_length / 2 ,
930
+ reinterpret_cast <const uint16_t *>(needle),
931
+ needle_length / 2 ,
932
+ offset / 2 );
933
+ result *= 2 ;
934
+ } else {
935
+ result = SearchString (
936
+ reinterpret_cast <const uint8_t *>(haystack),
937
+ haystack_length,
938
+ reinterpret_cast <const uint8_t *>(needle),
939
+ needle_length,
940
+ offset);
941
+ }
942
+
943
+ args.GetReturnValue ().Set (
944
+ result == haystack_length ? -1 : static_cast <int >(result));
945
+ }
876
946
877
947
void IndexOfNumber (const FunctionCallbackInfo<Value>& args) {
878
948
ASSERT (args[1 ]->IsNumber ());
@@ -882,25 +952,25 @@ void IndexOfNumber(const FunctionCallbackInfo<Value>& args) {
882
952
SPREAD_ARG (args[0 ], ts_obj);
883
953
884
954
uint32_t needle = args[1 ]->Uint32Value ();
885
- int32_t offset_i32 = args[2 ]->Int32Value ();
886
- uint32_t offset;
955
+ int64_t offset_i64 = args[2 ]->IntegerValue ();
956
+ size_t offset;
887
957
888
- if (offset_i32 < 0 ) {
889
- if (offset_i32 + static_cast <int32_t >(ts_obj_length) < 0 )
958
+ if (offset_i64 < 0 ) {
959
+ if (offset_i64 + static_cast <int64_t >(ts_obj_length) < 0 )
890
960
offset = 0 ;
891
961
else
892
- offset = static_cast <uint32_t >(ts_obj_length + offset_i32 );
962
+ offset = static_cast <size_t >(ts_obj_length + offset_i64 );
893
963
} else {
894
- offset = static_cast <uint32_t >(offset_i32 );
964
+ offset = static_cast <size_t >(offset_i64 );
895
965
}
896
966
897
967
if (ts_obj_length == 0 || offset + 1 > ts_obj_length)
898
968
return args.GetReturnValue ().Set (-1 );
899
969
900
970
void * ptr = memchr (ts_obj_data + offset, needle, ts_obj_length - offset);
901
971
char * ptr_char = static_cast <char *>(ptr);
902
- args.GetReturnValue ().Set (
903
- ptr ? static_cast < int32_t >(ptr_char - ts_obj_data) : -1 );
972
+ args.GetReturnValue ().Set (ptr ? static_cast < int >(ptr_char - ts_obj_data)
973
+ : -1 );
904
974
}
905
975
906
976
0 commit comments