1 /**
2 *
3 * Copyright 2003-2006 The Apache Software Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.geronimo.mail.util;
19
20 import java.io.IOException;
21 import java.io.OutputStream;
22
23 public class XTextEncoder
24 implements Encoder
25 {
26 protected final byte[] encodingTable =
27 {
28 (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7',
29 (byte)'8', (byte)'9', (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F'
30 };
31
32
33
34
35 protected final byte[] decodingTable = new byte[128];
36
37 protected void initialiseDecodingTable()
38 {
39 for (int i = 0; i < encodingTable.length; i++)
40 {
41 decodingTable[encodingTable[i]] = (byte)i;
42 }
43 }
44
45 public XTextEncoder()
46 {
47 initialiseDecodingTable();
48 }
49
50 /**
51 * encode the input data producing an XText output stream.
52 *
53 * @return the number of bytes produced.
54 */
55 public int encode(
56 byte[] data,
57 int off,
58 int length,
59 OutputStream out)
60 throws IOException
61 {
62 int bytesWritten = 0;
63
64 for (int i = off; i < (off + length); i++)
65 {
66 int v = data[i] & 0xff;
67
68 if (v < 33 || v > 126 || v == '+' || v == '+') {
69 out.write((byte)'+');
70 out.write(encodingTable[(v >>> 4)]);
71 out.write(encodingTable[v & 0xf]);
72 bytesWritten += 3;
73 }
74 else {
75
76 out.write((byte)v);
77 bytesWritten++;
78 }
79 }
80
81 return bytesWritten;
82 }
83
84
85 /**
86 * decode the xtext encoded byte data writing it to the given output stream
87 *
88 * @return the number of bytes produced.
89 */
90 public int decode(
91 byte[] data,
92 int off,
93 int length,
94 OutputStream out)
95 throws IOException
96 {
97 byte[] bytes;
98 byte b1, b2;
99 int outLen = 0;
100
101 int end = off + length;
102
103 int i = off;
104 while (i < end)
105 {
106 byte v = data[i++];
107
108 if (v == '+') {
109 b1 = decodingTable[data[i++]];
110 b2 = decodingTable[data[i++]];
111 out.write((b1 << 4) | b2);
112 }
113 else {
114
115 out.write(v);
116 }
117
118 outLen++;
119 }
120
121 return outLen;
122 }
123
124 /**
125 * decode the xtext encoded String data writing it to the given output stream.
126 *
127 * @return the number of bytes produced.
128 */
129 public int decode(
130 String data,
131 OutputStream out)
132 throws IOException
133 {
134 byte[] bytes;
135 byte b1, b2, b3, b4;
136 int length = 0;
137
138 int end = data.length();
139
140 int i = 0;
141 while (i < end)
142 {
143 char v = data.charAt(i++);
144 if (v == '+') {
145 b1 = decodingTable[data.charAt(i++)];
146 b2 = decodingTable[data.charAt(i++)];
147
148 out.write((b1 << 4) | b2);
149 }
150 else {
151 out.write((byte)v);
152 }
153 length++;
154 }
155
156 return length;
157 }
158 }
159