diff options
-rw-r--r-- | js/binaryXHR.js | 73 |
1 files changed, 66 insertions, 7 deletions
diff --git a/js/binaryXHR.js b/js/binaryXHR.js index 2cd02dd..d18f6a8 100644 --- a/js/binaryXHR.js +++ b/js/binaryXHR.js | |||
@@ -46,6 +46,8 @@ function BinaryFile(data) { | |||
46 | this.getByteAt = function(iOffset) { | 46 | this.getByteAt = function(iOffset) { |
47 | return data.charCodeAt(iOffset) & 0xFF; | 47 | return data.charCodeAt(iOffset) & 0xFF; |
48 | }; | 48 | }; |
49 | } else if (typeof DataView != "undefined" && data instanceof ArrayBuffer) { | ||
50 | dataLength = data.dataLength; | ||
49 | } else if (typeof data === "unknown") { | 51 | } else if (typeof data === "unknown") { |
50 | // Correct. "unknown" as type. MS JScript 8 added this. | 52 | // Correct. "unknown" as type. MS JScript 8 added this. |
51 | dataLength = IEBinary_getLength(data); | 53 | dataLength = IEBinary_getLength(data); |
@@ -61,8 +63,15 @@ function BinaryFile(data) { | |||
61 | return dataLength; | 63 | return dataLength; |
62 | }; | 64 | }; |
63 | 65 | ||
64 | // antique browser, use slower fallback implementation | 66 | if (typeof DataView != "undefined" && data instanceof ArrayBuffer) { |
65 | this.extendWithFallback(data, littleEndian); | 67 | // not an antique browser, use faster TypedArrays |
68 | this.extendWithDataView(data, littleEndian); | ||
69 | // other functions here do not need these | ||
70 | data = null; | ||
71 | } else { | ||
72 | // antique browser, use slower fallback implementation | ||
73 | this.extendWithFallback(data, littleEndian); | ||
74 | } | ||
66 | } | 75 | } |
67 | 76 | ||
68 | BinaryFile.prototype.extendWithFallback = function(data, littleEndian) { | 77 | BinaryFile.prototype.extendWithFallback = function(data, littleEndian) { |
@@ -172,6 +181,42 @@ BinaryFile.prototype.extendWithFallback = function(data, littleEndian) { | |||
172 | }; | 181 | }; |
173 | }; | 182 | }; |
174 | 183 | ||
184 | BinaryFile.prototype.extendWithDataView = function(data, littleEndian) { | ||
185 | "use strict"; | ||
186 | var dv = new DataView(data); | ||
187 | |||
188 | this.getByteAt = dv.getUint8.bind(dv); | ||
189 | this.getSByteAt = dv.getInt8.bind(dv); | ||
190 | this.getShortAt = function(iOffset) { | ||
191 | return dv.getUint16(iOffset, littleEndian); | ||
192 | }; | ||
193 | this.getSShortAt = function(iOffset) { | ||
194 | return dv.getInt16(iOffset, littleEndian); | ||
195 | }; | ||
196 | this.getLongAt = function(iOffset) { | ||
197 | return dv.getUint32(iOffset, littleEndian); | ||
198 | }; | ||
199 | this.getSLongAt = function(iOffset) { | ||
200 | return dv.getInt32(iOffset, littleEndian); | ||
201 | }; | ||
202 | this.getCharAt = function(iOffset) { | ||
203 | return String.fromCharCode(this.getByteAt(iOffset)); | ||
204 | }; | ||
205 | this.getCStringAt = function(iOffset, iMaxLength) { | ||
206 | var str = ""; | ||
207 | do { | ||
208 | var b = this.getByteAt(iOffset++); | ||
209 | if (b === 0) | ||
210 | break; | ||
211 | str += String.fromCharCode(b); | ||
212 | } while (--iMaxLength > 0); | ||
213 | return str; | ||
214 | }; | ||
215 | this.getDoubleAt = function(iOffset) { | ||
216 | return dv.getFloat64(iOffset, littleEndian); | ||
217 | }; | ||
218 | this.getFastDoubleAt = this.getDoubleAt.bind(this); | ||
219 | }; | ||
175 | 220 | ||
176 | 221 | ||
177 | // Use document.write only for stone-age browsers. | 222 | // Use document.write only for stone-age browsers. |
@@ -203,7 +248,7 @@ function FetchBinaryURL(url) { | |||
203 | } | 248 | } |
204 | request.send(null); | 249 | request.send(null); |
205 | 250 | ||
206 | var response=request.responseText; | 251 | var response = request.responseText; |
207 | try { | 252 | try { |
208 | // for older IE versions, the value in responseText is not usable | 253 | // for older IE versions, the value in responseText is not usable |
209 | if (IEBinary_getLength(this.responseBody)>0) { | 254 | if (IEBinary_getLength(this.responseBody)>0) { |
@@ -214,7 +259,18 @@ function FetchBinaryURL(url) { | |||
214 | // not IE, do nothing | 259 | // not IE, do nothing |
215 | } | 260 | } |
216 | 261 | ||
217 | var bf=new BinaryFile(response); | 262 | // cannot use responseType == "arraybuffer" for synchronous requests, so |
263 | // convert it afterwards | ||
264 | if (typeof ArrayBuffer != "undefined") { | ||
265 | var buffer = new ArrayBuffer(response.length); | ||
266 | var bv = new Uint8Array(buffer); | ||
267 | for (var i = 0; i < response.length; i++) { | ||
268 | bv[i] = response.charCodeAt(i); | ||
269 | } | ||
270 | response = buffer; | ||
271 | } | ||
272 | |||
273 | var bf = new BinaryFile(response); | ||
218 | return bf; | 274 | return bf; |
219 | } | 275 | } |
220 | 276 | ||
@@ -229,7 +285,8 @@ function FetchBinaryURLAsync(url, callback, callback_arg) { | |||
229 | "use strict"; | 285 | "use strict"; |
230 | var callback_wrapper = function() { | 286 | var callback_wrapper = function() { |
231 | if(this.readyState === 4) { | 287 | if(this.readyState === 4) { |
232 | var response=this.responseText; | 288 | // ArrayBuffer response or just the response as string |
289 | var response = this.response || this.responseText; | ||
233 | try { | 290 | try { |
234 | // for older IE versions, the value in responseText is not usable | 291 | // for older IE versions, the value in responseText is not usable |
235 | if (IEBinary_getLength(this.responseBody)>0) { | 292 | if (IEBinary_getLength(this.responseBody)>0) { |
@@ -240,7 +297,7 @@ function FetchBinaryURLAsync(url, callback, callback_arg) { | |||
240 | // not IE, do nothing | 297 | // not IE, do nothing |
241 | } | 298 | } |
242 | 299 | ||
243 | var bf=new BinaryFile(response); | 300 | var bf = new BinaryFile(response); |
244 | if (callback_arg) { | 301 | if (callback_arg) { |
245 | callback(bf, callback_arg); | 302 | callback(bf, callback_arg); |
246 | } else { | 303 | } else { |
@@ -251,7 +308,9 @@ function FetchBinaryURLAsync(url, callback, callback_arg) { | |||
251 | 308 | ||
252 | var request = new XMLHttpRequest(); | 309 | var request = new XMLHttpRequest(); |
253 | request.onreadystatechange = callback_wrapper; | 310 | request.onreadystatechange = callback_wrapper; |
254 | request.open("GET", url,true); | 311 | request.open("GET", url, true); |
312 | // Supported since Chrome 10, FF 6, IE 10, Opera 11.60 (source: MDN) | ||
313 | request.responseType = "arraybuffer"; | ||
255 | try { | 314 | try { |
256 | request.overrideMimeType('text/plain; charset=x-user-defined'); | 315 | request.overrideMimeType('text/plain; charset=x-user-defined'); |
257 | } catch (err) { | 316 | } catch (err) { |