Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(153)

Side by Side Diff: chrome/browser/resources/file_manager/js/byte_reader.js

Issue 9583009: [File Manager] Cleanup: Moving js/css/html files to dedicated directories (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 ByteReader = function(arrayBuffer, opt_offset, opt_length) {
6 opt_offset = opt_offset || 0;
7 opt_length = opt_length || (arrayBuffer.byteLength - opt_offset);
8 this.view_ = new DataView(arrayBuffer, opt_offset, opt_length);
9 this.pos_ = 0;
10 this.seekStack_ = [];
11 this.setByteOrder(ByteReader.BIG_ENDIAN);
12 };
13
14 // Static const and methods.
15
16 ByteReader.LITTLE_ENDIAN = 0; // Intel, 0x1234 is [0x34, 0x12]
17 ByteReader.BIG_ENDIAN = 1; // Motorola, 0x1234 is [0x12, 0x34]
18
19 ByteReader.SEEK_BEG = 0; // Seek relative to the beginning of the buffer.
20 ByteReader.SEEK_CUR = 1; // Seek relative to the current position.
21 ByteReader.SEEK_END = 2; // Seek relative to the end of the buffer.
22
23 /**
24 * Throw an error if (0 > pos >= end) or if (pos + size > end).
25 *
26 * Static utility function.
27 */
28 ByteReader.validateRead = function(pos, size, end) {
29 if (pos < 0 || pos >= end)
30 throw new Error('Invalid read position');
31
32 if (pos + size > end)
33 throw new Error('Read past end of buffer');
34 };
35
36 /**
37 * Read as a sequence of characters, returning them as a single string.
38 *
39 * This is a static utility function. There is a member function with the
40 * same name which side-effects the current read position.
41 */
42 ByteReader.readString = function(dataView, pos, size, opt_end) {
43 ByteReader.validateRead(pos, size, opt_end || dataView.byteLength);
44
45 var codes = [];
46
47 for (var i = 0; i < size; ++i)
48 codes.push(dataView.getUint8(pos + i));
49
50 return String.fromCharCode.apply(null, codes);
51 };
52
53 /**
54 * Read as a sequence of characters, returning them as a single string.
55 *
56 * This is a static utility function. There is a member function with the
57 * same name which side-effects the current read position.
58 */
59 ByteReader.readNullTerminatedString = function(dataView, pos, size, opt_end) {
60 ByteReader.validateRead(pos, size, opt_end || dataView.byteLength);
61
62 var codes = [];
63
64 for (var i = 0; i < size; ++i) {
65 var code = dataView.getUint8(pos + i);
66 if (code == 0) break;
67 codes.push(code);
68 }
69
70 return String.fromCharCode.apply(null, codes);
71 };
72
73 /**
74 * Read as a sequence of UTF16 characters, returning them as a single string.
75 *
76 * This is a static utility function. There is a member function with the
77 * same name which side-effects the current read position.
78 */
79 ByteReader.readNullTerminatedStringUTF16 = function(
80 dataView, pos, bom, size, opt_end) {
81 ByteReader.validateRead(pos, size, opt_end || dataView.byteLength);
82
83 var littleEndian = false;
84 var start = 0;
85
86 if (bom) {
87 littleEndian = (dataView.getUint8(pos) == 0xFF);
88 start = 2;
89 }
90
91 var codes = [];
92
93 for (var i = start; i < size; i += 2) {
94 var code = dataView.getUint16(pos + i, littleEndian);
95 if (code == 0) break;
96 codes.push(code);
97 }
98
99 return String.fromCharCode.apply(null, codes);
100 };
101
102 ByteReader.base64Alphabet_ =
103 ('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/').
104 split('');
105
106 /**
107 * Read as a sequence of bytes, returning them as a single base64 encoded
108 * string.
109 *
110 * This is a static utility function. There is a member function with the
111 * same name which side-effects the current read position.
112 */
113 ByteReader.readBase64 = function(dataView, pos, size, opt_end) {
114 ByteReader.validateRead(pos, size, opt_end || dataView.byteLength);
115
116 var rv = [];
117 var chars = [];
118 var padding = 0;
119
120 for (var i = 0; i < size; /* incremented inside */) {
121 var bits = dataView.getUint8(pos + (i++)) << 16;
122
123 if (i < size) {
124 bits |= dataView.getUint8(pos + (i++)) << 8;
125
126 if (i < size) {
127 bits |= dataView.getUint8(pos + (i++));
128 } else {
129 padding = 1;
130 }
131 } else {
132 padding = 2;
133 }
134
135 chars[3] = ByteReader.base64Alphabet_[bits & 63];
136 chars[2] = ByteReader.base64Alphabet_[(bits >> 6) & 63];
137 chars[1] = ByteReader.base64Alphabet_[(bits >> 12) & 63];
138 chars[0] = ByteReader.base64Alphabet_[(bits >> 18) & 63];
139
140 rv.push.apply(rv, chars);
141 }
142
143 if (padding > 0)
144 rv[rv.length - 1] = '=';
145 if (padding > 1)
146 rv[rv.length - 2] = '=';
147
148 return rv.join('');
149 };
150
151 /**
152 * Read as an image encoded in a data url.
153 *
154 * This is a static utility function. There is a member function with the
155 * same name which side-effects the current read position.
156 */
157 ByteReader.readImage = function(dataView, pos, size, opt_end) {
158 opt_end = opt_end || dataView.byteLength;
159 ByteReader.validateRead(pos, size, opt_end);
160
161 // Two bytes is enough to identify the mime type.
162 var prefixToMime = {
163 '\x89P' : 'png',
164 '\xFF\xD8' : 'jpeg',
165 'BM' : 'bmp',
166 'GI' : 'gif'
167 };
168
169 var prefix = ByteReader.readString(dataView, pos, 2, opt_end);
170 var mime = prefixToMime[prefix] ||
171 dataView.getUint16(pos, false).toString(16); // For debugging.
172
173 var b64 = ByteReader.readBase64(dataView, pos, size, opt_end);
174 return 'data:image/' + mime + ';base64,' + b64;
175 };
176
177 // Instance methods.
178
179 /**
180 * Return true if the requested number of bytes can be read from the buffer.
181 */
182 ByteReader.prototype.canRead = function(size) {
183 return this.pos_ + size <= this.view_.byteLength;
184 },
185
186 /**
187 * Return true if the current position is past the end of the buffer.
188 */
189 ByteReader.prototype.eof = function() {
190 return this.pos_ >= this.view_.byteLength;
191 };
192
193 /**
194 * Return true if the current position is before the beginning of the buffer.
195 */
196 ByteReader.prototype.bof = function() {
197 return this.pos_ < 0;
198 };
199
200 /**
201 * Return true if the current position is outside the buffer.
202 */
203 ByteReader.prototype.beof = function() {
204 return this.pos_ >= this.view_.byteLength || this.pos_ < 0;
205 };
206
207 /**
208 * Set the expected byte ordering for future reads.
209 */
210 ByteReader.prototype.setByteOrder = function(order) {
211 this.littleEndian_ = order == ByteReader.LITTLE_ENDIAN;
212 };
213
214 /**
215 * Throw an error if the reader is at an invalid position, or if a read a read
216 * of |size| would put it in one.
217 *
218 * You may optionally pass opt_end to override what is considered to be the
219 * end of the buffer.
220 */
221 ByteReader.prototype.validateRead = function(size, opt_end) {
222 if (typeof opt_end == 'undefined')
223 opt_end = this.view_.byteLength;
224
225 ByteReader.validateRead(this.view_, this.pos_, size, opt_end);
226 };
227
228 ByteReader.prototype.readScalar = function(width, opt_signed, opt_end) {
229 var method = opt_signed ? 'getInt' : 'getUint';
230
231 switch (width) {
232 case 1:
233 method += '8';
234 break;
235
236 case 2:
237 method += '16';
238 break;
239
240 case 4:
241 method += '32';
242 break;
243
244 case 8:
245 method += '64';
246 break;
247
248 default:
249 throw new Error('Invalid width: ' + width);
250 break;
251 }
252
253 this.validateRead(width, opt_end);
254 var rv = this.view_[method](this.pos_, this.littleEndian_);
255 this.pos_ += width;
256 return rv;
257 }
258
259 /**
260 * Read as a sequence of characters, returning them as a single string.
261 *
262 * Adjusts the current position on success. Throws an exception if the
263 * read would go past the end of the buffer.
264 */
265 ByteReader.prototype.readString = function(size, opt_end) {
266 var rv = ByteReader.readString(this.view_, this.pos_, size, opt_end);
267 this.pos_ += size;
268 return rv;
269 };
270
271
272 /**
273 * Read as a sequence of characters, returning them as a single string.
274 *
275 * Adjusts the current position on success. Throws an exception if the
276 * read would go past the end of the buffer.
277 */
278 ByteReader.prototype.readNullTerminatedString = function(size, opt_end) {
279 var rv = ByteReader.readNullTerminatedString(this.view_,
280 this.pos_,
281 size,
282 opt_end);
283 this.pos_ += rv.length;
284
285 if (rv.length < size) {
286 // If we've stopped reading because we found '0' but didn't hit size limit
287 // then we should skip additional '0' character
288 this.pos_++;
289 }
290
291 return rv;
292 };
293
294
295 /**
296 * Read as a sequence of UTF16 characters, returning them as a single string.
297 *
298 * Adjusts the current position on success. Throws an exception if the
299 * read would go past the end of the buffer.
300 */
301 ByteReader.prototype.readNullTerminatedStringUTF16 =
302 function(bom, size, opt_end) {
303 var rv = ByteReader.readNullTerminatedStringUTF16(
304 this.view_, this.pos_, bom, size, opt_end);
305
306 if (bom) {
307 // If the BOM word was present advance the position.
308 this.pos_ += 2;
309 }
310
311 this.pos_ += rv.length;
312
313 if (rv.length < size) {
314 // If we've stopped reading because we found '0' but didn't hit size limit
315 // then we should skip additional '0' character
316 this.pos_ += 2;
317 }
318
319 return rv;
320 };
321
322
323 /**
324 * Read as an array of numbers.
325 *
326 * Adjusts the current position on success. Throws an exception if the
327 * read would go past the end of the buffer.
328 */
329 ByteReader.prototype.readSlice = function(size, opt_end,
330 opt_arrayConstructor) {
331 this.validateRead(width, opt_end);
332
333 var arrayConstructor = opt_arrayConstructor || Uint8Array;
334 var slice = new arrayConstructor(
335 this.view_.buffer, this.view_.byteOffset + this.pos, size);
336 this.pos_ += size;
337
338 return slice;
339 };
340
341 /**
342 * Read as a sequence of bytes, returning them as a single base64 encoded
343 * string.
344 *
345 * Adjusts the current position on success. Throws an exception if the
346 * read would go past the end of the buffer.
347 */
348 ByteReader.prototype.readBase64 = function(size, opt_end) {
349 var rv = ByteReader.readBase64(this.view_, this.pos_, size, opt_end);
350 this.pos_ += size;
351 return rv;
352 };
353
354 /**
355 * Read an image returning it as a data url.
356 *
357 * Adjusts the current position on success. Throws an exception if the
358 * read would go past the end of the buffer.
359 */
360 ByteReader.prototype.readImage = function(size, opt_end) {
361 var rv = ByteReader.readImage(this.view_, this.pos_, size, opt_end);
362 this.pos_ += size;
363 return rv;
364 };
365
366 /**
367 * Seek to a give position relative to opt_seekStart.
368 */
369 ByteReader.prototype.seek = function(pos, opt_seekStart, opt_end) {
370 opt_end = opt_end || this.view_.byteLength;
371
372 var newPos;
373 if (opt_seekStart == ByteReader.SEEK_CUR) {
374 newPos = this.pos_ + pos;
375 } else if (opt_seekStart == ByteReader.SEEK_END) {
376 newPos = opt_end + pos;
377 } else {
378 newPos = pos;
379 }
380
381 if (newPos < 0 || newPos > this.view_.byteLength)
382 throw new Error('Seek outside of buffer: ' + (newPos - opt_end));
383
384 this.pos_ = newPos;
385 };
386
387 /**
388 * Seek to a given position relative to opt_seekStart, saving the current
389 * position.
390 *
391 * Recover the current position with a call to seekPop.
392 */
393 ByteReader.prototype.pushSeek = function(pos, opt_seekStart) {
394 var oldPos = this.pos_;
395 this.seek(pos, opt_seekStart);
396 // Alter the seekStack_ after the call to seek(), in case it throws.
397 this.seekStack_.push(oldPos);
398 };
399
400 /**
401 * Undo a previous seekPush.
402 */
403 ByteReader.prototype.popSeek = function() {
404 this.seek(this.seekStack_.pop());
405 };
406
407 /**
408 * Return the current read position.
409 */
410 ByteReader.prototype.tell = function() {
411 return this.pos_;
412 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698