/* * Copyright 1995-2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ package net.sourceforge.jnlp.tools; import java.io.InputStream; import java.io.ByteArrayInputStream; import java.io.OutputStream; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.io.IOException; import java.nio.ByteBuffer; /** * This class defines the encoding half of character encoders. * A character encoder is an algorithim for transforming 8 bit binary * data into text (generally 7 bit ASCII or 8 bit ISO-Latin-1 text) * for transmition over text channels such as e-mail and network news. * * The character encoders have been structured around a central theme * that, in general, the encoded text has the form: * *
* [Buffer Prefix] * [Line Prefix][encoded data atoms][Line Suffix] * [Buffer Suffix] ** * In the CharacterEncoder and CharacterDecoder classes, one complete * chunk of data is referred to as a buffer. Encoded buffers * are all text, and decoded buffers (sometimes just referred to as * buffers) are binary octets. * * To create a custom encoder, you must, at a minimum, overide three * abstract methods in this class. *
* The ByteBuffer's position will be advanced to ByteBuffer's limit. *
* To avoid an extra copy, the implementation will attempt to return the * byte array backing the ByteBuffer. If this is not possible, a * new byte array will be created. */ private byte [] getBytes(ByteBuffer bb) { /* * This should never return a BufferOverflowException, as we're * careful to allocate just the right amount. */ byte [] buf = null; /* * If it has a usable backing byte buffer, use it. Use only * if the array exactly represents the current ByteBuffer. */ if (bb.hasArray()) { byte [] tmp = bb.array(); if ((tmp.length == bb.capacity()) && (tmp.length == bb.remaining())) { buf = tmp; bb.position(bb.limit()); } } if (buf == null) { /* * This class doesn't have a concept of encode(buf, len, off), * so if we have a partial buffer, we must reallocate * space. */ buf = new byte[bb.remaining()]; /* * position() automatically updated */ bb.get(buf); } return buf; } /** * Encode the aBuffer ByteBuffer and write the encoded * result to the OutputStream aStream. *
* The ByteBuffer's position will be advanced to ByteBuffer's limit. */ public void encode(ByteBuffer aBuffer, OutputStream aStream) throws IOException { byte [] buf = getBytes(aBuffer); encode(buf, aStream); } /** * A 'streamless' version of encode that simply takes a ByteBuffer * and returns a string containing the encoded buffer. *
* The ByteBuffer's position will be advanced to ByteBuffer's limit. */ public String encode(ByteBuffer aBuffer) { byte [] buf = getBytes(aBuffer); return encode(buf); } /** * Encode bytes from the input stream, and write them as text characters * to the output stream. This method will run until it exhausts the * input stream. It differs from encode in that it will add the * line at the end of a final line that is shorter than bytesPerLine(). */ public void encodeBuffer(InputStream inStream, OutputStream outStream) throws IOException { int j; int numBytes; byte tmpbuffer[] = new byte[bytesPerLine()]; encodeBufferPrefix(outStream); while (true) { numBytes = readFully(inStream, tmpbuffer); if (numBytes == 0) { break; } encodeLinePrefix(outStream, numBytes); for (j = 0; j < numBytes; j += bytesPerAtom()) { if ((j + bytesPerAtom()) <= numBytes) { encodeAtom(outStream, tmpbuffer, j, bytesPerAtom()); } else { encodeAtom(outStream, tmpbuffer, j, (numBytes)- j); } } encodeLineSuffix(outStream); if (numBytes < bytesPerLine()) { break; } } encodeBufferSuffix(outStream); } /** * Encode the buffer in aBuffer and write the encoded * result to the OutputStream aStream. */ public void encodeBuffer(byte aBuffer[], OutputStream aStream) throws IOException { ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer); encodeBuffer(inStream, aStream); } /** * A 'streamless' version of encode that simply takes a buffer of * bytes and returns a string containing the encoded buffer. */ public String encodeBuffer(byte aBuffer[]) { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer); try { encodeBuffer(inStream, outStream); } catch (Exception IOException) { // This should never happen. throw new Error("CharacterEncoder.encodeBuffer internal error"); } return (outStream.toString()); } /** * Encode the aBuffer ByteBuffer and write the encoded * result to the OutputStream aStream. *
* The ByteBuffer's position will be advanced to ByteBuffer's limit. */ public void encodeBuffer(ByteBuffer aBuffer, OutputStream aStream) throws IOException { byte [] buf = getBytes(aBuffer); encodeBuffer(buf, aStream); } /** * A 'streamless' version of encode that simply takes a ByteBuffer * and returns a string containing the encoded buffer. *
* The ByteBuffer's position will be advanced to ByteBuffer's limit. */ public String encodeBuffer(ByteBuffer aBuffer) { byte [] buf = getBytes(aBuffer); return encodeBuffer(buf); } }