001/* 002 * SVG Salamander 003 * Copyright (c) 2004, Mark McKay 004 * All rights reserved. 005 * 006 * Redistribution and use in source and binary forms, with or 007 * without modification, are permitted provided that the following 008 * conditions are met: 009 * 010 * - Redistributions of source code must retain the above 011 * copyright notice, this list of conditions and the following 012 * disclaimer. 013 * - Redistributions in binary form must reproduce the above 014 * copyright notice, this list of conditions and the following 015 * disclaimer in the documentation and/or other materials 016 * provided with the distribution. 017 * 018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 019 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 020 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 021 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 022 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 023 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 025 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 026 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 027 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 029 * OF THE POSSIBILITY OF SUCH DAMAGE. 030 * 031 * Mark McKay can be contacted at mark@kitfox.com. Salamander and other 032 * projects can be found at http://www.kitfox.com 033 * 034 * Created on February 12, 2004, 12:50 PM 035 */ 036 037package com.kitfox.svg.xml.cpx; 038 039import java.io.*; 040import java.util.zip.*; 041 042/** 043 * @author Mark McKay 044 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a> 045 */ 046public class CPXOutputStream extends FilterOutputStream implements CPXConsts { 047 048 Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION); 049 050 /** Creates a new instance of CPXOutputStream */ 051 public CPXOutputStream(OutputStream os) throws IOException { 052 super(os); 053 054 //Write magic number 055 os.write(MAGIC_NUMBER); 056 } 057 058 /** 059 * Writes the specified <code>byte</code> to this output stream. 060 * <p> 061 * The <code>write</code> method of <code>FilterOutputStream</code> 062 * calls the <code>write</code> method of its underlying output stream, 063 * that is, it performs <tt>out.write(b)</tt>. 064 * <p> 065 * Implements the abstract <tt>write</tt> method of <tt>OutputStream</tt>. 066 * 067 * @param b the <code>byte</code>. 068 * @exception IOException if an I/O error occurs. 069 */ 070 public void write(int b) throws IOException { 071 final byte[] buf = new byte[1]; 072 buf[0] = (byte)b; 073 write(buf, 0, 1); 074 } 075 076 /** 077 * Writes <code>b.length</code> bytes to this output stream. 078 * <p> 079 * The <code>write</code> method of <code>FilterOutputStream</code> 080 * calls its <code>write</code> method of three arguments with the 081 * arguments <code>b</code>, <code>0</code>, and 082 * <code>b.length</code>. 083 * <p> 084 * Note that this method does not call the one-argument 085 * <code>write</code> method of its underlying stream with the single 086 * argument <code>b</code>. 087 * 088 * @param b the data to be written. 089 * @exception IOException if an I/O error occurs. 090 * @see java.io.FilterOutputStream#write(byte[], int, int) 091 */ 092 public void write(byte b[]) throws IOException { 093 write(b, 0, b.length); 094 } 095 096 byte[] deflateBuffer = new byte[2048]; 097 098 /** 099 * Writes <code>len</code> bytes from the specified 100 * <code>byte</code> array starting at offset <code>off</code> to 101 * this output stream. 102 * <p> 103 * The <code>write</code> method of <code>FilterOutputStream</code> 104 * calls the <code>write</code> method of one argument on each 105 * <code>byte</code> to output. 106 * <p> 107 * Note that this method does not call the <code>write</code> method 108 * of its underlying input stream with the same arguments. Subclasses 109 * of <code>FilterOutputStream</code> should provide a more efficient 110 * implementation of this method. 111 * 112 * @param b the data. 113 * @param off the start offset in the data. 114 * @param len the number of bytes to write. 115 * @exception IOException if an I/O error occurs. 116 * @see java.io.FilterOutputStream#write(int) 117 */ 118 public void write(byte b[], int off, int len) throws IOException 119 { 120 deflater.setInput(b, off, len); 121 122 processAllData(); 123 /* 124 int numDeflatedBytes; 125 while ((numDeflatedBytes = deflater.deflate(deflateBuffer)) != 0) 126 { 127// byte[] cipherBuf = cipher.update(deflateBuffer, 0, numDeflatedBytes); 128// out.write(cipherBytes); 129out.write(deflateBuffer, 0, numDeflatedBytes); 130 } 131 */ 132 } 133 134 protected void processAllData() throws IOException 135 { 136 int numDeflatedBytes; 137 while ((numDeflatedBytes = deflater.deflate(deflateBuffer)) != 0) 138 { 139// byte[] cipherBuf = cipher.update(deflateBuffer, 0, numDeflatedBytes); 140// out.write(cipherBytes); 141out.write(deflateBuffer, 0, numDeflatedBytes); 142 } 143 } 144 145 /** 146 * Flushes this output stream and forces any buffered output bytes 147 * to be written out to the stream. 148 * <p> 149 * The <code>flush</code> method of <code>FilterOutputStream</code> 150 * calls the <code>flush</code> method of its underlying output stream. 151 * 152 * @exception IOException if an I/O error occurs. 153 * @see java.io.FilterOutputStream#out 154 */ 155 public void flush() throws IOException { 156 out.flush(); 157 } 158 159 /** 160 * Closes this output stream and releases any system resources 161 * associated with the stream. 162 * <p> 163 * The <code>close</code> method of <code>FilterOutputStream</code> 164 * calls its <code>flush</code> method, and then calls the 165 * <code>close</code> method of its underlying output stream. 166 * 167 * @exception IOException if an I/O error occurs. 168 * @see java.io.FilterOutputStream#flush() 169 * @see java.io.FilterOutputStream#out 170 */ 171 public void close() throws IOException { 172 deflater.finish(); 173 processAllData(); 174 175 try { 176 flush(); 177 } catch (IOException ignored) { 178 } 179 out.close(); 180 } 181}