Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / trace_viewer / tracing / importer / gzip_importer.html
1 <!DOCTYPE html>
2 <!--
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.
6 -->
7
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">
11
12 <script>
13 'use strict';
14
15 /**
16  * @fileoverview GzipImporter inflates gzip compressed data and passes it along
17  * to an actual importer.
18  */
19 tvcm.exportTo('tracing.importer', function() {
20   var Importer = tracing.importer.Importer;
21
22   var GZIP_MEMBER_HEADER_ID_SIZE = 3;
23
24   var GZIP_HEADER_ID1 = 0x1f;
25   var GZIP_HEADER_ID2 = 0x8b;
26   var GZIP_DEFLATE_COMPRESSION = 8;
27
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);
34     } else
35       throw new Error('Unknown gzip data format');
36     this.model_ = model;
37     this.gzipData_ = eventData;
38   }
39
40   /**
41    * @param {eventData} Possibly gzip compressed data as a string or an
42    *                    ArrayBuffer.
43    * @return {boolean} Whether obj looks like gzip compressed data.
44    */
45   GzipImporter.canImport = function(eventData) {
46     var header;
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);
53     } else
54       return false;
55     return header[0] == GZIP_HEADER_ID1 &&
56         header[1] == GZIP_HEADER_ID2 &&
57         header[2] == GZIP_DEFLATE_COMPRESSION;
58   };
59
60   /**
61    * Inflates (decompresses) the data stored in the given gzip bitstream.
62    * @return {string} Inflated data.
63    */
64   GzipImporter.inflateGzipData_ = function(data) {
65     var position = 0;
66
67     function getByte() {
68       if (position >= data.length)
69         throw new Error('Unexpected end of gzip data');
70       return data[position++];
71     }
72
73     function getWord() {
74       var low = getByte();
75       var high = getByte();
76       return (high << 8) + low;
77     }
78
79     function skipBytes(amount) {
80       position += amount;
81     }
82
83     function skipZeroTerminatedString() {
84       while (getByte() != 0) {}
85     }
86
87     var id1 = getByte();
88     var id2 = getByte();
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);
99
100     // Skip modification time, extra flags and OS.
101     skipBytes(4 + 1 + 1);
102
103     // Skip remaining fields before compressed data.
104     if (have_extra_fields) {
105       var bytes_to_skip = getWord();
106       skipBytes(bytes_to_skip);
107     }
108     if (have_file_name)
109       skipZeroTerminatedString();
110     if (have_comment)
111       skipZeroTerminatedString();
112     if (have_header_crc)
113       getWord();
114
115     // Inflate the data using jszip.
116     var inflated_data =
117         JSZip.compressions['DEFLATE'].uncompress(data.subarray(position));
118     return JSZip.utils.transformTo('string', inflated_data);
119   },
120
121   GzipImporter.prototype = {
122     __proto__: Importer.prototype,
123
124     /**
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.
127      */
128     extractSubtraces: function() {
129       var eventData = GzipImporter.inflateGzipData_(this.gzipData_);
130       return eventData ? [eventData] : [];
131     }
132   };
133
134   tracing.TraceModel.registerImporter(GzipImporter);
135
136   return {
137     GzipImporter: GzipImporter
138   };
139 });
140 </script>