|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * The class PlainTextOutput is part of CrashAnalyser XmlFilePlugin plugin. |
|
16 * This class creates plain text output. |
|
17 * |
|
18 */ |
|
19 using System; |
|
20 using System.Collections.Generic; |
|
21 using System.Text; |
|
22 using System.IO; |
|
23 using XmlFilePlugin.PluginImplementations.FileFormat; |
|
24 using System.Text.RegularExpressions; |
|
25 |
|
26 namespace XmlFilePlugin.PluginImplementations.FileFormat |
|
27 { |
|
28 class PlainTextOutput |
|
29 { |
|
30 private static int KColumnWidth = 30; |
|
31 private static string KTitleCrashFile = "Crash File"; |
|
32 private static string KTitleCodesegments = "Crash Time Loaded Code Segments"; |
|
33 private static string KTitleRegisters = "Registers"; |
|
34 private static string KTitleCallStacks = "Call Stacks"; |
|
35 private static string KTitleOstTraces = "OST Traces"; |
|
36 private static string KTitleEventLog = "Event Log"; |
|
37 private static string KTitleSymbolFileNames = "Symbol File Names"; |
|
38 private static string KTitleUniqueValues = "Unique Values"; |
|
39 |
|
40 public static void Write(StreamWriter writer, List<CXmlDataBlock> datablocks) |
|
41 { |
|
42 foreach (CXmlDataBlock datablock in datablocks) |
|
43 { |
|
44 WriteDataBlock(writer, datablock); |
|
45 WriteUniqueValues(writer, datablock); |
|
46 } |
|
47 } |
|
48 |
|
49 /** |
|
50 * Writes one datablock as plain text. |
|
51 */ |
|
52 private static void WriteDataBlock(StreamWriter writer, CXmlDataBlock datablock) |
|
53 { |
|
54 writer.Write(PrettyTitle(KTitleCrashFile)); |
|
55 |
|
56 // Device |
|
57 if (datablock.Platform().Equals(XmlConsts.Kxml_sos)) |
|
58 { |
|
59 writer.Write(PrettyString(XmlConsts.Kxml_platform, XmlConsts.Kxml_s60)); |
|
60 } |
|
61 else |
|
62 { |
|
63 writer.Write(PrettyString(XmlConsts.Kxml_platform, datablock.Platform())); |
|
64 } |
|
65 |
|
66 writer.Write(PrettyString(XmlConsts.Kxml_code, datablock.ProductType())); |
|
67 writer.Write(PrettyString(XmlConsts.Kxml_version, datablock.SWVersion())); |
|
68 |
|
69 if (datablock.RomId() != null) |
|
70 { |
|
71 writer.Write(PrettyString(XmlConsts.Kxml_romid, "0x" + datablock.RomId().Value.ToString("X8"))); |
|
72 } |
|
73 |
|
74 // variant is not written. |
|
75 |
|
76 if (datablock.Imei() != string.Empty) |
|
77 { |
|
78 writer.Write(PrettyString(XmlConsts.Kxml_imei, datablock.Imei())); |
|
79 } |
|
80 |
|
81 writer.Write(PrettyString(XmlConsts.Kxml_timestamp, datablock.TimeStampText())); |
|
82 |
|
83 string crashtypestr = "Not found"; |
|
84 if (datablock.FileType() == XmlConsts.MobileCrashFileType.ETypeBasicCrash) |
|
85 { |
|
86 crashtypestr = XmlConsts.Kxml_type_crash; |
|
87 } |
|
88 else if (datablock.FileType() == XmlConsts.MobileCrashFileType.ETypeAliveMessage) |
|
89 { |
|
90 crashtypestr = XmlConsts.Kxml_type_alivemsg; |
|
91 } |
|
92 else if (datablock.FileType() == XmlConsts.MobileCrashFileType.ETypeCrashAPIReport) |
|
93 { |
|
94 crashtypestr = XmlConsts.Kxml_type_report; |
|
95 } |
|
96 else if (datablock.FileType() == XmlConsts.MobileCrashFileType.ETypeRegistrationMessage) |
|
97 { |
|
98 crashtypestr = XmlConsts.Kxml_type_regmsg; |
|
99 } |
|
100 |
|
101 writer.Write(PrettyString(XmlConsts.Kxml_type, crashtypestr)); |
|
102 |
|
103 writer.Write(PrettyString(XmlConsts.Kxml_file_name, datablock.BinFilename())); |
|
104 |
|
105 if (crashtypestr.Equals(XmlConsts.Kxml_type_report)) |
|
106 { |
|
107 writer.Write(PrettyString(XmlConsts.Kxml_report_category, datablock.ReportCategory())); |
|
108 } |
|
109 |
|
110 if (crashtypestr.Equals(XmlConsts.Kxml_type_report)) |
|
111 { |
|
112 writer.Write(PrettyString(XmlConsts.Kxml_report_type, datablock.ReportType())); |
|
113 } |
|
114 |
|
115 if (datablock.CrashedModuleName() != string.Empty) |
|
116 { |
|
117 writer.Write(PrettyString(XmlConsts.Kxml_crashed_module, datablock.CrashedModuleName())); |
|
118 } |
|
119 |
|
120 if (datablock.Hash() != string.Empty) |
|
121 { |
|
122 writer.Write(PrettyString(XmlConsts.Kxml_defect_hash, datablock.Hash())); |
|
123 } |
|
124 |
|
125 WriteDictionaryValues(writer, datablock); |
|
126 |
|
127 // Codesegments |
|
128 if (datablock.CodeSegs().Count > 0) |
|
129 writer.Write(PrettyTitle(KTitleCodesegments)); |
|
130 |
|
131 foreach (CXmlCodeSegItem codeseg in datablock.CodeSegs()) |
|
132 { |
|
133 string range = "0x" + codeseg.Start.ToString("X8") + " - " + "0x" + codeseg.End.ToString("x8"); |
|
134 writer.WriteLine(range + FillSpaces(range) + codeseg.Name); |
|
135 } |
|
136 |
|
137 // Registers |
|
138 if (datablock.RegStorage().BasicRegs().ToPrettyString().Length > 0 || |
|
139 datablock.RegStorage().OtherRegLists().Count > 0) |
|
140 { |
|
141 writer.Write(PrettyTitle(KTitleRegisters)); |
|
142 } |
|
143 writer.WriteLine(datablock.RegStorage().BasicRegs().ToPrettyString()); |
|
144 |
|
145 // Extra registers |
|
146 foreach (CXmlRegisterStorage.CCrashInfoRegisterList registerList in datablock.RegStorage().OtherRegLists()) |
|
147 { |
|
148 writer.WriteLine(registerList.ToPrettyString()); |
|
149 } |
|
150 |
|
151 // Call stacks |
|
152 if (datablock.CallStacks().Count > 0) |
|
153 writer.Write(PrettyTitle(KTitleCallStacks)); |
|
154 |
|
155 foreach (XmlFilePlugin.FileFormat.CXmlCallStack stack in datablock.CallStacks()) |
|
156 { |
|
157 writer.WriteLine(stack.ToString()); |
|
158 } |
|
159 |
|
160 // OST traces |
|
161 if (datablock.OstTraces().Count > 0) |
|
162 writer.Write(PrettyTitle(KTitleOstTraces)); |
|
163 |
|
164 foreach (string line in datablock.OstTraces()) |
|
165 { |
|
166 writer.WriteLine(line); |
|
167 } |
|
168 |
|
169 // Event log |
|
170 if (datablock.Eventlog().Count > 0) |
|
171 writer.Write(PrettyTitle(KTitleEventLog)); |
|
172 |
|
173 foreach (string line in datablock.Eventlog()) |
|
174 { |
|
175 writer.WriteLine(line); |
|
176 } |
|
177 } |
|
178 |
|
179 |
|
180 /** |
|
181 * Writes dictionary values. |
|
182 */ |
|
183 private static void WriteDictionaryValues(StreamWriter writer, CXmlDataBlock datablock) |
|
184 { |
|
185 writer.Write(PrettyString(XmlConsts.Kxml_panic_id, datablock.PanicId())); |
|
186 writer.Write(PrettyString(XmlConsts.Kxml_panic_category, datablock.PanicCategory())); |
|
187 writer.Write(PrettyString(XmlConsts.Kxml_panic_description, Regex.Replace(datablock.PanicDescription(), "<(.|\n)*?>", ""))); |
|
188 writer.Write(PrettyString(XmlConsts.Kxml_language, datablock.Language())); |
|
189 |
|
190 if (!datablock.Process().Equals(XmlConsts.Kxml_unknown_process)) |
|
191 { |
|
192 writer.Write(PrettyString(XmlConsts.Kxml_panicked_process, datablock.Process())); |
|
193 } |
|
194 |
|
195 writer.Write(PrettyString(XmlConsts.Kxml_network_country_code, datablock.NetworkCountry())); |
|
196 writer.Write(PrettyString(XmlConsts.Kxml_network_identity, datablock.NetworkIdentity())); |
|
197 writer.Write(PrettyString(XmlConsts.Kxml_s60version, datablock.S60Version())); |
|
198 writer.Write(PrettyString(XmlConsts.Kxml_product_code, datablock.ProductCode())); |
|
199 writer.Write(PrettyString(XmlConsts.Kxml_variant_version, datablock.VariantVersion())); |
|
200 |
|
201 if (datablock.ReportType() != string.Empty) |
|
202 { |
|
203 writer.Write(PrettyString(XmlConsts.Kxml_file_type, "1")); |
|
204 } |
|
205 else |
|
206 { |
|
207 writer.Write(PrettyString(XmlConsts.Kxml_file_type, "0")); |
|
208 } |
|
209 |
|
210 // Production mode |
|
211 if (datablock.ProductionMode() != -1) |
|
212 { |
|
213 if (datablock.ProductionMode() == 1) |
|
214 { |
|
215 writer.Write(PrettyString(XmlConsts.Kxml_production_mode, XmlConsts.Kxml_production_mode_value)); |
|
216 } |
|
217 else |
|
218 { |
|
219 writer.Write(PrettyString(XmlConsts.Kxml_production_mode, XmlConsts.Kxml_rnd_mode_value)); |
|
220 } |
|
221 } |
|
222 |
|
223 // Crash source |
|
224 if (datablock.CrashSource() != -1) |
|
225 { |
|
226 if (datablock.CrashSource() == 1) |
|
227 { |
|
228 writer.Write(PrettyString(XmlConsts.Kxml_crash_source, XmlConsts.Kxml_crash_source_user)); |
|
229 } |
|
230 else |
|
231 { |
|
232 writer.Write(PrettyString(XmlConsts.Kxml_crash_source, XmlConsts.Kxml_crash_source_kernel)); |
|
233 } |
|
234 } |
|
235 |
|
236 // Symbol file names |
|
237 if (datablock.SymbolFiles().Count > 0) |
|
238 writer.Write(PrettyTitle(KTitleSymbolFileNames)); |
|
239 |
|
240 foreach (string fileName in datablock.SymbolFiles()) |
|
241 { |
|
242 writer.WriteLine(fileName); |
|
243 } |
|
244 |
|
245 } |
|
246 |
|
247 |
|
248 /** |
|
249 * Writes unique values. |
|
250 */ |
|
251 private static void WriteUniqueValues(StreamWriter writer, CXmlDataBlock datablock) |
|
252 { |
|
253 // Unique values |
|
254 writer.Write(PrettyTitle(KTitleUniqueValues)); |
|
255 |
|
256 // Available memory |
|
257 writer.Write(PrettyString(XmlConsts.Kxml_available_memory, datablock.FreeMemory())); |
|
258 |
|
259 if (datablock.RegStorage() != null && datablock.RegStorage().ProgramCounter() != null) |
|
260 { |
|
261 writer.Write(PrettyString(XmlConsts.Kxml_program_counter, "0x" + datablock.RegStorage().ProgramCounter().Value.ToString("X8"))); |
|
262 writer.Write(PrettyString(XmlConsts.Kxml_program_counter_symbol, datablock.RegStorage().ProgramCounter().Symbol)); |
|
263 } |
|
264 |
|
265 writer.Write(PrettyString(XmlConsts.Kxml_misc_info, datablock.GetMiscInfo())); |
|
266 |
|
267 // Reporter not written. |
|
268 // Resetreason not written. |
|
269 |
|
270 writer.Write(PrettyString(XmlConsts.Kxml_uptime, datablock.Uptime())); |
|
271 writer.Write(PrettyString(XmlConsts.Kxml_siminfo, datablock.Imsi())); |
|
272 writer.Write(PrettyString(XmlConsts.Kxml_locinfo, datablock.LocInfo())); |
|
273 writer.Write(PrettyString(XmlConsts.Kxml_cellid, datablock.NetworkCell())); |
|
274 writer.Write(PrettyString(XmlConsts.Kxml_psninfo, datablock.SerialNumber())); |
|
275 |
|
276 if (datablock.UID() != null) |
|
277 writer.Write(PrettyString(XmlConsts.Kxml_uid, "0x" + datablock.UID().Value.ToString("X8"))); |
|
278 |
|
279 writer.Write(PrettyString(XmlConsts.Kxml_testset, datablock.TestSet())); |
|
280 writer.Write(PrettyString(XmlConsts.Kxml_diskinfo, datablock.DiskInfo())); |
|
281 writer.Write(PrettyString(XmlConsts.Kxml_phone_number, datablock.PhoneNumber())); |
|
282 |
|
283 writer.Write(PrettyString(XmlConsts.Kxml_report_ok, datablock.ReportOK())); |
|
284 writer.Write(PrettyString(XmlConsts.Kxml_report_fail, datablock.ReportFail())); |
|
285 writer.Write(PrettyString(XmlConsts.Kxml_report_param_name1, datablock.ReportParamName1())); |
|
286 writer.Write(PrettyString(XmlConsts.Kxml_report_param_value1, datablock.ReportParamValue1())); |
|
287 writer.Write(PrettyString(XmlConsts.Kxml_report_param_name2, datablock.ReportParamName2())); |
|
288 writer.Write(PrettyString(XmlConsts.Kxml_report_param_value2, datablock.ReportParamValue2())); |
|
289 writer.Write(PrettyString(XmlConsts.Kxml_report_param_name3, datablock.ReportParamName3())); |
|
290 writer.Write(PrettyString(XmlConsts.Kxml_report_param_value3, datablock.ReportParamValue3())); |
|
291 writer.Write(PrettyString(XmlConsts.Kxml_report_comments, datablock.ReportComments())); |
|
292 } |
|
293 |
|
294 |
|
295 /** |
|
296 * Returns string in the pretty format (i.e. two columns). |
|
297 * Converts int param to string. |
|
298 */ |
|
299 private static string PrettyString(string key, int? value) |
|
300 { |
|
301 if (value == null) |
|
302 { |
|
303 return string.Empty; |
|
304 } |
|
305 return PrettyString(key, value.ToString()); |
|
306 } |
|
307 |
|
308 /** |
|
309 * Returns string in the pretty format (i.e. two columns). |
|
310 * Converts ulong param to string. |
|
311 */ |
|
312 private static string PrettyString(string key, ulong? value) |
|
313 { |
|
314 if (value == null) |
|
315 { |
|
316 return string.Empty; |
|
317 } |
|
318 return PrettyString(key, value.ToString()); |
|
319 } |
|
320 |
|
321 /** |
|
322 * Returns string in the pretty format (i.e. two columns). |
|
323 * Converts uint param to string. |
|
324 */ |
|
325 private static string PrettyString(string key, uint? value) |
|
326 { |
|
327 if (value == null) |
|
328 { |
|
329 return string.Empty; |
|
330 } |
|
331 return PrettyString(key, value.ToString()); |
|
332 } |
|
333 |
|
334 /** |
|
335 * Returns string in the pretty format (i.e. two columns). |
|
336 * Converts double param to string. |
|
337 */ |
|
338 private static string PrettyString(string key, double? value) |
|
339 { |
|
340 if (value == null) |
|
341 { |
|
342 return string.Empty; |
|
343 } |
|
344 return PrettyString(key, value.ToString()); |
|
345 } |
|
346 |
|
347 /** |
|
348 * Returns string in the pretty format (i.e. two columns) |
|
349 */ |
|
350 private static string PrettyString(string key, string value) |
|
351 { |
|
352 if (value == string.Empty || value.Length == 0) |
|
353 return string.Empty; |
|
354 |
|
355 return key.ToUpper() + ":" + FillSpaces(key) + value + "\n"; |
|
356 } |
|
357 |
|
358 /** |
|
359 * Fill spaces so that the output looks nice. |
|
360 */ |
|
361 private static string FillSpaces(string key) |
|
362 { |
|
363 string spaceString = ""; |
|
364 |
|
365 for (int i = key.Length; i < KColumnWidth; i++) |
|
366 { |
|
367 spaceString += " "; |
|
368 } |
|
369 |
|
370 return spaceString; |
|
371 } |
|
372 |
|
373 /** |
|
374 * Writes title in the pretty format |
|
375 */ |
|
376 private static string PrettyTitle(string titleString) |
|
377 { |
|
378 return "\n === " + titleString + " ===\n"; |
|
379 } |
|
380 } |
|
381 } |