String.java 73 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205
  1. /* String.java -- immutable character sequences; the object of string literals
  2. Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
  3. Free Software Foundation, Inc.
  4. This file is part of GNU Classpath.
  5. GNU Classpath is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9. GNU Classpath is distributed in the hope that it will be useful, but
  10. WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GNU Classpath; see the file COPYING. If not, write to the
  15. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  16. 02110-1301 USA.
  17. Linking this library statically or dynamically with other modules is
  18. making a combined work based on this library. Thus, the terms and
  19. conditions of the GNU General Public License cover the whole
  20. combination.
  21. As a special exception, the copyright holders of this library give you
  22. permission to link this library with independent modules to produce an
  23. executable, regardless of the license terms of these independent
  24. modules, and to copy and distribute the resulting executable under
  25. terms of your choice, provided that you also meet, for each linked
  26. independent module, the terms and conditions of the license of that
  27. module. An independent module is a module which is not derived from
  28. or based on this library. If you modify this library, you may extend
  29. this exception to your version of the library, but you are not
  30. obligated to do so. If you do not wish to do so, delete this
  31. exception statement from your version. */
  32. package java.lang;
  33. import gnu.java.lang.CharData;
  34. import gnu.java.lang.CPStringBuilder;
  35. import java.io.Serializable;
  36. import java.io.UnsupportedEncodingException;
  37. import java.nio.ByteBuffer;
  38. import java.nio.CharBuffer;
  39. import java.nio.charset.CharacterCodingException;
  40. import java.nio.charset.Charset;
  41. import java.nio.charset.CharsetDecoder;
  42. import java.nio.charset.CharsetEncoder;
  43. import java.nio.charset.CodingErrorAction;
  44. import java.nio.charset.IllegalCharsetNameException;
  45. import java.nio.charset.UnsupportedCharsetException;
  46. import java.text.Collator;
  47. import java.util.Comparator;
  48. import java.util.Formatter;
  49. import java.util.Locale;
  50. import java.util.regex.Matcher;
  51. import java.util.regex.Pattern;
  52. import java.util.regex.PatternSyntaxException;
  53. /**
  54. * Strings represent an immutable set of characters. All String literals
  55. * are instances of this class, and two string literals with the same contents
  56. * refer to the same String object.
  57. *
  58. * <p>This class also includes a number of methods for manipulating the
  59. * contents of strings (of course, creating a new object if there are any
  60. * changes, as String is immutable). Case mapping relies on Unicode 3.0.0
  61. * standards, where some character sequences have a different number of
  62. * characters in the uppercase version than the lower case.
  63. *
  64. * <p>Strings are special, in that they are the only object with an overloaded
  65. * operator. When you use '+' with at least one String argument, both
  66. * arguments have String conversion performed on them, and another String (not
  67. * guaranteed to be unique) results.
  68. *
  69. * <p>String is special-cased when doing data serialization - rather than
  70. * listing the fields of this class, a String object is converted to a string
  71. * literal in the object stream.
  72. *
  73. * @author Paul N. Fisher
  74. * @author Eric Blake (ebb9@email.byu.edu)
  75. * @author Per Bothner (bothner@cygnus.com)
  76. * @author Tom Tromey (tromey@redhat.com)
  77. * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
  78. * @since 1.0
  79. * @status updated to 1.4; but could use better data sharing via offset field
  80. */
  81. public final class String
  82. implements Serializable, Comparable<String>, CharSequence
  83. {
  84. // WARNING: String is a CORE class in the bootstrap cycle. See the comments
  85. // in vm/reference/java/lang/Runtime for implications of this fact.
  86. /**
  87. * This is probably not necessary because this class is special cased already
  88. * but it will avoid showing up as a discrepancy when comparing SUIDs.
  89. */
  90. private static final long serialVersionUID = -6849794470754667710L;
  91. /**
  92. * Stores unicode multi-character uppercase expansion table.
  93. * @see #toUpperCase(Locale)
  94. * @see CharData#UPPER_EXPAND
  95. */
  96. private static final char[] upperExpand
  97. = zeroBasedStringValue(CharData.UPPER_EXPAND);
  98. /**
  99. * Stores unicode multi-character uppercase special casing table.
  100. * @see #upperCaseExpansion(char)
  101. * @see CharData#UPPER_SPECIAL
  102. */
  103. private static final char[] upperSpecial
  104. = zeroBasedStringValue(CharData.UPPER_SPECIAL);
  105. /**
  106. * Characters which make up the String.
  107. * Package access is granted for use by StringBuffer.
  108. */
  109. final char[] value;
  110. /**
  111. * Holds the number of characters in value. This number is generally
  112. * the same as value.length, but can be smaller because substrings and
  113. * StringBuffers can share arrays. Package visible for use by trusted code.
  114. */
  115. final int count;
  116. /**
  117. * Caches the result of hashCode(). If this value is zero, the hashcode
  118. * is considered uncached (even if 0 is the correct hash value).
  119. */
  120. private int cachedHashCode;
  121. /**
  122. * Holds the starting position for characters in value[]. Since
  123. * substring()'s are common, the use of offset allows the operation
  124. * to perform in O(1). Package access is granted for use by StringBuffer.
  125. */
  126. final int offset;
  127. /**
  128. * An implementation for {@link #CASE_INSENSITIVE_ORDER}.
  129. * This must be {@link Serializable}. The class name is dictated by
  130. * compatibility with Sun's JDK.
  131. */
  132. private static final class CaseInsensitiveComparator
  133. implements Comparator<String>, Serializable
  134. {
  135. /**
  136. * Compatible with JDK 1.2.
  137. */
  138. private static final long serialVersionUID = 8575799808933029326L;
  139. /**
  140. * The default private constructor generates unnecessary overhead.
  141. */
  142. CaseInsensitiveComparator() {}
  143. /**
  144. * Compares to Strings, using
  145. * <code>String.compareToIgnoreCase(String)</code>.
  146. *
  147. * @param o1 the first string
  148. * @param o2 the second string
  149. * @return &lt; 0, 0, or &gt; 0 depending on the case-insensitive
  150. * comparison of the two strings.
  151. * @throws NullPointerException if either argument is null
  152. * @throws ClassCastException if either argument is not a String
  153. * @see #compareToIgnoreCase(String)
  154. */
  155. public int compare(String o1, String o2)
  156. {
  157. return o1.compareToIgnoreCase(o2);
  158. }
  159. } // class CaseInsensitiveComparator
  160. /**
  161. * A Comparator that uses <code>String.compareToIgnoreCase(String)</code>.
  162. * This comparator is {@link Serializable}. Note that it ignores Locale,
  163. * for that, you want a Collator.
  164. *
  165. * @see Collator#compare(String, String)
  166. * @since 1.2
  167. */
  168. public static final Comparator<String> CASE_INSENSITIVE_ORDER
  169. = new CaseInsensitiveComparator();
  170. /**
  171. * Creates an empty String (length 0). Unless you really need a new object,
  172. * consider using <code>""</code> instead.
  173. */
  174. public String()
  175. {
  176. value = "".value;
  177. offset = 0;
  178. count = 0;
  179. }
  180. /**
  181. * Copies the contents of a String to a new String. Since Strings are
  182. * immutable, only a shallow copy is performed.
  183. *
  184. * @param str String to copy
  185. * @throws NullPointerException if value is null
  186. */
  187. public String(String str)
  188. {
  189. value = str.value;
  190. offset = str.offset;
  191. count = str.count;
  192. cachedHashCode = str.cachedHashCode;
  193. }
  194. /**
  195. * Creates a new String using the character sequence of the char array.
  196. * Subsequent changes to data do not affect the String.
  197. *
  198. * @param data char array to copy
  199. * @throws NullPointerException if data is null
  200. */
  201. public String(char[] data)
  202. {
  203. this(data, 0, data.length, false);
  204. }
  205. /**
  206. * Creates a new String using the character sequence of a subarray of
  207. * characters. The string starts at offset, and copies count chars.
  208. * Subsequent changes to data do not affect the String.
  209. *
  210. * @param data char array to copy
  211. * @param offset position (base 0) to start copying out of data
  212. * @param count the number of characters from data to copy
  213. * @throws NullPointerException if data is null
  214. * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
  215. * || offset + count &lt; 0 (overflow)
  216. * || offset + count &gt; data.length)
  217. * (while unspecified, this is a StringIndexOutOfBoundsException)
  218. */
  219. public String(char[] data, int offset, int count)
  220. {
  221. this(data, offset, count, false);
  222. }
  223. /**
  224. * Creates a new String using an 8-bit array of integer values, starting at
  225. * an offset, and copying up to the count. Each character c, using
  226. * corresponding byte b, is created in the new String as if by performing:
  227. *
  228. * <pre>
  229. * c = (char) (((hibyte &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
  230. * </pre>
  231. *
  232. * @param ascii array of integer values
  233. * @param hibyte top byte of each Unicode character
  234. * @param offset position (base 0) to start copying out of ascii
  235. * @param count the number of characters from ascii to copy
  236. * @throws NullPointerException if ascii is null
  237. * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
  238. * || offset + count &lt; 0 (overflow)
  239. * || offset + count &gt; ascii.length)
  240. * (while unspecified, this is a StringIndexOutOfBoundsException)
  241. * @see #String(byte[])
  242. * @see #String(byte[], String)
  243. * @see #String(byte[], int, int)
  244. * @see #String(byte[], int, int, String)
  245. * @deprecated use {@link #String(byte[], int, int, String)} to perform
  246. * correct encoding
  247. */
  248. public String(byte[] ascii, int hibyte, int offset, int count)
  249. {
  250. if (offset < 0)
  251. throw new StringIndexOutOfBoundsException("offset: " + offset);
  252. if (count < 0)
  253. throw new StringIndexOutOfBoundsException("count: " + count);
  254. // equivalent to: offset + count < 0 || offset + count > ascii.length
  255. if (ascii.length - offset < count)
  256. throw new StringIndexOutOfBoundsException("offset + count: "
  257. + (offset + count));
  258. value = new char[count];
  259. this.offset = 0;
  260. this.count = count;
  261. hibyte <<= 8;
  262. offset += count;
  263. while (--count >= 0)
  264. value[count] = (char) (hibyte | (ascii[--offset] & 0xff));
  265. }
  266. /**
  267. * Creates a new String using an 8-bit array of integer values. Each
  268. * character c, using corresponding byte b, is created in the new String
  269. * as if by performing:
  270. *
  271. * <pre>
  272. * c = (char) (((hibyte &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
  273. * </pre>
  274. *
  275. * @param ascii array of integer values
  276. * @param hibyte top byte of each Unicode character
  277. * @throws NullPointerException if ascii is null
  278. * @see #String(byte[])
  279. * @see #String(byte[], String)
  280. * @see #String(byte[], int, int)
  281. * @see #String(byte[], int, int, String)
  282. * @see #String(byte[], int, int, int)
  283. * @deprecated use {@link #String(byte[], String)} to perform
  284. * correct encoding
  285. */
  286. public String(byte[] ascii, int hibyte)
  287. {
  288. this(ascii, hibyte, 0, ascii.length);
  289. }
  290. /**
  291. * Creates a new String using the portion of the byte array starting at the
  292. * offset and ending at offset + count. Uses the specified encoding type
  293. * to decode the byte array, so the resulting string may be longer or
  294. * shorter than the byte array. For more decoding control, use
  295. * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
  296. * see {@link java.nio.charset.Charset}. The behavior is not specified if
  297. * the decoder encounters invalid characters; this implementation throws
  298. * an Error.
  299. *
  300. * @param data byte array to copy
  301. * @param offset the offset to start at
  302. * @param count the number of bytes in the array to use
  303. * @param encoding the name of the encoding to use
  304. * @throws NullPointerException if data or encoding is null
  305. * @throws IndexOutOfBoundsException if offset or count is incorrect
  306. * (while unspecified, this is a StringIndexOutOfBoundsException)
  307. * @throws UnsupportedEncodingException if encoding is not found
  308. * @throws Error if the decoding fails
  309. * @since 1.1
  310. */
  311. public String(byte[] data, int offset, int count, final String encoding)
  312. throws UnsupportedEncodingException
  313. {
  314. this(data, offset, count, stringToCharset(encoding));
  315. }
  316. /**
  317. * Wrapper method to convert exceptions resulting from
  318. * the selection of a {@link java.nio.charset.Charset} based on
  319. * a String.
  320. *
  321. * @throws UnsupportedEncodingException if encoding is not found
  322. */
  323. private static final Charset stringToCharset(final String encoding)
  324. throws UnsupportedEncodingException
  325. {
  326. try
  327. {
  328. return Charset.forName(encoding);
  329. }
  330. catch(IllegalCharsetNameException e)
  331. {
  332. throw new UnsupportedEncodingException("Encoding: "+encoding+
  333. " not found.");
  334. }
  335. catch(UnsupportedCharsetException e)
  336. {
  337. throw new UnsupportedEncodingException("Encoding: "+encoding+
  338. " not found.");
  339. }
  340. }
  341. /**
  342. * Creates a new String using the portion of the byte array starting at the
  343. * offset and ending at offset + count. Uses the specified encoding type
  344. * to decode the byte array, so the resulting string may be longer or
  345. * shorter than the byte array. For more decoding control, use
  346. * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
  347. * see {@link java.nio.charset.Charset}. Malformed input and unmappable
  348. * character sequences are replaced with the default replacement string
  349. * provided by the {@link java.nio.charset.Charset}.
  350. *
  351. * @param data byte array to copy
  352. * @param offset the offset to start at
  353. * @param count the number of bytes in the array to use
  354. * @param encoding the encoding to use
  355. * @throws NullPointerException if data or encoding is null
  356. * @throws IndexOutOfBoundsException if offset or count is incorrect
  357. * (while unspecified, this is a StringIndexOutOfBoundsException)
  358. * @since 1.6
  359. */
  360. public String(byte[] data, int offset, int count, Charset encoding)
  361. {
  362. if (offset < 0)
  363. throw new StringIndexOutOfBoundsException("offset: " + offset);
  364. if (count < 0)
  365. throw new StringIndexOutOfBoundsException("count: " + count);
  366. // equivalent to: offset + count < 0 || offset + count > data.length
  367. if (data.length - offset < count)
  368. throw new StringIndexOutOfBoundsException("offset + count: "
  369. + (offset + count));
  370. try
  371. {
  372. CharsetDecoder csd = encoding.newDecoder();
  373. csd.onMalformedInput(CodingErrorAction.REPLACE);
  374. csd.onUnmappableCharacter(CodingErrorAction.REPLACE);
  375. CharBuffer cbuf = csd.decode(ByteBuffer.wrap(data, offset, count));
  376. if(cbuf.hasArray())
  377. {
  378. value = cbuf.array();
  379. this.offset = cbuf.position();
  380. this.count = cbuf.remaining();
  381. } else {
  382. // Doubt this will happen. But just in case.
  383. value = new char[cbuf.remaining()];
  384. cbuf.get(value);
  385. this.offset = 0;
  386. this.count = value.length;
  387. }
  388. }
  389. catch(CharacterCodingException e)
  390. {
  391. // This shouldn't ever happen.
  392. throw (InternalError) new InternalError().initCause(e);
  393. }
  394. }
  395. /**
  396. * Creates a new String using the byte array. Uses the specified encoding
  397. * type to decode the byte array, so the resulting string may be longer or
  398. * shorter than the byte array. For more decoding control, use
  399. * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
  400. * see {@link java.nio.charset.Charset}. The behavior is not specified if
  401. * the decoder encounters invalid characters; this implementation throws
  402. * an Error.
  403. *
  404. * @param data byte array to copy
  405. * @param encoding the name of the encoding to use
  406. * @throws NullPointerException if data or encoding is null
  407. * @throws UnsupportedEncodingException if encoding is not found
  408. * @throws Error if the decoding fails
  409. * @see #String(byte[], int, int, String)
  410. * @since 1.1
  411. */
  412. public String(byte[] data, String encoding)
  413. throws UnsupportedEncodingException
  414. {
  415. this(data, 0, data.length, encoding);
  416. }
  417. /**
  418. * Creates a new String using the byte array. Uses the specified encoding
  419. * type to decode the byte array, so the resulting string may be longer or
  420. * shorter than the byte array. For more decoding control, use
  421. * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
  422. * see {@link java.nio.charset.Charset}. Malformed input and unmappable
  423. * character sequences are replaced with the default replacement string
  424. * provided by the {@link java.nio.charset.Charset}.
  425. *
  426. * @param data byte array to copy
  427. * @param encoding the name of the encoding to use
  428. * @throws NullPointerException if data or encoding is null
  429. * @see #String(byte[], int, int, java.nio.Charset)
  430. * @since 1.6
  431. */
  432. public String(byte[] data, Charset encoding)
  433. {
  434. this(data, 0, data.length, encoding);
  435. }
  436. /**
  437. * Creates a new String using the portion of the byte array starting at the
  438. * offset and ending at offset + count. Uses the encoding of the platform's
  439. * default charset, so the resulting string may be longer or shorter than
  440. * the byte array. For more decoding control, use
  441. * {@link java.nio.charset.CharsetDecoder}. The behavior is not specified
  442. * if the decoder encounters invalid characters; this implementation throws
  443. * an Error.
  444. *
  445. * @param data byte array to copy
  446. * @param offset the offset to start at
  447. * @param count the number of bytes in the array to use
  448. * @throws NullPointerException if data is null
  449. * @throws IndexOutOfBoundsException if offset or count is incorrect
  450. * @throws Error if the decoding fails
  451. * @see #String(byte[], int, int, String)
  452. * @since 1.1
  453. */
  454. public String(byte[] data, int offset, int count)
  455. {
  456. if (offset < 0)
  457. throw new StringIndexOutOfBoundsException("offset: " + offset);
  458. if (count < 0)
  459. throw new StringIndexOutOfBoundsException("count: " + count);
  460. // equivalent to: offset + count < 0 || offset + count > data.length
  461. if (data.length - offset < count)
  462. throw new StringIndexOutOfBoundsException("offset + count: "
  463. + (offset + count));
  464. int o, c;
  465. char[] v;
  466. String encoding;
  467. try
  468. {
  469. encoding = System.getProperty("file.encoding");
  470. CharsetDecoder csd = Charset.forName(encoding).newDecoder();
  471. csd.onMalformedInput(CodingErrorAction.REPLACE);
  472. csd.onUnmappableCharacter(CodingErrorAction.REPLACE);
  473. CharBuffer cbuf = csd.decode(ByteBuffer.wrap(data, offset, count));
  474. if(cbuf.hasArray())
  475. {
  476. v = cbuf.array();
  477. o = cbuf.position();
  478. c = cbuf.remaining();
  479. } else {
  480. // Doubt this will happen. But just in case.
  481. v = new char[cbuf.remaining()];
  482. cbuf.get(v);
  483. o = 0;
  484. c = v.length;
  485. }
  486. } catch(Exception ex){
  487. // If anything goes wrong (System property not set,
  488. // NIO provider not available, etc)
  489. // Default to the 'safe' encoding ISO8859_1
  490. v = new char[count];
  491. o = 0;
  492. c = count;
  493. for (int i=0;i<count;i++)
  494. v[i] = (char)data[offset+i];
  495. }
  496. this.value = v;
  497. this.offset = o;
  498. this.count = c;
  499. }
  500. /**
  501. * Creates a new String using the byte array. Uses the encoding of the
  502. * platform's default charset, so the resulting string may be longer or
  503. * shorter than the byte array. For more decoding control, use
  504. * {@link java.nio.charset.CharsetDecoder}. The behavior is not specified
  505. * if the decoder encounters invalid characters; this implementation throws
  506. * an Error.
  507. *
  508. * @param data byte array to copy
  509. * @throws NullPointerException if data is null
  510. * @throws Error if the decoding fails
  511. * @see #String(byte[], int, int)
  512. * @see #String(byte[], int, int, String)
  513. * @since 1.1
  514. */
  515. public String(byte[] data)
  516. {
  517. this(data, 0, data.length);
  518. }
  519. /**
  520. * Creates a new String using the character sequence represented by
  521. * the StringBuffer. Subsequent changes to buf do not affect the String.
  522. *
  523. * @param buffer StringBuffer to copy
  524. * @throws NullPointerException if buffer is null
  525. */
  526. public String(StringBuffer buffer)
  527. {
  528. synchronized (buffer)
  529. {
  530. offset = 0;
  531. count = buffer.count;
  532. // Share unless buffer is 3/4 empty.
  533. if ((count << 2) < buffer.value.length)
  534. {
  535. value = new char[count];
  536. VMSystem.arraycopy(buffer.value, 0, value, 0, count);
  537. }
  538. else
  539. {
  540. buffer.shared = true;
  541. value = buffer.value;
  542. }
  543. }
  544. }
  545. /**
  546. * Creates a new String using the character sequence represented by
  547. * the StringBuilder. Subsequent changes to buf do not affect the String.
  548. *
  549. * @param buffer StringBuilder to copy
  550. * @throws NullPointerException if buffer is null
  551. */
  552. public String(StringBuilder buffer)
  553. {
  554. this(buffer.value, 0, buffer.count);
  555. }
  556. /**
  557. * Special constructor which can share an array when safe to do so.
  558. *
  559. * @param data the characters to copy
  560. * @param offset the location to start from
  561. * @param count the number of characters to use
  562. * @param dont_copy true if the array is trusted, and need not be copied
  563. * @throws NullPointerException if chars is null
  564. * @throws StringIndexOutOfBoundsException if bounds check fails
  565. */
  566. String(char[] data, int offset, int count, boolean dont_copy)
  567. {
  568. if (offset < 0)
  569. throw new StringIndexOutOfBoundsException("offset: " + offset);
  570. if (count < 0)
  571. throw new StringIndexOutOfBoundsException("count: " + count);
  572. // equivalent to: offset + count < 0 || offset + count > data.length
  573. if (data.length - offset < count)
  574. throw new StringIndexOutOfBoundsException("offset + count: "
  575. + (offset + count));
  576. if (dont_copy)
  577. {
  578. value = data;
  579. this.offset = offset;
  580. }
  581. else
  582. {
  583. value = new char[count];
  584. VMSystem.arraycopy(data, offset, value, 0, count);
  585. this.offset = 0;
  586. }
  587. this.count = count;
  588. }
  589. /**
  590. * Creates a new String containing the characters represented in the
  591. * given subarray of Unicode code points.
  592. * @param codePoints the entire array of code points
  593. * @param offset the start of the subarray
  594. * @param count the length of the subarray
  595. *
  596. * @throws IllegalArgumentException if an invalid code point is found
  597. * in the codePoints array
  598. * @throws IndexOutOfBoundsException if offset is negative or offset + count
  599. * is greater than the length of the array.
  600. */
  601. public String(int[] codePoints, int offset, int count)
  602. {
  603. // FIXME: This implementation appears to give correct internal
  604. // representation of the String because:
  605. // - length() is correct
  606. // - getting a char[] from toCharArray() and testing
  607. // Character.codePointAt() on all the characters in that array gives
  608. // the appropriate results
  609. // however printing the String gives incorrect results. This may be
  610. // due to printing method errors (such as incorrectly looping through
  611. // the String one char at a time rather than one "character" at a time.
  612. if (offset < 0)
  613. throw new IndexOutOfBoundsException();
  614. int end = offset + count;
  615. int pos = 0;
  616. // This creates a char array that is long enough for all of the code
  617. // points to represent supplementary characters. This is more than likely
  618. // a waste of storage, so we use it only temporarily and then copy the
  619. // used portion into the value array.
  620. char[] temp = new char[2 * codePoints.length];
  621. for (int i = offset; i < end; i++)
  622. {
  623. pos += Character.toChars(codePoints[i], temp, pos);
  624. }
  625. this.count = pos;
  626. this.value = new char[pos];
  627. System.arraycopy(temp, 0, value, 0, pos);
  628. this.offset = 0;
  629. }
  630. /**
  631. * Returns the number of characters contained in this String.
  632. *
  633. * @return the length of this String
  634. */
  635. public int length()
  636. {
  637. return count;
  638. }
  639. /**
  640. * Returns the character located at the specified index within this String.
  641. *
  642. * @param index position of character to return (base 0)
  643. * @return character located at position index
  644. * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= length()
  645. * (while unspecified, this is a StringIndexOutOfBoundsException)
  646. */
  647. public char charAt(int index)
  648. {
  649. if (index < 0 || index >= count)
  650. throw new StringIndexOutOfBoundsException(index);
  651. return value[offset + index];
  652. }
  653. /**
  654. * Get the code point at the specified index. This is like #charAt(int),
  655. * but if the character is the start of a surrogate pair, and the
  656. * following character completes the pair, then the corresponding
  657. * supplementary code point is returned.
  658. * @param index the index of the codepoint to get, starting at 0
  659. * @return the codepoint at the specified index
  660. * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
  661. * @since 1.5
  662. */
  663. public synchronized int codePointAt(int index)
  664. {
  665. if (index < 0 || index >= count)
  666. throw new StringIndexOutOfBoundsException(index);
  667. // Use the CharSequence overload as we get better range checking
  668. // this way.
  669. return Character.codePointAt(this, index);
  670. }
  671. /**
  672. * Get the code point before the specified index. This is like
  673. * #codePointAt(int), but checks the characters at <code>index-1</code> and
  674. * <code>index-2</code> to see if they form a supplementary code point.
  675. * @param index the index just past the codepoint to get, starting at 0
  676. * @return the codepoint at the specified index
  677. * @throws IndexOutOfBoundsException if index is less than 1 or &gt; length()
  678. * (while unspecified, this is a StringIndexOutOfBoundsException)
  679. * @since 1.5
  680. */
  681. public synchronized int codePointBefore(int index)
  682. {
  683. if (index < 1 || index > count)
  684. throw new StringIndexOutOfBoundsException(index);
  685. // Use the CharSequence overload as we get better range checking
  686. // this way.
  687. return Character.codePointBefore(this, index);
  688. }
  689. /**
  690. * Copies characters from this String starting at a specified start index,
  691. * ending at a specified stop index, to a character array starting at
  692. * a specified destination begin index.
  693. *
  694. * @param srcBegin index to begin copying characters from this String
  695. * @param srcEnd index after the last character to be copied from this String
  696. * @param dst character array which this String is copied into
  697. * @param dstBegin index to start writing characters into dst
  698. * @throws NullPointerException if dst is null
  699. * @throws IndexOutOfBoundsException if any indices are out of bounds
  700. * (while unspecified, source problems cause a
  701. * StringIndexOutOfBoundsException, and dst problems cause an
  702. * ArrayIndexOutOfBoundsException)
  703. */
  704. public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
  705. {
  706. if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count)
  707. throw new StringIndexOutOfBoundsException();
  708. VMSystem.arraycopy(value, srcBegin + offset,
  709. dst, dstBegin, srcEnd - srcBegin);
  710. }
  711. /**
  712. * Copies the low byte of each character from this String starting at a
  713. * specified start index, ending at a specified stop index, to a byte array
  714. * starting at a specified destination begin index.
  715. *
  716. * @param srcBegin index to being copying characters from this String
  717. * @param srcEnd index after the last character to be copied from this String
  718. * @param dst byte array which each low byte of this String is copied into
  719. * @param dstBegin index to start writing characters into dst
  720. * @throws NullPointerException if dst is null and copy length is non-zero
  721. * @throws IndexOutOfBoundsException if any indices are out of bounds
  722. * (while unspecified, source problems cause a
  723. * StringIndexOutOfBoundsException, and dst problems cause an
  724. * ArrayIndexOutOfBoundsException)
  725. * @see #getBytes()
  726. * @see #getBytes(String)
  727. * @deprecated use {@link #getBytes()}, which uses a char to byte encoder
  728. */
  729. public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin)
  730. {
  731. if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count)
  732. throw new StringIndexOutOfBoundsException();
  733. int i = srcEnd - srcBegin;
  734. srcBegin += offset;
  735. while (--i >= 0)
  736. dst[dstBegin++] = (byte) value[srcBegin++];
  737. }
  738. /**
  739. * Converts the Unicode characters in this String to a byte array. Uses the
  740. * specified encoding method, so the result may be longer or shorter than
  741. * the String. For more encoding control, use
  742. * {@link java.nio.charset.CharsetEncoder}, and for valid character sets,
  743. * see {@link java.nio.charset.Charset}. Unsupported characters get
  744. * replaced by an encoding specific byte.
  745. *
  746. * @param enc encoding name
  747. * @return the resulting byte array
  748. * @throws NullPointerException if enc is null
  749. * @throws UnsupportedEncodingException if encoding is not supported
  750. * @since 1.1
  751. */
  752. public byte[] getBytes(final String enc)
  753. throws UnsupportedEncodingException
  754. {
  755. return getBytes(stringToCharset(enc));
  756. }
  757. /**
  758. * Converts the Unicode characters in this String to a byte array. Uses the
  759. * specified encoding method, so the result may be longer or shorter than
  760. * the String. For more encoding control, use
  761. * {@link java.nio.charset.CharsetEncoder}, and for valid character sets,
  762. * see {@link java.nio.charset.Charset}. Unsupported characters get
  763. * replaced by the {@link java.nio.charset.Charset}'s default replacement.
  764. *
  765. * @param enc encoding name
  766. * @return the resulting byte array
  767. * @throws NullPointerException if enc is null
  768. * @since 1.6
  769. */
  770. public byte[] getBytes(Charset enc)
  771. {
  772. try
  773. {
  774. CharsetEncoder cse = enc.newEncoder();
  775. cse.onMalformedInput(CodingErrorAction.REPLACE);
  776. cse.onUnmappableCharacter(CodingErrorAction.REPLACE);
  777. ByteBuffer bbuf = cse.encode(CharBuffer.wrap(value, offset, count));
  778. if(bbuf.hasArray())
  779. return bbuf.array();
  780. // Doubt this will happen. But just in case.
  781. byte[] bytes = new byte[bbuf.remaining()];
  782. bbuf.get(bytes);
  783. return bytes;
  784. }
  785. catch(CharacterCodingException e)
  786. {
  787. // This shouldn't ever happen.
  788. throw (InternalError) new InternalError().initCause(e);
  789. }
  790. }
  791. /**
  792. * Converts the Unicode characters in this String to a byte array. Uses the
  793. * encoding of the platform's default charset, so the result may be longer
  794. * or shorter than the String. For more encoding control, use
  795. * {@link java.nio.charset.CharsetEncoder}. Unsupported characters get
  796. * replaced by an encoding specific byte.
  797. *
  798. * @return the resulting byte array, or null on a problem
  799. * @since 1.1
  800. */
  801. public byte[] getBytes()
  802. {
  803. try
  804. {
  805. return getBytes(System.getProperty("file.encoding"));
  806. } catch(Exception e) {
  807. // XXX - Throw an error here?
  808. // For now, default to the 'safe' encoding.
  809. byte[] bytes = new byte[count];
  810. for(int i=0;i<count;i++)
  811. bytes[i] = (byte)((value[offset+i] <= 0xFF)?
  812. value[offset+i]:'?');
  813. return bytes;
  814. }
  815. }
  816. /**
  817. * Predicate which compares anObject to this. This is true only for Strings
  818. * with the same character sequence.
  819. *
  820. * @param anObject the object to compare
  821. * @return true if anObject is semantically equal to this
  822. * @see #compareTo(String)
  823. * @see #equalsIgnoreCase(String)
  824. */
  825. public boolean equals(Object anObject)
  826. {
  827. if (! (anObject instanceof String))
  828. return false;
  829. String str2 = (String) anObject;
  830. if (count != str2.count)
  831. return false;
  832. if (value == str2.value && offset == str2.offset)
  833. return true;
  834. int i = count;
  835. int x = offset;
  836. int y = str2.offset;
  837. while (--i >= 0)
  838. if (value[x++] != str2.value[y++])
  839. return false;
  840. return true;
  841. }
  842. /**
  843. * Compares the given StringBuffer to this String. This is true if the
  844. * StringBuffer has the same content as this String at this moment.
  845. *
  846. * @param buffer the StringBuffer to compare to
  847. * @return true if StringBuffer has the same character sequence
  848. * @throws NullPointerException if the given StringBuffer is null
  849. * @since 1.4
  850. */
  851. public boolean contentEquals(StringBuffer buffer)
  852. {
  853. synchronized (buffer)
  854. {
  855. if (count != buffer.count)
  856. return false;
  857. if (value == buffer.value)
  858. return true; // Possible if shared.
  859. int i = count;
  860. int x = offset + count;
  861. while (--i >= 0)
  862. if (value[--x] != buffer.value[i])
  863. return false;
  864. return true;
  865. }
  866. }
  867. /**
  868. * Compares the given CharSequence to this String. This is true if
  869. * the CharSequence has the same content as this String at this
  870. * moment.
  871. *
  872. * @param seq the CharSequence to compare to
  873. * @return true if CharSequence has the same character sequence
  874. * @throws NullPointerException if the given CharSequence is null
  875. * @since 1.5
  876. */
  877. public boolean contentEquals(CharSequence seq)
  878. {
  879. if (seq.length() != count)
  880. return false;
  881. for (int i = 0; i < count; ++i)
  882. if (value[offset + i] != seq.charAt(i))
  883. return false;
  884. return true;
  885. }
  886. /**
  887. * Compares a String to this String, ignoring case. This does not handle
  888. * multi-character capitalization exceptions; instead the comparison is
  889. * made on a character-by-character basis, and is true if:<br><ul>
  890. * <li><code>c1 == c2</code></li>
  891. * <li><code>Character.toUpperCase(c1)
  892. * == Character.toUpperCase(c2)</code></li>
  893. * <li><code>Character.toLowerCase(c1)
  894. * == Character.toLowerCase(c2)</code></li>
  895. * </ul>
  896. *
  897. * @param anotherString String to compare to this String
  898. * @return true if anotherString is equal, ignoring case
  899. * @see #equals(Object)
  900. * @see Character#toUpperCase(char)
  901. * @see Character#toLowerCase(char)
  902. */
  903. public boolean equalsIgnoreCase(String anotherString)
  904. {
  905. if (anotherString == null || count != anotherString.count)
  906. return false;
  907. int i = count;
  908. int x = offset;
  909. int y = anotherString.offset;
  910. while (--i >= 0)
  911. {
  912. char c1 = value[x++];
  913. char c2 = anotherString.value[y++];
  914. // Note that checking c1 != c2 is redundant, but avoids method calls.
  915. if (c1 != c2
  916. && Character.toUpperCase(c1) != Character.toUpperCase(c2)
  917. && Character.toLowerCase(c1) != Character.toLowerCase(c2))
  918. return false;
  919. }
  920. return true;
  921. }
  922. /**
  923. * Compares this String and another String (case sensitive,
  924. * lexicographically). The result is less than 0 if this string sorts
  925. * before the other, 0 if they are equal, and greater than 0 otherwise.
  926. * After any common starting sequence is skipped, the result is
  927. * <code>this.charAt(k) - anotherString.charAt(k)</code> if both strings
  928. * have characters remaining, or
  929. * <code>this.length() - anotherString.length()</code> if one string is
  930. * a subsequence of the other.
  931. *
  932. * @param anotherString the String to compare against
  933. * @return the comparison
  934. * @throws NullPointerException if anotherString is null
  935. */
  936. public int compareTo(String anotherString)
  937. {
  938. int i = Math.min(count, anotherString.count);
  939. int x = offset;
  940. int y = anotherString.offset;
  941. while (--i >= 0)
  942. {
  943. int result = value[x++] - anotherString.value[y++];
  944. if (result != 0)
  945. return result;
  946. }
  947. return count - anotherString.count;
  948. }
  949. /**
  950. * Compares this String and another String (case insensitive). This
  951. * comparison is <em>similar</em> to equalsIgnoreCase, in that it ignores
  952. * locale and multi-characater capitalization, and compares characters
  953. * after performing
  954. * <code>Character.toLowerCase(Character.toUpperCase(c))</code> on each
  955. * character of the string. This is unsatisfactory for locale-based
  956. * comparison, in which case you should use {@link java.text.Collator}.
  957. *
  958. * @param str the string to compare against
  959. * @return the comparison
  960. * @see Collator#compare(String, String)
  961. * @since 1.2
  962. */
  963. public int compareToIgnoreCase(String str)
  964. {
  965. int i = Math.min(count, str.count);
  966. int x = offset;
  967. int y = str.offset;
  968. while (--i >= 0)
  969. {
  970. int result = Character.toLowerCase(Character.toUpperCase(value[x++]))
  971. - Character.toLowerCase(Character.toUpperCase(str.value[y++]));
  972. if (result != 0)
  973. return result;
  974. }
  975. return count - str.count;
  976. }
  977. /**
  978. * Predicate which determines if this String matches another String
  979. * starting at a specified offset for each String and continuing
  980. * for a specified length. Indices out of bounds are harmless, and give
  981. * a false result.
  982. *
  983. * @param toffset index to start comparison at for this String
  984. * @param other String to compare region to this String
  985. * @param ooffset index to start comparison at for other
  986. * @param len number of characters to compare
  987. * @return true if regions match (case sensitive)
  988. * @throws NullPointerException if other is null
  989. */
  990. public boolean regionMatches(int toffset, String other, int ooffset, int len)
  991. {
  992. return regionMatches(false, toffset, other, ooffset, len);
  993. }
  994. /**
  995. * Predicate which determines if this String matches another String
  996. * starting at a specified offset for each String and continuing
  997. * for a specified length, optionally ignoring case. Indices out of bounds
  998. * are harmless, and give a false result. Case comparisons are based on
  999. * <code>Character.toLowerCase()</code> and
  1000. * <code>Character.toUpperCase()</code>, not on multi-character
  1001. * capitalization expansions.
  1002. *
  1003. * @param ignoreCase true if case should be ignored in comparision
  1004. * @param toffset index to start comparison at for this String
  1005. * @param other String to compare region to this String
  1006. * @param ooffset index to start comparison at for other
  1007. * @param len number of characters to compare
  1008. * @return true if regions match, false otherwise
  1009. * @throws NullPointerException if other is null
  1010. */
  1011. public boolean regionMatches(boolean ignoreCase, int toffset,
  1012. String other, int ooffset, int len)
  1013. {
  1014. if (toffset < 0 || ooffset < 0 || toffset + len > count
  1015. || ooffset + len > other.count)
  1016. return false;
  1017. toffset += offset;
  1018. ooffset += other.offset;
  1019. while (--len >= 0)
  1020. {
  1021. char c1 = value[toffset++];
  1022. char c2 = other.value[ooffset++];
  1023. // Note that checking c1 != c2 is redundant when ignoreCase is true,
  1024. // but it avoids method calls.
  1025. if (c1 != c2
  1026. && (! ignoreCase
  1027. || (Character.toLowerCase(c1) != Character.toLowerCase(c2)
  1028. && (Character.toUpperCase(c1)
  1029. != Character.toUpperCase(c2)))))
  1030. return false;
  1031. }
  1032. return true;
  1033. }
  1034. /**
  1035. * Predicate which determines if this String contains the given prefix,
  1036. * beginning comparison at toffset. The result is false if toffset is
  1037. * negative or greater than this.length(), otherwise it is the same as
  1038. * <code>this.substring(toffset).startsWith(prefix)</code>.
  1039. *
  1040. * @param prefix String to compare
  1041. * @param toffset offset for this String where comparison starts
  1042. * @return true if this String starts with prefix
  1043. * @throws NullPointerException if prefix is null
  1044. * @see #regionMatches(boolean, int, String, int, int)
  1045. */
  1046. public boolean startsWith(String prefix, int toffset)
  1047. {
  1048. return regionMatches(false, toffset, prefix, 0, prefix.count);
  1049. }
  1050. /**
  1051. * Predicate which determines if this String starts with a given prefix.
  1052. * If the prefix is an empty String, true is returned.
  1053. *
  1054. * @param prefix String to compare
  1055. * @return true if this String starts with the prefix
  1056. * @throws NullPointerException if prefix is null
  1057. * @see #startsWith(String, int)
  1058. */
  1059. public boolean startsWith(String prefix)
  1060. {
  1061. return regionMatches(false, 0, prefix, 0, prefix.count);
  1062. }
  1063. /**
  1064. * Predicate which determines if this String ends with a given suffix.
  1065. * If the suffix is an empty String, true is returned.
  1066. *
  1067. * @param suffix String to compare
  1068. * @return true if this String ends with the suffix
  1069. * @throws NullPointerException if suffix is null
  1070. * @see #regionMatches(boolean, int, String, int, int)
  1071. */
  1072. public boolean endsWith(String suffix)
  1073. {
  1074. return regionMatches(false, count - suffix.count, suffix, 0, suffix.count);
  1075. }
  1076. /**
  1077. * Computes the hashcode for this String. This is done with int arithmetic,
  1078. * where ** represents exponentiation, by this formula:<br>
  1079. * <code>s[0]*31**(n-1) + s[1]*31**(n-2) + ... + s[n-1]</code>.
  1080. *
  1081. * @return hashcode value of this String
  1082. */
  1083. public int hashCode()
  1084. {
  1085. if (cachedHashCode != 0)
  1086. return cachedHashCode;
  1087. // Compute the hash code using a local variable to be reentrant.
  1088. int hashCode = 0;
  1089. int limit = count + offset;
  1090. for (int i = offset; i < limit; i++)
  1091. hashCode = hashCode * 31 + value[i];
  1092. return cachedHashCode = hashCode;
  1093. }
  1094. /**
  1095. * Finds the first instance of a character in this String.
  1096. *
  1097. * @param ch character to find
  1098. * @return location (base 0) of the character, or -1 if not found
  1099. */
  1100. public int indexOf(int ch)
  1101. {
  1102. return indexOf(ch, 0);
  1103. }
  1104. /**
  1105. * Finds the first instance of a character in this String, starting at
  1106. * a given index. If starting index is less than 0, the search
  1107. * starts at the beginning of this String. If the starting index
  1108. * is greater than the length of this String, -1 is returned.
  1109. *
  1110. * @param ch character to find
  1111. * @param fromIndex index to start the search
  1112. * @return location (base 0) of the character, or -1 if not found
  1113. */
  1114. public int indexOf(int ch, int fromIndex)
  1115. {
  1116. if ((char) ch != ch)
  1117. return -1;
  1118. if (fromIndex < 0)
  1119. fromIndex = 0;
  1120. int i = fromIndex + offset;
  1121. for ( ; fromIndex < count; fromIndex++)
  1122. if (value[i++] == ch)
  1123. return fromIndex;
  1124. return -1;
  1125. }
  1126. /**
  1127. * Finds the last instance of a character in this String.
  1128. *
  1129. * @param ch character to find
  1130. * @return location (base 0) of the character, or -1 if not found
  1131. */
  1132. public int lastIndexOf(int ch)
  1133. {
  1134. return lastIndexOf(ch, count - 1);
  1135. }
  1136. /**
  1137. * Finds the last instance of a character in this String, starting at
  1138. * a given index. If starting index is greater than the maximum valid
  1139. * index, then the search begins at the end of this String. If the
  1140. * starting index is less than zero, -1 is returned.
  1141. *
  1142. * @param ch character to find
  1143. * @param fromIndex index to start the search
  1144. * @return location (base 0) of the character, or -1 if not found
  1145. */
  1146. public int lastIndexOf(int ch, int fromIndex)
  1147. {
  1148. if ((char) ch != ch)
  1149. return -1;
  1150. if (fromIndex >= count)
  1151. fromIndex = count - 1;
  1152. int i = fromIndex + offset;
  1153. for ( ; fromIndex >= 0; fromIndex--)
  1154. if (value[i--] == ch)
  1155. return fromIndex;
  1156. return -1;
  1157. }
  1158. /**
  1159. * Finds the first instance of a String in this String.
  1160. *
  1161. * @param str String to find
  1162. * @return location (base 0) of the String, or -1 if not found
  1163. * @throws NullPointerException if str is null
  1164. */
  1165. public int indexOf(String str)
  1166. {
  1167. return indexOf(str, 0);
  1168. }
  1169. /**
  1170. * Finds the first instance of a String in this String, starting at
  1171. * a given index. If starting index is less than 0, the search
  1172. * starts at the beginning of this String. If the starting index
  1173. * is greater than the length of this String, -1 is returned.
  1174. *
  1175. * @param str String to find
  1176. * @param fromIndex index to start the search
  1177. * @return location (base 0) of the String, or -1 if not found
  1178. * @throws NullPointerException if str is null
  1179. */
  1180. public int indexOf(String str, int fromIndex)
  1181. {
  1182. if (fromIndex < 0)
  1183. fromIndex = 0;
  1184. int limit = count - str.count;
  1185. for ( ; fromIndex <= limit; fromIndex++)
  1186. if (regionMatches(fromIndex, str, 0, str.count))
  1187. return fromIndex;
  1188. return -1;
  1189. }
  1190. /**
  1191. * Finds the last instance of a String in this String.
  1192. *
  1193. * @param str String to find
  1194. * @return location (base 0) of the String, or -1 if not found
  1195. * @throws NullPointerException if str is null
  1196. */
  1197. public int lastIndexOf(String str)
  1198. {
  1199. return lastIndexOf(str, count - str.count);
  1200. }
  1201. /**
  1202. * Finds the last instance of a String in this String, starting at
  1203. * a given index. If starting index is greater than the maximum valid
  1204. * index, then the search begins at the end of this String. If the
  1205. * starting index is less than zero, -1 is returned.
  1206. *
  1207. * @param str String to find
  1208. * @param fromIndex index to start the search
  1209. * @return location (base 0) of the String, or -1 if not found
  1210. * @throws NullPointerException if str is null
  1211. */
  1212. public int lastIndexOf(String str, int fromIndex)
  1213. {
  1214. fromIndex = Math.min(fromIndex, count - str.count);
  1215. for ( ; fromIndex >= 0; fromIndex--)
  1216. if (regionMatches(fromIndex, str, 0, str.count))
  1217. return fromIndex;
  1218. return -1;
  1219. }
  1220. /**
  1221. * Creates a substring of this String, starting at a specified index
  1222. * and ending at the end of this String.
  1223. *
  1224. * @param begin index to start substring (base 0)
  1225. * @return new String which is a substring of this String
  1226. * @throws IndexOutOfBoundsException if begin &lt; 0 || begin &gt; length()
  1227. * (while unspecified, this is a StringIndexOutOfBoundsException)
  1228. */
  1229. public String substring(int begin)
  1230. {
  1231. return substring(begin, count);
  1232. }
  1233. /**
  1234. * Creates a substring of this String, starting at a specified index
  1235. * and ending at one character before a specified index.
  1236. *
  1237. * @param beginIndex index to start substring (inclusive, base 0)
  1238. * @param endIndex index to end at (exclusive)
  1239. * @return new String which is a substring of this String
  1240. * @throws IndexOutOfBoundsException if begin &lt; 0 || end &gt; length()
  1241. * || begin &gt; end (while unspecified, this is a
  1242. * StringIndexOutOfBoundsException)
  1243. */
  1244. public String substring(int beginIndex, int endIndex)
  1245. {
  1246. if (beginIndex < 0 || endIndex > count || beginIndex > endIndex)
  1247. throw new StringIndexOutOfBoundsException();
  1248. if (beginIndex == 0 && endIndex == count)
  1249. return this;
  1250. int len = endIndex - beginIndex;
  1251. // Package constructor avoids an array copy.
  1252. return new String(value, beginIndex + offset, len,
  1253. (len << 2) >= value.length);
  1254. }
  1255. /**
  1256. * Creates a substring of this String, starting at a specified index
  1257. * and ending at one character before a specified index. This behaves like
  1258. * <code>substring(begin, end)</code>.
  1259. *
  1260. * @param begin index to start substring (inclusive, base 0)
  1261. * @param end index to end at (exclusive)
  1262. * @return new String which is a substring of this String
  1263. * @throws IndexOutOfBoundsException if begin &lt; 0 || end &gt; length()
  1264. * || begin &gt; end
  1265. * @since 1.4
  1266. */
  1267. public CharSequence subSequence(int begin, int end)
  1268. {
  1269. return substring(begin, end);
  1270. }
  1271. /**
  1272. * Concatenates a String to this String. This results in a new string unless
  1273. * one of the two originals is "".
  1274. *
  1275. * @param str String to append to this String
  1276. * @return newly concatenated String
  1277. * @throws NullPointerException if str is null
  1278. */
  1279. public String concat(String str)
  1280. {
  1281. if (str.count == 0)
  1282. return this;
  1283. if (count == 0)
  1284. return str;
  1285. char[] newStr = new char[count + str.count];
  1286. VMSystem.arraycopy(value, offset, newStr, 0, count);
  1287. VMSystem.arraycopy(str.value, str.offset, newStr, count, str.count);
  1288. // Package constructor avoids an array copy.
  1289. return new String(newStr, 0, newStr.length, true);
  1290. }
  1291. /**
  1292. * Replaces every instance of a character in this String with a new
  1293. * character. If no replacements occur, this is returned.
  1294. *
  1295. * @param oldChar the old character to replace
  1296. * @param newChar the new character
  1297. * @return new String with all instances of oldChar replaced with newChar
  1298. */
  1299. public String replace(char oldChar, char newChar)
  1300. {
  1301. if (oldChar == newChar)
  1302. return this;
  1303. int i = count;
  1304. int x = offset - 1;
  1305. while (--i >= 0)
  1306. if (value[++x] == oldChar)
  1307. break;
  1308. if (i < 0)
  1309. return this;
  1310. char[] newStr = toCharArray();
  1311. newStr[x - offset] = newChar;
  1312. while (--i >= 0)
  1313. if (value[++x] == oldChar)
  1314. newStr[x - offset] = newChar;
  1315. // Package constructor avoids an array copy.
  1316. return new String(newStr, 0, count, true);
  1317. }
  1318. /**
  1319. * Test if this String matches a regular expression. This is shorthand for
  1320. * <code>{@link Pattern}.matches(regex, this)</code>.
  1321. *
  1322. * @param regex the pattern to match
  1323. * @return true if the pattern matches
  1324. * @throws NullPointerException if regex is null
  1325. * @throws PatternSyntaxException if regex is invalid
  1326. * @see Pattern#matches(String, CharSequence)
  1327. * @since 1.4
  1328. */
  1329. public boolean matches(String regex)
  1330. {
  1331. return Pattern.matches(regex, this);
  1332. }
  1333. /**
  1334. * Replaces the first substring match of the regular expression with a
  1335. * given replacement. This is shorthand for <code>{@link Pattern}
  1336. * .compile(regex).matcher(this).replaceFirst(replacement)</code>.
  1337. *
  1338. * @param regex the pattern to match
  1339. * @param replacement the replacement string
  1340. * @return the modified string
  1341. * @throws NullPointerException if regex or replacement is null
  1342. * @throws PatternSyntaxException if regex is invalid
  1343. * @see #replaceAll(String, String)
  1344. * @see Pattern#compile(String)
  1345. * @see Pattern#matcher(CharSequence)
  1346. * @see Matcher#replaceFirst(String)
  1347. * @since 1.4
  1348. */
  1349. public String replaceFirst(String regex, String replacement)
  1350. {
  1351. return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
  1352. }
  1353. /**
  1354. * Replaces all matching substrings of the regular expression with a
  1355. * given replacement. This is shorthand for <code>{@link Pattern}
  1356. * .compile(regex).matcher(this).replaceAll(replacement)</code>.
  1357. *
  1358. * @param regex the pattern to match
  1359. * @param replacement the replacement string
  1360. * @return the modified string
  1361. * @throws NullPointerException if regex or replacement is null
  1362. * @throws PatternSyntaxException if regex is invalid
  1363. * @see #replaceFirst(String, String)
  1364. * @see Pattern#compile(String)
  1365. * @see Pattern#matcher(CharSequence)
  1366. * @see Matcher#replaceAll(String)
  1367. * @since 1.4
  1368. */
  1369. public String replaceAll(String regex, String replacement)
  1370. {
  1371. return Pattern.compile(regex).matcher(this).replaceAll(replacement);
  1372. }
  1373. /**
  1374. * Split this string around the matches of a regular expression. Each
  1375. * element of the returned array is the largest block of characters not
  1376. * terminated by the regular expression, in the order the matches are found.
  1377. *
  1378. * <p>The limit affects the length of the array. If it is positive, the
  1379. * array will contain at most n elements (n - 1 pattern matches). If
  1380. * negative, the array length is unlimited, but there can be trailing empty
  1381. * entries. if 0, the array length is unlimited, and trailing empty entries
  1382. * are discarded.
  1383. *
  1384. * <p>For example, splitting "boo:and:foo" yields:<br>
  1385. * <table border=0>
  1386. * <th><td>Regex</td> <td>Limit</td> <td>Result</td></th>
  1387. * <tr><td>":"</td> <td>2</td> <td>{ "boo", "and:foo" }</td></tr>
  1388. * <tr><td>":"</td> <td>t</td> <td>{ "boo", "and", "foo" }</td></tr>
  1389. * <tr><td>":"</td> <td>-2</td> <td>{ "boo", "and", "foo" }</td></tr>
  1390. * <tr><td>"o"</td> <td>5</td> <td>{ "b", "", ":and:f", "", "" }</td></tr>
  1391. * <tr><td>"o"</td> <td>-2</td> <td>{ "b", "", ":and:f", "", "" }</td></tr>
  1392. * <tr><td>"o"</td> <td>0</td> <td>{ "b", "", ":and:f" }</td></tr>
  1393. * </table>
  1394. *
  1395. * <p>This is shorthand for
  1396. * <code>{@link Pattern}.compile(regex).split(this, limit)</code>.
  1397. *
  1398. * @param regex the pattern to match
  1399. * @param limit the limit threshold
  1400. * @return the array of split strings
  1401. * @throws NullPointerException if regex or replacement is null
  1402. * @throws PatternSyntaxException if regex is invalid
  1403. * @see Pattern#compile(String)
  1404. * @see Pattern#split(CharSequence, int)
  1405. * @since 1.4
  1406. */
  1407. public String[] split(String regex, int limit)
  1408. {
  1409. return Pattern.compile(regex).split(this, limit);
  1410. }
  1411. /**
  1412. * Split this string around the matches of a regular expression. Each
  1413. * element of the returned array is the largest block of characters not
  1414. * terminated by the regular expression, in the order the matches are found.
  1415. * The array length is unlimited, and trailing empty entries are discarded,
  1416. * as though calling <code>split(regex, 0)</code>.
  1417. *
  1418. * @param regex the pattern to match
  1419. * @return the array of split strings
  1420. * @throws NullPointerException if regex or replacement is null
  1421. * @throws PatternSyntaxException if regex is invalid
  1422. * @see #split(String, int)
  1423. * @see Pattern#compile(String)
  1424. * @see Pattern#split(CharSequence, int)
  1425. * @since 1.4
  1426. */
  1427. public String[] split(String regex)
  1428. {
  1429. return Pattern.compile(regex).split(this, 0);
  1430. }
  1431. /**
  1432. * Convert string to lower case for a Turkish locale that requires special
  1433. * handling of '\u0049'
  1434. */
  1435. private String toLowerCaseTurkish()
  1436. {
  1437. // First, see if the current string is already lower case.
  1438. int i = count;
  1439. int x = offset - 1;
  1440. while (--i >= 0)
  1441. {
  1442. char ch = value[++x];
  1443. if ((ch == '\u0049') || ch != Character.toLowerCase(ch))
  1444. break;
  1445. }
  1446. if (i < 0)
  1447. return this;
  1448. // Now we perform the conversion. Fortunately, there are no multi-character
  1449. // lowercase expansions in Unicode 3.0.0.
  1450. char[] newStr = new char[count];
  1451. VMSystem.arraycopy(value, offset, newStr, 0, x - offset);
  1452. do
  1453. {
  1454. char ch = value[x];
  1455. // Hardcoded special case.
  1456. if (ch != '\u0049')
  1457. {
  1458. newStr[x - offset] = Character.toLowerCase(ch);
  1459. }
  1460. else
  1461. {
  1462. newStr[x - offset] = '\u0131';
  1463. }
  1464. x++;
  1465. }
  1466. while (--i >= 0);
  1467. // Package constructor avoids an array copy.
  1468. return new String(newStr, 0, count, true);
  1469. }
  1470. /**
  1471. * Lowercases this String according to a particular locale. This uses
  1472. * Unicode's special case mappings, as applied to the given Locale, so the
  1473. * resulting string may be a different length.
  1474. *
  1475. * @param loc locale to use
  1476. * @return new lowercased String, or this if no characters were lowercased
  1477. * @throws NullPointerException if loc is null
  1478. * @see #toUpperCase(Locale)
  1479. * @since 1.1
  1480. */
  1481. public String toLowerCase(Locale loc)
  1482. {
  1483. // First, see if the current string is already lower case.
  1484. // Is loc turkish? String equality test is ok as Locale.language is interned
  1485. if ("tr" == loc.getLanguage())
  1486. {
  1487. return toLowerCaseTurkish();
  1488. }
  1489. else
  1490. {
  1491. int i = count;
  1492. int x = offset - 1;
  1493. while (--i >= 0)
  1494. {
  1495. char ch = value[++x];
  1496. if (ch != Character.toLowerCase(ch))
  1497. break;
  1498. }
  1499. if (i < 0)
  1500. return this;
  1501. // Now we perform the conversion. Fortunately, there are no
  1502. // multi-character lowercase expansions in Unicode 3.0.0.
  1503. char[] newStr = new char[count];
  1504. VMSystem.arraycopy(value, offset, newStr, 0, x - offset);
  1505. do
  1506. {
  1507. char ch = value[x];
  1508. // Hardcoded special case.
  1509. newStr[x - offset] = Character.toLowerCase(ch);
  1510. x++;
  1511. }
  1512. while (--i >= 0);
  1513. // Package constructor avoids an array copy.
  1514. return new String(newStr, 0, count, true);
  1515. }
  1516. }
  1517. /**
  1518. * Lowercases this String. This uses Unicode's special case mappings, as
  1519. * applied to the platform's default Locale, so the resulting string may
  1520. * be a different length.
  1521. *
  1522. * @return new lowercased String, or this if no characters were lowercased
  1523. * @see #toLowerCase(Locale)
  1524. * @see #toUpperCase()
  1525. */
  1526. public String toLowerCase()
  1527. {
  1528. return toLowerCase(Locale.getDefault());
  1529. }
  1530. /**
  1531. * Uppercase this string for a Turkish locale
  1532. */
  1533. private String toUpperCaseTurkish()
  1534. {
  1535. // First, see how many characters we have to grow by, as well as if the
  1536. // current string is already upper case.
  1537. int expand = 0;
  1538. boolean unchanged = true;
  1539. int i = count;
  1540. int x = i + offset;
  1541. while (--i >= 0)
  1542. {
  1543. char ch = value[--x];
  1544. expand += upperCaseExpansion(ch);
  1545. unchanged = (unchanged && expand == 0
  1546. && ch != '\u0069'
  1547. && ch == Character.toUpperCase(ch));
  1548. }
  1549. if (unchanged)
  1550. return this;
  1551. // Now we perform the conversion.
  1552. i = count;
  1553. if (expand == 0)
  1554. {
  1555. char[] newStr = new char[count];
  1556. VMSystem.arraycopy(value, offset, newStr, 0, count - (x - offset));
  1557. while (--i >= 0)
  1558. {
  1559. char ch = value[x];
  1560. // Hardcoded special case.
  1561. if (ch != '\u0069')
  1562. {
  1563. newStr[x - offset] = Character.toUpperCase(ch);
  1564. }
  1565. else
  1566. {
  1567. newStr[x - offset] = '\u0130';
  1568. }
  1569. x++;
  1570. }
  1571. // Package constructor avoids an array copy.
  1572. return new String(newStr, 0, count, true);
  1573. }
  1574. // Expansion is necessary.
  1575. char[] newStr = new char[count + expand];
  1576. int j = 0;
  1577. while (--i >= 0)
  1578. {
  1579. char ch = value[x++];
  1580. // Hardcoded special case.
  1581. if (ch == '\u0069')
  1582. {
  1583. newStr[j++] = '\u0130';
  1584. continue;
  1585. }
  1586. expand = upperCaseExpansion(ch);
  1587. if (expand > 0)
  1588. {
  1589. int index = upperCaseIndex(ch);
  1590. while (expand-- >= 0)
  1591. newStr[j++] = upperExpand[index++];
  1592. }
  1593. else
  1594. newStr[j++] = Character.toUpperCase(ch);
  1595. }
  1596. // Package constructor avoids an array copy.
  1597. return new String(newStr, 0, newStr.length, true);
  1598. }
  1599. /**
  1600. * Uppercases this String according to a particular locale. This uses
  1601. * Unicode's special case mappings, as applied to the given Locale, so the
  1602. * resulting string may be a different length.
  1603. *
  1604. * @param loc locale to use
  1605. * @return new uppercased String, or this if no characters were uppercased
  1606. * @throws NullPointerException if loc is null
  1607. * @see #toLowerCase(Locale)
  1608. * @since 1.1
  1609. */
  1610. public String toUpperCase(Locale loc)
  1611. {
  1612. // First, see how many characters we have to grow by, as well as if the
  1613. // current string is already upper case.
  1614. // Is loc turkish? String equality test is ok as Locale.language is interned
  1615. if ("tr" == loc.getLanguage())
  1616. {
  1617. return toUpperCaseTurkish();
  1618. }
  1619. else
  1620. {
  1621. int expand = 0;
  1622. boolean unchanged = true;
  1623. int i = count;
  1624. int x = i + offset;
  1625. while (--i >= 0)
  1626. {
  1627. char ch = value[--x];
  1628. expand += upperCaseExpansion(ch);
  1629. unchanged = (unchanged && expand == 0
  1630. && ch == Character.toUpperCase(ch));
  1631. }
  1632. if (unchanged)
  1633. return this;
  1634. // Now we perform the conversion.
  1635. i = count;
  1636. if (expand == 0)
  1637. {
  1638. char[] newStr = new char[count];
  1639. VMSystem.arraycopy(value, offset, newStr, 0, count - (x - offset));
  1640. while (--i >= 0)
  1641. {
  1642. char ch = value[x];
  1643. newStr[x - offset] = Character.toUpperCase(ch);
  1644. x++;
  1645. }
  1646. // Package constructor avoids an array copy.
  1647. return new String(newStr, 0, count, true);
  1648. }
  1649. // Expansion is necessary.
  1650. char[] newStr = new char[count + expand];
  1651. int j = 0;
  1652. while (--i >= 0)
  1653. {
  1654. char ch = value[x++];
  1655. expand = upperCaseExpansion(ch);
  1656. if (expand > 0)
  1657. {
  1658. int index = upperCaseIndex(ch);
  1659. while (expand-- >= 0)
  1660. newStr[j++] = upperExpand[index++];
  1661. }
  1662. else
  1663. newStr[j++] = Character.toUpperCase(ch);
  1664. }
  1665. // Package constructor avoids an array copy.
  1666. return new String(newStr, 0, newStr.length, true);
  1667. }
  1668. }
  1669. /**
  1670. * Uppercases this String. This uses Unicode's special case mappings, as
  1671. * applied to the platform's default Locale, so the resulting string may
  1672. * be a different length.
  1673. *
  1674. * @return new uppercased String, or this if no characters were uppercased
  1675. * @see #toUpperCase(Locale)
  1676. * @see #toLowerCase()
  1677. */
  1678. public String toUpperCase()
  1679. {
  1680. return toUpperCase(Locale.getDefault());
  1681. }
  1682. /**
  1683. * Trims all characters less than or equal to <code>'\u0020'</code>
  1684. * (<code>' '</code>) from the beginning and end of this String. This
  1685. * includes many, but not all, ASCII control characters, and all
  1686. * {@link Character#isWhitespace(char)}.
  1687. *
  1688. * @return new trimmed String, or this if nothing trimmed
  1689. */
  1690. public String trim()
  1691. {
  1692. int limit = count + offset;
  1693. if (count == 0 || (value[offset] > '\u0020'
  1694. && value[limit - 1] > '\u0020'))
  1695. return this;
  1696. int begin = offset;
  1697. do
  1698. if (begin == limit)
  1699. return "";
  1700. while (value[begin++] <= '\u0020');
  1701. int end = limit;
  1702. while (value[--end] <= '\u0020')
  1703. ;
  1704. return substring(begin - offset - 1, end - offset + 1);
  1705. }
  1706. /**
  1707. * Returns this, as it is already a String!
  1708. *
  1709. * @return this
  1710. */
  1711. public String toString()
  1712. {
  1713. return this;
  1714. }
  1715. /**
  1716. * Copies the contents of this String into a character array. Subsequent
  1717. * changes to the array do not affect the String.
  1718. *
  1719. * @return character array copying the String
  1720. */
  1721. public char[] toCharArray()
  1722. {
  1723. char[] copy = new char[count];
  1724. VMSystem.arraycopy(value, offset, copy, 0, count);
  1725. return copy;
  1726. }
  1727. /**
  1728. * Returns a String representation of an Object. This is "null" if the
  1729. * object is null, otherwise it is <code>obj.toString()</code> (which
  1730. * can be null).
  1731. *
  1732. * @param obj the Object
  1733. * @return the string conversion of obj
  1734. */
  1735. public static String valueOf(Object obj)
  1736. {
  1737. return obj == null ? "null" : obj.toString();
  1738. }
  1739. /**
  1740. * Returns a String representation of a character array. Subsequent
  1741. * changes to the array do not affect the String.
  1742. *
  1743. * @param data the character array
  1744. * @return a String containing the same character sequence as data
  1745. * @throws NullPointerException if data is null
  1746. * @see #valueOf(char[], int, int)
  1747. * @see #String(char[])
  1748. */
  1749. public static String valueOf(char[] data)
  1750. {
  1751. return valueOf (data, 0, data.length);
  1752. }
  1753. /**
  1754. * Returns a String representing the character sequence of the char array,
  1755. * starting at the specified offset, and copying chars up to the specified
  1756. * count. Subsequent changes to the array do not affect the String.
  1757. *
  1758. * @param data character array
  1759. * @param offset position (base 0) to start copying out of data
  1760. * @param count the number of characters from data to copy
  1761. * @return String containing the chars from data[offset..offset+count]
  1762. * @throws NullPointerException if data is null
  1763. * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
  1764. * || offset + count &gt; data.length)
  1765. * (while unspecified, this is a StringIndexOutOfBoundsException)
  1766. * @see #String(char[], int, int)
  1767. */
  1768. public static String valueOf(char[] data, int offset, int count)
  1769. {
  1770. return new String(data, offset, count, false);
  1771. }
  1772. /**
  1773. * Returns a String representing the character sequence of the char array,
  1774. * starting at the specified offset, and copying chars up to the specified
  1775. * count. Subsequent changes to the array do not affect the String.
  1776. *
  1777. * @param data character array
  1778. * @param offset position (base 0) to start copying out of data
  1779. * @param count the number of characters from data to copy
  1780. * @return String containing the chars from data[offset..offset+count]
  1781. * @throws NullPointerException if data is null
  1782. * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
  1783. * || offset + count &lt; 0 (overflow)
  1784. * || offset + count &lt; 0 (overflow)
  1785. * || offset + count &gt; data.length)
  1786. * (while unspecified, this is a StringIndexOutOfBoundsException)
  1787. * @see #String(char[], int, int)
  1788. */
  1789. public static String copyValueOf(char[] data, int offset, int count)
  1790. {
  1791. return new String(data, offset, count, false);
  1792. }
  1793. /**
  1794. * Returns a String representation of a character array. Subsequent
  1795. * changes to the array do not affect the String.
  1796. *
  1797. * @param data the character array
  1798. * @return a String containing the same character sequence as data
  1799. * @throws NullPointerException if data is null
  1800. * @see #copyValueOf(char[], int, int)
  1801. * @see #String(char[])
  1802. */
  1803. public static String copyValueOf(char[] data)
  1804. {
  1805. return copyValueOf (data, 0, data.length);
  1806. }
  1807. /**
  1808. * Returns a String representing a boolean.
  1809. *
  1810. * @param b the boolean
  1811. * @return "true" if b is true, else "false"
  1812. */
  1813. public static String valueOf(boolean b)
  1814. {
  1815. return b ? "true" : "false";
  1816. }
  1817. /**
  1818. * Returns a String representing a character.
  1819. *
  1820. * @param c the character
  1821. * @return String containing the single character c
  1822. */
  1823. public static String valueOf(char c)
  1824. {
  1825. // Package constructor avoids an array copy.
  1826. return new String(new char[] { c }, 0, 1, true);
  1827. }
  1828. /**
  1829. * Returns a String representing an integer.
  1830. *
  1831. * @param i the integer
  1832. * @return String containing the integer in base 10
  1833. * @see Integer#toString(int)
  1834. */
  1835. public static String valueOf(int i)
  1836. {
  1837. // See Integer to understand why we call the two-arg variant.
  1838. return Integer.toString(i, 10);
  1839. }
  1840. /**
  1841. * Returns a String representing a long.
  1842. *
  1843. * @param l the long
  1844. * @return String containing the long in base 10
  1845. * @see Long#toString(long)
  1846. */
  1847. public static String valueOf(long l)
  1848. {
  1849. return Long.toString(l);
  1850. }
  1851. /**
  1852. * Returns a String representing a float.
  1853. *
  1854. * @param f the float
  1855. * @return String containing the float
  1856. * @see Float#toString(float)
  1857. */
  1858. public static String valueOf(float f)
  1859. {
  1860. return Float.toString(f);
  1861. }
  1862. /**
  1863. * Returns a String representing a double.
  1864. *
  1865. * @param d the double
  1866. * @return String containing the double
  1867. * @see Double#toString(double)
  1868. */
  1869. public static String valueOf(double d)
  1870. {
  1871. return Double.toString(d);
  1872. }
  1873. /** @since 1.5 */
  1874. public static String format(Locale locale, String format, Object... args)
  1875. {
  1876. Formatter f = new Formatter(locale);
  1877. return f.format(format, args).toString();
  1878. }
  1879. /** @since 1.5 */
  1880. public static String format(String format, Object... args)
  1881. {
  1882. return format(Locale.getDefault(), format, args);
  1883. }
  1884. /**
  1885. * If two Strings are considered equal, by the equals() method,
  1886. * then intern() will return the same String instance. ie.
  1887. * if (s1.equals(s2)) then (s1.intern() == s2.intern()).
  1888. * All string literals and string-valued constant expressions
  1889. * are already interned.
  1890. *
  1891. * @return the interned String
  1892. */
  1893. public String intern()
  1894. {
  1895. return VMString.intern(this);
  1896. }
  1897. /**
  1898. * Return the number of code points between two indices in the
  1899. * <code>String</code>. An unpaired surrogate counts as a
  1900. * code point for this purpose. Characters outside the indicated
  1901. * range are not examined, even if the range ends in the middle of a
  1902. * surrogate pair.
  1903. *
  1904. * @param start the starting index
  1905. * @param end one past the ending index
  1906. * @return the number of code points
  1907. * @since 1.5
  1908. */
  1909. public synchronized int codePointCount(int start, int end)
  1910. {
  1911. if (start < 0 || end > count || start > end)
  1912. throw new StringIndexOutOfBoundsException();
  1913. start += offset;
  1914. end += offset;
  1915. int count = 0;
  1916. while (start < end)
  1917. {
  1918. char base = value[start];
  1919. if (base < Character.MIN_HIGH_SURROGATE
  1920. || base > Character.MAX_HIGH_SURROGATE
  1921. || start == end
  1922. || start == count
  1923. || value[start + 1] < Character.MIN_LOW_SURROGATE
  1924. || value[start + 1] > Character.MAX_LOW_SURROGATE)
  1925. {
  1926. // Nothing.
  1927. }
  1928. else
  1929. {
  1930. // Surrogate pair.
  1931. ++start;
  1932. }
  1933. ++start;
  1934. ++count;
  1935. }
  1936. return count;
  1937. }
  1938. /**
  1939. * Helper function used to detect which characters have a multi-character
  1940. * uppercase expansion. Note that this is only used in locations which
  1941. * track one-to-many capitalization (java.lang.Character does not do this).
  1942. * As of Unicode 3.0.0, the result is limited in the range 0 to 2, as the
  1943. * longest uppercase expansion is three characters (a growth of 2 from the
  1944. * lowercase character).
  1945. *
  1946. * @param ch the char to check
  1947. * @return the number of characters to add when converting to uppercase
  1948. * @see CharData#DIRECTION
  1949. * @see CharData#UPPER_SPECIAL
  1950. * @see #toUpperCase(Locale)
  1951. */
  1952. private static int upperCaseExpansion(char ch)
  1953. {
  1954. return Character.direction[0][Character.readCodePoint((int)ch) >> 7] & 3;
  1955. }
  1956. /**
  1957. * Helper function used to locate the offset in upperExpand given a
  1958. * character with a multi-character expansion. The binary search is
  1959. * optimized under the assumption that this method will only be called on
  1960. * characters which exist in upperSpecial.
  1961. *
  1962. * @param ch the char to check
  1963. * @return the index where its expansion begins
  1964. * @see CharData#UPPER_SPECIAL
  1965. * @see CharData#UPPER_EXPAND
  1966. * @see #toUpperCase(Locale)
  1967. */
  1968. private static int upperCaseIndex(char ch)
  1969. {
  1970. // Simple binary search for the correct character.
  1971. int low = 0;
  1972. int hi = upperSpecial.length - 2;
  1973. int mid = ((low + hi) >> 2) << 1;
  1974. char c = upperSpecial[mid];
  1975. while (ch != c)
  1976. {
  1977. if (ch < c)
  1978. hi = mid - 2;
  1979. else
  1980. low = mid + 2;
  1981. mid = ((low + hi) >> 2) << 1;
  1982. c = upperSpecial[mid];
  1983. }
  1984. return upperSpecial[mid + 1];
  1985. }
  1986. /**
  1987. * Returns the value array of the given string if it is zero based or a
  1988. * copy of it that is zero based (stripping offset and making length equal
  1989. * to count). Used for accessing the char[]s of gnu.java.lang.CharData.
  1990. * Package private for use in Character.
  1991. */
  1992. static char[] zeroBasedStringValue(String s)
  1993. {
  1994. char[] value;
  1995. if (s.offset == 0 && s.count == s.value.length)
  1996. value = s.value;
  1997. else
  1998. {
  1999. int count = s.count;
  2000. value = new char[count];
  2001. VMSystem.arraycopy(s.value, s.offset, value, 0, count);
  2002. }
  2003. return value;
  2004. }
  2005. /**
  2006. * Returns true iff this String contains the sequence of Characters
  2007. * described in s.
  2008. * @param s the CharSequence
  2009. * @return true iff this String contains s
  2010. *
  2011. * @since 1.5
  2012. */
  2013. public boolean contains (CharSequence s)
  2014. {
  2015. return this.indexOf(s.toString()) != -1;
  2016. }
  2017. /**
  2018. * Returns a string that is this string with all instances of the sequence
  2019. * represented by <code>target</code> replaced by the sequence in
  2020. * <code>replacement</code>.
  2021. * @param target the sequence to be replaced
  2022. * @param replacement the sequence used as the replacement
  2023. * @return the string constructed as above
  2024. */
  2025. public String replace (CharSequence target, CharSequence replacement)
  2026. {
  2027. String targetString = target.toString();
  2028. String replaceString = replacement.toString();
  2029. int targetLength = target.length();
  2030. int replaceLength = replacement.length();
  2031. int startPos = this.indexOf(targetString);
  2032. CPStringBuilder result = new CPStringBuilder(this);
  2033. while (startPos != -1)
  2034. {
  2035. // Replace the target with the replacement
  2036. result.replace(startPos, startPos + targetLength, replaceString);
  2037. // Search for a new occurrence of the target
  2038. startPos = result.indexOf(targetString, startPos + replaceLength);
  2039. }
  2040. return result.toString();
  2041. }
  2042. /**
  2043. * Return the index into this String that is offset from the given index by
  2044. * <code>codePointOffset</code> code points.
  2045. * @param index the index at which to start
  2046. * @param codePointOffset the number of code points to offset
  2047. * @return the index into this String that is <code>codePointOffset</code>
  2048. * code points offset from <code>index</code>.
  2049. *
  2050. * @throws IndexOutOfBoundsException if index is negative or larger than the
  2051. * length of this string.
  2052. * @throws IndexOutOfBoundsException if codePointOffset is positive and the
  2053. * substring starting with index has fewer than codePointOffset code points.
  2054. * @throws IndexOutOfBoundsException if codePointOffset is negative and the
  2055. * substring ending with index has fewer than (-codePointOffset) code points.
  2056. * @since 1.5
  2057. */
  2058. public int offsetByCodePoints(int index, int codePointOffset)
  2059. {
  2060. if (index < 0 || index > count)
  2061. throw new IndexOutOfBoundsException();
  2062. return Character.offsetByCodePoints(value, offset, count, offset + index,
  2063. codePointOffset);
  2064. }
  2065. /**
  2066. * Returns true if, and only if, {@link #length()}
  2067. * is <code>0</code>.
  2068. *
  2069. * @return true if the length of the string is zero.
  2070. * @since 1.6
  2071. */
  2072. public boolean isEmpty()
  2073. {
  2074. return count == 0;
  2075. }
  2076. }