1 /* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to deal 5 * in the Software without restriction, including without limitation the rights 6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 * sell copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 * IN THE SOFTWARE. */ 20 21 package org.ksoap2.kobjects.mime; 22 23 import java.io.*; 24 import java.util.*; 25 import org.ksoap2.kobjects.base64.*; 26 27 public class Decoder { 28 29 InputStream is; 30 Hashtable header; 31 boolean eof; 32 boolean consumed; 33 String boundary; 34 String characterEncoding; 35 36 char[] buf = new char[256]; 37 38 // add some kind of buffering here!!! 39 40 private final String readLine() throws IOException { 41 42 int cnt = 0; 43 44 while (true) { 45 int i = is.read(); 46 if (i == -1 && cnt == 0) 47 return null; 48 else if (i == -1 || i == '\n') 49 return new String(buf, 0, cnt); 50 else if (i != '\r') { 51 if (cnt >= buf.length) { 52 char[] tmp = new char[(buf.length * 3) / 2]; 53 System.arraycopy(buf, 0, tmp, 0, buf.length); 54 buf = tmp; 55 } 56 57 buf[cnt++] = (char) i; 58 } 59 } 60 } 61 62 /** 63 * The "main" element is returned in the 64 * hashtable with an empty key ("") */ 65 66 public static Hashtable getHeaderElements(String header) { 67 68 String key = ""; 69 int pos = 0; 70 Hashtable result = new Hashtable(); 71 int len = header.length(); 72 73 while (true) { 74 // skip spaces 75 76 while (pos < len && header.charAt(pos) <= ' ') 77 pos++; 78 if (pos >= len) 79 break; 80 81 if (header.charAt(pos) == '"') { 82 pos++; 83 int cut = header.indexOf('"', pos); 84 if (cut == -1) 85 throw new RuntimeException("End quote expected in " + header); 86 87 result.put(key, header.substring(pos, cut)); 88 pos = cut + 2; 89 90 if (pos >= len) 91 break; 92 if (header.charAt(pos - 1) != ';') 93 throw new RuntimeException("; expected in " + header); 94 } 95 else { 96 int cut = header.indexOf(';', pos); 97 if (cut == -1) { 98 result.put(key, header.substring(pos)); 99 break; 100 } 101 result.put(key, header.substring(pos, cut)); 102 pos = cut + 1; 103 } 104 105 int cut = header.indexOf('=', pos); 106 107 if (cut == -1) 108 break; 109 110 key = header.substring(pos, cut).toLowerCase().trim(); 111 pos = cut + 1; 112 } 113 // System.out.println("header: "+result); 114 115 return result; 116 } 117 118 public Decoder(InputStream is, String _bound) throws IOException { 119 this(is, _bound, null); 120 } 121 122 public Decoder(InputStream is, String _bound, String characterEncoding) throws IOException { 123 124 this.characterEncoding = characterEncoding; 125 this.is = is; 126 this.boundary = "--" + _bound; 127 128 // StringBuffer buf = new StringBuffer(); 129 130 String line = null; 131 while (true) { 132 line = readLine(); 133 if (line == null) 134 throw new IOException("Unexpected EOF"); 135 136 // System.out.println("line: '" + line + "'"); 137 // System.out.println("bound: '" + boundary + "'"); 138 139 if (line.startsWith(boundary)) 140 break; 141 // buf.append(line); 142 } 143 144 // data = buf.toString().getBytes(); 145 if (line.endsWith("--")) { 146 eof = true; 147 is.close(); 148 } 149 150 consumed = true; 151 } 152 153 public Enumeration getHeaderNames() { 154 return header.keys(); 155 } 156 157 public String getHeader(String key) { 158 return (String) header.get(key.toLowerCase()); 159 } 160 161 public String readContent() throws IOException { 162 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 163 readContent(bos); 164 String result = characterEncoding == null 165 ? new String(bos.toByteArray()) 166 : new String(bos.toByteArray(), characterEncoding); 167 168 System.out.println("Field content: '" + result + "'"); 169 return result; 170 } 171 172 public void readContent(OutputStream os) throws IOException { 173 if (consumed) 174 throw new RuntimeException("Content already consumed!"); 175 176 String line = ""; 177 178 String contentType = getHeader("Content-Type"); 179 // System.out.println("header: " + header); 180 // System.out.println("Content-Type: "+contentType); 181 182 if ("base64".equals(getHeader("Content-Transfer-Encoding"))) { 183 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 184 while (true) { 185 line = readLine(); 186 if (line == null) 187 throw new IOException("Unexpected EOF"); 188 if (line.startsWith(boundary)) 189 break; 190 191 Base64.decode(line, os); 192 } 193 } 194 else { 195 196 String deli = "\r\n" + boundary; 197 int match = 0; 198 199 while (true) { 200 int i = is.read(); 201 /* if (i >= 32 && i <= 127) 202 System.out.print((char) i); 203 else 204 System.out.print("#" + i + ";"); */ 205 if (i == -1) 206 throw new RuntimeException("Unexpected EOF"); 207 208 if (((char) i) == deli.charAt(match)) { 209 match++; 210 if (match == deli.length()) 211 break; 212 } 213 else { 214 if (match > 0) { 215 for (int j = 0; j < match; j++) 216 os.write((byte) deli.charAt(j)); 217 218 match = ((char) i == deli.charAt(0)) ? 1 : 0; 219 } 220 if (match == 0) 221 os.write((byte) i); 222 } 223 } 224 225 line = readLine(); // read crlf and possibly remaining -- 226 } 227 228 if (line.endsWith("--")) 229 eof = true; 230 231 consumed = true; 232 } 233 234 // public boolean next() throws IOException { 235 236 // if(!consumed) 237 // readContent(null); 238 239 // if (eof) 240 // return false; 241 242 // // read header 243 244 // header = new Hashtable(); 245 // String line; 246 247 // while (true) { 248 // line = readLine(); 249 // if (line == null || line.equals("")) 250 // break; 251 // int cut = line.indexOf(':'); 252 // if (cut == -1) 253 // throw new IOException("colon missing in multipart header line: " + line); 254 255 // header.put( 256 // line.substring(0, cut).trim().toLowerCase(), 257 // line.substring(cut + 1).trim()); 258 /* 259 System.out.println( 260 "key: '" 261 + line.substring(0, cut).trim().toLowerCase() 262 + "' value: '" 263 + line.substring(cut + 1).trim());*/ 264 265 // } 266 267 // consumed = false; 268 // 269 // return true; 270 // } 271 } 272