You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by ve...@apache.org on 2016/05/14 11:45:29 UTC

svn commit: r1743812 - /webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/stream/serializer/OutputStreamXmlWriter.java

Author: veithen
Date: Sat May 14 11:45:29 2016
New Revision: 1743812

URL: http://svn.apache.org/viewvc?rev=1743812&view=rev
Log:
Improve the unmappable code handling logic to reduce code duplication.

Modified:
    webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/stream/serializer/OutputStreamXmlWriter.java

Modified: webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/stream/serializer/OutputStreamXmlWriter.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/stream/serializer/OutputStreamXmlWriter.java?rev=1743812&r1=1743811&r2=1743812&view=diff
==============================================================================
--- webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/stream/serializer/OutputStreamXmlWriter.java (original)
+++ webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/stream/serializer/OutputStreamXmlWriter.java Sat May 14 11:45:29 2016
@@ -31,7 +31,8 @@ final class OutputStreamXmlWriter extend
     private final CharBuffer encoderIn;
     private final ByteBuffer encoderOut;
     private final CharsetEncoder encoder;
-    private CharBuffer characterReferenceBuffer;
+    private boolean processingUnmappableCharacter;
+    private CharBuffer encoderInAlt;
 
     OutputStreamXmlWriter(OutputStream out, Charset charset) {
         this.out = out;
@@ -45,71 +46,69 @@ final class OutputStreamXmlWriter extend
         encoderOut.clear();
     }
 
-    private void flushEncodingIn(boolean force) throws IOException {
-        if (force || !encoderIn.hasRemaining()) {
-            encoderIn.flip();
-            while (true) {
-                CoderResult coderResult = encoder.encode(encoderIn, encoderOut, false);
-                if (coderResult.isUnderflow()) {
-                    encoderIn.compact();
-                    break;
-                } else if (coderResult.isOverflow()) {
-                    flushEncodingOut();
-                } else if (coderResult.isUnmappable()) {
-                    // Note that we can't use writeCharacterReference here because we are still
-                    // processing the encoderIn buffer
-                    switch (coderResult.length()) {
-                        case 1:
-                            insertCharacterReference(encoderIn.get());
-                            break;
-                        case 2:
-                            throw new UnsupportedOperationException("TODO");
-                        default:
-                            throw new IllegalStateException();
-                    }
-                } else {
-                    throw new IOException("Malformed character sequence");
-                }
+    private CharBuffer getEncoderIn() throws IOException {
+        if (processingUnmappableCharacter) {
+            if (encoderInAlt == null) {
+                encoderInAlt = CharBuffer.allocate(64);
             }
+            return encoderInAlt;
+        } else {
+            return encoderIn;
         }
     }
 
-    private void insertCharacterReference(int codePoint) throws IOException {
-        CharBuffer buffer = characterReferenceBuffer;
-        if (characterReferenceBuffer == null) {
-            buffer = characterReferenceBuffer = CharBuffer.allocate(16);
-        } else {
-            buffer.clear();
-        }
-        buffer.put("&#");
-        // TODO: optimize this
-        buffer.put(Integer.toString(codePoint));
-        buffer.put(';');
-        buffer.flip();
+    private void flush(CharBuffer encoderIn) throws IOException {
+        encoderIn.flip();
         while (true) {
-            CoderResult coderResult = encoder.encode(buffer, encoderOut, false);
+            CoderResult coderResult = encoder.encode(encoderIn, encoderOut, false);
             if (coderResult.isUnderflow()) {
+                encoderIn.compact();
                 break;
             } else if (coderResult.isOverflow()) {
                 flushEncodingOut();
+            } else if (coderResult.isUnmappable()) {
+                if (processingUnmappableCharacter) {
+                    throw new IllegalStateException();
+                }
+                processingUnmappableCharacter = true;
+                try {
+                    switch (coderResult.length()) {
+                        case 1:
+                            writeCharacterReference(encoderIn.get());
+                            break;
+                        case 2:
+                            throw new UnsupportedOperationException("TODO");
+                        default:
+                            throw new IllegalStateException();
+                    }
+                    flush(encoderInAlt);
+                } finally {
+                    processingUnmappableCharacter = false;
+                }
             } else {
-                throw new IllegalStateException();
+                throw new IOException("Malformed character sequence");
             }
         }
     }
 
     @Override
     void write(char c) throws IOException {
-        flushEncodingIn(false);
+        CharBuffer encoderIn = getEncoderIn();
+        if (!encoderIn.hasRemaining()) {
+            flush(encoderIn);
+        }
         encoderIn.put(c);
     }
 
     @Override
     void write(String src) throws IOException {
+        CharBuffer encoderIn = getEncoderIn();
         int offset = 0;
         int length = src.length();
         while (length > 0) {
-            flushEncodingIn(false);
+            if (!encoderIn.hasRemaining()) {
+                flush(encoderIn);
+            }
             int c = Math.min(length, encoderIn.remaining());
             encoderIn.put(src, offset, length);
             offset += c;
@@ -119,8 +118,11 @@ final class OutputStreamXmlWriter extend
 
     @Override
     void write(char[] src, int offset, int length) throws IOException {
+        CharBuffer encoderIn = getEncoderIn();
         while (length > 0) {
-            flushEncodingIn(false);
+            if (!encoderIn.hasRemaining()) {
+                flush(encoderIn);
+            }
             int c = Math.min(length, encoderIn.remaining());
             encoderIn.put(src, offset, length);
             offset += c;
@@ -130,7 +132,7 @@ final class OutputStreamXmlWriter extend
 
     @Override
     void flushBuffer() throws IOException {
-        flushEncodingIn(true);
+        flush(encoderIn);
         flushEncodingOut();
     }
 }