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 020 package org.apache.geronimo.mail.util; 021 022 import java.io.IOException; 023 import java.io.OutputStream; 024 025 /** 026 * @version $Rev: 467553 $ $Date: 2006-10-25 06:01:51 +0200 (Mi, 25. Okt 2006) $ 027 */ 028 public class HexEncoder 029 implements Encoder 030 { 031 protected final byte[] encodingTable = 032 { 033 (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', 034 (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f' 035 }; 036 037 /* 038 * set up the decoding table. 039 */ 040 protected final byte[] decodingTable = new byte[128]; 041 042 protected void initialiseDecodingTable() 043 { 044 for (int i = 0; i < encodingTable.length; i++) 045 { 046 decodingTable[encodingTable[i]] = (byte)i; 047 } 048 049 decodingTable['A'] = decodingTable['a']; 050 decodingTable['B'] = decodingTable['b']; 051 decodingTable['C'] = decodingTable['c']; 052 decodingTable['D'] = decodingTable['d']; 053 decodingTable['E'] = decodingTable['e']; 054 decodingTable['F'] = decodingTable['f']; 055 } 056 057 public HexEncoder() 058 { 059 initialiseDecodingTable(); 060 } 061 062 /** 063 * encode the input data producing a Hex output stream. 064 * 065 * @return the number of bytes produced. 066 */ 067 public int encode( 068 byte[] data, 069 int off, 070 int length, 071 OutputStream out) 072 throws IOException 073 { 074 for (int i = off; i < (off + length); i++) 075 { 076 int v = data[i] & 0xff; 077 078 out.write(encodingTable[(v >>> 4)]); 079 out.write(encodingTable[v & 0xf]); 080 } 081 082 return length * 2; 083 } 084 085 private boolean ignore( 086 char c) 087 { 088 return (c == '\n' || c =='\r' || c == '\t' || c == ' '); 089 } 090 091 /** 092 * decode the Hex encoded byte data writing it to the given output stream, 093 * whitespace characters will be ignored. 094 * 095 * @return the number of bytes produced. 096 */ 097 public int decode( 098 byte[] data, 099 int off, 100 int length, 101 OutputStream out) 102 throws IOException 103 { 104 byte[] bytes; 105 byte b1, b2; 106 int outLen = 0; 107 108 int end = off + length; 109 110 while (end > 0) 111 { 112 if (!ignore((char)data[end - 1])) 113 { 114 break; 115 } 116 117 end--; 118 } 119 120 int i = off; 121 while (i < end) 122 { 123 while (i < end && ignore((char)data[i])) 124 { 125 i++; 126 } 127 128 b1 = decodingTable[data[i++]]; 129 130 while (i < end && ignore((char)data[i])) 131 { 132 i++; 133 } 134 135 b2 = decodingTable[data[i++]]; 136 137 out.write((b1 << 4) | b2); 138 139 outLen++; 140 } 141 142 return outLen; 143 } 144 145 /** 146 * decode the Hex encoded String data writing it to the given output stream, 147 * whitespace characters will be ignored. 148 * 149 * @return the number of bytes produced. 150 */ 151 public int decode( 152 String data, 153 OutputStream out) 154 throws IOException 155 { 156 byte[] bytes; 157 byte b1, b2, b3, b4; 158 int length = 0; 159 160 int end = data.length(); 161 162 while (end > 0) 163 { 164 if (!ignore(data.charAt(end - 1))) 165 { 166 break; 167 } 168 169 end--; 170 } 171 172 int i = 0; 173 while (i < end) 174 { 175 while (i < end && ignore(data.charAt(i))) 176 { 177 i++; 178 } 179 180 b1 = decodingTable[data.charAt(i++)]; 181 182 while (i < end && ignore(data.charAt(i))) 183 { 184 i++; 185 } 186 187 b2 = decodingTable[data.charAt(i++)]; 188 189 out.write((b1 << 4) | b2); 190 191 length++; 192 } 193 194 return length; 195 } 196 }