src/java.base/share/classes/java/lang/StringCoding.java

Print this page




 111             // Use sun.misc.MessageUtils rather than the Logging API or
 112             // System.err since this method may be called during VM
 113             // initialization before either is available.
 114             MessageUtils.err("WARNING: Default charset " + csn +
 115                              " not supported, using ISO-8859-1 instead");
 116             warnUnsupportedCharset = false;
 117         }
 118     }
 119 
 120 
 121     // -- Decoding --
 122     private static class StringDecoder {
 123         private final String requestedCharsetName;
 124         private final Charset cs;
 125         private final CharsetDecoder cd;
 126         private final boolean isTrusted;
 127 
 128         private StringDecoder(Charset cs, String rcn) {
 129             this.requestedCharsetName = rcn;
 130             this.cs = cs;
 131             this.cd = cs.newDecoder()
 132                 .onMalformedInput(CodingErrorAction.REPLACE)
 133                 .onUnmappableCharacter(CodingErrorAction.REPLACE);
 134             this.isTrusted = (cs.getClass().getClassLoader0() == null);
 135         }
 136 
 137         String charsetName() {
 138             if (cs instanceof HistoricallyNamedCharset)
 139                 return ((HistoricallyNamedCharset)cs).historicalName();
 140             return cs.name();
 141         }
 142 
 143         final String requestedCharsetName() {
 144             return requestedCharsetName;
 145         }
 146 
 147         char[] decode(byte[] ba, int off, int len) {
 148             int en = scale(len, cd.maxCharsPerByte());
 149             char[] ca = new char[en];
 150             if (len == 0)
 151                 return ca;
 152             if (cd instanceof ArrayDecoder) {
 153                 int clen = ((ArrayDecoder)cd).decode(ba, off, len, ca);
 154                 return safeTrim(ca, clen, cs, isTrusted);
 155             } else {
 156                 cd.reset();
 157                 ByteBuffer bb = ByteBuffer.wrap(ba, off, len);
 158                 CharBuffer cb = CharBuffer.wrap(ca);
 159                 try {
 160                     CoderResult cr = cd.decode(bb, cb, true);
 161                     if (!cr.isUnderflow())
 162                         cr.throwException();
 163                     cr = cd.flush(cb);
 164                     if (!cr.isUnderflow())
 165                         cr.throwException();
 166                 } catch (CharacterCodingException x) {
 167                     // Substitution is always enabled,
 168                     // so this shouldn't happen
 169                     throw new Error(x);
 170                 }
 171                 return safeTrim(ca, cb.position(), cs, isTrusted);



















 172             }
 173         }




 174     }
 175 
 176     static char[] decode(String charsetName, byte[] ba, int off, int len)
 177         throws UnsupportedEncodingException
 178     {
 179         StringDecoder sd = deref(decoder);
 180         String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
 181         if ((sd == null) || !(csn.equals(sd.requestedCharsetName())
 182                               || csn.equals(sd.charsetName()))) {
 183             sd = null;
 184             try {
 185                 Charset cs = lookupCharset(csn);
 186                 if (cs != null)
 187                     sd = new StringDecoder(cs, csn);
 188             } catch (IllegalCharsetNameException x) {}
 189             if (sd == null)
 190                 throw new UnsupportedEncodingException(csn);
 191             set(decoder, sd);
 192         }
 193         return sd.decode(ba, off, len);
 194     }
 195 
 196     static char[] decode(Charset cs, byte[] ba, int off, int len) {
 197         // (1)We never cache the "external" cs, the only benefit of creating
 198         // an additional StringDe/Encoder object to wrap it is to share the
 199         // de/encode() method. These SD/E objects are short-lived, the young-gen
 200         // gc should be able to take care of them well. But the best approach
 201         // is still not to generate them if not really necessary.
 202         // (2)The defensive copy of the input byte/char[] has a big performance
 203         // impact, as well as the outgoing result byte/char[]. Need to do the
 204         // optimization check of (sm==null && classLoader0==null) for both.
 205         // (3)getClass().getClassLoader0() is expensive
 206         // (4)There might be a timing gap in isTrusted setting. getClassLoader0()
 207         // is only checked (and then isTrusted gets set) when (SM==null). It is
 208         // possible that the SM==null for now but then SM is NOT null later
 209         // when safeTrim() is invoked...the "safe" way to do is to redundant
 210         // check (... && (isTrusted || SM == null || getClassLoader0())) in trim
 211         // but it then can be argued that the SM is null when the operation
 212         // is started...
 213         CharsetDecoder cd = cs.newDecoder();
 214         int en = scale(len, cd.maxCharsPerByte());
 215         char[] ca = new char[en];
 216         if (len == 0)
 217             return ca;
 218         boolean isTrusted = false;
 219         if (System.getSecurityManager() != null) {
 220             if (!(isTrusted = (cs.getClass().getClassLoader0() == null))) {
 221                 ba =  Arrays.copyOfRange(ba, off, off + len);
 222                 off = 0;
 223             }
 224         }
 225         cd.onMalformedInput(CodingErrorAction.REPLACE)
 226           .onUnmappableCharacter(CodingErrorAction.REPLACE)
 227           .reset();
 228         if (cd instanceof ArrayDecoder) {
 229             int clen = ((ArrayDecoder)cd).decode(ba, off, len, ca);
 230             return safeTrim(ca, clen, cs, isTrusted);
 231         } else {
 232             ByteBuffer bb = ByteBuffer.wrap(ba, off, len);
















































 233             CharBuffer cb = CharBuffer.wrap(ca);
 234             try {
 235                 CoderResult cr = cd.decode(bb, cb, true);
 236                 if (!cr.isUnderflow())
 237                     cr.throwException();
 238                 cr = cd.flush(cb);
 239                 if (!cr.isUnderflow())
 240                     cr.throwException();
 241             } catch (CharacterCodingException x) {
 242                 // Substitution is always enabled,
 243                 // so this shouldn't happen
 244                 throw new Error(x);
 245             }
 246             return safeTrim(ca, cb.position(), cs, isTrusted);
 247         }
 248     }
 249 
 250     static char[] decode(byte[] ba, int off, int len) {
 251         String csn = Charset.defaultCharset().name();
 252         try {
 253             // use charset name decode() variant which provides caching.
 254             return decode(csn, ba, off, len);
 255         } catch (UnsupportedEncodingException x) {
 256             warnUnsupportedCharset(csn);
 257         }
 258         try {
 259             return decode("ISO-8859-1", ba, off, len);
 260         } catch (UnsupportedEncodingException x) {
 261             // If this code is hit during VM initialization, MessageUtils is
 262             // the only way we will be able to get any kind of error message.
 263             MessageUtils.err("ISO-8859-1 charset not available: "
 264                              + x.toString());
 265             // If we can not find ISO-8859-1 (a required encoding) then things
 266             // are seriously wrong with the installation.
 267             System.exit(1);
 268             return null;


 289             if (cs instanceof HistoricallyNamedCharset)
 290                 return ((HistoricallyNamedCharset)cs).historicalName();
 291             return cs.name();
 292         }
 293 
 294         final String requestedCharsetName() {
 295             return requestedCharsetName;
 296         }
 297 
 298         byte[] encode(char[] ca, int off, int len) {
 299             int en = scale(len, ce.maxBytesPerChar());
 300             byte[] ba = new byte[en];
 301             if (len == 0)
 302                 return ba;
 303             if (ce instanceof ArrayEncoder) {
 304                 int blen = ((ArrayEncoder)ce).encode(ca, off, len, ba);
 305                 return safeTrim(ba, blen, cs, isTrusted);
 306             } else {
 307                 ce.reset();
 308                 ByteBuffer bb = ByteBuffer.wrap(ba);
 309                 CharBuffer cb = CharBuffer.wrap(ca, off, len);
 310                 try {
 311                     CoderResult cr = ce.encode(cb, bb, true);
 312                     if (!cr.isUnderflow())
 313                         cr.throwException();
 314                     cr = ce.flush(bb);
 315                     if (!cr.isUnderflow())
 316                         cr.throwException();
 317                 } catch (CharacterCodingException x) {
 318                     // Substitution is always enabled,
 319                     // so this shouldn't happen
 320                     throw new Error(x);
 321                 }
 322                 return safeTrim(ba, bb.position(), cs, isTrusted);
 323             }
 324         }
 325     }
 326 
 327     static byte[] encode(String charsetName, char[] ca, int off, int len)
 328         throws UnsupportedEncodingException
 329     {




 330         StringEncoder se = deref(encoder);
 331         String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
 332         if ((se == null) || !(csn.equals(se.requestedCharsetName())
 333                               || csn.equals(se.charsetName()))) {
 334             se = null;
 335             try {
 336                 Charset cs = lookupCharset(csn);
 337                 if (cs != null)
 338                     se = new StringEncoder(cs, csn);
 339             } catch (IllegalCharsetNameException x) {}
 340             if (se == null)
 341                 throw new UnsupportedEncodingException (csn);
 342             set(encoder, se);
 343         }
 344         return se.encode(ca, off, len);

 345     }
 346 
 347     static byte[] encode(Charset cs, char[] ca, int off, int len) {
 348         CharsetEncoder ce = cs.newEncoder();
 349         int en = scale(len, ce.maxBytesPerChar());
 350         byte[] ba = new byte[en];
 351         if (len == 0)
 352             return ba;
 353         boolean isTrusted = false;
 354         if (System.getSecurityManager() != null) {
 355             if (!(isTrusted = (cs.getClass().getClassLoader0() == null))) {
 356                 ca =  Arrays.copyOfRange(ca, off, off + len);
 357                 off = 0;
 358             }
 359         }
 360         ce.onMalformedInput(CodingErrorAction.REPLACE)
 361           .onUnmappableCharacter(CodingErrorAction.REPLACE)
 362           .reset();
 363         if (ce instanceof ArrayEncoder) {
 364             int blen = ((ArrayEncoder)ce).encode(ca, off, len, ba);
 365             return safeTrim(ba, blen, cs, isTrusted);
 366         } else {
 367             ByteBuffer bb = ByteBuffer.wrap(ba);



































 368             CharBuffer cb = CharBuffer.wrap(ca, off, len);
 369             try {
 370                 CoderResult cr = ce.encode(cb, bb, true);
 371                 if (!cr.isUnderflow())
 372                     cr.throwException();
 373                 cr = ce.flush(bb);
 374                 if (!cr.isUnderflow())
 375                     cr.throwException();
 376             } catch (CharacterCodingException x) {
 377                 throw new Error(x);
 378             }
 379             return safeTrim(ba, bb.position(), cs, isTrusted);
 380         }





 381     }
 382 
 383     static byte[] encode(char[] ca, int off, int len) {
 384         String csn = Charset.defaultCharset().name();
 385         try {
 386             // use charset name encode() variant which provides caching.
 387             return encode(csn, ca, off, len);
 388         } catch (UnsupportedEncodingException x) {
 389             warnUnsupportedCharset(csn);
 390         }
 391         try {
 392             return encode("ISO-8859-1", ca, off, len);
 393         } catch (UnsupportedEncodingException x) {
 394             // If this code is hit during VM initialization, MessageUtils is
 395             // the only way we will be able to get any kind of error message.
 396             MessageUtils.err("ISO-8859-1 charset not available: "
 397                              + x.toString());
 398             // If we can not find ISO-8859-1 (a required encoding) then things
 399             // are seriously wrong with the installation.
 400             System.exit(1);


 111             // Use sun.misc.MessageUtils rather than the Logging API or
 112             // System.err since this method may be called during VM
 113             // initialization before either is available.
 114             MessageUtils.err("WARNING: Default charset " + csn +
 115                              " not supported, using ISO-8859-1 instead");
 116             warnUnsupportedCharset = false;
 117         }
 118     }
 119 
 120 
 121     // -- Decoding --
 122     private static class StringDecoder {
 123         private final String requestedCharsetName;
 124         private final Charset cs;
 125         private final CharsetDecoder cd;
 126         private final boolean isTrusted;
 127 
 128         private StringDecoder(Charset cs, String rcn) {
 129             this.requestedCharsetName = rcn;
 130             this.cs = cs;
 131             this.cd = cs.newDecoder();
 132             setupDecoder(cd);

 133             this.isTrusted = (cs.getClass().getClassLoader0() == null);
 134         }
 135 
 136         String charsetName() {
 137             if (cs instanceof HistoricallyNamedCharset)
 138                 return ((HistoricallyNamedCharset)cs).historicalName();
 139             return cs.name();
 140         }
 141 
 142         final String requestedCharsetName() {
 143             return requestedCharsetName;
 144         }
 145 
 146         char[] decode(byte[] ba, int off, int len) {
 147             int en = scale(len, cd.maxCharsPerByte());
 148             char[] ca = new char[en];
 149             if (len == 0)
 150                 return ca;
 151             if (cd instanceof ArrayDecoder) {
 152                 int clen = ((ArrayDecoder)cd).decode(ba, off, len, ca);
 153                 return safeTrim(ca, clen, cs, isTrusted);
 154             } else {
 155                 cd.reset();
 156                 ByteBuffer bb = ByteBuffer.wrap(ba, off, len);
 157                 return performDecode(cs, isTrusted, ca, cd, bb);











 158             }
 159         }
 160 
 161         char[] decode(ByteBuffer bb) {
 162             int len = bb.remaining();
 163             int en = scale(len, cd.maxCharsPerByte());
 164             char[] ca = new char[en];
 165             if (len == 0)
 166                 return ca;
 167 
 168             if (!isTrusted) {
 169                 // copy the bytebuffer
 170                 ByteBuffer originalByteBuffer = bb;
 171                 bb = ByteBuffer.allocate(len)
 172                                .put(originalByteBuffer);
 173                 bb.position(0);
 174             }
 175 
 176             cd.reset();
 177 
 178             return performDecode(cs, isTrusted, ca, cd, bb);
 179         }
 180     }
 181 
 182     static char[] decode(String charsetName, byte[] ba, int off, int len) throws UnsupportedEncodingException {
 183         StringDecoder sd = getStringDecoder(charsetName);
 184         return sd.decode(ba, off, len);
 185     }
 186 
 187     private static StringDecoder getStringDecoder(String charsetName) throws UnsupportedEncodingException {


 188         StringDecoder sd = deref(decoder);
 189         String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
 190         if ((sd == null) || !(csn.equals(sd.requestedCharsetName())
 191                               || csn.equals(sd.charsetName()))) {
 192             sd = null;
 193             try {
 194                 Charset cs = lookupCharset(csn);
 195                 if (cs != null)
 196                     sd = new StringDecoder(cs, csn);
 197             } catch (IllegalCharsetNameException x) {}
 198             if (sd == null)
 199                 throw new UnsupportedEncodingException(csn);
 200             set(decoder, sd);
 201         }
 202         return sd;
 203     }
 204 
 205     static char[] decode(Charset cs, byte[] ba, int off, int len) {
 206         // (1)We never cache the "external" cs, the only benefit of creating
 207         // an additional StringDe/Encoder object to wrap it is to share the
 208         // de/encode() method. These SD/E objects are short-lived, the young-gen
 209         // gc should be able to take care of them well. But the best approach
 210         // is still not to generate them if not really necessary.
 211         // (2)The defensive copy of the input byte/char[] has a big performance
 212         // impact, as well as the outgoing result byte/char[]. Need to do the
 213         // optimization check of (sm==null && classLoader0==null) for both.
 214         // (3)getClass().getClassLoader0() is expensive
 215         // (4)There might be a timing gap in isTrusted setting. getClassLoader0()
 216         // is only checked (and then isTrusted gets set) when (SM==null). It is
 217         // possible that the SM==null for now but then SM is NOT null later
 218         // when safeTrim() is invoked...the "safe" way to do is to redundant
 219         // check (... && (isTrusted || SM == null || getClassLoader0())) in trim
 220         // but it then can be argued that the SM is null when the operation
 221         // is started...
 222         CharsetDecoder cd = cs.newDecoder();
 223         int en = scale(len, cd.maxCharsPerByte());
 224         char[] ca = new char[en];
 225         if (len == 0)
 226             return ca;
 227         
 228         boolean isTrusted = isTrusted(cs);
 229         if (!isTrusted) {
 230             ba =  Arrays.copyOfRange(ba, off, off + len);
 231             off = 0;
 232         }
 233 
 234         setupDecoder(cd);
 235 

 236         if (cd instanceof ArrayDecoder) {
 237             int clen = ((ArrayDecoder)cd).decode(ba, off, len, ca);
 238             return safeTrim(ca, clen, cs, isTrusted);
 239         } else {
 240             ByteBuffer bb = ByteBuffer.wrap(ba, off, len);
 241             return performDecode(cs, isTrusted, ca, cd, bb);
 242         }
 243     }
 244 
 245     static char[] decode(Charset cs, ByteBuffer bb) {
 246         // See comment at top of decode(Charset,byte[],int,int)
 247         CharsetDecoder cd = cs.newDecoder();
 248         int len = bb.remaining();
 249         int en = scale(len, cd.maxCharsPerByte());
 250         char[] ca = new char[en];
 251         if (len == 0)
 252             return ca;
 253 
 254         boolean isTrusted = isTrusted(cs);
 255         if (!isTrusted) {
 256             // copy the bytebuffer
 257             ByteBuffer originalByteBuffer = bb;
 258             bb = ByteBuffer.allocate(len)
 259                            .put(originalByteBuffer);
 260             bb.position(0);
 261         }
 262 
 263         setupDecoder(cd);
 264 
 265         return performDecode(cs, isTrusted, ca, cd, bb);
 266     }
 267 
 268     static char[] decode(String charsetName, ByteBuffer bb) throws UnsupportedEncodingException {
 269         StringDecoder sd = getStringDecoder(charsetName);
 270         return sd.decode(bb);
 271     }
 272 
 273     private static boolean isTrusted(Charset cs) {
 274         return System.getSecurityManager() != null
 275             // null classloader means the class is on the boot classpath
 276             && cs.getClass().getClassLoader0() == null;
 277     }
 278 
 279     private static void setupDecoder(CharsetDecoder cd) {
 280         cd.onMalformedInput(CodingErrorAction.REPLACE)
 281           .onUnmappableCharacter(CodingErrorAction.REPLACE)
 282           .reset();
 283     }
 284 
 285     static char[] performDecode(
 286         Charset cs, boolean isTrusted, char[] ca, 
 287         CharsetDecoder cd, ByteBuffer bb) {
 288 
 289         CharBuffer cb = CharBuffer.wrap(ca);
 290         try {
 291             CoderResult cr = cd.decode(bb, cb, true);
 292             if (!cr.isUnderflow())
 293                 cr.throwException();
 294             cr = cd.flush(cb);
 295             if (!cr.isUnderflow())
 296                 cr.throwException();
 297         } catch (CharacterCodingException x) {
 298             // Substitution is always enabled,
 299             // so this shouldn't happen
 300             throw new Error(x);
 301         }
 302         return safeTrim(ca, cb.position(), cs, isTrusted);
 303     }

 304 
 305     static char[] decode(byte[] ba, int off, int len) {
 306         String csn = Charset.defaultCharset().name();
 307         try {
 308             // use charset name decode() variant which provides caching.
 309             return decode(csn, ba, off, len);
 310         } catch (UnsupportedEncodingException x) {
 311             warnUnsupportedCharset(csn);
 312         }
 313         try {
 314             return decode("ISO-8859-1", ba, off, len);
 315         } catch (UnsupportedEncodingException x) {
 316             // If this code is hit during VM initialization, MessageUtils is
 317             // the only way we will be able to get any kind of error message.
 318             MessageUtils.err("ISO-8859-1 charset not available: "
 319                              + x.toString());
 320             // If we can not find ISO-8859-1 (a required encoding) then things
 321             // are seriously wrong with the installation.
 322             System.exit(1);
 323             return null;


 344             if (cs instanceof HistoricallyNamedCharset)
 345                 return ((HistoricallyNamedCharset)cs).historicalName();
 346             return cs.name();
 347         }
 348 
 349         final String requestedCharsetName() {
 350             return requestedCharsetName;
 351         }
 352 
 353         byte[] encode(char[] ca, int off, int len) {
 354             int en = scale(len, ce.maxBytesPerChar());
 355             byte[] ba = new byte[en];
 356             if (len == 0)
 357                 return ba;
 358             if (ce instanceof ArrayEncoder) {
 359                 int blen = ((ArrayEncoder)ce).encode(ca, off, len, ba);
 360                 return safeTrim(ba, blen, cs, isTrusted);
 361             } else {
 362                 ce.reset();
 363                 ByteBuffer bb = ByteBuffer.wrap(ba);
 364                 StringCoding.encode(ca, off, len, bb, ce);












 365                 return safeTrim(ba, bb.position(), cs, isTrusted);
 366             }
 367         }
 368     }
 369 
 370     static byte[] encode(String charsetName, char[] ca, int off, int len)
 371         throws UnsupportedEncodingException {
 372         StringEncoder se = getStringEncoder(charsetName);
 373         return se.encode(ca, off, len);
 374     }
 375 
 376     private static StringEncoder getStringEncoder(String charsetName) throws UnsupportedEncodingException {
 377         StringEncoder se = deref(encoder);
 378         String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
 379         if ((se == null) || !(csn.equals(se.requestedCharsetName())
 380                               || csn.equals(se.charsetName()))) {
 381             se = null;
 382             try {
 383                 Charset cs = lookupCharset(csn);
 384                 if (cs != null)
 385                     se = new StringEncoder(cs, csn);
 386             } catch (IllegalCharsetNameException x) {}
 387             if (se == null)
 388                 throw new UnsupportedEncodingException (csn);
 389             set(encoder, se);
 390         }
 391         se.ce.reset();
 392         return se;
 393     }
 394 
 395     static byte[] encode(Charset cs, char[] ca, int off, int len) {
 396         CharsetEncoder ce = cs.newEncoder();
 397         int en = scale(len, ce.maxBytesPerChar());
 398         byte[] ba = new byte[en];
 399         if (len == 0)
 400             return ba;
 401         boolean isTrusted = isTrusted(cs);
 402         if (!isTrusted) {

 403             ca =  Arrays.copyOfRange(ca, off, off + len);
 404             off = 0;
 405         }
 406         setupEncoder(ce);



 407         if (ce instanceof ArrayEncoder) {
 408             int blen = ((ArrayEncoder)ce).encode(ca, off, len, ba);
 409             return safeTrim(ba, blen, cs, isTrusted);
 410         } else {
 411             ByteBuffer bb = ByteBuffer.wrap(ba);
 412             encode(ca, off, len, bb, ce);
 413             return safeTrim(ba, bb.position(), cs, isTrusted);
 414         }
 415     }
 416 
 417 
 418     static int encode(Charset cs, char[] ca, int off, int len, byte[] destBuffer, int destOffset) {
 419         ByteBuffer bb = ByteBuffer.wrap(destBuffer, destOffset, destBuffer.length - destOffset);
 420         return encode(cs, ca, off, len, bb);
 421     }
 422 
 423     static int encode(Charset cs, char[] ca, int off, int len, ByteBuffer destBuffer) {
 424         CharsetEncoder ce = cs.newEncoder();
 425         return encodeBuffer(ca, off, len, destBuffer, ce);
 426     }
 427 
 428     static int encode(String charsetName, char[] ca, int off, int len, byte[] destBuffer, int destOffset) throws UnsupportedEncodingException {
 429         ByteBuffer bb = ByteBuffer.wrap(destBuffer, destOffset, destBuffer.length - destOffset);
 430         return encode(charsetName, ca, off, len, bb);
 431     }
 432 
 433     static int encode(String charsetName, char[] ca, int off, int len, ByteBuffer destBuffer) throws UnsupportedEncodingException {
 434         StringEncoder se = getStringEncoder(charsetName);
 435         return encodeBuffer(ca, off, len, destBuffer, se.ce);
 436     }
 437 
 438     // encode(charsetName, value, 0, value.length, destBuffer, destOffset);
 439 
 440     private static int encodeBuffer(char[] ca, int off, int len, ByteBuffer destBuffer, CharsetEncoder ce) {
 441         int originalPosition = destBuffer.position();
 442         encode(ca, off, len, destBuffer, ce);
 443         return destBuffer.position() - originalPosition;
 444     }
 445 
 446     private static void encode(char[] ca, int off, int len, ByteBuffer destBuffer, CharsetEncoder ce) {
 447         CharBuffer cb = CharBuffer.wrap(ca, off, len);
 448         try {
 449             CoderResult cr = ce.encode(cb, destBuffer, true);
 450             if (!cr.isUnderflow())
 451                 cr.throwException();
 452             cr = ce.flush(destBuffer);
 453             if (!cr.isUnderflow())
 454                 cr.throwException();
 455         } catch (CharacterCodingException x) {
 456             throw new Error(x);
 457         }

 458     }
 459 
 460     private static void setupEncoder(CharsetEncoder encoder) {
 461         encoder.onMalformedInput(CodingErrorAction.REPLACE)
 462                .onUnmappableCharacter(CodingErrorAction.REPLACE)
 463                .reset();
 464     }
 465 
 466     static byte[] encode(char[] ca, int off, int len) {
 467         String csn = Charset.defaultCharset().name();
 468         try {
 469             // use charset name encode() variant which provides caching.
 470             return encode(csn, ca, off, len);
 471         } catch (UnsupportedEncodingException x) {
 472             warnUnsupportedCharset(csn);
 473         }
 474         try {
 475             return encode("ISO-8859-1", ca, off, len);
 476         } catch (UnsupportedEncodingException x) {
 477             // If this code is hit during VM initialization, MessageUtils is
 478             // the only way we will be able to get any kind of error message.
 479             MessageUtils.err("ISO-8859-1 charset not available: "
 480                              + x.toString());
 481             // If we can not find ISO-8859-1 (a required encoding) then things
 482             // are seriously wrong with the installation.
 483             System.exit(1);