You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2006/03/29 14:28:40 UTC
svn commit: r389782 - in
/incubator/harmony/enhanced/classlib/trunk/modules/nio_char/src:
main/java/java/nio/charset/Charset.java
test/java/org/apache/harmony/tests/java/nio/charset/CharsetTest.java
Author: tellison
Date: Wed Mar 29 04:28:36 2006
New Revision: 389782
URL: http://svn.apache.org/viewcvs?rev=389782&view=rev
Log:
Apply patch HARMONY-150 (java.nio.charset.Charset.decode(in) doesn't use the same cached decoder)
Modified:
incubator/harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/java/nio/charset/Charset.java
incubator/harmony/enhanced/classlib/trunk/modules/nio_char/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetTest.java
Modified: incubator/harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/java/nio/charset/Charset.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/java/nio/charset/Charset.java?rev=389782&r1=389781&r2=389782&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/java/nio/charset/Charset.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/java/nio/charset/Charset.java Wed Mar 29 04:28:36 2006
@@ -115,26 +115,6 @@
* --------------------------------------------------------------------
*/
- // a cached instance of encoder for each thread
- ThreadLocal cachedEncoder = new ThreadLocal() {
- protected synchronized Object initialValue() {
- CharsetEncoder e = newEncoder();
- e.onMalformedInput(CodingErrorAction.REPLACE);
- e.onUnmappableCharacter(CodingErrorAction.REPLACE);
- return e;
- }
- };
-
- // a cached instance of decoder for each thread
- ThreadLocal cachedDecoder = new ThreadLocal() {
- protected synchronized Object initialValue() {
- CharsetDecoder d = newDecoder();
- d.onMalformedInput(CodingErrorAction.REPLACE);
- d.onUnmappableCharacter(CodingErrorAction.REPLACE);
- return d;
- }
- };
-
private final String canonicalName;
// the aliases set
@@ -142,6 +122,13 @@
// cached Charset table
private static HashMap cachedCharsetTable = new HashMap();
+
+ // cached CharsetDecoder table
+ private static HashMap cachedCharsetDecoderTable = new HashMap();
+
+ // cached CharsetEncoder table
+ private static HashMap cachedCharsetEncoderTable = new HashMap();
+
/*
* -------------------------------------------------------------------
* Global initialization
@@ -637,14 +624,33 @@
* the character buffer containing the content to be encoded
* @return the result of the encoding
*/
- public final ByteBuffer encode(CharBuffer buffer) {
- CharsetEncoder e = (CharsetEncoder) this.cachedEncoder.get();
+ synchronized public final ByteBuffer encode(CharBuffer buffer) {
+ CharsetEncoder e = getCachedCharsetEncoder(canonicalName);
+ if(null == e){
+ e = this.newEncoder();
+ e.onMalformedInput(CodingErrorAction.REPLACE);
+ e.onUnmappableCharacter(CodingErrorAction.REPLACE);
+ cacheCharsetEncoder(this.canonicalName,e);
+ }
try {
return e.encode(buffer);
} catch (CharacterCodingException ex) {
throw new Error(ex.getMessage(), ex);
}
}
+
+ /*
+ * get cached CharsetEncoder by canonical name
+ */
+ private CharsetEncoder getCachedCharsetEncoder(String name){
+ return (CharsetEncoder) cachedCharsetEncoderTable.get(name);
+ }
+ /*
+ * save CharsetEncoder into cachedCharsetEncoderTable
+ */
+ private void cacheCharsetEncoder(String name, CharsetEncoder encoder){
+ cachedCharsetEncoderTable.put(name,encoder);
+ }
/**
* Encodes a string and outputs to a byte buffer that is to be retured.
@@ -673,13 +679,32 @@
* the byte buffer containing the content to be decoded
* @return a character buffer containing the output of the dencoding
*/
- public final CharBuffer decode(ByteBuffer buffer) {
- CharsetDecoder d = (CharsetDecoder) this.cachedDecoder.get();
+ synchronized public final CharBuffer decode(ByteBuffer buffer) {
+ CharsetDecoder d = getCachedCharsetDecoder(canonicalName);
+ if(null == d){
+ d = this.newDecoder();
+ d.onMalformedInput(CodingErrorAction.REPLACE);
+ d.onUnmappableCharacter(CodingErrorAction.REPLACE);
+ cacheCharsetDecoder(canonicalName,d);
+ }
try {
return d.decode(buffer);
} catch (CharacterCodingException ex) {
throw new Error(ex.getMessage(), ex);
}
+ }
+
+ /*
+ * get cached CharsetDecoder by canonical name
+ */
+ private CharsetDecoder getCachedCharsetDecoder(String name){
+ return (CharsetDecoder) cachedCharsetDecoderTable.get(name);
+ }
+ /*
+ * save CharsetDecoder into cachedCharsetDecoderTable
+ */
+ private void cacheCharsetDecoder(String name, CharsetDecoder decoder){
+ cachedCharsetDecoderTable.put(name,decoder);
}
/*
Modified: incubator/harmony/enhanced/classlib/trunk/modules/nio_char/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetTest.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/nio_char/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetTest.java?rev=389782&r1=389781&r2=389782&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/nio_char/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetTest.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/nio_char/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetTest.java Wed Mar 29 04:28:36 2006
@@ -15,7 +15,12 @@
package org.apache.harmony.tests.java.nio.charset;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
import java.nio.charset.IllegalCharsetNameException;
import java.util.HashSet;
import java.util.Iterator;
@@ -150,5 +155,142 @@
Charset cs3 = Charset.forName("ASCII");
Charset cs4 = Charset.forName("US-ASCII");
assertSame(cs3, cs4);
- }
+ }
+
+ /*
+ * test cached decoder
+ */
+ public void test_DecodeLjava_nio_ByteBuffer() throws Exception{
+ MockCharsetForDecoder cs1 = new MockCharsetForDecoder("CachedCharset",null);
+ MockCharsetForDecoder cs2 = new MockCharsetForDecoder("CachedCharset",null);
+ ByteBuffer in = ByteBuffer.wrap(new byte[]{0x00});
+ cs1.decode(in);
+ in.flip();
+ cs2.decode(in);
+ in.flip();
+ }
+ /*
+ * Mock Charset for cached decoder test
+ */
+ static class MockCharsetForDecoder extends Charset{
+
+ public MockCharsetForDecoder(String canonicalName, String[] aliases){
+ super(canonicalName, aliases);
+ }
+
+ public boolean contains(Charset charset) {
+ return false;
+ }
+
+ public CharsetEncoder newEncoder() {
+ return null;
+ }
+
+ public CharsetDecoder newDecoder() {
+ return new MockCachedDecoder(this);
+ }
+
+
+ }
+ /*
+ * Mock decoder. Only one caller is permitted.
+ */
+ static class MockCachedDecoder extends CharsetDecoder {
+ static MockCachedDecoder caller = null;
+
+ public MockCachedDecoder(Charset cs) {
+ super(cs, 1, 10);
+ }
+
+ /*
+ * Only one caller is permitted.
+ * If there's another caller, throw RuntimeException.
+ */
+ protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
+ if(null == caller){
+ caller = this;
+ }else{
+ if(caller != this){
+ // Another instance
+ fail("should use the same instance");
+ }
+ }
+ return CoderResult.UNDERFLOW;
+ }
+ }
+
+ /*
+ * test cached encoder
+ */
+ public void test_EncodeLjava_nio_CharBuffer() throws Exception {
+ MockCharsetForEncoder cs1 = new MockCharsetForEncoder("CachedCharset", null);
+ MockCharsetForEncoder cs2 = new MockCharsetForEncoder("CachedCharset", null);
+ CharBuffer in = CharBuffer.wrap("A");
+ cs1.encode(in);
+ in.flip();
+ cs2.encode(in);
+ }
+
+ /*
+ * Mock Charset for cached encoder test
+ */
+ static class MockCharsetForEncoder extends Charset {
+
+ public MockCharsetForEncoder(String canonicalName, String[] aliases) {
+ super(canonicalName, aliases);
+ }
+
+ public boolean contains(Charset charset) {
+ return false;
+ }
+
+ public CharsetDecoder newDecoder() {
+ return new MockDecoderForEncoder(this);
+ }
+
+ public CharsetEncoder newEncoder() {
+ return new MockCachedEncoder(this);
+ }
+ }
+
+ /*
+ * Mock encoder. Only one caller is permitted.
+ */
+ static class MockCachedEncoder extends CharsetEncoder {
+ static MockCachedEncoder caller = null;
+
+ public MockCachedEncoder(Charset cs) {
+ super(cs, 1, 10);
+ }
+
+ /*
+ * Only one caller is permitted.
+ */
+ protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
+ if (null == caller) {
+ caller = this;
+ } else {
+ if (caller != this) {
+ // Another instance
+ fail("should use the same instance");
+ }
+ }
+ return CoderResult.UNDERFLOW;
+ }
+ }
+
+ /*
+ * Mock decoder for MockCachedEncoder.
+ */
+ static class MockDecoderForEncoder extends CharsetDecoder {
+ public MockDecoderForEncoder(Charset cs) {
+ super(cs, 1, 10);
+ }
+
+ protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
+ in.position(in.limit());
+ return CoderResult.UNDERFLOW;
+ }
+ }
+
}