@@ -805,7 +805,7 @@ public String(char[] data, int start, int length) {
805
805
}
806
806
}
807
807
808
- String (byte [] data , int start , int length , boolean compressed ) {
808
+ private String (byte [] data , int start , int length , boolean compressed ) {
809
809
if (length == 0 ) {
810
810
value = emptyValue ;
811
811
@@ -824,19 +824,25 @@ public String(char[] data, int start, int length) {
824
824
} else {
825
825
char theChar = helpers .getCharFromArrayByIndex (data , start );
826
826
827
- if (theChar <= 255 ) {
828
- value = decompressedAsciiTable [theChar ];
827
+ if (COMPACT_STRINGS && (theChar <= 255 )) {
828
+ value = compressedAsciiTable [theChar ];
829
+ coder = LATIN1 ;
830
+ hash = theChar ;
829
831
} else {
830
- value = new byte [2 ];
832
+ if (theChar <= 255 ) {
833
+ value = decompressedAsciiTable [theChar ];
834
+ } else {
835
+ value = new byte [2 ];
831
836
832
- helpers .putCharInArrayByIndex (value , 0 , theChar );
833
- }
837
+ helpers .putCharInArrayByIndex (value , 0 , theChar );
838
+ }
834
839
835
- coder = UTF16 ;
836
- hash = theChar ;
840
+ coder = UTF16 ;
841
+ hash = theChar ;
837
842
838
- if (COMPACT_STRINGS ) {
839
- initCompressionFlag ();
843
+ if (COMPACT_STRINGS ) {
844
+ initCompressionFlag ();
845
+ }
840
846
}
841
847
}
842
848
} else {
@@ -845,17 +851,19 @@ public String(char[] data, int start, int length) {
845
851
value = data ;
846
852
} else {
847
853
value = new byte [length ];
848
-
849
854
compressedArrayCopy (data , start , value , 0 , length );
850
855
}
851
856
857
+ coder = LATIN1 ;
858
+ } else if (COMPACT_STRINGS && helpers .canEncodeAsLatin1 (data , start , length )) {
859
+ value = new byte [length ];
860
+ compress (data , start , value , 0 , length );
852
861
coder = LATIN1 ;
853
862
} else {
854
863
if (start == 0 && data .length == length * 2 ) {
855
864
value = data ;
856
865
} else {
857
866
value = StringUTF16 .newBytesFor (length );
858
-
859
867
decompressedArrayCopy (data , start , value , 0 , length );
860
868
}
861
869
@@ -868,7 +876,7 @@ public String(char[] data, int start, int length) {
868
876
}
869
877
}
870
878
871
- String (byte [] data , int start , int length , boolean compressed , boolean sharingIsAllowed ) {
879
+ private String (byte [] data , int start , int length , boolean compressed , boolean sharingIsAllowed ) {
872
880
if (length == 0 ) {
873
881
value = emptyValue ;
874
882
@@ -887,41 +895,38 @@ public String(char[] data, int start, int length) {
887
895
} else {
888
896
char theChar = helpers .getCharFromArrayByIndex (data , start );
889
897
890
- if (theChar <= 255 ) {
891
- value = decompressedAsciiTable [theChar ];
898
+ if (COMPACT_STRINGS && (theChar <= 255 )) {
899
+ value = compressedAsciiTable [theChar ];
900
+ coder = LATIN1 ;
901
+ hash = theChar ;
892
902
} else {
893
- value = new byte [2 ];
894
-
895
- helpers .putCharInArrayByIndex (value , 0 , theChar );
896
- }
903
+ if (theChar <= 255 ) {
904
+ value = decompressedAsciiTable [theChar ];
905
+ } else {
906
+ value = new byte [2 ];
907
+ helpers .putCharInArrayByIndex (value , 0 , theChar );
908
+ }
897
909
898
- coder = UTF16 ;
899
- hash = theChar ;
910
+ coder = UTF16 ;
911
+ hash = theChar ;
900
912
901
- if (COMPACT_STRINGS ) {
902
- initCompressionFlag ();
913
+ if (COMPACT_STRINGS ) {
914
+ initCompressionFlag ();
915
+ }
903
916
}
904
917
}
905
918
} else {
906
919
if (COMPACT_STRINGS && compressed ) {
907
- if (sharingIsAllowed && start == 0 && data .length == length ) {
908
- value = data ;
909
- } else {
910
- value = new byte [length ];
911
-
912
- compressedArrayCopy (data , start , value , 0 , length );
913
- }
914
-
920
+ value = new byte [length ];
921
+ compressedArrayCopy (data , start , value , 0 , length );
922
+ coder = LATIN1 ;
923
+ } else if (COMPACT_STRINGS && helpers .canEncodeAsLatin1 (data , start , length )) {
924
+ value = new byte [length ];
925
+ compress (data , start , value , 0 , length );
915
926
coder = LATIN1 ;
916
927
} else {
917
- if (sharingIsAllowed && start == 0 && data .length == length * 2 ) {
918
- value = data ;
919
- } else {
920
- value = StringUTF16 .newBytesFor (length );
921
-
922
- decompressedArrayCopy (data , start , value , 0 , length );
923
- }
924
-
928
+ value = StringUTF16 .newBytesFor (length );
929
+ decompressedArrayCopy (data , start , value , 0 , length );
925
930
coder = UTF16 ;
926
931
927
932
if (COMPACT_STRINGS ) {
@@ -2581,7 +2586,12 @@ public String replace(char oldChar, char newChar) {
2581
2586
helpers .putCharInArrayByIndex (buffer , index ++, (char ) newChar );
2582
2587
} while ((index = indexOf (oldChar , index )) != -1 );
2583
2588
2584
- return new String (buffer , UTF16 );
2589
+ if (newChar > 255 ) {
2590
+ // If the original String isn't compressed and the replacement character isn't Latin1, the result is uncompressed.
2591
+ return new String (buffer , UTF16 );
2592
+ }
2593
+
2594
+ return new String (buffer , 0 , len , false );
2585
2595
}
2586
2596
}
2587
2597
@@ -3194,7 +3204,7 @@ public String replaceAll(String regex, String substitute) {
3194
3204
if (COMPACT_STRINGS && isCompressed () && (substituteLength == 0 || substitute .isCompressed ())) {
3195
3205
byte [] newChars = new byte [length ];
3196
3206
byte toReplace = helpers .getByteFromArrayByIndex (regex .value , 0 );
3197
- byte replacement = (byte )- 1 ; // assign dummy value that will never be used
3207
+ byte replacement = (byte )0 ; // assign dummy value that isn't used
3198
3208
if (substituteLength == 1 ) {
3199
3209
replacement = helpers .getByteFromArrayByIndex (substitute .value , 0 );
3200
3210
checkLastChar ((char )replacement );
@@ -3212,7 +3222,7 @@ public String replaceAll(String regex, String substitute) {
3212
3222
} else if (!COMPACT_STRINGS || !isCompressed ()) {
3213
3223
byte [] newChars = StringUTF16 .newBytesFor (length );
3214
3224
char toReplace = regex .charAtInternal (0 );
3215
- char replacement = (char )- 1 ; // assign dummy value that will never be used
3225
+ char replacement = (char )0 ; // assign dummy value that must be Latin1 (0 - 255)
3216
3226
if (substituteLength == 1 ) {
3217
3227
replacement = substitute .charAtInternal (0 );
3218
3228
checkLastChar (replacement );
@@ -3226,6 +3236,10 @@ public String replaceAll(String regex, String substitute) {
3226
3236
helpers .putCharInArrayByIndex (newChars , newCharIndex ++, replacement );
3227
3237
}
3228
3238
}
3239
+ if (replacement > 255 ) {
3240
+ // If the original String isn't compressed and the replacement character isn't Latin1, the result is uncompressed.
3241
+ return new String (newChars , UTF16 );
3242
+ }
3229
3243
return new String (newChars , 0 , newCharIndex , false );
3230
3244
}
3231
3245
}
0 commit comments