Home | History | Annotate | Download | only in mime
      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