Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / tools / binary_size / java / src / org / chromium / tools / binary_size / NmDumper.java
1 // Copyright 2014 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 package org.chromium.tools.binary_size;
5
6 import java.io.File;
7 import java.io.FileNotFoundException;
8 import java.io.IOException;
9 import java.io.PrintWriter;
10
11 /**
12  * Converts records to a format that simulates output from 'nm'.
13  */
14 class NmDumper {
15     private final String mOutPath;
16     private final String mSkipPath;
17     private final String mFailPath;
18     private final Output mOutput;
19
20     /**
21      * Create a new dumper that will output to the specified paths.
22      * @param outPath where to write all records and lines, including lines
23      * that are skipped or records that failed to resolve
24      * @param failPath if not null, a path to which <em>only</em> records that
25      * failed to resolve will be written
26      * @param skipPath if not null, a path to which <em>only</em> lines that
27      * were skipped will be written
28      */
29     NmDumper(final String outPath, final String failPath, final String skipPath) {
30         mOutPath = outPath;
31         mFailPath = failPath;
32         mSkipPath = skipPath;
33         mOutput = new Output();
34     }
35
36     /**
37      * Close all output files.
38      */
39     void close() {
40         mOutput.closeAll();
41     }
42
43     /**
44      * Output a line that was skipped.
45      * @param line the line
46      */
47     void skipped(String line) {
48         mOutput.printSkip(line);
49     }
50
51     /**
52      * Output a record that failed to resolve.
53      * @param record the record
54      */
55     void failed(Record record) {
56         mOutput.printFail(simulateNmOutput(record));
57     }
58
59     /**
60      * Output a record that successfully resolved.
61      * @param record the record
62      */
63     void succeeded(Record record) {
64         mOutput.print(simulateNmOutput(record));
65     }
66
67     /**
68      * Generate a string that looks like output from nm for a given record.
69      * @param record the record
70      * @return nm-like output
71      */
72     private static final String simulateNmOutput(final Record record) {
73         StringBuilder builder = new StringBuilder(record.address);
74         builder.append(' ');
75         builder.append(record.size);
76         builder.append(' ');
77         builder.append(record.symbolType);
78         builder.append(' ');
79         builder.append(record.symbolName != null ? record.symbolName : "unknown");
80         if (record.location != null) {
81             builder.append('\t');
82             builder.append(record.location);
83         }
84         return builder.toString();
85     }
86
87     private class Output {
88         private final PrintWriter skipWriter;
89         private final PrintWriter failWriter;
90         private final PrintWriter outWriter;
91
92         private Output() {
93             try {
94                 File parentDir = new File(mOutPath).getParentFile();
95                 assert (parentDir.mkdirs() || parentDir.isDirectory());
96                 outWriter = new PrintWriter(mOutPath);
97             } catch (FileNotFoundException e) {
98                 throw new RuntimeException("Can't open output file: " + mOutPath, e);
99             }
100
101             if (mFailPath != null) {
102                 try {
103                     File parentDir = new File(mFailPath).getParentFile();
104                     assert (parentDir.mkdirs() || parentDir.isDirectory());
105                     failWriter = new PrintWriter(mFailPath);
106                 } catch (FileNotFoundException e) {
107                     throw new RuntimeException("Can't open fail file: " + mFailPath, e);
108                 }
109             } else {
110                 failWriter = null;
111             }
112
113             if (mSkipPath != null) {
114                 try {
115                     File parentDir = new File(mSkipPath).getParentFile();
116                     assert (parentDir.mkdirs() || parentDir.isDirectory());
117                     skipWriter = new PrintWriter(mSkipPath);
118                 } catch (IOException e) {
119                     throw new RuntimeException("Can't open skip file: " + mSkipPath, e);
120                 }
121             } else  {
122                 skipWriter = null;
123             }
124         }
125
126         private void println(PrintWriter writer, String string) {
127             if (writer != null) {
128                 synchronized (writer) {
129                     writer.println(string);
130                     writer.flush();
131                 }
132             }
133         }
134
135         void print(String string) {
136             println(outWriter, string);
137         }
138
139         void printSkip(String string) {
140             println(skipWriter, string);
141             println(outWriter, string);
142         }
143
144         void printFail(String string) {
145             println(failWriter, string);
146             println(outWriter, string);
147         }
148
149         private void closeAll() {
150             for (PrintWriter writer : new PrintWriter[]{outWriter, failWriter, skipWriter}) {
151                 if (writer != null) {
152                     try {
153                         writer.flush(); }
154                     catch (Exception ignored) {
155                         // Nothing to be done.
156                     }
157                     try {
158                         writer.close(); }
159                     catch (Exception ignored) {
160                         // Nothing to be done.
161                     }
162                 }
163             }
164         }
165     }
166 }