You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by eb...@apache.org on 2012/03/06 01:48:34 UTC

svn commit: r1297309 - /commons/sandbox/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java

Author: ebourg
Date: Tue Mar  6 00:48:34 2012
New Revision: 1297309

URL: http://svn.apache.org/viewvc?rev=1297309&view=rev
Log:
Changed CSVPrinter to print to any Appendable and optimized the internals to avoid string copies

Modified:
    commons/sandbox/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java

Modified: commons/sandbox/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java
URL: http://svn.apache.org/viewvc/commons/sandbox/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java?rev=1297309&r1=1297308&r2=1297309&view=diff
==============================================================================
--- commons/sandbox/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java (original)
+++ commons/sandbox/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java Tue Mar  6 00:48:34 2012
@@ -17,8 +17,8 @@
 
 package org.apache.commons.csv;
 
+import java.io.Flushable;
 import java.io.IOException;
-import java.io.Writer;
 
 /**
  * Print values as a comma separated list.
@@ -26,15 +26,12 @@ import java.io.Writer;
 public class CSVPrinter {
 
     /** The place that the values get written. */
-    private final Writer out;
+    private final Appendable out;
     private final CSVFormat format;
 
     /** True if we just began a new line. */
     private boolean newLine = true;
 
-    /** Temporary buffer */
-    private char[] buf = new char[0];  
-
     /**
      * Create a printer that will print values to the given stream following the CSVFormat.
      * <p/>
@@ -44,7 +41,7 @@ public class CSVPrinter {
      * @param out    stream to which to print.
      * @param format describes the CSV variation.
      */
