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