OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Webworker spec says that the worker global object is called self. That's | 5 // Webworker spec says that the worker global object is called self. That's |
6 // a terrible name since we use it all over the chrome codebase to capture | 6 // a terrible name since we use it all over the chrome codebase to capture |
7 // the 'this' keyword in lambdas. | 7 // the 'this' keyword in lambdas. |
8 var global = self; | 8 var global = self; |
9 | 9 |
10 // All of these scripts could be imported with a single call to importScripts, | 10 // All of these scripts could be imported with a single call to importScripts, |
11 // but then load and compile time errors would all be reported from the same | 11 // but then load and compile time errors would all be reported from the same |
12 // line. | 12 // line. |
13 importScripts('metadata_parser.js'); | 13 importScripts('metadata_parser.js'); |
14 importScripts('byte_reader.js'); | 14 importScripts('byte_reader.js'); |
15 | 15 |
16 /** | 16 /** |
17 * Dispatches metadata requests to the correct parser. | 17 * Dispatches metadata requests to the correct parser. |
18 */ | 18 */ |
19 function MetadataDispatcher() { | 19 function MetadataDispatcher() { |
20 importScripts('exif_parser.js'); | 20 importScripts('exif_parser.js'); |
| 21 importScripts('image_parsers.js'); |
21 importScripts('mpeg_parser.js'); | 22 importScripts('mpeg_parser.js'); |
22 importScripts('id3_parser.js'); | 23 importScripts('id3_parser.js'); |
23 | 24 |
24 var patterns = ['blob:']; // We use blob urls in gallery_demo.js | 25 var patterns = ['blob:']; // We use blob urls in gallery_demo.js |
25 | 26 |
26 for (var i = 0; i < MetadataDispatcher.parserClasses_.length; i++) { | 27 for (var i = 0; i < MetadataDispatcher.parserClasses_.length; i++) { |
27 var parserClass = MetadataDispatcher.parserClasses_[i]; | 28 var parserClass = MetadataDispatcher.parserClasses_[i]; |
28 this.log('new parser: ' + parserClass.parserType); | |
29 var parser = new parserClass(this); | 29 var parser = new parserClass(this); |
| 30 this.log('new parser: ' + parser.type); |
30 this.parserInstances_.push(parser); | 31 this.parserInstances_.push(parser); |
31 patterns.push(parser.urlFilter.source); | 32 patterns.push(parser.urlFilter.source); |
32 } | 33 } |
33 | 34 |
34 this.parserRegexp_ = new RegExp('(' + patterns.join('|') + ')', 'i'); | 35 this.parserRegexp_ = new RegExp('(' + patterns.join('|') + ')', 'i'); |
35 } | 36 } |
36 | 37 |
37 MetadataDispatcher.parserClasses_ = []; | 38 MetadataDispatcher.parserClasses_ = []; |
38 | 39 |
39 MetadataDispatcher.registerParserClass = function(parserClass) { | 40 MetadataDispatcher.registerParserClass = function(parserClass) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 | 118 |
118 MetadataDispatcher.prototype.processOneFile = function(fileURL, callback) { | 119 MetadataDispatcher.prototype.processOneFile = function(fileURL, callback) { |
119 var self = this; | 120 var self = this; |
120 var currentStep = -1; | 121 var currentStep = -1; |
121 | 122 |
122 function nextStep(var_args) { | 123 function nextStep(var_args) { |
123 self.vlog('nextStep: ' + steps[currentStep + 1].name); | 124 self.vlog('nextStep: ' + steps[currentStep + 1].name); |
124 steps[++currentStep].apply(self, arguments); | 125 steps[++currentStep].apply(self, arguments); |
125 } | 126 } |
126 | 127 |
127 // Even if the error occurs we still need to pass mimeType. | 128 var defaultMetadata; // To pass along with error. |
128 var metadata = {}; | |
129 | 129 |
130 function onError(err, stepName) { | 130 function onError(err, stepName) { |
131 self.error(fileURL, stepName || steps[currentStep].name, err, metadata); | 131 self.error(fileURL, stepName || steps[currentStep].name, err.toString(), |
| 132 defaultMetadata); |
132 } | 133 } |
133 | 134 |
134 var steps = | 135 var steps = |
135 [ // Step one, find the parser matching the url. | 136 [ // Step one, find the parser matching the url. |
136 function detectFormat() { | 137 function detectFormat() { |
137 for (var i = 0; i != self.parserInstances_.length; i++) { | 138 for (var i = 0; i != self.parserInstances_.length; i++) { |
138 var parser = self.parserInstances_[i]; | 139 var parser = self.parserInstances_[i]; |
139 if (fileURL.match(parser.urlFilter)) { | 140 if (fileURL.match(parser.urlFilter)) { |
| 141 defaultMetadata = parser.createDefaultMetadata(); |
140 nextStep(parser); | 142 nextStep(parser); |
141 return; | 143 return; |
142 } | 144 } |
143 } | 145 } |
144 onError('unsupported format'); | 146 onError('unsupported format'); |
145 }, | 147 }, |
146 | 148 |
147 // Step two, turn the url into an entry. | 149 // Step two, turn the url into an entry. |
148 function getEntry(parser) { | 150 function getEntry(parser) { |
149 webkitResolveLocalFileSystemURL( | 151 webkitResolveLocalFileSystemURL( |
150 fileURL, | 152 fileURL, |
151 function(entry) { nextStep(entry, parser) }, | 153 function(entry) { nextStep(entry, parser) }, |
152 onError); | 154 onError); |
153 }, | 155 }, |
154 | 156 |
155 // Step three, turn the entry into a file. | 157 // Step three, turn the entry into a file. |
156 function getFile(entry, parser) { | 158 function getFile(entry, parser) { |
157 entry.file(function(file) { nextStep(file, parser) }, onError); | 159 entry.file(function(file) { nextStep(file, parser) }, onError); |
158 }, | 160 }, |
159 | 161 |
160 // Step four, parse the file content. | 162 // Step four, parse the file content. |
161 function parseContent(file, parser) { | 163 function parseContent(file, parser) { |
162 metadata.mimeType = parser.mimeType; | |
163 parser.parse(file, callback, onError); | 164 parser.parse(file, callback, onError); |
164 } | 165 } |
165 ]; | 166 ]; |
166 | 167 |
167 if (fileURL.indexOf('blob:') == 0) { | 168 if (fileURL.indexOf('blob:') == 0) { |
168 // Blob urls require different steps: | 169 // Blob urls require different steps: |
169 steps = | 170 steps = |
170 [ // Read the blob into an array buffer and get the content type | 171 [ // Read the blob into an array buffer and get the content type |
171 function readBlob() { | 172 function readBlob() { |
172 var xhr = new XMLHttpRequest(); | 173 var xhr = new XMLHttpRequest(); |
173 xhr.open('GET', fileURL, true); | 174 xhr.open('GET', fileURL, true); |
174 xhr.responseType = 'arraybuffer'; | 175 xhr.responseType = 'arraybuffer'; |
175 xhr.onload = function(e) { | 176 xhr.onload = function(e) { |
176 if (xhr.status == 200) { | 177 if (xhr.status == 200) { |
177 nextStep(xhr.getResponseHeader('Content-Type'), xhr.response); | 178 nextStep(xhr.getResponseHeader('Content-Type'), xhr.response); |
178 } else { | 179 } else { |
179 onError('HTTP ' + xhr.status); | 180 onError('HTTP ' + xhr.status); |
180 } | 181 } |
181 }; | 182 }; |
182 xhr.send(); | 183 xhr.send(); |
183 }, | 184 }, |
184 | 185 |
185 // Step two, find the parser matching the content type. | 186 // Step two, find the parser matching the content type. |
186 function detectFormat(mimeType, arrayBuffer) { | 187 function detectFormat(mimeType, arrayBuffer) { |
187 for (var i = 0; i != self.parserInstances_.length; i++) { | 188 for (var i = 0; i != self.parserInstances_.length; i++) { |
188 var parser = self.parserInstances_[i]; | 189 var parser = self.parserInstances_[i]; |
189 if (parser.mimeType && mimeType.match(parser.mimeType)) { | 190 if (parser.acceptsMimeType(mimeType)) { |
| 191 defaultMetadata = parser.createDefaultMetadata(); |
190 var blobBuilder = new WebKitBlobBuilder(); | 192 var blobBuilder = new WebKitBlobBuilder(); |
191 blobBuilder.append(arrayBuffer); | 193 blobBuilder.append(arrayBuffer); |
192 nextStep(blobBuilder.getBlob(), parser); | 194 nextStep(blobBuilder.getBlob(), parser); |
193 return; | 195 return; |
194 } | 196 } |
195 } | 197 } |
196 callback({}); // Unrecognized mime type. | 198 callback({}); // Unrecognized mime type. |
197 }, | 199 }, |
198 | 200 |
199 // Reuse the last step from the standard sequence. | 201 // Reuse the last step from the standard sequence. |
200 steps[steps.length - 1] | 202 steps[steps.length - 1] |
201 ]; | 203 ]; |
202 } | 204 } |
203 | 205 |
204 nextStep(); | 206 nextStep(); |
205 }; | 207 }; |
206 | 208 |
207 var dispatcher = new MetadataDispatcher(); | 209 var dispatcher = new MetadataDispatcher(); |
208 global.onmessage = dispatcher.onMessage.bind(dispatcher); | 210 global.onmessage = dispatcher.onMessage.bind(dispatcher); |
OLD | NEW |