3 Copyright (c) 2013 The Chromium Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file.
8 <link rel="import" href="/tracing/importer/importer.html">
9 <link rel="import" href="/tracing/trace_model.html">
10 <link rel="import" href="/tracing/importer/jszip.html">
16 * @fileoverview GzipImporter inflates gzip compressed data and passes it along
17 * to an actual importer.
19 tvcm.exportTo('tracing.importer', function() {
20 var Importer = tracing.importer.Importer;
22 var GZIP_MEMBER_HEADER_ID_SIZE = 3;
24 var GZIP_HEADER_ID1 = 0x1f;
25 var GZIP_HEADER_ID2 = 0x8b;
26 var GZIP_DEFLATE_COMPRESSION = 8;
28 function GzipImporter(model, eventData) {
29 // Normalize the data into an Uint8Array.
30 if (typeof(eventData) === 'string' || eventData instanceof String) {
31 eventData = JSZip.utils.transformTo('uint8array', eventData);
32 } else if (eventData instanceof ArrayBuffer) {
33 eventData = new Uint8Array(eventData);
35 throw new Error('Unknown gzip data format');
37 this.gzipData_ = eventData;
41 * @param {eventData} Possibly gzip compressed data as a string or an
43 * @return {boolean} Whether obj looks like gzip compressed data.
45 GzipImporter.canImport = function(eventData) {
47 if (eventData instanceof ArrayBuffer)
48 header = new Uint8Array(eventData.slice(0, GZIP_MEMBER_HEADER_ID_SIZE));
49 else if (typeof(eventData) === 'string' || eventData instanceof String) {
50 header = eventData.substring(0, GZIP_MEMBER_HEADER_ID_SIZE);
51 // Convert the string to a byteArray for correct value comparison.
52 header = JSZip.utils.transformTo('uint8array', header);
55 return header[0] == GZIP_HEADER_ID1 &&
56 header[1] == GZIP_HEADER_ID2 &&
57 header[2] == GZIP_DEFLATE_COMPRESSION;
61 * Inflates (decompresses) the data stored in the given gzip bitstream.
62 * @return {string} Inflated data.
64 GzipImporter.inflateGzipData_ = function(data) {
68 if (position >= data.length)
69 throw new Error('Unexpected end of gzip data');
70 return data[position++];
76 return (high << 8) + low;
79 function skipBytes(amount) {
83 function skipZeroTerminatedString() {
84 while (getByte() != 0) {}
89 if (id1 !== GZIP_HEADER_ID1 || id2 !== GZIP_HEADER_ID2)
90 throw new Error('Not gzip data');
91 var compression_method = getByte();
92 if (compression_method !== GZIP_DEFLATE_COMPRESSION)
93 throw new Error('Unsupported compression method: ' + compression_method);
94 var flags = getByte();
95 var have_header_crc = flags & (1 << 1);
96 var have_extra_fields = flags & (1 << 2);
97 var have_file_name = flags & (1 << 3);
98 var have_comment = flags & (1 << 4);
100 // Skip modification time, extra flags and OS.
101 skipBytes(4 + 1 + 1);
103 // Skip remaining fields before compressed data.
104 if (have_extra_fields) {
105 var bytes_to_skip = getWord();
106 skipBytes(bytes_to_skip);
109 skipZeroTerminatedString();
111 skipZeroTerminatedString();
115 // Inflate the data using jszip.
117 JSZip.compressions['DEFLATE'].uncompress(data.subarray(position));
118 return JSZip.utils.transformTo('string', inflated_data);
121 GzipImporter.prototype = {
122 __proto__: Importer.prototype,
125 * Called by the Model to extract subtraces from the event data. The
126 * subtraces are passed on to other importers that can recognize them.
128 extractSubtraces: function() {
129 var eventData = GzipImporter.inflateGzipData_(this.gzipData_);
130 return eventData ? [eventData] : [];
134 tracing.TraceModel.registerImporter(GzipImporter);
137 GzipImporter: GzipImporter