/* * ftp4j - A pure Java FTP client library * * Copyright (C) 2008-2010 Carlo Pelliccia (www.sauronsoftware.it) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version * 2.1, as published by the Free Software Foundation. * * This program 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 Lesser General Public License 2.1 for more details. * * You should have received a copy of the GNU Lesser General Public * License version 2.1 along with this program. * If not, see . */ package it.sauronsoftware.ftp4j.connectors; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; /** *

* Base64 encoding and decoding utility methods, both for binary and textual * informations. *

* * @author Carlo Pelliccia * @since 1.1 * @version 1.3 */ class Base64 { static String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static char pad = '='; /** *

* Encodes a string. *

*

* Before the string is encoded in Base64, it is converted in a binary * sequence using the system default charset. *

* * @param str * The source string. * @return The encoded string. * @throws RuntimeException * If an unexpected error occurs. */ public static String encode(String str) throws RuntimeException { byte[] bytes = str.getBytes(); byte[] encoded = encode(bytes); try { return new String(encoded, "ASCII"); } catch (UnsupportedEncodingException e) { throw new RuntimeException("ASCII is not supported!", e); } } /** *

* Encodes a string. *

*

* Before the string is encoded in Base64, it is converted in a binary * sequence using the supplied charset. *

* * @param str * The source string * @param charset * The charset name. * @return The encoded string. * @throws RuntimeException * If an unexpected error occurs. * @since 1.2 */ public static String encode(String str, String charset) throws RuntimeException { byte[] bytes; try { bytes = str.getBytes(charset); } catch (UnsupportedEncodingException e) { throw new RuntimeException("Unsupported charset: " + charset, e); } byte[] encoded = encode(bytes); try { return new String(encoded, "ASCII"); } catch (UnsupportedEncodingException e) { throw new RuntimeException("ASCII is not supported!", e); } } /** *

* Decodes the supplied string. *

*

* The supplied string is decoded into a binary sequence, and then the * sequence is encoded with the system default charset and returned. *

* * @param str * The encoded string. * @return The decoded string. * @throws RuntimeException * If an unexpected error occurs. */ public static String decode(String str) throws RuntimeException { byte[] bytes; try { bytes = str.getBytes("ASCII"); } catch (UnsupportedEncodingException e) { throw new RuntimeException("ASCII is not supported!", e); } byte[] decoded = decode(bytes); return new String(decoded); } /** *

* Decodes the supplied string. *

*

* The supplied string is decoded into a binary sequence, and then the * sequence is encoded with the supplied charset and returned. *

* * @param str * The encoded string. * @param charset * The charset name. * @return The decoded string. * @throws RuntimeException * If an unexpected error occurs. * @since 1.2 */ public static String decode(String str, String charset) throws RuntimeException { byte[] bytes; try { bytes = str.getBytes("ASCII"); } catch (UnsupportedEncodingException e) { throw new RuntimeException("ASCII is not supported!", e); } byte[] decoded = decode(bytes); try { return new String(decoded, charset); } catch (UnsupportedEncodingException e) { throw new RuntimeException("Unsupported charset: " + charset, e); } } /** *

* Encodes a binary sequence. *

*

* If data are large, i.e. if you are working with large binary files, * consider to use a {@link Base64OutputStream} instead of loading too much * data in memory. *

* * @param bytes * The source sequence. * @return The encoded sequence. * @throws RuntimeException * If an unexpected error occurs. * @since 1.2 */ public static byte[] encode(byte[] bytes) throws RuntimeException { return encode(bytes, 0); } /** *

* Encodes a binary sequence, wrapping every encoded line every * wrapAt characters. A wrapAt value less than 1 disables * wrapping. *

*

* If data are large, i.e. if you are working with large binary files, * consider to use a {@link Base64OutputStream} instead of loading too much * data in memory. *

* * @param bytes * The source sequence. * @param wrapAt * The max line length for encoded data. If less than 1 no wrap * is applied. * @return The encoded sequence. * @throws RuntimeException * If an unexpected error occurs. * @since 1.2 */ public static byte[] encode(byte[] bytes, int wrapAt) throws RuntimeException { ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); try { encode(inputStream, outputStream, wrapAt); } catch (IOException e) { throw new RuntimeException("Unexpected I/O error", e); } finally { try { inputStream.close(); } catch (Throwable t) { ; } try { outputStream.close(); } catch (Throwable t) { ; } } return outputStream.toByteArray(); } /** *

* Decodes a binary sequence. *

*

* If data are large, i.e. if you are working with large binary files, * consider to use a {@link Base64InputStream} instead of loading too much * data in memory. *

* * @param bytes * The encoded sequence. * @return The decoded sequence. * @throws RuntimeException * If an unexpected error occurs. * @since 1.2 */ public static byte[] decode(byte[] bytes) throws RuntimeException { ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); try { decode(inputStream, outputStream); } catch (IOException e) { throw new RuntimeException("Unexpected I/O error", e); } finally { try { inputStream.close(); } catch (Throwable t) { ; } try { outputStream.close(); } catch (Throwable t) { ; } } return outputStream.toByteArray(); } /** *

* Encodes data from the given input stream and writes them in the given * output stream. *

*

* The supplied input stream is read until its end is reached, but it's not * closed by this method. *

*

* The supplied output stream is nor flushed neither closed by this method. *

* * @param inputStream * The input stream. * @param outputStream * The output stream. * @throws IOException * If an I/O error occurs. */ public static void encode(InputStream inputStream, OutputStream outputStream) throws IOException { encode(inputStream, outputStream, 0); } /** *

* Encodes data from the given input stream and writes them in the given * output stream, wrapping every encoded line every wrapAt * characters. A wrapAt value less than 1 disables wrapping. *

*

* The supplied input stream is read until its end is reached, but it's not * closed by this method. *

*

* The supplied output stream is nor flushed neither closed by this method. *

* * @param inputStream * The input stream from which clear data are read. * @param outputStream * The output stream in which encoded data are written. * @param wrapAt * The max line length for encoded data. If less than 1 no wrap * is applied. * @throws IOException * If an I/O error occurs. */ public static void encode(InputStream inputStream, OutputStream outputStream, int wrapAt) throws IOException { Base64OutputStream aux = new Base64OutputStream(outputStream, wrapAt); copy(inputStream, aux); aux.commit(); } /** *

* Decodes data from the given input stream and writes them in the given * output stream. *

*

* The supplied input stream is read until its end is reached, but it's not * closed by this method. *

*

* The supplied output stream is nor flushed neither closed by this method. *

* * @param inputStream * The input stream from which encoded data are read. * @param outputStream * The output stream in which decoded data are written. * @throws IOException * If an I/O error occurs. */ public static void decode(InputStream inputStream, OutputStream outputStream) throws IOException { copy(new Base64InputStream(inputStream), outputStream); } /** *

* Encodes data from the given source file contents and writes them in the * given target file, wrapping every encoded line every wrapAt * characters. A wrapAt value less than 1 disables wrapping. *

* * @param source * The source file, from which decoded data are read. * @param target * The target file, in which encoded data are written. * @param wrapAt * The max line length for encoded data. If less than 1 no wrap * is applied. * @throws IOException * If an I/O error occurs. * @since 1.3 */ public static void encode(File source, File target, int wrapAt) throws IOException { InputStream inputStream = null; OutputStream outputStream = null; try { inputStream = new FileInputStream(source); outputStream = new FileOutputStream(target); Base64.encode(inputStream, outputStream, wrapAt); } finally { if (outputStream != null) { try { outputStream.close(); } catch (Throwable t) { ; } } if (inputStream != null) { try { inputStream.close(); } catch (Throwable t) { ; } } } } /** *

* Encodes data from the given source file contents and writes them in the * given target file. *

* * @param source * The source file, from which decoded data are read. * @param target * The target file, in which encoded data are written. * @throws IOException * If an I/O error occurs. * @since 1.3 */ public static void encode(File source, File target) throws IOException { InputStream inputStream = null; OutputStream outputStream = null; try { inputStream = new FileInputStream(source); outputStream = new FileOutputStream(target); Base64.encode(inputStream, outputStream); } finally { if (outputStream != null) { try { outputStream.close(); } catch (Throwable t) { ; } } if (inputStream != null) { try { inputStream.close(); } catch (Throwable t) { ; } } } } /** *

* Decodes data from the given source file contents and writes them in the * given target file. *

* * @param source * The source file, from which encoded data are read. * @param target * The target file, in which decoded data are written. * @throws IOException * If an I/O error occurs. * @since 1.3 */ public static void decode(File source, File target) throws IOException { InputStream inputStream = null; OutputStream outputStream = null; try { inputStream = new FileInputStream(source); outputStream = new FileOutputStream(target); decode(inputStream, outputStream); } finally { if (outputStream != null) { try { outputStream.close(); } catch (Throwable t) { ; } } if (inputStream != null) { try { inputStream.close(); } catch (Throwable t) { ; } } } } /** * Copies data from a stream to another. * * @param inputStream * The input stream. * @param outputStream * The output stream. * @throws IOException * If a unexpected I/O error occurs. */ private static void copy(InputStream inputStream, OutputStream outputStream) throws IOException { // 1KB buffer byte[] b = new byte[1024]; int len; while ((len = inputStream.read(b)) != -1) { outputStream.write(b, 0, len); } } }