001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.quercus.lib.i18n;
031:
032: import com.caucho.quercus.QuercusModuleException;
033: import com.caucho.quercus.UnimplementedException;
034: import com.caucho.quercus.env.*;
035: import com.caucho.vfs.*;
036:
037: import javax.mail.internet.MimeUtility;
038: import java.io.IOException;
039: import java.io.Reader;
040: import java.io.UnsupportedEncodingException;
041: import java.util.logging.*;
042:
043: public class IconvUtility {
044: private static final Logger log = Logger
045: .getLogger(IconvUtility.class.getName());
046:
047: public static StringValue decodeEncode(Env env, StringValue str,
048: String inCharset, String outCharset)
049: throws UnsupportedEncodingException {
050: return decodeEncode(env, str, inCharset, outCharset, 0,
051: Integer.MAX_VALUE);
052: }
053:
054: public static StringValue decodeEncode(Env env, StringValue str,
055: String inCharset, String outCharset, int offset)
056: throws UnsupportedEncodingException {
057: return decodeEncode(env, str, inCharset, outCharset, offset,
058: Integer.MAX_VALUE);
059: }
060:
061: /**
062: * Decodes and encodes to specified charsets at the same time.
063: */
064: public static StringValue decodeEncode(Env env, StringValue str,
065: String inCharset, String outCharset, int offset, int length)
066: throws UnsupportedEncodingException {
067: TempCharBuffer tb = TempCharBuffer.allocate();
068: char[] charBuf = tb.getBuffer();
069:
070: try {
071: Reader in;
072:
073: try {
074: in = str.toReader(inCharset);
075: } catch (IOException e) {
076: log.log(Level.WARNING, e.toString(), e);
077:
078: in = str.toReader("utf-8");
079: }
080:
081: TempStream ts = new TempStream();
082: WriteStream out = new WriteStream(ts);
083:
084: try {
085: out.setEncoding(outCharset);
086: } catch (IOException e) {
087: log.log(Level.WARNING, e.toString(), e);
088:
089: out.setEncoding("utf-8");
090: }
091:
092: while (offset > 0) {
093: if (in.read() < 0)
094: break;
095: offset--;
096: }
097:
098: int sublen;
099:
100: while (length > 0
101: && (sublen = in.read(charBuf, 0, charBuf.length)) >= 0) {
102:
103: sublen = Math.min(length, sublen);
104:
105: out.print(charBuf, 0, sublen);
106: length -= sublen;
107: }
108:
109: out.flush();
110:
111: StringValue sb = env.createBinaryBuilder();
112: for (TempBuffer ptr = ts.getHead(); ptr != null; ptr = ptr
113: .getNext()) {
114: sb.append(ptr.getBuffer(), 0, ptr.getLength());
115: }
116:
117: return sb;
118: } catch (IOException e) {
119: throw new QuercusModuleException(e);
120: }
121:
122: finally {
123: TempCharBuffer.free(tb);
124: }
125: }
126:
127: /**
128: * Returns decoded Mime header/field.
129: */
130: public static StringValue decodeMime(Env env, CharSequence word,
131: String charset) throws UnsupportedEncodingException {
132: StringValue str = env.createString(MimeUtility
133: .unfold(MimeUtility.decodeText(word.toString())));
134:
135: return str.toBinaryValue(env, charset);
136: }
137:
138: public static Value encodeMime(Env env, StringValue name,
139: StringValue value, String inCharset, String outCharset,
140: String scheme) throws UnsupportedEncodingException {
141: return encodeMime(env, name, value, inCharset, outCharset,
142: scheme, "\r\n", 76);
143: }
144:
145: /**
146: * Encodes a MIME header.
147: *
148: * XXX: preferences
149: *
150: * @param field_name header field name
151: * @param field_value header field value
152: * @param preferences
153: */
154: /**
155: * Returns an encoded Mime header.
156: */
157: public static StringValue encodeMime(Env env, StringValue name,
158: StringValue value, String inCharset, String outCharset,
159: String scheme, String lineBreakChars, int lineLength)
160: throws UnsupportedEncodingException {
161: name = name.toUnicodeValue(env, inCharset);
162: value = value.toUnicodeValue(env, inCharset);
163:
164: StringValue sb = env.createUnicodeBuilder();
165: sb.append(name);
166: sb.append(':');
167: sb.append(' ');
168:
169: String word = encodeMimeWord(value.toString(), outCharset,
170: scheme, lineBreakChars, lineLength);
171:
172: sb.append(MimeUtility.fold(sb.length(), word));
173:
174: return sb;
175: }
176:
177: public static String encodeMimeWord(String value, String charset,
178: String scheme, String lineBreakChars, int lineLength)
179: throws UnsupportedEncodingException {
180: if (lineLength != 76)
181: throw new UnimplementedException("Mime line length option");
182:
183: if (!lineBreakChars.equals("\r\n"))
184: throw new UnimplementedException("Mime line break option");
185:
186: return MimeUtility.encodeWord(value, charset, scheme);
187: }
188: }
|