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 /** 051 * Creates a new instance of CPXOutputStream 052 * @param os 053 * @throws java.io.IOException 054 */ 055 public CPXOutputStream(OutputStream os) throws IOException { 056 super(os); 057 058 //Write magic number 059 os.write(MAGIC_NUMBER); 060 } 061 062 /** 063 * Writes the specified <code>byte</code> to this output stream. 064 * <p> 065 * The <code>write</code> method of <code>FilterOutputStream</code> 066 * calls the <code>write</code> method of its underlying output stream, 067 * that is, it performs <tt>out.write(b)</tt>. 068 * <p> 069 * Implements the abstract <tt>write</tt> method of <tt>OutputStream</tt>. 070 * 071 * @param b the <code>byte</code>. 072 * @exception IOException if an I/O error occurs. 073 */ 074 @Override 075 public void write(int b) throws IOException { 076 final byte[] buf = new byte[1]; 077 buf[0] = (byte)b; 078 write(buf, 0, 1); 079 } 080 081 /** 082 * Writes <code>b.length</code> bytes to this output stream. 083 * <p> 084 * The <code>write</code> method of <code>FilterOutputStream</code> 085 * calls its <code>write</code> method of three arguments with the 086 * arguments <code>b</code>, <code>0</code>, and 087 * <code>b.length</code>. 088 * <p> 089 * Note that this method does not call the one-argument 090 * <code>write</code> method of its underlying stream with the single 091 * argument <code>b</code>. 092 * 093 * @param b the data to be written. 094 * @exception IOException if an I/O error occurs. 095 * @see java.io.FilterOutputStream#write(byte[], int, int) 096 */ 097 @Override 098 public void write(byte b[]) throws IOException { 099 write(b, 0, b.length); 100 } 101 102 byte[] deflateBuffer = new byte[2048]; 103 104 /** 105 * Writes <code>len</code> bytes from the specified 106 * <code>byte</code> array starting at offset <code>off</code> to 107 * this output stream. 108 * <p> 109 * The <code>write</code> method of <code>FilterOutputStream</code> 110 * calls the <code>write</code> method of one argument on each 111 * <code>byte</code> to output. 112 * <p> 113 * Note that this method does not call the <code>write</code> method 114 * of its underlying input stream with the same arguments. Subclasses 115 * of <code>FilterOutputStream</code> should provide a more efficient 116 * implementation of this method. 117 * 118 * @param b the data. 119 * @param off the start offset in the data. 120 * @param len the number of bytes to write. 121 * @exception IOException if an I/O error occurs. 122 * @see java.io.FilterOutputStream#write(int) 123 */ 124 @Override 125 public void write(byte b[], int off, int len) throws IOException 126 { 127 deflater.setInput(b, off, len); 128 129 processAllData(); 130 /* 131 int numDeflatedBytes; 132 while ((numDeflatedBytes = deflater.deflate(deflateBuffer)) != 0) 133 { 134// byte[] cipherBuf = cipher.update(deflateBuffer, 0, numDeflatedBytes); 135// out.write(cipherBytes); 136out.write(deflateBuffer, 0, numDeflatedBytes); 137 } 138 */ 139 } 140 141 protected void processAllData() throws IOException 142 { 143 int numDeflatedBytes; 144 while ((numDeflatedBytes = deflater.deflate(deflateBuffer)) != 0) 145 { 146// byte[] cipherBuf = cipher.update(deflateBuffer, 0, numDeflatedBytes); 147// out.write(cipherBytes); 148out.write(deflateBuffer, 0, numDeflatedBytes); 149 } 150 } 151 152 /** 153 * Flushes this output stream and forces any buffered output bytes 154 * to be written out to the stream. 155 * <p> 156 * The <code>flush</code> method of <code>FilterOutputStream</code> 157 * calls the <code>flush</code> method of its underlying output stream. 158 * 159 * @exception IOException if an I/O error occurs. 160 * @see java.io.FilterOutputStream#out 161 */ 162 @Override 163 public void flush() throws IOException { 164 out.flush(); 165 } 166 167 /** 168 * Closes this output stream and releases any system resources 169 * associated with the stream. 170 * <p> 171 * The <code>close</code> method of <code>FilterOutputStream</code> 172 * calls its <code>flush</code> method, and then calls the 173 * <code>close</code> method of its underlying output stream. 174 * 175 * @exception IOException if an I/O error occurs. 176 * @see java.io.FilterOutputStream#flush() 177 * @see java.io.FilterOutputStream#out 178 */ 179 @Override 180 public void close() throws IOException { 181 deflater.finish(); 182 processAllData(); 183 184 try { 185 flush(); 186 } catch (IOException ignored) { 187 } 188 out.close(); 189 } 190}