Java tutorial
/* * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at <http://www.mozilla.org/MPL/>. * * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT * WARRANTY OF ANY KIND, either express or implied. See the License for the specific * language governing rights and limitations under the License. * * The Original Code is the Venice Web Communities System. * * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@users.sf.net>, * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are * Copyright (C) 2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. * * Contributor(s): */ package com.silverwrist.util; import java.io.*; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.*; public class Base64EncodeInputStream extends FilterInputStream { /*-------------------------------------------------------------------------------- * Static data members *-------------------------------------------------------------------------------- */ private static Logger logger = Logger.getLogger(Base64EncodeInputStream.class); private static final int NREAD = 768; // must be divisible by three /*-------------------------------------------------------------------------------- * Attributes *-------------------------------------------------------------------------------- */ private byte[] m_coded_data = null; private int m_ptr = 0; /*-------------------------------------------------------------------------------- * Constructor *-------------------------------------------------------------------------------- */ public Base64EncodeInputStream(InputStream inner) { super(inner); } // end constructor /*-------------------------------------------------------------------------------- * Internal operations *-------------------------------------------------------------------------------- */ private boolean backfill() throws IOException { if ((m_coded_data != null) && (m_coded_data.length <= m_ptr)) { // the buffer is empty - clear it logger.debug("buffer drained"); m_coded_data = null; } // end if if (m_coded_data == null) { // read in a chunk from the underlying stream byte[] data = new byte[NREAD]; int nr = in.read(data); if (nr <= 0) { // done with underlying stream logger.debug("B64EIS - underlying stream at EOF"); return true; } // end if if (logger.isDebugEnabled()) logger.debug("read " + nr + " bytes from underlying stream"); if (nr < NREAD) { // shorten the read-in array byte[] data2 = new byte[nr]; System.arraycopy(data, 0, data2, 0, nr); data = data2; } // end if m_coded_data = Base64.encodeBase64(data); m_ptr = 0; if (logger.isDebugEnabled()) logger.debug("reset buffer - now have " + m_coded_data.length + " bytes"); } // end if return false; } // end backfill /*-------------------------------------------------------------------------------- * Overrides from class FilterInputStream *-------------------------------------------------------------------------------- */ public synchronized int read() throws IOException { if (backfill()) return -1; // end of file return (int) (m_coded_data[m_ptr++]); } // end read public synchronized int read(byte[] b, int off, int len) throws IOException { if (b == null) throw new NullPointerException("null array"); if (off < 0) throw new IndexOutOfBoundsException("negative offset"); if (len < 0) throw new IndexOutOfBoundsException("negative length"); if ((off + len) > b.length) throw new IndexOutOfBoundsException("off right end of array"); if (len == 0) return 0; int rc = 0; while (len > 0) { // force a backfill before copying if (backfill()) break; // end of the underlying file int ncpy = Math.min(len, m_coded_data.length - m_ptr); System.arraycopy(m_coded_data, m_ptr, b, off, ncpy); m_ptr += ncpy; off += ncpy; rc += ncpy; len -= ncpy; } // end while if (rc == 0) rc = -1; // EOF return rc; } // end read public synchronized long skip(long n) throws IOException { long rc = 0; while (n > 0) { // force a backfill before skipping if (backfill()) break; // end of the underlying file long nskp = Math.min(n, m_coded_data.length - m_ptr); m_ptr += (int) nskp; rc += nskp; n -= nskp; } // end while return rc; } // end skip public void close() throws IOException { in.close(); m_coded_data = null; } // end close public synchronized int available() throws IOException { if (backfill()) return 0; // at end of file return (m_coded_data.length - m_ptr) + (in.available() * 4 / 3); } // end available public void mark(int readLimit) { // do nothing } // end mark public void reset() { // do nothing } // end reset public boolean markSupported() { return false; } // end markSupported } // end class Base64EncodeInputStream