You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by br...@apache.org on 2002/04/03 06:37:30 UTC

cvs commit: jakarta-commons-sandbox/net/src/java/org/apache/commons/io CopyStreamAdapter.java CopyStreamEvent.java CopyStreamException.java CopyStreamListener.java DotTerminatedMessageReader.java DotTerminatedMessageWriter.java FromNetASCIIInputStream.java FromNetASCIIOutputStream.java SocketInputStream.java SocketOutputStream.java ToNetASCIIInputStream.java ToNetASCIIOutputStream.java Util.java

brekke      02/04/02 20:37:30

  Added:       net/src/java/org/apache/commons/io CopyStreamAdapter.java
                        CopyStreamEvent.java CopyStreamException.java
                        CopyStreamListener.java
                        DotTerminatedMessageReader.java
                        DotTerminatedMessageWriter.java
                        FromNetASCIIInputStream.java
                        FromNetASCIIOutputStream.java
                        SocketInputStream.java SocketOutputStream.java
                        ToNetASCIIInputStream.java
                        ToNetASCIIOutputStream.java Util.java
  Log:
  Moving com.oroinc.io to org.apache.common.io package for now.
  
  Revision  Changes    Path
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/io/CopyStreamAdapter.java
  
  Index: CopyStreamAdapter.java
  ===================================================================
  package org.apache.commons.io;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.util.*;
  
  import org.apache.commons.util.ListenerList;
  
  /***
   * The CopyStreamAdapter will relay CopyStreamEvents to a list of listeners
   * when either of its bytesTransferred() methods are called.  Its purpose
   * is to facilitate the notification of the progress of a copy operation
   * performed by one of the static copyStream() methods in org.apache.commons.io.Util
   * to multiple listeners.  The static copyStream() methods invoke the
   * bytesTransfered(long, int) of a CopyStreamListener for performance
   * reasons and also because multiple listeners cannot be registered given
   * that the methods are static.
   * <p>
   * <p>
   * @see CopyStreamEvent
   * @see CopyStreamListener
   * @see Util
   * @author Daniel F. Savarese
   ***/
  
  public class CopyStreamAdapter implements CopyStreamListener {
    private ListenerList __listeners;
  
    /***
     * Creates a new copyStreamAdapter.
     ***/
    public CopyStreamAdapter() {
      __listeners = new ListenerList();
    }
  
    /***
     * This method is invoked by a CopyStreamEvent source after copying
     * a block of bytes from a stream.  The CopyStreamEvent will contain
     * the total number of bytes transferred so far and the number of bytes
     * transferred in the last write.  The CopyStreamAdapater will relay
     * the event to all of its registered listeners, listing itself as the
     * source of the event.
     * <p>
     * @param event The CopyStreamEvent fired by the copying of a block of
     *              bytes.
     ***/
    public void bytesTransferred(CopyStreamEvent event) {
      bytesTransferred(event.getTotalBytesTransferred(),
  		     event.getBytesTransferred(),
  		     event.getStreamSize());
    }
  
  
    /***
     * This method is not part of the JavaBeans model and is used by the
     * static methods in the org.apache.commons.io.Util class for efficiency.
     * It is invoked after a block of bytes to inform the listener of the
     * transfer.  The CopyStreamAdapater will create a CopyStreamEvent
     * from the arguments and relay the event to all of its registered
     * listeners, listing itself as the source of the event.
     * <p>
     * @param totalBytesTransferred  The total number of bytes transferred
     *         so far by the copy operation.
     * @param bytesTransferred  The number of bytes copied by the most recent
     *          write.
     * @param streamSize The number of bytes in the stream being copied.
     *        This may be equal to CopyStreamEvent.UNKNOWN_STREAM_SIZE if
     *        the size is unknown.
     ***/
    public void bytesTransferred(long totalBytesTransferred,
  			       int bytesTransferred, long streamSize)
    {
      Enumeration listeners;
      CopyStreamEvent event;
  
      listeners = __listeners.getListeners();
  
      event = new CopyStreamEvent(this, totalBytesTransferred, bytesTransferred,
  				streamSize);
  
      while(listeners.hasMoreElements())
        ((CopyStreamListener)(listeners.nextElement())).bytesTransferred(event);
    }
  
  
    /***
     * Registers a CopyStreamListener to receive CopyStreamEvents.
     * Although this method is not declared to be synchronized, it is
     * implemented in a thread safe manner.
     * <p>
     * @param listener  The CopyStreamlistener to register.
     ***/
    public void addCopyStreamListener(CopyStreamListener listener) {
      __listeners.addListener(listener);
    }
  
    /***
     * Unregisters a CopyStreamListener.  Although this method is not
     * synchronized, it is implemented in a thread safe manner.
     * <p>
     * @param listener  The CopyStreamlistener to unregister.
     ***/
    public void removeCopyStreamListener(CopyStreamListener listener){
      __listeners.removeListener(listener);
    }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/io/CopyStreamEvent.java
  
  Index: CopyStreamEvent.java
  ===================================================================
  package org.apache.commons.io;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.util.*;
  
  /***
   * A CopyStreamEvent is triggered after every write performed by a
   * stream copying operation.  The event stores the number of bytes
   * transferred by the write triggering the event as well as the total
   * number of bytes transferred so far by the copy operation.
   * <p>
   * <p>
   * @see CopyStreamListener
   * @see CopyStreamAdapter
   * @see Util
   * @author Daniel F. Savarese
   ***/
  
  public class CopyStreamEvent extends EventObject {
    public static final long UNKNOWN_STREAM_SIZE = -1;
  
    private int __bytesTransferred;
    private long __totalBytesTransferred, __streamSize;
  
    /***
     * Creates a new CopyStreamEvent instance.
     * <p>
     * @param source  The source of the event.
     * @param totalBytesTransferred The total number of bytes transferred so
     *   far during a copy operation.
     * @param bytesTransferred  The number of bytes transferred during the
     *        write that triggered the CopyStreamEvent.
     * @param streamSize  The number of bytes in the stream being copied.
     *          This may be set to <code>UNKNOWN_STREAM_SIZE</code> if the
     *          size is unknown.
     ***/
    public CopyStreamEvent(Object source, long totalBytesTransferred,
  			 int bytesTransferred, long streamSize)
    {
      super(source);
      __bytesTransferred = bytesTransferred;
      __totalBytesTransferred = totalBytesTransferred;
    }
  
    /***
     * Returns the number of bytes transferred by the write that triggered
     * the event.
     * <p>
     * @return The number of bytes transferred by the write that triggered
     * the vent.
     ***/
    public int getBytesTransferred() { return __bytesTransferred; }
  
    /***
     * Returns the total number of bytes transferred so far by the copy
     * operation.
     * <p>
     * @return The total number of bytes transferred so far by the copy
     * operation.
     ***/
    public long getTotalBytesTransferred() { return __totalBytesTransferred; }
  
    /***
     * Returns the size of the stream being copied.
     * This may be set to <code>UNKNOWN_STREAM_SIZE</code> if the
     * size is unknown.
     * <p>
     * @return The size of the stream being copied.
     ***/
    public long getStreamSize() { return __streamSize; }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/io/CopyStreamException.java
  
  Index: CopyStreamException.java
  ===================================================================
  package org.apache.commons.io;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.*;
  
  
  /***
   * The CopyStreamException class is thrown by the org.apache.commons.io.Util
   * copyStream() methods.  It stores the number of bytes confirmed to
   * have been transferred before an I/O error as well as the IOException
   * responsible for the failure of a copy operation.
   * <p>
   * <p>
   * @see Util
   * @author Daniel F. Savarese
   ***/
  
  public class CopyStreamException extends IOException {
    private long __bytesTransferred;
    private IOException __exception;
  
    /***
     * Creates a new CopyStreamException instance.
     * <p>
     * @param message  A message describing the error.
     * @param bytesTransferred  The total number of bytes transferred before
     *        an exception was thrown in a copy operation.
     * @param exception  The IOException thrown during a copy operation.
     ***/
    public CopyStreamException(String message, long bytesTransferred,
  			     IOException exception)
    {
      super(message);
      __bytesTransferred = bytesTransferred;
      __exception = exception;
    }
  
    /***
     * Returns the total number of bytes confirmed to have been transferred by a 
     * failed copy operation.
     * <p>
     * @return The total number of bytes confirmed to have been transferred by a 
     * failed copy operation.
     ***/
    public long getTotalBytesTransferred() { return __bytesTransferred; }
  
  
    /***
     * Returns the IOException responsible for the failure of a copy operation.
     * <p>
     * @return The IOException responsible for the failure of a copy operation.
     ***/
    public IOException getIOException() { return __exception; }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/io/CopyStreamListener.java
  
  Index: CopyStreamListener.java
  ===================================================================
  package org.apache.commons.io;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.util.*;
  
  
  /***
   * The CopyStreamListener class can accept CopyStreamEvents to keep track
   * of the progress of a stream copying operation.  However, it is currently
   * not used that way within NetComponents for performance reasons.  Rather
   * the bytesTransferred(long, int) method is called directly rather than
   * passing an event to bytesTransferred(CopyStreamEvent), saving the creation
   * of a CopyStreamEvent instance.  Also, the only place where
   * CopyStreamListener is currently used within NetComponents is in the
   * static methods of the uninstantiable org.apache.commons.io.Util class, which
   * would preclude the use of addCopyStreamListener and
   * removeCopyStreamListener methods.  However, future additions may use the
   * JavaBean event model, which is why the hooks have been included from the
   * beginning.
   * <p>
   * <p>
   * @see CopyStreamEvent
   * @see CopyStreamAdapter
   * @see Util
   * @author Daniel F. Savarese
   ***/
  
  public interface CopyStreamListener extends EventListener {
  
    /***
     * This method is invoked by a CopyStreamEvent source after copying
     * a block of bytes from a stream.  The CopyStreamEvent will contain
     * the total number of bytes transferred so far and the number of bytes
     * transferred in the last write.
     * <p>
     * @param event The CopyStreamEvent fired by the copying of a block of
     *              bytes.
     ***/
    public void bytesTransferred(CopyStreamEvent event);
  
  
    /***
     * This method is not part of the JavaBeans model and is used by the
     * static methods in the org.apache.commons.io.Util class for efficiency.
     * It is invoked after a block of bytes to inform the listener of the
     * transfer.
     * <p>
     * @param totalBytesTransferred  The total number of bytes transferred
     *         so far by the copy operation.
     * @param bytesTransferred  The number of bytes copied by the most recent
     *          write.
     * @param streamSize The number of bytes in the stream being copied.
     *        This may be equal to CopyStreamEvent.UNKNOWN_STREAM_SIZE if
     *        the size is unknown.
     ***/
    public void bytesTransferred(long totalBytesTransferred,
  			       int bytesTransferred,
  			       long streamSize);
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/io/DotTerminatedMessageReader.java
  
  Index: DotTerminatedMessageReader.java
  ===================================================================
  package org.apache.commons.io;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.*;
  import java.util.*;
  
  /***
   * DotTerminatedMessageReader is a class used to read messages from a
   * server that are terminated by a single dot followed by a 
   * &lt;CR&gt;&lt;LF&gt;
   * sequence and with double dots appearing at the begining of lines which
   * do not signal end of message yet start with a dot.  Various Internet
   * protocols such as NNTP and POP3 produce messages of this type.
   * <p>
   * This class handles stripping of the duplicate period at the beginning
   * of lines starting with a period, converts NETASCII newlines to the
   * local line separator format, truncates the end of message indicator,
   * and ensures you cannot read past the end of the message.
   * <p>
   * <p>
   * @author Daniel F. Savarese
   ***/
  
  public final class DotTerminatedMessageReader extends Reader {
    private static final String __lineSeparator;
    private static final char[] __lineSeparatorChars;
  
    static {
      __lineSeparator        = System.getProperty("line.separator");
      __lineSeparatorChars   = __lineSeparator.toCharArray();
    }
  
    private boolean __atBeginning, __eof;
    private int __pos;
    private char[] __buffer;
    private PushbackReader __in;
  
    /***
     * Creates a DotTerminatedMessageReader that wraps an existing Reader
     * input source.
     * <p>
     * @param reader  The Reader input source containing the message.
     ***/
    public DotTerminatedMessageReader(Reader reader) {
      super(reader);
      __buffer = new char[__lineSeparatorChars.length + 3];
      __pos    = __buffer.length;
      // Assumes input is at start of message
      __atBeginning = true;
      __eof         = false;
      __in = new PushbackReader(reader);
    }
  
  
    /***
     * Reads and returns the next character in the message.  If the end of the
     * message has been reached, returns -1.  Note that a call to this method
     * may result in multiple reads from the underlying input stream to decode
     * the message properly (removing doubled dots and so on).  All of
     * this is transparent to the programmer and is only mentioned for
     * completeness.
     * <p>
     * @return The next character in the message. Returns -1 if the end of the
     *          message has been reached.
     * @exception IOException If an error occurs while reading the underlying
     *            stream.
     ***/
    public int read() throws IOException {
      int ch;
  
      synchronized(lock) {
        if(__pos < __buffer.length)
  	return __buffer[__pos++];
  
        if(__eof)
  	return -1;
  
        if((ch = __in.read()) == -1) {
  	__eof = true;
  	return -1;
        }
  
        if(__atBeginning) {
  	__atBeginning = false;
  	if(ch == '.') {
  	  ch = __in.read();
  
  	  if(ch != '.') {
  	    // read newline
  	    __eof = true;
  	    __in.read();
  	    return -1;
  	  } else
  	    return '.';
  	}
        }
  
        if(ch == '\r') {
  	ch = __in.read();
  
  	if(ch == '\n') {
  	  ch = __in.read();
  
  	  if(ch == '.') {
  	    ch = __in.read();
  
  	    if(ch != '.') {
  	      // read newline and indicate end of file
  	      __in.read();
  	      __eof = true;
  	    } else
  	      __buffer[--__pos] = (char)ch;
  	  } else
  	    __in.unread(ch);
  
  	  __pos-=__lineSeparatorChars.length;
  	  System.arraycopy(__lineSeparatorChars, 0, __buffer, __pos,
  			   __lineSeparatorChars.length);
  	  ch = __buffer[__pos++];
  	} else {
  	  __buffer[--__pos] = (char)ch;
  	  return '\r';
  	}
        }
  
        return ch;
      }
    }
  
  
    /***
     * Reads the next characters from the message into an array and
     * returns the number of characters read.  Returns -1 if the end of the
     * message has been reached.
     * <p>
     * @param buffer  The character array in which to store the characters.
     * @return The number of characters read. Returns -1 if the
     *          end of the message has been reached.
     * @exception IOException If an error occurs in reading the underlying
     *            stream.
     ***/
    public int read(char[] buffer) throws IOException {
      return read(buffer, 0, buffer.length);
    }                 
  
  
    /***
     * Reads the next characters from the message into an array and
     * returns the number of characters read.  Returns -1 if the end of the
     * message has been reached.  The characters are stored in the array
     * starting from the given offset and up to the length specified.
     * <p>
     * @param bufffer  The character array in which to store the characters.
     * @param offset   The offset into the array at which to start storing
     *              characters.
     * @param length   The number of characters to read.
     * @return The number of characters read. Returns -1 if the
     *          end of the message has been reached.
     * @exception IOException If an error occurs in reading the underlying
     *            stream.
     ***/
    public int read(char[] buffer, int offset, int length) throws IOException {
      int ch, off;
      synchronized(lock) {
        if(length < 1)
  	return 0;
  
        if((ch = read()) == -1)
  	return -1;
  
        off = offset;
  
        do {
  	buffer[offset++] = (char)ch;
        } while(--length > 0 && (ch = read()) != -1);
  
        return (offset - off);
      }
    }
  
  
    /***
     * Determines if the message is ready to be read.
     * <p>
     * @return True if the message is ready to be read, false if not.
     * @exception IOException If an error occurs while checking the underlying
     *            stream.
     ***/
    public boolean ready() throws IOException {
      synchronized(lock) {
        return (__pos < __buffer.length || __in.ready());
      }
    }
  
  
    /***
     * Closes the message for reading.  This doesn't actually close the
     * underlying stream.  The underlying stream may still be used for 
     * communicating with the server and therefore is not closed.
     * <p>
     * If the end of the message has not yet been reached, this method
     * will read the remainder of the message until it reaches the end,
     * so that the underlying stream may continue to be used properly
     * for communicating with the server.  If you do not fully read
     * a message, you MUST close it, otherwise your program will likely
     * hang or behave improperly.
     * <p>
     * @exception IOException  If an error occurs while reading the
     *            underlying stream.
     ***/
    public void close() throws IOException {
      synchronized(lock) {
        if(__in == null)
  	return;
  
        if(!__eof)
  	while(read() != -1);
  
        __eof         = true;
        __atBeginning = false;
        __pos         = __buffer.length;
        __in          = null;
      }
    }
  
  }
  
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/io/DotTerminatedMessageWriter.java
  
  Index: DotTerminatedMessageWriter.java
  ===================================================================
  package org.apache.commons.io;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.*;
  import java.util.*;
  
  /***
   * DotTerminatedMessageWriter is a class used to write messages to a
   * server that are terminated by a single dot followed by a
   * &lt;CR&gt;&lt;LF&gt;
   * sequence and with double dots appearing at the begining of lines which
   * do not signal end of message yet start with a dot.  Various Internet
   * protocols such as NNTP and POP3 produce messages of this type.
   * <p>
   * This class handles the doubling of line-starting periods,
   * converts single linefeeds to NETASCII newlines, and on closing
   * will send the final message terminator dot and NETASCII newline
   * sequence.
   * <p>
   * <p>
   * @author Daniel F. Savarese
   ***/
  
  public final class DotTerminatedMessageWriter extends Writer {
    private static final int __NOTHING_SPECIAL_STATE = 0;
    private static final int __LAST_WAS_CR_STATE     = 1;
    private static final int __LAST_WAS_NL_STATE     = 2;
  
    private int __state;
    private Writer __output;
  
  
    /***
     * Creates a DotTerminatedMessageWriter that wraps an existing Writer
     * output destination.
     * <p>
     * @param output  The Writer output destination to write the message.
     ***/
    public DotTerminatedMessageWriter(Writer output) {
      super(output);
      __output = output;
      __state = __NOTHING_SPECIAL_STATE;
    }
  
  
    /***
     * Writes a character to the output.  Note that a call to this method
     * may result in multiple writes to the underling Writer in order to
     * convert naked linefeeds to NETASCII line separators and to double
     * line-leading periods.  This is transparent to the programmer and
     * is only mentioned for completeness.
     * <p>
     * @param ch  The character to write.
     * @exception IOException  If an error occurs while writing to the
     *            underlying output.
     ***/
    public void write(int ch) throws IOException {
      synchronized(lock) {
        switch(ch) {
        case '\r':
  	__state = __LAST_WAS_CR_STATE;
  	__output.write('\r');
  	return;
        case '\n':
  	if(__state != __LAST_WAS_CR_STATE)
  	  __output.write('\r');
  	__output.write('\n');
  	__state = __LAST_WAS_NL_STATE;
  	return;
        case '.':
  	// Double the dot at the beginning of a line
  	if(__state == __LAST_WAS_NL_STATE)
  	  __output.write('.');
  	// Fall through
        default:
  	__state = __NOTHING_SPECIAL_STATE;
  	__output.write(ch);
  	return;
        }
      }
    }
  
  
    /***
     * Writes a number of characters from a character array to the output
     * starting from a given offset.
     * <p>
     * @param buffer  The character array to write.
     * @param offset  The offset into the array at which to start copying data.
     * @param length  The number of characters to write.
     * @exception IOException If an error occurs while writing to the underlying
     *            output.
     ***/
    public void write(char[] buffer, int offset, int length) throws IOException {
      synchronized(lock) {
        while(length-- > 0)
  	write(buffer[offset++]);
      }
    }
  
  
    /***
     * Writes a character array to the output.
     * <p>
     * @param buffer  The character array to write.
     * @exception IOException If an error occurs while writing to the underlying
     *            output.
     ***/
    public void write(char[] buffer) throws IOException {
      write(buffer, 0, buffer.length);
    }
  
  
    /***
     * Writes a String to the output.
     * <p>
     * @param string  The String to write.
     * @exception IOException If an error occurs while writing to the underlying
     *            output.
     ***/
    public void write(String string) throws IOException {
      write(string.toCharArray());
    }
  
  
    /***
     * Writes part of a String to the output starting from a given offset.
     * <p>
     * @param string  The String to write.
     * @param offset  The offset into the String at which to start copying data.
     * @param length  The number of characters to write.
     * @exception IOException If an error occurs while writing to the underlying
     *            output.
     ***/
    public void write(String string, int offset, int length) throws IOException {
      write(string.toCharArray(), offset, length);
    } 
  
  
    /***
     * Flushes the underlying output, writing all buffered output.
     * <p>
     * @exception IOException If an error occurs while writing to the underlying
     *            output.
     ***/
    public void flush() throws IOException {
      synchronized(lock) {
        __output.flush();
      }
    }
  
  
    /***
     * Flushes the underlying output, writing all buffered output, but doesn't
     * actually close the underlying stream.  The underlying stream may still
     * be used for communicating with the server and therefore is not closed.
     * <p>
     * @exception IOException If an error occurs while writing to the underlying
     *            output or closing the Writer.
     ***/
    public void close() throws IOException {
      synchronized(lock) {
        if (__output == null)
  	return;
  
        if(__state == __LAST_WAS_CR_STATE)
  	__output.write('\n');
        else if(__state != __LAST_WAS_NL_STATE)
  	__output.write("\r\n");
  
        __output.write(".\r\n");
  
        __output.flush();
        __output = null;
      }
    }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/io/FromNetASCIIInputStream.java
  
  Index: FromNetASCIIInputStream.java
  ===================================================================
  package org.apache.commons.io;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.*;
  
  /***
   * This class wraps an input stream, replacing all occurrences
   * of &lt;CR&gt;&lt;LF&gt; (carriage return followed by a linefeed),
   * which is the NETASCII standard for representing a newline, with the
   * local line separator representation.  You would use this class to 
   * implement ASCII file transfers requiring conversion from NETASCII.
   * <p>
   * <p>
   * @author Daniel F. Savarese
   ***/
  
  public final class FromNetASCIIInputStream extends PushbackInputStream {
    static final boolean _noConversionRequired;
    static final String _lineSeparator;
    static final byte[] _lineSeparatorBytes;
  
    static {
      _lineSeparator        = System.getProperty("line.separator");
      _noConversionRequired = _lineSeparator.equals("\r\n");
      _lineSeparatorBytes   = _lineSeparator.getBytes();
    }
  
    private int __length = 0;
  
    /***
     * Returns true if the NetASCII line separator differs from the system
     * line separator, false if they are the same.  This method is useful
     * to determine whether or not you need to instantiate a
     * FromNetASCIIInputStream object.
     * <p>
     * @return True if the NETASCII line separator differs from the local
     *   system line separator, false if they are the same.
     ***/
    public static final boolean isConversionRequired() {
      return !_noConversionRequired;
    }
  
    /***
     * Creates a FromNetASCIIInputStream instance that wraps an existing
     * InputStream.
     ***/
    public FromNetASCIIInputStream(InputStream input) {
      super(input, _lineSeparatorBytes.length + 1);
    }
  
  
    private int __read() throws IOException {
      int ch;
  
      ch = super.read();
  
      if(ch == '\r') {
        ch = super.read();
        if(ch == '\n') {
  	unread(_lineSeparatorBytes);
  	ch = super.read();
  	// This is a kluge for read(byte[], ...) to read the right amount
  	--__length;
        } else {
  	if(ch != -1)
  	  unread(ch);
  	return '\r';
        }
      }
  
      return ch;
    }
  
  
    /***
     * Reads and returns the next byte in the stream.  If the end of the
     * message has been reached, returns -1.  Note that a call to this method
     * may result in multiple reads from the underlying input stream in order
     * to convert NETASCII line separators to the local line separator format.
     * This is transparent to the programmer and is only mentioned for
     * completeness.
     * <p>
     * @return The next character in the stream. Returns -1 if the end of the
     *          stream has been reached.
     * @exception IOException If an error occurs while reading the underlying
     *            stream.
     ***/
    public int read() throws IOException {
      if(_noConversionRequired)
        return super.read();
  
      return __read();
    }
  
  
    /***
     * Reads the next number of bytes from the stream into an array and
     * returns the number of bytes read.  Returns -1 if the end of the
     * stream has been reached.
     * <p>
     * @param buffer  The byte array in which to store the data.
     * @return The number of bytes read. Returns -1 if the
     *          end of the message has been reached.
     * @exception IOException If an error occurs in reading the underlying
     *            stream.
     ***/
    public int read(byte buffer[]) throws IOException {
      return read(buffer, 0, buffer.length);
    }                 
  
  
    /***
     * Reads the next number of bytes from the stream into an array and returns
     * the number of bytes read.  Returns -1 if the end of the
     * message has been reached.  The characters are stored in the array
     * starting from the given offset and up to the length specified.
     * <p>
     * @param buffer The byte array in which to store the data.
     * @param offset  The offset into the array at which to start storing data.
     * @param length   The number of bytes to read.
     * @return The number of bytes read. Returns -1 if the
     *          end of the stream has been reached.
     * @exception IOException If an error occurs while reading the underlying
     *            stream.
     ***/
    public int read(byte buffer[], int offset, int length) throws IOException {
      int ch, off;
  
      if(length < 1)
        return 0;
  
      ch = available();
  
      __length = (length > ch ? ch : length);
  
      // If nothing is available, block to read only one character
      if(__length < 1)
        __length = 1;
  
      if(_noConversionRequired)
        return super.read(buffer, offset, __length);
  
      if((ch = __read()) == -1)
        return -1;
  
      off = offset;
  
      do {
        buffer[offset++] = (byte)ch;
      } while(--__length > 0 && (ch = __read()) != -1);
  
  
      return (offset - off);
    }
  
  
    // PushbackInputStream in JDK 1.1.3 returns the wrong thing
    /***
     * Returns the number of bytes that can be read without blocking EXCEPT
     * when newline conversions have to be made somewhere within the
     * available block of bytes.  In other words, you really should not
     * rely on the value returned by this method if you are trying to avoid 
     * blocking.
     ***/
    public int available() throws IOException {
      return (buf.length - pos) + in.available();
    }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/io/FromNetASCIIOutputStream.java
  
  Index: FromNetASCIIOutputStream.java
  ===================================================================
  package org.apache.commons.io;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.*;
  
  /***
   * This class wraps an output stream, replacing all occurrences
   * of &lt;CR&gt;&lt;LF&gt; (carriage return followed by a linefeed),
   * which is the NETASCII standard for representing a newline, with the
   * local line separator representation.  You would use this class to 
   * implement ASCII file transfers requiring conversion from NETASCII.
   * <p>
   * Because of the translation process, a call to <code>flush()</code> will
   * not flush the last byte written if that byte was a carriage
   * return.  A call to <a href="#close"> close() </a>, however, will
   * flush the carriage return.
   * <p>
   * <p>
   * @author Daniel F. Savarese
   ***/
  
  public final class FromNetASCIIOutputStream extends FilterOutputStream {
    private boolean __lastWasCR;
  
    /***
     * Creates a FromNetASCIIOutputStream instance that wraps an existing
     * OutputStream.
     * <p>
     * @param output  The OutputStream to wrap.
     ***/
    public FromNetASCIIOutputStream(OutputStream output) {
      super(output);
      __lastWasCR = false;
    }
  
  
    private void __write(int ch) throws IOException {
      switch(ch) {
      case '\r':
        __lastWasCR = true;
        // Don't write anything.  We need to see if next one is linefeed
        break;
      case '\n':
        if(__lastWasCR) {
  	out.write(FromNetASCIIInputStream._lineSeparatorBytes);
  	__lastWasCR = false;
  	break;
        }
        __lastWasCR = false;
        out.write('\n');
        break;
      default:
        if(__lastWasCR) {
  	out.write('\r');
  	__lastWasCR = false;
        }
        out.write(ch);
        break;
      }
    }
  
  
    /***
     * Writes a byte to the stream.    Note that a call to this method
     * might not actually write a byte to the underlying stream until a
     * subsequent character is written, from which it can be determined if
     * a NETASCII line separator was encountered.
     * This is transparent to the programmer and is only mentioned for
     * completeness.
     * <p>
     * @param ch The byte to write.
     * @exception IOException If an error occurs while writing to the underlying
     *            stream.
     ***/
    public synchronized void write(int ch) throws IOException {
      if(FromNetASCIIInputStream._noConversionRequired) {
        out.write(ch);
        return;
      }
  
      __write(ch);
    }
  
  
    /***
     * Writes a byte array to the stream.
     * <p>
     * @param buffer  The byte array to write.
     * @exception IOException If an error occurs while writing to the underlying
     *            stream.
     ***/
    public synchronized void write(byte buffer[]) throws IOException {
      write(buffer, 0, buffer.length);
    }                 
  
  
    /***
     * Writes a number of bytes from a byte array to the stream starting from
     * a given offset.
     * <p>
     * @param buffer  The byte array to write.
     * @param offset  The offset into the array at which to start copying data.
     * @param length  The number of bytes to write.
     * @exception IOException If an error occurs while writing to the underlying
     *            stream.
     ***/
    public synchronized void write(byte buffer[], int offset, int length)
         throws IOException
    {
      if(FromNetASCIIInputStream._noConversionRequired) {
        // FilterOutputStream method is very slow.
        //super.write(buffer, offset, length);
        out.write(buffer, offset, length);
        return;
      }
  
      while(length-- > 0)
        __write(buffer[offset++]);
    }
  
  
    /*** 
     * Closes the stream, writing all pending data.
     * <p>
     * @exception IOException  If an error occurs while closing the stream.
     ***/
    public synchronized void close() throws IOException {
      if(FromNetASCIIInputStream._noConversionRequired) {
        super.close();
        return;
      }
  
      if(__lastWasCR)
        out.write('\r');
      super.close();
    }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/io/SocketInputStream.java
  
  Index: SocketInputStream.java
  ===================================================================
  package org.apache.commons.io;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.*;
  import java.net.*;
  
  /***
   * This class wraps an input stream, storing a reference to its originating
   * socket.  When the stream is closed, it will also close the socket
   * immediately afterward.  This class is useful for situations where you
   * are dealing with a stream originating from a socket, but do not have
   * a reference to the socket, and want to make sure it closes when the
   * stream closes.
   * <p>
   * <p>
   * @author Daniel F. Savarese
   * @see SocketOutputStream
   ***/
  
  public class SocketInputStream extends FilterInputStream {
    private Socket __socket;
  
    /***
     * Creates a SocketInputStream instance wrapping an input stream and
     * storing a reference to a socket that should be closed on closing
     * the stream.
     * <p>
     * @param socket  The socket to close on closing the stream.
     * @param stream  The input stream to wrap.
     ***/
    public SocketInputStream(Socket socket, InputStream stream) {
      super(stream);
      __socket = socket;
    }
  
    /***
     * Closes the stream and immediately afterward closes the referenced
     * socket.
     * <p>
     * @exception IOException  If there is an error in closing the stream
     *                         or socket.
     ***/
    public void close() throws IOException {
      super.close();
      __socket.close();
    }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/io/SocketOutputStream.java
  
  Index: SocketOutputStream.java
  ===================================================================
  package org.apache.commons.io;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.*;
  import java.net.*;
  
  /***
   * This class wraps an output stream, storing a reference to its originating
   * socket.  When the stream is closed, it will also close the socket
   * immediately afterward.  This class is useful for situations where you
   * are dealing with a stream originating from a socket, but do not have
   * a reference to the socket, and want to make sure it closes when the
   * stream closes.
   * <p>
   * <p>
   * @author Daniel F. Savarese
   * @see SocketInputStream
   ***/
  
  public class SocketOutputStream extends FilterOutputStream {
    private Socket __socket;
  
    /***
     * Creates a SocketOutputStream instance wrapping an output stream and
     * storing a reference to a socket that should be closed on closing
     * the stream.
     * <p>
     * @param socket  The socket to close on closing the stream.
     * @param stream  The input stream to wrap.
     ***/
    public SocketOutputStream(Socket socket, OutputStream stream) {
      super(stream);
      __socket = socket;
    }
  
  
    /***
     * Writes a number of bytes from a byte array to the stream starting from
     * a given offset.  This method bypasses the equivalent method in
     * FilterOutputStream because the FilterOutputStream implementation is
     * very inefficient.
     * <p>
     * @param buffer  The byte array to write.
     * @param offset  The offset into the array at which to start copying data.
     * @param length  The number of bytes to write.
     * @exception IOException If an error occurs while writing to the underlying
     *            stream.
     ***/
    public void write(byte buffer[], int offset, int length) throws IOException {
      out.write(buffer, offset, length);
    }
  
  
    /***
     * Closes the stream and immediately afterward closes the referenced
     * socket.
     * <p>
     * @exception IOException  If there is an error in closing the stream
     *                         or socket.
     ***/
    public void close() throws IOException {
      super.close();
      __socket.close();
    }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/io/ToNetASCIIInputStream.java
  
  Index: ToNetASCIIInputStream.java
  ===================================================================
  package org.apache.commons.io;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.*;
  
  /***
   * This class wraps an input stream, replacing all singly occurring
   * &lt;LF&gt; (linefeed) characters with &lt;CR&gt;&lt;LF&gt; (carriage return
   * followed by linefeed), which is the NETASCII standard for representing
   * a newline.
   * You would use this class to implement ASCII file transfers requiring
   * conversion to NETASCII.
   * <p>
   * <p>
   * @author Daniel F. Savarese
   ***/
  
  public final class ToNetASCIIInputStream extends FilterInputStream {
    private static final int __NOTHING_SPECIAL = 0;
    private static final int __LAST_WAS_CR     = 1;
    private static final int __LAST_WAS_NL     = 2;
    private int __status;
  
    /***
     * Creates a ToNetASCIIInputStream instance that wraps an existing
     * InputStream.
     * <p>
     * @param input  The InputStream to .
     ***/
    public ToNetASCIIInputStream(InputStream input) {
      super(input);
      __status = __NOTHING_SPECIAL;
    }
  
  
    /***
     * Reads and returns the next byte in the stream.  If the end of the
     * message has been reached, returns -1.
     * <p>
     * @return The next character in the stream. Returns -1 if the end of the
     *          stream has been reached.
     * @exception IOException If an error occurs while reading the underlying
     *            stream.
     ***/
    public int read() throws IOException {
      int ch;
  
      if(__status == __LAST_WAS_NL) {
        __status = __NOTHING_SPECIAL;
        return '\n';
      }
  
      ch = in.read();
  
      switch(ch) {
      case '\r':
        __status = __LAST_WAS_CR;
        return '\r';
      case '\n':
        if(__status != __LAST_WAS_CR) {
  	__status = __LAST_WAS_NL;
  	return '\r';
        }
        // else fall through
      default:
        __status = __NOTHING_SPECIAL;
        return ch;
      }
      // statement not reached
      //return ch;
    }
  
  
    /***
     * Reads the next number of bytes from the stream into an array and
     * returns the number of bytes read.  Returns -1 if the end of the
     * stream has been reached.
     * <p>
     * @param buffer  The byte array in which to store the data.
     * @return The number of bytes read. Returns -1 if the
     *          end of the message has been reached.
     * @exception IOException If an error occurs in reading the underlying
     *            stream.
     ***/
    public int read(byte buffer[]) throws IOException {
      return read(buffer, 0, buffer.length);
    }                 
  
   
    /***
     * Reads the next number of bytes from the stream into an array and returns
     * the number of bytes read.  Returns -1 if the end of the
     * message has been reached.  The characters are stored in the array
     * starting from the given offset and up to the length specified.
     * <p>
     * @param buffer The byte array in which to store the data.
     * @param offset  The offset into the array at which to start storing data.
     * @param length   The number of bytes to read.
     * @return The number of bytes read. Returns -1 if the
     *          end of the stream has been reached.
     * @exception IOException If an error occurs while reading the underlying
     *            stream.
     ***/
    public int read(byte buffer[], int offset, int length) throws IOException {
      int ch, off;
  
      if(length < 1)
        return 0;
  
      ch = available();
  
      if(length > ch)
        length = ch;
  
      // If nothing is available, block to read only one character
      if(length < 1)
        length = 1;
  
      if((ch = read()) == -1)
        return -1;
  
      off = offset;
  
      do {
        buffer[offset++] = (byte)ch;
      } while(--length > 0 && (ch = read()) != -1);
  
      return (offset - off);
    }
  
    /*** Returns false.  Mark is not supported. ***/
    public boolean markSupported() { return false; }
  
    public int available() throws IOException {
      int result;
  
      result = in.available();
  
      if(__status == __LAST_WAS_NL)
        return (result + 1);
  
      return result;
    }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/io/ToNetASCIIOutputStream.java
  
  Index: ToNetASCIIOutputStream.java
  ===================================================================
  package org.apache.commons.io;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.*;
  
  /***
   * This class wraps an output stream, replacing all singly occurring
   * &lt;LF&gt; (linefeed) characters with &lt;CR&gt;&lt;LF&gt; (carriage return
   * followed by linefeed), which is the NETASCII standard for representing
   * a newline.
   * You would use this class to implement ASCII file transfers requiring
   * conversion to NETASCII.
   * <p>
   * <p>
   * @author Daniel F. Savarese
   ***/
  
  public final class ToNetASCIIOutputStream extends FilterOutputStream {
    private boolean __lastWasCR;
  
    /***
     * Creates a ToNetASCIIOutputStream instance that wraps an existing
     * OutputStream.
     * <p>
     * @param output  The OutputStream to wrap.
     ***/
    public ToNetASCIIOutputStream(OutputStream output) {
      super(output);
      __lastWasCR = false;
    }
  
  
    /***
     * Writes a byte to the stream.    Note that a call to this method
     * may result in multiple writes to the underlying input stream in order
     * to convert naked newlines to NETASCII line separators.
     * This is transparent to the programmer and is only mentioned for
     * completeness.
     * <p>
     * @param ch The byte to write.
     * @exception IOException If an error occurs while writing to the underlying
     *            stream.
     ***/
    public synchronized void write(int ch) throws IOException {
      switch(ch) {
      case '\r':
        __lastWasCR = true;
        out.write('\r');
        return;
      case '\n':
        if(!__lastWasCR)
  	out.write('\r');
        // Fall through
      default:
        __lastWasCR = false;
        out.write(ch);
        return;
      }
    }
  
  
    /***
     * Writes a byte array to the stream.
     * <p>
     * @param buffer  The byte array to write.
     * @exception IOException If an error occurs while writing to the underlying
     *            stream.
     ***/
    public synchronized void write(byte buffer[]) throws IOException {
      write(buffer, 0, buffer.length);
    }                 
  
  
    /***
     * Writes a number of bytes from a byte array to the stream starting from
     * a given offset.
     * <p>
     * @param buffer  The byte array to write.
     * @param offset  The offset into the array at which to start copying data.
     * @param length  The number of bytes to write.
     * @exception IOException If an error occurs while writing to the underlying
     *            stream.
     ***/
    public synchronized void write(byte buffer[], int offset, int length)
         throws IOException
    {
      while(length-- > 0)
        write(buffer[offset++]);
    }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/io/Util.java
  
  Index: Util.java
  ===================================================================
  package org.apache.commons.io;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.*;
  
  
  /***
   * The Util class cannot be instantiated and stores short static convenience
   * methods that are often quite useful.
   * <p>
   * <p>
   * @see CopyStreamException
   * @see CopyStreamListener
   * @see CopyStreamAdapter
   * @author Daniel F. Savarese
   ***/
  
  public final class Util {
    /***
     * The default buffer size used by <a href="#copyStream"> copyStream </a>
     * and <a href="#copyReader"> copyReader </a>. It's value is 1024.
     ***/
    public static final int DEFAULT_COPY_BUFFER_SIZE = 1024;
  
    // Cannot be instantiated
    private Util() { }
  
  
    /***
     * Copies the contents of an InputStream to an OutputStream using a
     * copy buffer of a given size and notifies the provided
     * CopyStreamListener of the progress of the copy operation by calling
     * its bytesTransferred(long, int) method after each write to the 
     * destination.  If you wish to notify more than one listener you should
     * use a CopyStreamAdapter as the listener and register the additional
     * listeners with the CopyStreamAdapter.
     * <p>
     * The contents of the InputStream are
     * read until the end of the stream is reached, but neither the
     * source nor the destination are closed.  You must do this yourself
     * outside of the method call.  The number of bytes read/written is
     * returned.
     * <p>
     * @param source  The source InputStream.
     * @param dest    The destination OutputStream.
     * @param bufferSize  The number of bytes to buffer during the copy.
     * @param streamSize  The number of bytes in the stream being copied.
     *          Should be set to CopyStreamEvent.UNKNOWN_STREAM_SIZE if unknown.
     * @param listener  The CopyStreamListener to notify of progress.  If
     *      this parameter is null, notification is not attempted.
     * @exception CopyStreamException  If an error occurs while reading from the
     *            source or writing to the destination.  The CopyStreamException
     *            will contain the number of bytes confirmed to have been
     *            transferred before an
     *            IOException occurred, and it will also contain the IOException
     *            that caused the error.  These values can be retrieved with
     *            the CopyStreamException getTotalBytesTransferred() and
     *            getIOException() methods.
     ***/
    public static final long copyStream(InputStream source, OutputStream dest,
  				      int bufferSize, long streamSize,
  				      CopyStreamListener listener)
         throws CopyStreamException
    {
      int bytes;
      long total;
      byte[] buffer;
  
      buffer = new byte[bufferSize];
      total  = 0;
  
      try {
        while((bytes = source.read(buffer)) != -1) {
  	// Technically, some read(byte[]) methods may return 0 and we cannot
  	// accept that as an indication of EOF.
  
  	if(bytes == 0) {
  	  bytes = source.read();
  	  if(bytes < 0)
  	    break;
  	  dest.write(bytes);
  	  dest.flush();
  	  ++total;
  	  if(listener != null)
  	    listener.bytesTransferred(total, 1, streamSize);
  	  continue;
  	}
  
  	dest.write(buffer, 0, bytes);
  	dest.flush();
  	total+=bytes;
  	if(listener != null)
  	  listener.bytesTransferred(total, bytes, streamSize);
        }
      } catch(IOException e) {
        throw new CopyStreamException("IOException caught while copying.",
  				    total, e);
      } 
  
      return total;
    }
  
  
    /***
     * Copies the contents of an InputStream to an OutputStream using a
     * copy buffer of a given size.  The contents of the InputStream are
     * read until the end of the stream is reached, but neither the
     * source nor the destination are closed.  You must do this yourself
     * outside of the method call.  The number of bytes read/written is
     * returned.
     * <p>
     * @param source  The source InputStream.
     * @param dest    The destination OutputStream.
     * @return  The number of bytes read/written in the copy operation.
     * @exception CopyStreamException  If an error occurs while reading from the
     *            source or writing to the destination.  The CopyStreamException
     *            will contain the number of bytes confirmed to have been
     *            transferred before an
     *            IOException occurred, and it will also contain the IOException
     *            that caused the error.  These values can be retrieved with
     *            the CopyStreamException getTotalBytesTransferred() and
     *            getIOException() methods.
     ***/
    public static final long copyStream(InputStream source, OutputStream dest,
  				     int bufferSize)
         throws CopyStreamException
    {
      return copyStream(source, dest, bufferSize,
  		      CopyStreamEvent.UNKNOWN_STREAM_SIZE, null);
    }
  
  
    /***
     * Same as <code> copyStream(source, dest, DEFAULT_COPY_BUFFER_SIZE); </code>
     ***/
    public static final long copyStream(InputStream source, OutputStream dest)
         throws CopyStreamException
    {
      return copyStream(source, dest, DEFAULT_COPY_BUFFER_SIZE);
    }
  
  
    /***
     * Copies the contents of a Reader to a Writer using a
     * copy buffer of a given size and notifies the provided
     * CopyStreamListener of the progress of the copy operation by calling
     * its bytesTransferred(long, int) method after each write to the 
     * destination.  If you wish to notify more than one listener you should
     * use a CopyStreamAdapter as the listener and register the additional
     * listeners with the CopyStreamAdapter.
     * <p> 
     * The contents of the Reader are
     * read until its end is reached, but neither the source nor the
     * destination are closed.  You must do this yourself outside of the
     * method call.  The number of characters read/written is returned.
     * <p>
     * @param source  The source Reader.
     * @param dest    The destination writer.
     * @param bufferSize  The number of characters to buffer during the copy.
     * @param streamSize  The number of characters in the stream being copied.
     *          Should be set to CopyStreamEvent.UNKNOWN_STREAM_SIZE if unknown.
     * @param listener  The CopyStreamListener to notify of progress.  If
     *      this parameter is null, notification is not attempted.
     * @return  The number of characters read/written in the copy operation.
     * @exception CopyStreamException  If an error occurs while reading from the
     *            source or writing to the destination.  The CopyStreamException
     *            will contain the number of bytes confirmed to have been
     *            transferred before an
     *            IOException occurred, and it will also contain the IOException
     *            that caused the error.  These values can be retrieved with
     *            the CopyStreamException getTotalBytesTransferred() and
     *            getIOException() methods.
     ***/
    public static final long copyReader(Reader source, Writer dest, 
  				      int bufferSize, long streamSize,
  				      CopyStreamListener listener)
         throws CopyStreamException
    {
      int chars;
      long total;
      char[] buffer;
  
      buffer = new char[bufferSize];
      total  = 0;
  
      try {
        while((chars = source.read(buffer)) != -1) {
  	// Technically, some read(char[]) methods may return 0 and we cannot
  	// accept that as an indication of EOF.
  	if(chars == 0) {
  	  chars = source.read();
  	  if(chars < 0)
  	    break;
  	  dest.write(chars);
  	  dest.flush();
  	  ++total;
  	  if(listener != null)
  	    listener.bytesTransferred(total, chars, streamSize);
  	  continue;
  	}
  
  	dest.write(buffer, 0, chars);
  	dest.flush();
  	total+=chars;
  	if(listener != null)
  	  listener.bytesTransferred(total, chars, streamSize);
        }
      } catch(IOException e) {
        throw new CopyStreamException("IOException caught while copying.",
  				    total, e);
      } 
  
      return total;
    }
  
  
    /***
     * Copies the contents of a Reader to a Writer using a
     * copy buffer of a given size.  The contents of the Reader are
     * read until its end is reached, but neither the source nor the
     * destination are closed.  You must do this yourself outside of the
     * method call.  The number of characters read/written is returned.
     * <p>
     * @param source  The source Reader.
     * @param dest    The destination writer.
     * @param bufferSize  The number of characters to buffer during the copy.
     * @return  The number of characters read/written in the copy operation.
     * @exception CopyStreamException  If an error occurs while reading from the
     *            source or writing to the destination.  The CopyStreamException
     *            will contain the number of bytes confirmed to have been
     *            transferred before an
     *            IOException occurred, and it will also contain the IOException
     *            that caused the error.  These values can be retrieved with
     *            the CopyStreamException getTotalBytesTransferred() and
     *            getIOException() methods.
     ***/
    public static final long copyReader(Reader source, Writer dest, 
  				      int bufferSize)
         throws CopyStreamException
    {
      return copyReader(source, dest, bufferSize,
  		      CopyStreamEvent.UNKNOWN_STREAM_SIZE, null);
    }
  
  
    /***
     * Same as <code> copyReader(source, dest, DEFAULT_COPY_BUFFER_SIZE); </code>
     ***/
    public static final long copyReader(Reader source, Writer dest)
         throws CopyStreamException
    {
      return copyReader(source, dest, DEFAULT_COPY_BUFFER_SIZE);
    }
  
  }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>