| /* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a copy |
| * of this software and associated documentation files (the "Software"), to deal |
| * in the Software without restriction, including without limitation the rights |
| * to use, copy, modify, merge, publish, distribute, sublicense, and/or |
| * sell copies of the Software, and to permit persons to whom the Software is |
| * furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included in |
| * all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| * IN THE SOFTWARE. */ |
| |
| package org.ksoap2.kobjects.mime; |
| |
| import java.io.*; |
| import java.util.*; |
| import org.ksoap2.kobjects.base64.Base64; |
| |
| public class Decoder { |
| |
| InputStream is; |
| Hashtable header; |
| boolean eof; |
| boolean consumed; |
| String boundary; |
| String characterEncoding; |
| |
| char[] buf = new char[256]; |
| |
| // add some kind of buffering here!!! |
| |
| private final String readLine() throws IOException { |
| |
| int cnt = 0; |
| |
| while (true) { |
| int i = is.read(); |
| if (i == -1 && cnt == 0) |
| return null; |
| else if (i == -1 || i == '\n') |
| return new String(buf, 0, cnt); |
| else if (i != '\r') { |
| if (cnt >= buf.length) { |
| char[] tmp = new char[(buf.length * 3) / 2]; |
| System.arraycopy(buf, 0, tmp, 0, buf.length); |
| buf = tmp; |
| } |
| |
| buf[cnt++] = (char) i; |
| } |
| } |
| } |
| |
| /** |
| * The "main" element is returned in the |
| * hashtable with an empty key ("") */ |
| |
| public static Hashtable getHeaderElements(String header) { |
| |
| String key = ""; |
| int pos = 0; |
| Hashtable result = new Hashtable(); |
| int len = header.length(); |
| |
| while (true) { |
| // skip spaces |
| |
| while (pos < len && header.charAt(pos) <= ' ') |
| pos++; |
| if (pos >= len) |
| break; |
| |
| if (header.charAt(pos) == '"') { |
| pos++; |
| int cut = header.indexOf('"', pos); |
| if (cut == -1) |
| throw new RuntimeException("End quote expected in " + header); |
| |
| result.put(key, header.substring(pos, cut)); |
| pos = cut + 2; |
| |
| if (pos >= len) |
| break; |
| if (header.charAt(pos - 1) != ';') |
| throw new RuntimeException("; expected in " + header); |
| } |
| else { |
| int cut = header.indexOf(';', pos); |
| if (cut == -1) { |
| result.put(key, header.substring(pos)); |
| break; |
| } |
| result.put(key, header.substring(pos, cut)); |
| pos = cut + 1; |
| } |
| |
| int cut = header.indexOf('=', pos); |
| |
| if (cut == -1) |
| break; |
| |
| key = header.substring(pos, cut).toLowerCase().trim(); |
| pos = cut + 1; |
| } |
| // System.out.println("header: "+result); |
| |
| return result; |
| } |
| |
| public Decoder(InputStream is, String _bound) throws IOException { |
| this(is, _bound, null); |
| } |
| |
| public Decoder(InputStream is, String _bound, String characterEncoding) throws IOException { |
| |
| this.characterEncoding = characterEncoding; |
| this.is = is; |
| this.boundary = "--" + _bound; |
| |
| // StringBuffer buf = new StringBuffer(); |
| |
| String line = null; |
| while (true) { |
| line = readLine(); |
| if (line == null) |
| throw new IOException("Unexpected EOF"); |
| |
| // System.out.println("line: '" + line + "'"); |
| // System.out.println("bound: '" + boundary + "'"); |
| |
| if (line.startsWith(boundary)) |
| break; |
| // buf.append(line); |
| } |
| |
| // data = buf.toString().getBytes(); |
| if (line.endsWith("--")) { |
| eof = true; |
| is.close(); |
| } |
| |
| consumed = true; |
| } |
| |
| public Enumeration getHeaderNames() { |
| return header.keys(); |
| } |
| |
| public String getHeader(String key) { |
| return (String) header.get(key.toLowerCase()); |
| } |
| |
| public String readContent() throws IOException { |
| ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
| readContent(bos); |
| String result = characterEncoding == null |
| ? new String(bos.toByteArray()) |
| : new String(bos.toByteArray(), characterEncoding); |
| |
| System.out.println("Field content: '" + result + "'"); |
| return result; |
| } |
| |
| public void readContent(OutputStream os) throws IOException { |
| if (consumed) |
| throw new RuntimeException("Content already consumed!"); |
| |
| String line = ""; |
| |
| String contentType = getHeader("Content-Type"); |
| // System.out.println("header: " + header); |
| // System.out.println("Content-Type: "+contentType); |
| |
| if ("base64".equals(getHeader("Content-Transfer-Encoding"))) { |
| ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
| while (true) { |
| line = readLine(); |
| if (line == null) |
| throw new IOException("Unexpected EOF"); |
| if (line.startsWith(boundary)) |
| break; |
| |
| Base64.decode(line, os); |
| } |
| } |
| else { |
| |
| String deli = "\r\n" + boundary; |
| int match = 0; |
| |
| while (true) { |
| int i = is.read(); |
| /* if (i >= 32 && i <= 127) |
| System.out.print((char) i); |
| else |
| System.out.print("#" + i + ";"); */ |
| if (i == -1) |
| throw new RuntimeException("Unexpected EOF"); |
| |
| if (((char) i) == deli.charAt(match)) { |
| match++; |
| if (match == deli.length()) |
| break; |
| } |
| else { |
| if (match > 0) { |
| for (int j = 0; j < match; j++) |
| os.write((byte) deli.charAt(j)); |
| |
| match = ((char) i == deli.charAt(0)) ? 1 : 0; |
| } |
| if (match == 0) |
| os.write((byte) i); |
| } |
| } |
| |
| line = readLine(); // read crlf and possibly remaining -- |
| } |
| |
| if (line.endsWith("--")) |
| eof = true; |
| |
| consumed = true; |
| } |
| |
| // public boolean next() throws IOException { |
| |
| // if(!consumed) |
| // readContent(null); |
| |
| // if (eof) |
| // return false; |
| |
| // // read header |
| |
| // header = new Hashtable(); |
| // String line; |
| |
| // while (true) { |
| // line = readLine(); |
| // if (line == null || line.equals("")) |
| // break; |
| // int cut = line.indexOf(':'); |
| // if (cut == -1) |
| // throw new IOException("colon missing in multipart header line: " + line); |
| |
| // header.put( |
| // line.substring(0, cut).trim().toLowerCase(), |
| // line.substring(cut + 1).trim()); |
| /* |
| System.out.println( |
| "key: '" |
| + line.substring(0, cut).trim().toLowerCase() |
| + "' value: '" |
| + line.substring(cut + 1).trim());*/ |
| |
| // } |
| |
| // consumed = false; |
| // |
| // return true; |
| // } |
| } |