1 18 package org.apache.batik.util; 19 20 import java.io.ByteArrayInputStream ; 21 import java.io.IOException ; 22 import java.io.InputStream ; 23 import java.util.Iterator ; 24 25 33 public class ParsedURLDataProtocolHandler 34 extends AbstractParsedURLProtocolHandler { 35 36 static final String DATA_PROTOCOL = "data"; 37 static final String BASE64 = "base64"; 38 static final String CHARSET = "charset"; 39 40 public ParsedURLDataProtocolHandler() { 41 super(DATA_PROTOCOL); 42 } 43 44 public ParsedURLData parseURL(ParsedURL baseURL, String urlStr) { 45 return parseURL(urlStr); 47 } 48 49 public ParsedURLData parseURL(String urlStr) { 50 DataParsedURLData ret = new DataParsedURLData(); 51 52 int pidx=0, idx; 53 idx = urlStr.indexOf(':'); 54 if (idx != -1) { 55 ret.protocol = urlStr.substring(pidx, idx); 57 if (ret.protocol.indexOf('/') == -1) 58 pidx = idx+1; 59 else { 60 ret.protocol = null; 63 pidx = 0; 64 } 65 } 66 67 idx = urlStr.indexOf(',',pidx); 68 if ((idx != -1) && (idx != pidx)) { 69 ret.host = urlStr.substring(pidx, idx); 70 pidx = idx+1; 71 72 int aidx = ret.host.lastIndexOf(';'); 73 if ((aidx == -1) || (aidx==ret.host.length())) { 74 ret.contentType = ret.host; 75 } else { 76 String enc = ret.host.substring(aidx+1); 77 idx = enc.indexOf('='); 78 if (idx == -1) { 79 ret.contentEncoding = enc; 81 ret.contentType = ret.host.substring(0, aidx); 82 } else { 83 ret.contentType = ret.host; 84 } 85 aidx = 0; 87 idx = ret.contentType.indexOf(';', aidx); 88 if (idx != -1) { 89 aidx = idx+1; 90 while (aidx < ret.contentType.length()) { 91 idx = ret.contentType.indexOf(';', aidx); 92 if (idx == -1) idx = ret.contentType.length(); 93 String param = ret.contentType.substring(aidx, idx); 94 int eqIdx = param.indexOf('='); 95 if ((eqIdx != -1) && 96 (CHARSET.equals(param.substring(0,eqIdx)))) 97 ret.charset = param.substring(eqIdx+1); 98 aidx = idx+1; 99 } 100 } 101 } 102 } 103 104 if (pidx != urlStr.length()) 105 ret.path = urlStr.substring(pidx); 106 107 return ret; 108 } 109 110 113 static class DataParsedURLData extends ParsedURLData { 114 String charset= null; 115 116 public boolean complete() { 117 return (path != null); 118 } 119 120 public String getPortStr() { 121 String portStr ="data:"; 122 if (host != null) portStr += host; 123 portStr += ","; 124 return portStr; 125 } 126 127 public String toString() { 128 String ret = getPortStr(); 129 if (path != null) ret += path; 130 return ret; 131 } 132 133 137 public String getContentType(String userAgent) { 138 return contentType; 139 } 140 141 145 public String getContentEncoding(String userAgent) { 146 return contentEncoding; 147 } 148 149 protected InputStream openStreamInternal 150 (String userAgent, Iterator mimeTypes, Iterator encodingTypes) 151 throws IOException { 152 if (BASE64.equals(contentEncoding)) { 153 byte [] data = path.getBytes(); 154 stream = new ByteArrayInputStream (data); 155 stream = new Base64DecodeStream(stream); 156 } else { 157 stream = decode(path); 158 } 159 return stream; 160 } 161 162 public static InputStream decode(String s) { 163 int len = s.length(); 164 byte [] data = new byte[len]; 165 int j=0; 166 for(int i=0; i<len; i++) { 167 char c = s.charAt(i); 168 switch (c) { 169 default : data[j++]= (byte)c; break; 170 case '%': { 171 if (i+2 < len) { 172 i += 2; 173 byte b; 174 char c1 = s.charAt(i-1); 175 if (c1 >= '0' && c1 <= '9') b=(byte)(c1-'0'); 176 else if (c1 >= 'a' && c1 <= 'z') b=(byte)(c1-'a'+10); 177 else if (c1 >= 'A' && c1 <= 'Z') b=(byte)(c1-'A'+10); 178 else break; 179 b*=16; 180 181 char c2 = s.charAt(i); 182 if (c2 >= '0' && c2 <= '9') b+=(byte)(c2-'0'); 183 else if (c2 >= 'a' && c2 <= 'z') b+=(byte)(c2-'a'+10); 184 else if (c2 >= 'A' && c2 <= 'Z') b+=(byte)(c2-'A'+10); 185 else break; 186 data[j++] = b; 187 } 188 } 189 break; 190 } 191 } 192 return new ByteArrayInputStream (data, 0, j); 193 } 194 } 195 } 196 197 | Popular Tags |