-    public CSVPrinter(Writer out, CSVFormat format) {
+    public CSVPrinter(Appendable out, CSVFormat format) {
         this.out = out;
         this.format = format == null ? CSVFormat.DEFAULT : format;
     }
@@ -57,7 +54,7 @@ public class CSVPrinter {
      * Output a blank line
      */
     public void println() throws IOException {
-        out.write(format.getLineSeparator());
+        out.append(format.getLineSeparator());
         newLine = true;
     }
 
@@ -67,10 +64,11 @@ public class CSVPrinter {
      * @throws IOException
      */
     public void flush() throws IOException {
-        out.flush();
+        if (out instanceof Flushable) {
+            ((Flushable) out).flush();
+        }
     }
 
-
     /**
      * Print a single line of comma separated values.
      * The values will be quoted if needed.  Quotes and
@@ -103,8 +101,8 @@ public class CSVPrinter {
         if (!newLine) {
             println();
         }
-        out.write(format.getCommentStart());
-        out.write(' ');
+        out.append(format.getCommentStart());
+        out.append(' ');
         for (int i = 0; i < comment.length(); i++) {
             char c = comment.charAt(i);
             switch (c) {
@@ -115,11 +113,11 @@ public class CSVPrinter {
                     // break intentionally excluded.
                 case '\n':
                     println();
-                    out.write(format.getCommentStart());
-                    out.write(' ');
+                    out.append(format.getCommentStart());
+                    out.append(' ');
                     break;
                 default:
-                    out.write(c);
+                    out.append(c);
                     break;
             }
         }
@@ -127,14 +125,14 @@ public class CSVPrinter {
     }
 
 
-    private void print(char[] value, int offset, int len) throws IOException {        
+    private void print(CharSequence value, int offset, int len) throws IOException {        
         if (format.isEncapsulating()) {
             printAndEncapsulate(value, offset, len);
         } else if (format.isEscaping()) {
             printAndEscape(value, offset, len);
         } else {
             printSep();
-            out.write(value, offset, len);
+            out.append(value, offset, offset + len);
         }
     }
 
@@ -142,11 +140,11 @@ public class CSVPrinter {
         if (newLine) {
             newLine = false;
         } else {
-            out.write(format.getDelimiter());
+            out.append(format.getDelimiter());
         }
     }
 
-    void printAndEscape(char[] value, int offset, int len) throws IOException {
+    void printAndEscape(CharSequence value, int offset, int len) throws IOException {
         int start = offset;
         int pos = offset;
         int end = offset + len;
@@ -157,12 +155,11 @@ public class CSVPrinter {
         char escape = format.getEscape();
 
         while (pos < end) {
-            char c = value[pos];
+            char c = value.charAt(pos);
             if (c == '\r' || c == '\n' || c == delim || c == escape) {
                 // write out segment up until this char
-                int l = pos - start;
-                if (l > 0) {
-                    out.write(value, start, l);
+                if (pos > start) {
+                    out.append(value, start, pos);
                 }
                 if (c == '\n') {
                     c = 'n';
@@ -170,8 +167,8 @@ public class CSVPrinter {
                     c = 'r';
                 }
 
-                out.write(escape);
-                out.write(c);
+                out.append(escape);
+                out.append(c);
 
                 start = pos + 1; // start on the current char after this one
             }
@@ -180,13 +177,12 @@ public class CSVPrinter {
         }
 
         // write last segment
-        int l = pos - start;
-        if (l > 0) {
-            out.write(value, start, l);
+        if (pos > start) {
+            out.append(value, start, pos);
         }
     }
 
-    void printAndEncapsulate(char[] value, int offset, int len) throws IOException {
+    void printAndEncapsulate(CharSequence value, int offset, int len) throws IOException {
         boolean first = newLine;  // is this the first value on this line?
         boolean quote = false;
         int start = offset;
@@ -207,7 +203,7 @@ public class CSVPrinter {
                 quote = true;
             }
         } else {
-            char c = value[pos];
+            char c = value.charAt(pos);
 
             // Hmmm, where did this rule come from?
             if (first
@@ -224,7 +220,7 @@ public class CSVPrinter {
                 quote = true;
             } else {
                 while (pos < end) {
-                    c = value[pos];
+                    c = value.charAt(pos);
                     if (c == '\n' || c == '\r' || c == encapsulator || c == delim) {
                         quote = true;
                         break;
@@ -234,7 +230,7 @@ public class CSVPrinter {
 
                 if (!quote) {
                     pos = end - 1;
-                    c = value[pos];
+                    c = value.charAt(pos);
                     // if (c == ' ' || c == '\f' || c == '\t') {
                     // Some other chars at the end caused the parser to fail, so for now
                     // encapsulate if we end in anything less than ' '
@@ -247,22 +243,22 @@ public class CSVPrinter {
 
         if (!quote) {
             // no encapsulation needed - write out the original value
-            out.write(value, offset, len);
+            out.append(value, start, end);
             return;
         }
 
         // we hit something that needed encapsulation
-        out.write(encapsulator);
+        out.append(encapsulator);
 
         // Pick up where we left off: pos should be positioned on the first character that caused
         // the need for encapsulation.
         while (pos < end) {
-            char c = value[pos];
+            char c = value.charAt(pos);
             if (c == encapsulator) {
                 // write out the chunk up until this point
 
                 // add 1 to the length to write out the encapsulator also
-                out.write(value, start, pos - start + 1);
+                out.append(value, start, pos + 1);
                 // put the next starting position on the encapsulator so we will
                 // write it out again with the next string (effectively doubling it)
                 start = pos;
@@ -271,8 +267,8 @@ public class CSVPrinter {
         }
 
         // write the last segment
-        out.write(value, start, pos - start);
-        out.write(encapsulator);
+        out.append(value, start, pos);
+        out.append(encapsulator);
     }
 
     /**
@@ -290,16 +286,10 @@ public class CSVPrinter {
         if (!checkForEscape) {
             // write directly from string
             printSep();
-            out.write(value);
-            return;
-        }
-
-        if (buf.length < value.length()) {
-            buf = new char[value.length()];
+            out.append(value);
+        } else {
+            print(value, 0, value.length());
         }
-
-        value.getChars(0, value.length(), buf, 0);
-        print(buf, 0, value.length());
     }
 
     /**