package org.okip.service.filing.impl.rfs; import org.okip.service.filing.api.*; /** Copyright (c) 2002 Massachusetts Institute of Technology This work, including software, documents, or other related items (the "Software"), is being provided by the copyright holder(s) subject to the terms of the MIT OKI™ API Implementation License. By obtaining, using and/or copying this Software, you agree that you have read, understand, and will comply with the following terms and conditions of the MIT OKI™ API Implementation License: Permission to use, copy, modify, and distribute this Software and its documentation, with or without modification, for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the Software or portions thereof, including modifications or derivatives, that you make: * The full text of the MIT OKI™ API Implementation License in a location viewable to users of the redistributed or derivative work. * Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, a short notice similar to the following should be used within the body of any redistributed or derivative Software: "Copyright (c) 2002 Massachusetts Institute of Technology All Rights Reserved." * Notice of any changes or modifications to the MIT OKI™ Software, including the date the changes were made. Any modified software must be distributed in such as manner as to avoid any confusion with the original MIT OKI™ Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. The name and trademarks of copyright holder(s) and/or MIT may NOT be used in advertising or publicity pertaining to the Software without specific, written prior permission. Title to copyright in the Software and any associated documentation will at all times remain with the copyright holders. The export of software employing encryption technology may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting this Software. */ /* * $Source: /home/svn/cvs2svn-2.1.1/at-cvs-repo/VUE2/src/oki/old/filing/RfsOutputStream.java,v $ */ /** * RFS OutputStream. Provides a buffered OkiOutputStream to a local or remote file. * RfsOutputBuffer handles the actual data transfer and write calls. * <p> * Licensed under the {@link org.okip.service.ApiImplementationLicenseMIT MIT OKI™ API Implementation License}. * * @version $Name: not supported by cvs2svn $ / $Revision: 1.1 $ / $Date: 2003-04-14 20:48:28 $ */ class RfsOutputStream implements OkiOutputStream { private RfsFactory factory = null; private String idStr = null; private boolean append = false; private int bufferSize; private int bufferPos = 0; private RfsOutputBuffer out = null; private RfsEntryCache watchingCache = null; protected RfsOutputStream(RfsFactory factory, String idStr, RfsEntryCache cache) throws FilingException { this(factory, idStr, -1, false, cache); } protected RfsOutputStream(RfsFactory factory, String idStr, int bufferSize, boolean append, RfsEntryCache cache) throws FilingException { this.factory = factory; this.idStr = idStr; this.append = append; this.watchingCache = cache; if (bufferSize <= 0) this.bufferSize = factory.getIOBufferSize(); else this.bufferSize = bufferSize; } private RfsOutputBuffer getOutputBuffer() throws FilingException { if (this.out == null) this.out = new RfsOutputBuffer(factory, idStr, bufferSize, append, watchingCache); return this.out; } private byte[] getBuffer() throws FilingException { return getOutputBuffer().getBuffer(); } /** * Writes b.length bytes to this IO Object. */ public void write(byte[] b) throws FilingException { write(b, 0, b.length); } /* * Write the given data buffer straight through * without touching our internal buffer. */ protected void writeThrough(byte[] data, int off, int len) throws FilingException { if (len <= 0) return; DataBlock dataBlock = new DataBlock(data, off, len); writeThrough(dataBlock); dataBlock.buf = null; } protected void writeThrough(DataBlock dataBlock) throws FilingException { flush(); getOutputBuffer().writeThrough(dataBlock); } /** * Writes len bytes from the specified byte array starting at * offset off to this IO Object. */ public void write(byte[] data, int off, int len) throws FilingException { try { int toSend = len; int dataIndex = off; int roomLeft; /* * Keep filling & flushing our buffer until we've * processed all the data we've been asked to send. */ while (toSend > 0) { if (this.bufferPos == 0 && toSend >= this.bufferSize) { /* Don't bother doing the arraycopy if we're at * the start of a buffer (nothing to flush) and would need to * immediately flush the buffer -- just deliver right * from the user buffer. */ writeThrough(data, dataIndex, this.bufferSize); dataIndex += this.bufferSize; toSend -= this.bufferSize; } else if (toSend >= (roomLeft = this.bufferSize - this.bufferPos)) { /* * We're going to exceed our remaining buffer space -- fill it, flush it, * and come back around for more. */ System.arraycopy(data, dataIndex, getBuffer(), this.bufferPos, roomLeft); dataIndex += roomLeft; toSend -= roomLeft; this.bufferPos += roomLeft; flush(); } else { /* * There isn't enough data left to fill our buffer -- * copy data into our buffer and return. */ System.arraycopy(data, dataIndex, getBuffer(), this.bufferPos, toSend); this.bufferPos += toSend; toSend = 0; } } } catch (FilingException e) { throw e; } catch (Exception e) { throw new FilingException(e); } } /** * Writes the specified byte to this IO Object. */ public void write(int b) throws FilingException { byte[] buffer = getBuffer(); buffer[this.bufferPos++] = (byte) b; if (this.bufferPos == buffer.length) flush(); } /** * Flushes this IO Object and forces any buffered output bytes * to be written out to the stream. */ public void flush() throws FilingException { if (this.out != null && this.bufferPos > 0) { this.out.writeBuffer(this.bufferPos); this.bufferPos = 0; } } /** * Closes this IO Object and releases any system resources * associated with the IO Object. */ public void close() throws FilingException { flush(); if (this.out != null) { this.out.closeBufferStream(); this.out = null; } } public void finalize() throws FilingException { close(); } /** * Return OutputStream in native environment which can be used to * access this ByteStore. In Java, this is a java.io.OutputStream * object. From this one may obtain a Writer via OutputStreamReader. * * @return A java.io.OutputStream object which may be used to write to this * ByteStore. * * @throws FilingPermissionDeniedException - if Factory Owner * does not have permission to write to this ByteStore. * @throws FilingIOException - if an IO error occurs. */ public java.io.OutputStream getNativeOutputStream() throws FilingException { return new org.okip.service.filing.api.JavaOutputStreamAdapter(this); } public String toString() { return "RfsOutputStream[" + idStr + "] len=" + bufferSize + " pos="+bufferPos; } }