jdk/src/share/classes/java/lang/StringCoding.java
author martin
Mon, 10 Mar 2008 14:32:51 -0700
changeset 48 dc5744ca15ea
parent 42 6c846a8c97d3
child 715 f16baef3a20e
permissions -rw-r--r--
4960438: (process) Need IO redirection API for subprocesses Reviewed-by: alanb, iris
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package java.lang;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.CharConversionException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.UnsupportedEncodingException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.lang.ref.SoftReference;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.nio.ByteBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.nio.CharBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.nio.BufferOverflowException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.nio.BufferUnderflowException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.nio.charset.Charset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.nio.charset.CharsetDecoder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.nio.charset.CharsetEncoder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.nio.charset.CharacterCodingException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.nio.charset.CoderResult;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.nio.charset.CodingErrorAction;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import java.nio.charset.IllegalCharsetNameException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import java.nio.charset.MalformedInputException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import java.nio.charset.UnsupportedCharsetException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import java.util.Arrays;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import sun.misc.MessageUtils;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
import sun.nio.cs.HistoricallyNamedCharset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * Utility class for string encoding and decoding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
class StringCoding {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
    private StringCoding() { }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
41
dfebd2609e77 6671834: (str) Eliminate StringCoding.java compile warnings
martin
parents: 2
diff changeset
    56
    /** The cached coders for each thread */
dfebd2609e77 6671834: (str) Eliminate StringCoding.java compile warnings
martin
parents: 2
diff changeset
    57
    private final static ThreadLocal<SoftReference<StringDecoder>> decoder =
dfebd2609e77 6671834: (str) Eliminate StringCoding.java compile warnings
martin
parents: 2
diff changeset
    58
        new ThreadLocal<SoftReference<StringDecoder>>();
dfebd2609e77 6671834: (str) Eliminate StringCoding.java compile warnings
martin
parents: 2
diff changeset
    59
    private final static ThreadLocal<SoftReference<StringEncoder>> encoder =
dfebd2609e77 6671834: (str) Eliminate StringCoding.java compile warnings
martin
parents: 2
diff changeset
    60
        new ThreadLocal<SoftReference<StringEncoder>>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    private static boolean warnUnsupportedCharset = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
41
dfebd2609e77 6671834: (str) Eliminate StringCoding.java compile warnings
martin
parents: 2
diff changeset
    64
    private static <T> T deref(ThreadLocal<SoftReference<T>> tl) {
dfebd2609e77 6671834: (str) Eliminate StringCoding.java compile warnings
martin
parents: 2
diff changeset
    65
        SoftReference<T> sr = tl.get();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
        if (sr == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
        return sr.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
41
dfebd2609e77 6671834: (str) Eliminate StringCoding.java compile warnings
martin
parents: 2
diff changeset
    71
    private static <T> void set(ThreadLocal<SoftReference<T>> tl, T ob) {
dfebd2609e77 6671834: (str) Eliminate StringCoding.java compile warnings
martin
parents: 2
diff changeset
    72
        tl.set(new SoftReference<T>(ob));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    // Trim the given byte array to the given length
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    private static byte[] safeTrim(byte[] ba, int len, Charset cs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
        if (len == ba.length
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
            && (System.getSecurityManager() == null
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
                || cs.getClass().getClassLoader0() == null))
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
            return ba;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
            return Arrays.copyOf(ba, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    // Trim the given char array to the given length
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    private static char[] safeTrim(char[] ca, int len, Charset cs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
        if (len == ca.length
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
            && (System.getSecurityManager() == null
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
                || cs.getClass().getClassLoader0() == null))
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
            return ca;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
            return Arrays.copyOf(ca, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    private static int scale(int len, float expansionFactor) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
        // We need to perform double, not float, arithmetic; otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
        // we lose low order bits when len is larger than 2**24.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        return (int)(len * (double)expansionFactor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    private static Charset lookupCharset(String csn) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        if (Charset.isSupported(csn)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
                return Charset.forName(csn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
            } catch (UnsupportedCharsetException x) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
                throw new Error(x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    private static void warnUnsupportedCharset(String csn) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        if (warnUnsupportedCharset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
            // Use sun.misc.MessageUtils rather than the Logging API or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
            // System.err since this method may be called during VM
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
            // initialization before either is available.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
            MessageUtils.err("WARNING: Default charset " + csn +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
                             " not supported, using ISO-8859-1 instead");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
            warnUnsupportedCharset = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    // -- Decoding --
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    private static class StringDecoder {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        private final String requestedCharsetName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        private final Charset cs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        private final CharsetDecoder cd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        private StringDecoder(Charset cs, String rcn) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
            this.requestedCharsetName = rcn;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
            this.cs = cs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
            this.cd = cs.newDecoder()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
                .onMalformedInput(CodingErrorAction.REPLACE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
                .onUnmappableCharacter(CodingErrorAction.REPLACE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        String charsetName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
            if (cs instanceof HistoricallyNamedCharset)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
                return ((HistoricallyNamedCharset)cs).historicalName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
            return cs.name();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        final String requestedCharsetName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
            return requestedCharsetName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        char[] decode(byte[] ba, int off, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
            int en = scale(len, cd.maxCharsPerByte());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
            char[] ca = new char[en];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
            if (len == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                return ca;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
            cd.reset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
            ByteBuffer bb = ByteBuffer.wrap(ba, off, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
            CharBuffer cb = CharBuffer.wrap(ca);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
                CoderResult cr = cd.decode(bb, cb, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
                if (!cr.isUnderflow())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
                    cr.throwException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
                cr = cd.flush(cb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
                if (!cr.isUnderflow())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
                    cr.throwException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
            } catch (CharacterCodingException x) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
                // Substitution is always enabled,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
                // so this shouldn't happen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
                throw new Error(x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
            return safeTrim(ca, cb.position(), cs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    static char[] decode(String charsetName, byte[] ba, int off, int len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        throws UnsupportedEncodingException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    {
41
dfebd2609e77 6671834: (str) Eliminate StringCoding.java compile warnings
martin
parents: 2
diff changeset
   178
        StringDecoder sd = deref(decoder);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        if ((sd == null) || !(csn.equals(sd.requestedCharsetName())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
                              || csn.equals(sd.charsetName()))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
            sd = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
                Charset cs = lookupCharset(csn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
                if (cs != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
                    sd = new StringDecoder(cs, csn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
            } catch (IllegalCharsetNameException x) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
            if (sd == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
                throw new UnsupportedEncodingException(csn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            set(decoder, sd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        return sd.decode(ba, off, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    static char[] decode(Charset cs, byte[] ba, int off, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        StringDecoder sd = new StringDecoder(cs, cs.name());
42
6c846a8c97d3 6633613: (str) StringCoding optimizations to avoid unnecessary array copies with Charset arg
martin
parents: 41
diff changeset
   197
        return sd.decode(Arrays.copyOfRange(ba, off, off + len), 0, len);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
    static char[] decode(byte[] ba, int off, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        String csn = Charset.defaultCharset().name();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            return decode(csn, ba, off, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        } catch (UnsupportedEncodingException x) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            warnUnsupportedCharset(csn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
            return decode("ISO-8859-1", ba, off, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        } catch (UnsupportedEncodingException x) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            // If this code is hit during VM initialization, MessageUtils is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            // the only way we will be able to get any kind of error message.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            MessageUtils.err("ISO-8859-1 charset not available: "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                             + x.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
            // If we can not find ISO-8859-1 (a required encoding) then things
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
            // are seriously wrong with the installation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
            System.exit(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    // -- Encoding --
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    private static class StringEncoder {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        private Charset cs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        private CharsetEncoder ce;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        private final String requestedCharsetName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        private StringEncoder(Charset cs, String rcn) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
            this.requestedCharsetName = rcn;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
            this.cs = cs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
            this.ce = cs.newEncoder()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                .onMalformedInput(CodingErrorAction.REPLACE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                .onUnmappableCharacter(CodingErrorAction.REPLACE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        String charsetName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
            if (cs instanceof HistoricallyNamedCharset)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                return ((HistoricallyNamedCharset)cs).historicalName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
            return cs.name();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        final String requestedCharsetName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
            return requestedCharsetName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        byte[] encode(char[] ca, int off, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
            int en = scale(len, ce.maxBytesPerChar());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
            byte[] ba = new byte[en];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
            if (len == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
                return ba;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
            ce.reset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            ByteBuffer bb = ByteBuffer.wrap(ba);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
            CharBuffer cb = CharBuffer.wrap(ca, off, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
                CoderResult cr = ce.encode(cb, bb, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
                if (!cr.isUnderflow())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                    cr.throwException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                cr = ce.flush(bb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                if (!cr.isUnderflow())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
                    cr.throwException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
            } catch (CharacterCodingException x) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
                // Substitution is always enabled,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
                // so this shouldn't happen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
                throw new Error(x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            return safeTrim(ba, bb.position(), cs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    static byte[] encode(String charsetName, char[] ca, int off, int len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        throws UnsupportedEncodingException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
    {
41
dfebd2609e77 6671834: (str) Eliminate StringCoding.java compile warnings
martin
parents: 2
diff changeset
   276
        StringEncoder se = deref(encoder);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        if ((se == null) || !(csn.equals(se.requestedCharsetName())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                              || csn.equals(se.charsetName()))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
            se = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
                Charset cs = lookupCharset(csn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
                if (cs != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                    se = new StringEncoder(cs, csn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            } catch (IllegalCharsetNameException x) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
            if (se == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                throw new UnsupportedEncodingException (csn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            set(encoder, se);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        return se.encode(ca, off, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    static byte[] encode(Charset cs, char[] ca, int off, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        StringEncoder se = new StringEncoder(cs, cs.name());
42
6c846a8c97d3 6633613: (str) StringCoding optimizations to avoid unnecessary array copies with Charset arg
martin
parents: 41
diff changeset
   295
        return se.encode(Arrays.copyOfRange(ca, off, off + len), 0, len);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    static byte[] encode(char[] ca, int off, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        String csn = Charset.defaultCharset().name();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
            return encode(csn, ca, off, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        } catch (UnsupportedEncodingException x) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
            warnUnsupportedCharset(csn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            return encode("ISO-8859-1", ca, off, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        } catch (UnsupportedEncodingException x) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
            // If this code is hit during VM initialization, MessageUtils is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            // the only way we will be able to get any kind of error message.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            MessageUtils.err("ISO-8859-1 charset not available: "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                             + x.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            // If we can not find ISO-8859-1 (a required encoding) then things
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            // are seriously wrong with the installation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            System.exit(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
}