static void escape(final Reader reader, final Writer writer) throws IOException {

        if (reader == null) {
            return;
        }

        /*
         * Escape in CSV requires using buffers because CSV escaped text might be surrounded by quotes or not
         * depending on whether they contain any non-alphanumeric chars or not, which is something we cannot
         * know until we find any.
         */

        int doQuote = -1;

        int bufferSize = 0;
        char[] buffer = new char[10];

        int read = reader.read(buffer, 0, buffer.length);
        if (read < 0) {
            return;
        }

        char cq;
        while (doQuote < 0 && read >= 0) {

            int i = bufferSize;
            bufferSize += read;

            while (doQuote < 0 && i < bufferSize) {
                cq = buffer[i++];
                if (!((cq >= 'a' && cq <= 'z') || (cq >= 'A' && cq <= 'Z') || (cq >= '0' && cq <= '9'))) {
                    doQuote = 1; // We must add quotes!
                    break;
                }
            }

            if (doQuote < 0 && read >= 0) {

                if (bufferSize == buffer.length) {
                    // Actually, there is no room for reading more, so let's grow the buffer
                    final char[] newBuffer = new char[buffer.length + (buffer.length / 2)];
                    System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
                    buffer = newBuffer;
                }

                read = reader.read(buffer, bufferSize, (buffer.length - bufferSize));

            }

        }

        doQuote = Math.max(doQuote, 0); // 0 = no quote, 1 = quote


        /*
         * Output initial quotes, if needed
         */
        if (doQuote == 1) {
            writer.write('"');
        }


        /*
         * First we will output the already-checked buffer, escaping quotes as needed
         */
        if (bufferSize > 0) {

            char c;
            for (int i = 0; i < bufferSize; i++) {

                c = buffer[i];

                /*
                 * Check whether the character is a double-quote (in which case, we escape it)
                 */
                if (c == DOUBLE_QUOTE) {
                    writer.write(TWO_DOUBLE_QUOTES);
                } else {
                    writer.write(c);
                }

            }

        }


        /*
         * Once the buffer has been processed, we will process the rest of the input by reading it on-the-fly
         */
        if (read >= 0) {

            int c1, c2; // c1: current char, c2: next char

            c1 = -1;
            c2 = reader.read();

            while (c2 >= 0) {

                c1 = c2;
                c2 = reader.read();

                /*
                 * Check whether the character is a double-quote (in which case, we escape it)
                 */
                if (c1 == DOUBLE_QUOTE) {
                    writer.write(TWO_DOUBLE_QUOTES);
                } else {
                    writer.write(c1);
                }

            }

        }


        /*
         * Output ending quotes, if needed
         */
        if (doQuote == 1) {
            writer.write('"');
        }

    }
static void escape ( final Reader reader , final Writer writer ) throws IOException { if ( reader == null ) { return ; } int doQuote = - 1 ; int bufferSize = 0 ; char [ ] buffer = new char [ 10 ] ; int read = reader . read ( buffer , 0 , buffer . length ) ; if ( read < 0 ) { return ; } char cq ; while ( doQuote < 0 && read >= 0 ) { int i = bufferSize ; bufferSize += read ; while ( doQuote < 0 && i < bufferSize ) { cq = buffer [ i ++ ] ; if ( ! ( ( cq >= 'a' && cq <= 'z' ) || ( cq >= 'A' && cq <= 'Z' ) || ( cq >= '0' && cq <= '9' ) ) ) { doQuote = 1 ; break ; } } if ( doQuote < 0 && read >= 0 ) { if ( bufferSize == buffer . length ) { final char [ ] newBuffer = new char [ buffer . length + ( buffer . length / 2 ) ] ; System . arraycopy ( buffer , 0 , newBuffer , 0 , buffer . length ) ; buffer = newBuffer ; } read = reader . read ( buffer , bufferSize , ( buffer . length - bufferSize ) ) ; } } doQuote = Math . max ( doQuote , 0 ) ; if ( doQuote == 1 ) { writer . write ( '"' ) ; } if ( bufferSize > 0 ) { char c ; for ( int i = 0 ; i < bufferSize ; i ++ ) { c = buffer [ i ] ; if ( c == DOUBLE_QUOTE ) { writer . write ( TWO_DOUBLE_QUOTES ) ; } else { writer . write ( c ) ; } } } if ( read >= 0 ) { int c1 , c2 ; c1 = - 1 ; c2 = reader . read ( ) ; while ( c2 >= 0 ) { c1 = c2 ; c2 = reader . read ( ) ; if ( c1 == DOUBLE_QUOTE ) { writer . write ( TWO_DOUBLE_QUOTES ) ; } else { writer . write ( c1 ) ; } } } if ( doQuote == 1 ) { writer . write ( '"' ) ; } }
/*
Perform an escape operation, based on a Reader, writing the results to a Writer.

Note this reader is going to be read char-by-char, so some kind of buffering might be appropriate if this
is an inconvenience for the specific Reader implementation.