1/*
2 * Copyright 2001-2004 The Apache Software Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.apache.commons.codec.net;
18
19import java.io.UnsupportedEncodingException;
20import org.apache.commons.codec.DecoderException;
21import org.apache.commons.codec.EncoderException;
22import org.apache.commons.codec.StringDecoder;
23import org.apache.commons.codec.StringEncoder;
24import org.apache.commons.codec.binary.Base64;
25
26/**
27 * <p>
28 * Identical to the Base64 encoding defined by <a href="http://www.ietf.org/rfc/rfc1521.txt">RFC
29 * 1521</a> and allows a character set to be specified.
30 * </p>
31 *
32 * <p>
33 * <a href="http://www.ietf.org/rfc/rfc1522.txt">RFC 1522</a> describes techniques to allow the encoding of non-ASCII
34 * text in various portions of a RFC 822 [2] message header, in a manner which is unlikely to confuse existing message
35 * handling software.
36 * </p>
37 *
38 * @see <a href="http://www.ietf.org/rfc/rfc1522.txt">MIME (Multipurpose Internet Mail Extensions) Part Two: Message
39 *          Header Extensions for Non-ASCII Text</a>
40 *
41 * @author Apache Software Foundation
42 * @since 1.3
43 * @version $Id: BCodec.java,v 1.5 2004/04/13 22:46:37 ggregory Exp $
44 */
45public class BCodec extends RFC1522Codec implements StringEncoder, StringDecoder {
46    /**
47     * The default charset used for string decoding and encoding.
48     */
49    private String charset = StringEncodings.UTF8;
50
51    /**
52     * Default constructor.
53     */
54    public BCodec() {
55        super();
56    }
57
58    /**
59     * Constructor which allows for the selection of a default charset
60     *
61     * @param charset
62     *                  the default string charset to use.
63     *
64     * @see <a href="http://java.sun.com/j2se/1.3/docs/api/java/lang/package-summary.html#charenc">JRE character
65     *          encoding names</a>
66     */
67    public BCodec(final String charset) {
68        super();
69        this.charset = charset;
70    }
71
72    protected String getEncoding() {
73        return "B";
74    }
75
76    protected byte[] doEncoding(byte[] bytes) throws EncoderException {
77        if (bytes == null) {
78            return null;
79        }
80        return Base64.encodeBase64(bytes);
81    }
82
83    protected byte[] doDecoding(byte[] bytes) throws DecoderException {
84        if (bytes == null) {
85            return null;
86        }
87        return Base64.decodeBase64(bytes);
88    }
89
90    /**
91     * Encodes a string into its Base64 form using the specified charset. Unsafe characters are escaped.
92     *
93     * @param value
94     *                  string to convert to Base64 form
95     * @param charset
96     *                  the charset for pString
97     * @return Base64 string
98     *
99     * @throws EncoderException
100     *                  thrown if a failure condition is encountered during the encoding process.
101     */
102    public String encode(final String value, final String charset) throws EncoderException {
103        if (value == null) {
104            return null;
105        }
106        try {
107            return encodeText(value, charset);
108        } catch (UnsupportedEncodingException e) {
109            throw new EncoderException(e.getMessage());
110        }
111    }
112
113    /**
114     * Encodes a string into its Base64 form using the default charset. Unsafe characters are escaped.
115     *
116     * @param value
117     *                  string to convert to Base64 form
118     * @return Base64 string
119     *
120     * @throws EncoderException
121     *                  thrown if a failure condition is encountered during the encoding process.
122     */
123    public String encode(String value) throws EncoderException {
124        if (value == null) {
125            return null;
126        }
127        return encode(value, getDefaultCharset());
128    }
129
130    /**
131     * Decodes a Base64 string into its original form. Escaped characters are converted back to their original
132     * representation.
133     *
134     * @param value
135     *                  Base64 string to convert into its original form
136     *
137     * @return original string
138     *
139     * @throws DecoderException
140     *                  A decoder exception is thrown if a failure condition is encountered during the decode process.
141     */
142    public String decode(String value) throws DecoderException {
143        if (value == null) {
144            return null;
145        }
146        try {
147            return decodeText(value);
148        } catch (UnsupportedEncodingException e) {
149            throw new DecoderException(e.getMessage());
150        }
151    }
152
153    /**
154     * Encodes an object into its Base64 form using the default charset. Unsafe characters are escaped.
155     *
156     * @param value
157     *                  object to convert to Base64 form
158     * @return Base64 object
159     *
160     * @throws EncoderException
161     *                  thrown if a failure condition is encountered during the encoding process.
162     */
163    public Object encode(Object value) throws EncoderException {
164        if (value == null) {
165            return null;
166        } else if (value instanceof String) {
167            return encode((String) value);
168        } else {
169            throw new EncoderException("Objects of type "
170                + value.getClass().getName()
171                + " cannot be encoded using BCodec");
172        }
173    }
174
175    /**
176     * Decodes a Base64 object into its original form. Escaped characters are converted back to their original
177     * representation.
178     *
179     * @param value
180     *                  Base64 object to convert into its original form
181     *
182     * @return original object
183     *
184     * @throws DecoderException
185     *                  A decoder exception is thrown if a failure condition is encountered during the decode process.
186     */
187    public Object decode(Object value) throws DecoderException {
188        if (value == null) {
189            return null;
190        } else if (value instanceof String) {
191            return decode((String) value);
192        } else {
193            throw new DecoderException("Objects of type "
194                + value.getClass().getName()
195                + " cannot be decoded using BCodec");
196        }
197    }
198
199    /**
200     * The default charset used for string decoding and encoding.
201     *
202     * @return the default string charset.
203     */
204    public String getDefaultCharset() {
205        return this.charset;
206    }
207}
208