You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ap...@apache.org on 2007/09/19 14:59:10 UTC
svn commit: r577294 - in
/harmony/enhanced/classlib/trunk/modules/nio_char/src:
main/java/java/nio/charset/ main/java/org/apache/harmony/niochar/charset/
test/java/org/apache/harmony/nio_char/tests/java/nio/charset/
Author: apetrenko
Date: Wed Sep 19 05:59:09 2007
New Revision: 577294
URL: http://svn.apache.org/viewvc?rev=577294&view=rev
Log:
Patch for HARMONY-4815 "[classlib][nio] Charset encoding/decoding is ineffective"
Modified:
harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/java/nio/charset/Charset.java
harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/java/nio/charset/CharsetEncoder.java
harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/org/apache/harmony/niochar/charset/ISO_8859_1.java
harmony/enhanced/classlib/trunk/modules/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetTest.java
Modified: harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/java/nio/charset/Charset.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/java/nio/charset/Charset.java?rev=577294&r1=577293&r2=577294&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/java/nio/charset/Charset.java (original)
+++ harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/java/nio/charset/Charset.java Wed Sep 19 05:59:09 2007
@@ -108,16 +108,6 @@
// cached Charset table
private static HashMap<String, Charset> cachedCharsetTable = new HashMap<String, Charset>();
- // cached CharsetDecoder table
- private static HashMap<String, CharsetDecoder> cachedCharsetDecoderTable = new HashMap<String, CharsetDecoder>();
-
- // cached CharsetEncoder table
- private static HashMap<String, CharsetEncoder> cachedCharsetEncoderTable = new HashMap<String, CharsetEncoder>();
-
- private CharsetEncoder cachedEncoder = null;
-
- private CharsetDecoder cachedDecoder = null;
-
static {
/*
* Create built-in charset provider even if no privilege to access
@@ -637,36 +627,19 @@
* the character buffer containing the content to be encoded
* @return the result of the encoding
*/
- synchronized public final ByteBuffer encode(CharBuffer buffer) {
- if (cachedEncoder == null) {
- cachedEncoder = getCachedCharsetEncoder(canonicalName);
- }
-
- try {
- synchronized (cachedEncoder) {
- return cachedEncoder.encode(buffer);
- }
+ public final ByteBuffer encode(CharBuffer buffer) {
+ try
+ {
+ return this.newEncoder()
+ .onMalformedInput(CodingErrorAction.REPLACE)
+ .onUnmappableCharacter(CodingErrorAction.REPLACE)
+ .encode(buffer);
+
} catch (CharacterCodingException ex) {
throw new Error(ex.getMessage(), ex);
}
}
- /*
- * get cached CharsetEncoder by canonical name
- */
- private CharsetEncoder getCachedCharsetEncoder(String name) {
- synchronized (cachedCharsetEncoderTable) {
- CharsetEncoder e = cachedCharsetEncoderTable.get(name);
- if (null == e) {
- e = this.newEncoder();
- e.onMalformedInput(CodingErrorAction.REPLACE);
- e.onUnmappableCharacter(CodingErrorAction.REPLACE);
- cachedCharsetEncoderTable.put(name, e);
- }
- return e;
- }
- }
-
/**
* Encodes a string and outputs to a byte buffer that is to be returned.
* <p>
@@ -695,34 +668,17 @@
* @return a character buffer containing the output of the decoding
*/
public final CharBuffer decode(ByteBuffer buffer) {
- if (cachedDecoder == null) {
- cachedDecoder = getCachedCharsetDecoder(canonicalName);
- }
- try {
- synchronized (cachedDecoder) {
- return cachedDecoder.decode(buffer);
- }
- } catch (CharacterCodingException ex) {
- throw new Error(ex.getMessage(), ex);
- }
- }
-
- /*
- * get cached CharsetDecoder by canonical name
- */
- private CharsetDecoder getCachedCharsetDecoder(String name) {
- synchronized (cachedCharsetDecoderTable) {
- CharsetDecoder d = cachedCharsetDecoderTable.get(name);
- if (null == d) {
- d = this.newDecoder();
- d.onMalformedInput(CodingErrorAction.REPLACE);
- d.onUnmappableCharacter(CodingErrorAction.REPLACE);
- cachedCharsetDecoderTable.put(name, d);
- }
- return d;
- }
- }
+ try {
+ return this.newDecoder()
+ .onMalformedInput(CodingErrorAction.REPLACE)
+ .onUnmappableCharacter(CodingErrorAction.REPLACE)
+ .decode(buffer);
+
+ } catch (CharacterCodingException ex) {
+ throw new Error(ex.getMessage(), ex);
+ }
+ }
/*
* -------------------------------------------------------------------
Modified: harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/java/nio/charset/CharsetEncoder.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/java/nio/charset/CharsetEncoder.java?rev=577294&r1=577293&r2=577294&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/java/nio/charset/CharsetEncoder.java (original)
+++ harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/java/nio/charset/CharsetEncoder.java Wed Sep 19 05:59:09 2007
@@ -343,32 +343,35 @@
CoderResult result = null;
while (true) {
result = encode(in, output, false);
- checkCoderResult(result);
- if (result.isUnderflow()) {
+ if (result==CoderResult.UNDERFLOW) {
break;
- } else if (result.isOverflow()) {
+ } else if (result==CoderResult.OVERFLOW) {
output = allocateMore(output);
+ continue;
}
+ checkCoderResult(result);
}
result = encode(in, output, true);
checkCoderResult(result);
while (true) {
result = flush(output);
- checkCoderResult(result);
- if (result.isOverflow()) {
- output = allocateMore(output);
- } else {
+ if (result==CoderResult.UNDERFLOW) {
+ output.flip();
break;
+ } else if (result==CoderResult.OVERFLOW) {
+ output = allocateMore(output);
+ continue;
}
- }
-
+ checkCoderResult(result);
output.flip();
if (result.isMalformed()) {
throw new MalformedInputException(result.length());
} else if (result.isUnmappable()) {
throw new UnmappableCharacterException(result.length());
}
+ break;
+ }
status = FLUSH;
return output;
}
@@ -378,10 +381,9 @@
*/
private void checkCoderResult(CoderResult result)
throws CharacterCodingException {
- if (result.isMalformed() && malformAction == CodingErrorAction.REPORT) {
+ if (malformAction == CodingErrorAction.REPORT && result.isMalformed() ) {
throw new MalformedInputException(result.length());
- } else if (result.isUnmappable()
- && unmapAction == CodingErrorAction.REPORT) {
+ } else if (unmapAction == CodingErrorAction.REPORT && result.isUnmappable()) {
throw new UnmappableCharacterException(result.length());
}
}
@@ -478,16 +480,19 @@
} catch (BufferUnderflowException e) {
throw new CoderMalfunctionError(e);
}
- if (result.isUnderflow()) {
- int remaining = in.remaining();
+ if (result==CoderResult.UNDERFLOW) {
status = endOfInput ? END : ONGOING;
- if (endOfInput && remaining > 0) {
+ if (endOfInput) {
+ int remaining = in.remaining();
+ if( remaining > 0) {
result = CoderResult.malformedForLength(remaining);
} else {
return result;
}
+ } else {
+ return result;
}
- if (result.isOverflow()) {
+ } else if (result==CoderResult.OVERFLOW) {
status = endOfInput ? END : ONGOING;
return result;
}
Modified: harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/org/apache/harmony/niochar/charset/ISO_8859_1.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/org/apache/harmony/niochar/charset/ISO_8859_1.java?rev=577294&r1=577293&r2=577294&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/org/apache/harmony/niochar/charset/ISO_8859_1.java (original)
+++ harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/org/apache/harmony/niochar/charset/ISO_8859_1.java Wed Sep 19 05:59:09 2007
@@ -54,52 +54,66 @@
public native int nDecode(char[] array, int arrPosition, int remaining, long outAddr, int absolutePos);
- protected CoderResult decodeLoop(ByteBuffer bb, CharBuffer cb){
- int cbRemaining = cb.remaining();
-
- if(bb.isDirect() && bb.hasRemaining() && cb.hasArray()){
- int toProceed = bb.remaining();
- boolean throwOverflow = false;
- int cbPos = cb.position();
- int bbPos = bb.position();
- if( cbRemaining < toProceed ) {
- toProceed = cbRemaining;
- throwOverflow = true;
- }
- int res = nDecode(cb.array(), cb.arrayOffset()+cbPos, toProceed, AddressUtil.getDirectBufferAddress(bb), bbPos);
- cb.position(cbPos+res);
- bb.position(bbPos+res);
- if(throwOverflow) return CoderResult.OVERFLOW;
- }else{
- if(bb.hasArray() && cb.hasArray()) {
- int rem = bb.remaining();
- rem = cbRemaining >= rem ? rem : cbRemaining;
- byte[] arr = bb.array();
- char[] cArr = cb.array();
- int bStart = bb.position();
- int cStart = cb.position();
- int i;
- for(i=bStart; i<bStart+rem; i++) {
- cArr[cStart++] = (char)((int)arr[i] & 0xFF);
- }
- bb.position(i);
- cb.position(cStart);
- if(rem == cbRemaining && bb.hasRemaining()) return CoderResult.OVERFLOW;
- } else {
- int rem = bb.remaining();
- rem = cbRemaining >= rem ? rem : cbRemaining;
- byte[] arr = new byte[rem];
- bb.get(arr);
- char[] cArr = new char[rem];
- for(int i=0; i<rem; i++) {
- cArr[i] = (char)((int)arr[i] & 0xFF);
- }
- cb.put(cArr); if(cb.remaining() == 0) return CoderResult.OVERFLOW;
- }
- }
- return CoderResult.UNDERFLOW;
+ protected CoderResult decodeLoop(ByteBuffer bb, CharBuffer cb) {
+ int bbRemaining = bb.remaining();
+ if (bbRemaining == 0) {
+ return CoderResult.UNDERFLOW;
+ }
+ int cbRemaining = cb.remaining();
+ boolean cbHasArray = cb.hasArray();
+ if (cbHasArray) {
+ if (bb.hasArray()) {
+ int rem = bbRemaining;
+ rem = cbRemaining >= rem ? rem : cbRemaining;
+ byte[] arr = bb.array();
+ char[] cArr = cb.array();
+ int bStart = bb.position();
+ int cStart = cb.position();
+ int i;
+ for (i = bStart; i < bStart + rem; i++) {
+ cArr[cStart++] = (char) ((int) arr[i] & 0xFF);
+ }
+ bb.position(i);
+ cb.position(cStart);
+ if (rem == cbRemaining && bb.hasRemaining()) {
+ return CoderResult.OVERFLOW;
+ }
+ return CoderResult.UNDERFLOW;
+ } else if (bb.isDirect()) {
+ int toProceed = bbRemaining;
+ boolean throwOverflow = false;
+ int cbPos = cb.position();
+ int bbPos = bb.position();
+ if (cbRemaining < toProceed) {
+ toProceed = cbRemaining;
+ throwOverflow = true;
+ }
+ int res = nDecode(cb.array(), cb.arrayOffset() + cbPos,
+ toProceed, AddressUtil.getDirectBufferAddress(bb),
+ bbPos);
+ cb.position(cbPos + res);
+ bb.position(bbPos + res);
+ if (throwOverflow) {
+ return CoderResult.OVERFLOW;
+ }
+ return CoderResult.UNDERFLOW;
+ }
+ }
+ int rem = bbRemaining;
+ rem = cbRemaining >= rem ? rem : cbRemaining;
+ byte[] arr = new byte[rem];
+ bb.get(arr);
+ char[] cArr = new char[rem];
+ for (int i = 0; i < rem; i++) {
+ cArr[i] = (char) ((int) arr[i] & 0xFF);
+ }
+ cb.put(cArr);
+ if (cb.remaining() == 0) {
+ return CoderResult.OVERFLOW;
+ }
+ return CoderResult.UNDERFLOW;
}
- }
+ }
private final class Encoder extends CharsetEncoder{
private Encoder(Charset cs){
@@ -108,101 +122,116 @@
private native void nEncode(long outAddr, int absolutePos, char[] array, int arrPosition, int[] res);
- protected CoderResult encodeLoop(CharBuffer cb, ByteBuffer bb){
- int bbRemaining = bb.remaining();
- if(bb.isDirect() && cb.hasRemaining() && cb.hasArray()){
- int toProceed = cb.remaining();
- boolean throwOverflow = false;
- int cbPos = cb.position();
- int bbPos = bb.position();
- if( bbRemaining < toProceed ) {
- toProceed = bbRemaining;
- throwOverflow = true;
- }
- int[] res = {toProceed, 0};
- nEncode(AddressUtil.getDirectBufferAddress(bb), bbPos, cb.array(), cb.arrayOffset()+cbPos, res);
- if( res[0] <= 0 ) {
- bb.position(bbPos-res[0]);
- cb.position(cbPos-res[0]);
- if(res[1]!=0) {
- if(res[1] < 0)
- return CoderResult.malformedForLength(-res[1]);
- else
- return CoderResult.unmappableForLength(res[1]);
- }
- }else{
- bb.position(bbPos+res[0]);
- cb.position(cbPos+res[0]);
- if(throwOverflow) return CoderResult.OVERFLOW;
- }
- }else{
- if(bb.hasArray() && cb.hasArray()) {
- byte[] byteArr = bb.array();
- char[] charArr = cb.array();
- int rem = cb.remaining();
- int byteArrStart = bb.position();
- rem = bbRemaining <= rem ? bbRemaining : rem;
- int x;
- for(x=cb.position(); x < cb.position()+rem; x++) {
- char c = charArr[x];
- if(c > (char)0x00FF){
- if (c >= 0xD800 && c <= 0xDFFF) {
- if(x+1 < cb.limit()) {
- char c1 = charArr[x+1];
- if(c1 >= 0xD800 && c1 <= 0xDFFF) {
- bb.position(byteArrStart); cb.position(x);
- return CoderResult.unmappableForLength(2);
- }
- } else {
- bb.position(byteArrStart); cb.position(x);
- return CoderResult.UNDERFLOW;
- }
- bb.position(byteArrStart); cb.position(x);
- return CoderResult.malformedForLength(1);
- }
- bb.position(byteArrStart); cb.position(x);
- return CoderResult.unmappableForLength(1);
- }else{
- byteArr[byteArrStart++] = (byte)c;
- }
- }
- bb.position(byteArrStart);
- cb.position(x);
- if(rem == bbRemaining && cb.hasRemaining()) {
- return CoderResult.OVERFLOW;
- }
- } else {
- while(cb.hasRemaining()){
- if( bbRemaining == 0 ) return CoderResult.OVERFLOW;
- char c = cb.get();
- if(c > (char)0x00FF){
- if (c >= 0xD800 && c <= 0xDFFF) {
- if(cb.hasRemaining()) {
- char c1 = cb.get();
- if(c1 >= 0xD800 && c1 <= 0xDFFF) {
- cb.position(cb.position()-2);
- return CoderResult.unmappableForLength(2);
- } else {
- cb.position(cb.position()-1);
- }
- } else {
- cb.position(cb.position()-1);
- return CoderResult.UNDERFLOW;
- }
- cb.position(cb.position()-1);
- return CoderResult.malformedForLength(1);
- }
- cb.position(cb.position()-1);
- return CoderResult.unmappableForLength(1);
- }else{
- bb.put((byte)c);
- bbRemaining--;
- }
- }
-
- }
- }
- return CoderResult.UNDERFLOW;
+ protected CoderResult encodeLoop(CharBuffer cb, ByteBuffer bb) {
+ int cbRemaining = cb.remaining();
+ if (cbRemaining == 0) {
+ return CoderResult.UNDERFLOW;
+ }
+ int bbRemaining = bb.remaining();
+ boolean cbHasArray = cb.hasArray();
+ boolean bbHasArray = bb.hasArray();
+ if (cbHasArray) {
+ if (bbHasArray) {
+ byte[] byteArr = bb.array();
+ char[] charArr = cb.array();
+ int byteArrStart = bb.position();
+ int rem = bbRemaining <= cbRemaining ? bbRemaining
+ : cbRemaining;
+ int cbPos = cb.position();
+ int x;
+ int jchar = 0;
+ for (x = cbPos; x < cbPos + rem; x++) {
+ jchar = (int) charArr[x];
+ if (jchar <= 0xFF) {
+ byteArr[byteArrStart++] = (byte) jchar;
+ } else {
+ break;
+ }
+ }
+ bb.position(byteArrStart);
+ cb.position(x);
+ if (x == cbPos + rem) {
+ // everything is ok
+ if (rem == bbRemaining && cb.hasRemaining()) {
+ return CoderResult.OVERFLOW;
+ }
+ return CoderResult.UNDERFLOW;
+ }
+ // here is jchar >0xFF
+ if (jchar >= 0xD800 && jchar <= 0xDFFF) {
+ if (x + 1 < cb.limit()) {
+ char c1 = charArr[x + 1];
+ if (c1 >= 0xD800 && c1 <= 0xDFFF) {
+ return CoderResult.unmappableForLength(2);
+ }
+ } else {
+ return CoderResult.UNDERFLOW;
+ }
+ return CoderResult.malformedForLength(1);
+ }
+ return CoderResult.unmappableForLength(1);
+ } else if (bb.isDirect()) {
+ int toProceed = cbRemaining;
+ boolean throwOverflow = false;
+ int cbPos = cb.position();
+ int bbPos = bb.position();
+ if (bbRemaining < toProceed) {
+ toProceed = bbRemaining;
+ throwOverflow = true;
+ }
+ int[] res = { toProceed, 0 };
+ nEncode(AddressUtil.getDirectBufferAddress(bb), bbPos, cb
+ .array(), cb.arrayOffset() + cbPos, res);
+ if (res[0] <= 0) {
+ bb.position(bbPos - res[0]);
+ cb.position(cbPos - res[0]);
+ if (res[1] != 0) {
+ if (res[1] < 0) {
+ return CoderResult.malformedForLength(-res[1]);
+ } else {
+ return CoderResult.unmappableForLength(res[1]);
+ }
+ }
+ } else {
+ bb.position(bbPos + res[0]);
+ cb.position(cbPos + res[0]);
+ if (throwOverflow) {
+ return CoderResult.OVERFLOW;
+ }
+ }
+ return CoderResult.UNDERFLOW;
+ }
+ }
+ while (cb.hasRemaining()) {
+ if (bbRemaining == 0) {
+ return CoderResult.OVERFLOW;
+ }
+ char c = cb.get();
+ if (c > (char) 0x00FF) {
+ if (c >= 0xD800 && c <= 0xDFFF) {
+ if (cb.hasRemaining()) {
+ char c1 = cb.get();
+ if (c1 >= 0xD800 && c1 <= 0xDFFF) {
+ cb.position(cb.position() - 2);
+ return CoderResult.unmappableForLength(2);
+ } else {
+ cb.position(cb.position() - 1);
+ }
+ } else {
+ cb.position(cb.position() - 1);
+ return CoderResult.UNDERFLOW;
+ }
+ cb.position(cb.position() - 1);
+ return CoderResult.malformedForLength(1);
+ }
+ cb.position(cb.position() - 1);
+ return CoderResult.unmappableForLength(1);
+ } else {
+ bb.put((byte) c);
+ bbRemaining--;
+ }
+ }
+ return CoderResult.UNDERFLOW;
}
}
Modified: harmony/enhanced/classlib/trunk/modules/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetTest.java?rev=577294&r1=577293&r2=577294&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetTest.java Wed Sep 19 05:59:09 2007
@@ -156,15 +156,15 @@
/*
* 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();
- }
+// 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
*/
@@ -218,14 +218,14 @@
/*
* 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);
- }
+// 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