1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.host.file;
16
17 import java.io.IOException;
18 import java.nio.charset.Charset;
19 import java.nio.charset.StandardCharsets;
20 import java.nio.charset.UnsupportedCharsetException;
21 import java.util.Base64;
22 import java.util.Locale;
23
24 import org.apache.commons.io.Charsets;
25 import org.apache.commons.lang3.StringUtils;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.htmlunit.corejs.javascript.Function;
29 import org.htmlunit.corejs.javascript.ScriptableObject;
30 import org.htmlunit.corejs.javascript.typedarrays.NativeArrayBuffer;
31 import org.htmlunit.javascript.JavaScriptEngine;
32 import org.htmlunit.javascript.configuration.JsxClass;
33 import org.htmlunit.javascript.configuration.JsxConstant;
34 import org.htmlunit.javascript.configuration.JsxConstructor;
35 import org.htmlunit.javascript.configuration.JsxFunction;
36 import org.htmlunit.javascript.configuration.JsxGetter;
37 import org.htmlunit.javascript.configuration.JsxSetter;
38 import org.htmlunit.javascript.host.event.Event;
39 import org.htmlunit.javascript.host.event.EventTarget;
40 import org.htmlunit.protocol.data.DataURLConnection;
41 import org.htmlunit.util.MimeType;
42
43
44
45
46
47
48
49 @JsxClass
50 public class FileReader extends EventTarget {
51
52 private static final Log LOG = LogFactory.getLog(FileReader.class);
53
54
55 @JsxConstant
56 public static final int EMPTY = 0;
57
58
59 @JsxConstant
60 public static final int LOADING = 1;
61
62
63 @JsxConstant
64 public static final int DONE = 2;
65
66 private int readyState_ = EMPTY;
67 private Object result_;
68
69
70
71
72 @Override
73 @JsxConstructor
74 public void jsConstructor() {
75 super.jsConstructor();
76 }
77
78
79
80
81
82
83 @JsxGetter
84 public int getReadyState() {
85 return readyState_;
86 }
87
88
89
90
91
92 @JsxGetter
93 public Object getResult() {
94 return result_;
95 }
96
97
98
99
100
101
102 @JsxFunction
103 public void readAsDataURL(final Object object) throws IOException {
104 readyState_ = LOADING;
105
106 result_ = DataURLConnection.DATA_PREFIX;
107
108 final byte[] bytes = ((Blob) object).getBytes();
109 final String value = new String(Base64.getEncoder().encode(bytes), StandardCharsets.US_ASCII);
110
111 String contentType = ((Blob) object).getType();
112 if (StringUtils.isEmpty(contentType)) {
113 contentType = MimeType.APPLICATION_OCTET_STREAM;
114 }
115
116 result_ += contentType + ";base64," + value;
117 readyState_ = DONE;
118
119 final Event event = new Event(this, Event.TYPE_LOAD);
120 fireEvent(event);
121 }
122
123
124
125
126
127 @JsxFunction
128 public void readAsArrayBuffer(final Object object) {
129 readyState_ = LOADING;
130
131 if (object instanceof Blob) {
132 final byte[] bytes = ((Blob) object).getBytes();
133
134 final NativeArrayBuffer buffer = new NativeArrayBuffer(bytes.length);
135 System.arraycopy(bytes, 0, buffer.getBuffer(), 0, bytes.length);
136 buffer.setParentScope(getParentScope());
137 buffer.setPrototype(ScriptableObject.getClassPrototype(getWindow(), buffer.getClassName()));
138
139 result_ = buffer;
140 }
141
142 readyState_ = DONE;
143
144 final Event event = new Event(this, Event.TYPE_LOAD);
145 fireEvent(event);
146 }
147
148
149
150
151
152
153
154
155
156 @JsxFunction
157 public void readAsText(final Object object, final Object encoding) {
158 readyState_ = LOADING;
159
160 Charset charset = StandardCharsets.UTF_8;
161 if (encoding != null && !JavaScriptEngine.isUndefined(encoding)) {
162 final String encAsString = JavaScriptEngine.toString(encoding);
163 if (StringUtils.isNotBlank(encAsString)) {
164 try {
165 charset = Charsets.toCharset(encAsString.trim().toLowerCase(Locale.ROOT));
166 }
167 catch (final UnsupportedCharsetException e) {
168 if (LOG.isWarnEnabled()) {
169 LOG.warn("FileReader readAsText was called with an unsupported encoding '"
170 + encoding + "'. Using UTF-8 instead.");
171 }
172 }
173 }
174 }
175
176 if (object instanceof Blob) {
177 result_ = new String(((Blob) object).getBytes(), charset);
178 }
179
180 readyState_ = DONE;
181
182 final Event event = new Event(this, Event.TYPE_LOAD);
183 fireEvent(event);
184 }
185
186
187
188
189
190 @JsxGetter
191 public Function getOnload() {
192 return getEventHandler(Event.TYPE_LOAD);
193 }
194
195
196
197
198
199 @JsxSetter
200 public void setOnload(final Object onload) {
201 setEventHandler(Event.TYPE_LOAD, onload);
202 }
203
204
205
206
207
208 @JsxGetter
209 public Function getOnerror() {
210 return getEventHandler(Event.TYPE_ERROR);
211 }
212
213
214
215
216
217 @JsxSetter
218 public void setOnerror(final Object onerror) {
219 setEventHandler(Event.TYPE_ERROR, onerror);
220 }
221 }