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-lifed, the young-gen
200 // gc should be able to take care of them well. But the best approash
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 chcked (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 opertaion
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 {
|
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 {
|