1 /* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * @(#)QEncoderStream.java 1.4 02/03/27 28 */ 29 30 31 32 package com.sun.xml.internal.messaging.saaj.packaging.mime.util; 33 34 import java.io.IOException; 35 import java.io.OutputStream; 36 37 /** 38 * This class implements a Q Encoder as defined by RFC 2047 for 39 * encoding MIME headers. It subclasses the QPEncoderStream class. 40 * 41 * @author John Mani 42 */ 43 44 public class QEncoderStream extends QPEncoderStream { 45 46 private String specials; 47 private static String WORD_SPECIALS = "=_?\"#$%&'(),.:;<>@[\\]^`{|}~"; 48 private static String TEXT_SPECIALS = "=_?"; 49 50 /** 51 * Create a Q encoder that encodes the specified input stream 52 * @param out the output stream 53 * @param encodingWord true if we are Q-encoding a word within a 54 * phrase. 55 */ 56 public QEncoderStream(OutputStream out, boolean encodingWord) { 57 super(out, Integer.MAX_VALUE); // MAX_VALUE is 2^31, should 58 // suffice (!) to indicate that 59 // CRLFs should not be inserted 60 // when encoding rfc822 headers 61 62 // a RFC822 "word" token has more restrictions than a 63 // RFC822 "text" token. 64 specials = encodingWord ? WORD_SPECIALS : TEXT_SPECIALS; 65 } 66 67 /** 68 * Encodes the specified <code>byte</code> to this output stream. 69 * @param c the <code>byte</code>. 70 * @exception IOException if an I/O error occurs. 71 */ 72 public void write(int c) throws IOException { 73 c = c & 0xff; // Turn off the MSB. 74 if (c == ' ') 75 output('_', false); 76 else if (c < 040 || c >= 0177 || specials.indexOf(c) >= 0) 77 // Encoding required. 78 output(c, true); 79 else // No encoding required 80 output(c, false); 81 } 82 83 /** 84 * Returns the length of the encoded version of this byte array. 85 */ 86 public static int encodedLength(byte[] b, boolean encodingWord) { 87 int len = 0; 88 String specials = encodingWord ? WORD_SPECIALS: TEXT_SPECIALS; 89 for (int i = 0; i < b.length; i++) { 90 int c = b[i] & 0xff; // Mask off MSB 91 if (c < 040 || c >= 0177 || specials.indexOf(c) >= 0) 92 // needs encoding 93 len += 3; // Q-encoding is 1 -> 3 conversion 94 else 95 len++; 96 } 97 return len; 98 } 99 100 /**** begin TEST program *** 101 public static void main(String argv[]) throws Exception { 102 FileInputStream infile = new FileInputStream(argv[0]); 103 QEncoderStream encoder = new QEncoderStream(System.out); 104 int c; 105 106 while ((c = infile.read()) != -1) 107 encoder.write(c); 108 encoder.close(); 109 } 110 *** end TEST program ***/ 111 }