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
035package com.kitfox.svg.xml;
036
037import java.io.FilterOutputStream;
038import java.io.IOException;
039import java.io.OutputStream;
040
041/**
042 *
043 * @author kitfox
044 */
045public class Base64OutputStream extends FilterOutputStream
046{
047    int buf;
048    int numBytes;
049    int numChunks;
050    
051    public Base64OutputStream(OutputStream out)
052    {
053        super(out);
054    }
055    
056    public void flush() throws IOException
057    {
058        out.flush();
059    }
060    
061    public void close() throws IOException
062    {
063        switch (numBytes)
064        {
065            case 1:
066                buf <<= 4;
067                out.write(getBase64Byte(1));
068                out.write(getBase64Byte(0));
069                out.write('=');
070                out.write('=');
071                break;
072            case 2:
073                buf <<= 2;
074                out.write(getBase64Byte(2));
075                out.write(getBase64Byte(1));
076                out.write(getBase64Byte(0));
077                out.write('=');
078                break;
079            case 3:
080                out.write(getBase64Byte(3));
081                out.write(getBase64Byte(2));
082                out.write(getBase64Byte(1));
083                out.write(getBase64Byte(0));
084                break;
085            default:
086                assert false;
087        }
088        
089        out.close();
090    }
091    
092    public void write(int b) throws IOException
093    {
094        buf = (buf << 8) | (0xff & b);
095        numBytes++;
096        
097        if (numBytes == 3)
098        {
099            out.write(getBase64Byte(3));
100            out.write(getBase64Byte(2));
101            out.write(getBase64Byte(1));
102            out.write(getBase64Byte(0));
103            
104            numBytes = 0;
105            numChunks++;
106            if (numChunks == 16)
107            {
108//                out.write('\r');
109//                out.write('\n');
110                numChunks = 0;
111            }
112        }
113    }
114    
115    public byte getBase64Byte(int index)
116    {
117        return Base64Util.encodeByte((buf >> (index * 6)) & 0x3f);
118    }
119}