001/****************************************************************
002 * Licensed to the Apache Software Foundation (ASF) under one   *
003 * or more contributor license agreements.  See the NOTICE file *
004 * distributed with this work for additional information        *
005 * regarding copyright ownership.  The ASF licenses this file   *
006 * to you under the Apache License, Version 2.0 (the            *
007 * "License"); you may not use this file except in compliance   *
008 * with the License.  You may obtain a copy of the License at   *
009 *                                                              *
010 *   http://www.apache.org/licenses/LICENSE-2.0                 *
011 *                                                              *
012 * Unless required by applicable law or agreed to in writing,   *
013 * software distributed under the License is distributed on an  *
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
015 * KIND, either express or implied.  See the License for the    *
016 * specific language governing permissions and limitations      *
017 * under the License.                                           *
018 ****************************************************************/
019
020package org.apache.james.mime4j.util;
021
022import java.nio.ByteBuffer;
023import java.nio.CharBuffer;
024import java.nio.charset.Charset;
025
026/**
027 * Utility methods for converting textual content of a message.
028 */
029public class ContentUtil {
030
031    private ContentUtil() {
032    }
033
034    /**
035     * Encodes the specified string into an immutable sequence of bytes using
036     * the US-ASCII charset.
037     *
038     * @param string
039     *            string to encode.
040     * @return encoded string as an immutable sequence of bytes.
041     */
042    public static ByteSequence encode(String string) {
043        if (string == null) {
044            return null;
045        }
046        ByteArrayBuffer buf = new ByteArrayBuffer(string.length());
047        for (int i = 0; i < string.length(); i++) {
048            buf.append((byte) string.charAt(i));
049        }
050        return buf;
051    }
052
053    /**
054     * Encodes the specified string into an immutable sequence of bytes using
055     * the specified charset.
056     *
057     * @param charset
058     *            Java charset to be used for the conversion.
059     * @param string
060     *            string to encode.
061     * @return encoded string as an immutable sequence of bytes.
062     */
063    public static ByteSequence encode(Charset charset, String string) {
064        if (string == null) {
065            return null;
066        }
067        if (charset == null) {
068            charset = Charset.defaultCharset();
069        }
070        ByteBuffer encoded = charset.encode(CharBuffer.wrap(string));
071        ByteArrayBuffer buf = new ByteArrayBuffer(encoded.remaining());
072        buf.append(encoded.array(), encoded.position(), encoded.remaining());
073        return buf;
074    }
075
076    /**
077     * Decodes the specified sequence of bytes into a string using the US-ASCII
078     * charset.
079     *
080     * @param byteSequence
081     *            sequence of bytes to decode.
082     * @return decoded string.
083     */
084    public static String decode(ByteSequence byteSequence) {
085        if (byteSequence == null) {
086            return null;
087        }
088        return decode(byteSequence, 0, byteSequence.length());
089    }
090
091    /**
092     * Decodes the specified sequence of bytes into a string using the specified
093     * charset.
094     *
095     * @param charset
096     *            Java charset to be used for the conversion.
097     * @param byteSequence
098     *            sequence of bytes to decode.
099     * @return decoded string.
100     */
101    public static String decode(Charset charset, ByteSequence byteSequence) {
102        return decode(charset, byteSequence, 0, byteSequence.length());
103    }
104
105    /**
106     * Decodes a sub-sequence of the specified sequence of bytes into a string
107     * using the US-ASCII charset.
108     *
109     * @param byteSequence
110     *            sequence of bytes to decode.
111     * @param offset
112     *            offset into the byte sequence.
113     * @param length
114     *            number of bytes.
115     * @return decoded string.
116     */
117    public static String decode(ByteSequence byteSequence, int offset, int length) {
118        if (byteSequence == null) {
119            return null;
120        }
121        StringBuilder buf = new StringBuilder(length);
122        for (int i = offset; i < offset + length; i++) {
123            buf.append((char) (byteSequence.byteAt(i) & 0xff));
124        }
125        return buf.toString();
126    }
127
128    /**
129     * Decodes a sub-sequence of the specified sequence of bytes into a string
130     * using the specified charset.
131     *
132     * @param charset
133     *            Java charset to be used for the conversion.
134     * @param byteSequence
135     *            sequence of bytes to decode.
136     * @param offset
137     *            offset into the byte sequence.
138     * @param length
139     *            number of bytes.
140     * @return decoded string.
141     */
142    public static String decode(Charset charset, ByteSequence byteSequence,
143            int offset, int length) {
144        if (byteSequence == null) {
145            return null;
146        }
147        if (charset == null) {
148            charset = Charset.defaultCharset();
149        }
150        if (byteSequence instanceof ByteArrayBuffer) {
151            ByteArrayBuffer bab = (ByteArrayBuffer) byteSequence;
152            return decode(charset, bab.buffer(), offset, length);
153        } else {
154            byte[] bytes = byteSequence.toByteArray();
155            return decode(charset, bytes, offset, length);
156        }
157    }
158
159    private static String decode(Charset charset, byte[] buffer, int offset,
160            int length) {
161        return charset.decode(ByteBuffer.wrap(buffer, offset, length))
162                .toString();
163    }
164
165}