diff -r 7a31f7298d8f -r 0c91f0baec58 crashanalysercmd/Libraries/File Formats/Plugins/XmlFilePlugin/FileFormat/CXmlFileDocument.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/Libraries/File Formats/Plugins/XmlFilePlugin/FileFormat/CXmlFileDocument.cs Wed Apr 21 09:51:02 2010 +0300 @@ -0,0 +1,465 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* The class CXmlFileDocument is part of CrashAnalyser XmlFilePlugin plugin. +* Container and output implementation for data in XML File format. +* XML format is an intermediate file used in the MobileCrash server +* CXmlFileSink creates an instance of this class and uses it to output +* crash data to file in XML format. +* +*/ + +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml; + +using CrashItemLib.Crash.Base; +using CrashItemLib.Crash.Processes; +using CrashItemLib.Crash.Container; +using System.IO; +using CrashItemLib.Sink; + +namespace XmlFilePlugin.PluginImplementations.FileFormat +{ + internal class CXmlFileDocument + { + #region Constructors + public CXmlFileDocument() + + { + } + + #endregion + + /** Creates a new datablock and inputs data from container to the datablock */ + public void ReadDataFromContainer(CISinkSerializationParameters aParams) + { + CIContainer container = aParams.Container; + + //Create a datablock for this container's contents + CXmlDataBlock datablock = new CXmlDataBlock(); + + //Read all interesting data from container to the datablock + datablock.AddHeader(container); + datablock.AddSWInfos(container); + datablock.AddThreadAndExitInfo(container); + datablock.AddPanicedProcess(container); + datablock.AddRegisterLists(container); + datablock.AddStacks(container); + datablock.AddCodeSegments(container); + datablock.AddMemoryInfo(container); + datablock.AddHWInfo(container); + datablock.AddTelephony(container); + datablock.AddEnvInfo(container); + datablock.AddReportParameters(container); + datablock.AddMessages(container); + datablock.AddCrashHash(container); + + string archivedFileName = (String)aParams.OperationData1; + datablock.AddFileNames(container, archivedFileName); + datablock.AddEventlog(container); + + datablock.AddOstTraces(container); + + //If all went well, we will add datablock to stored datablocks + iDatablocks.Add(datablock); + } + + public void WriteToXmlStream(XmlWriter aOutput) + { + System.Diagnostics.Debug.Assert(aOutput != null); + + WriteHeader(aOutput); + + if (iDatablocks.Count > 0) + { + WriteReport(aOutput); + } + + WriteFooter(aOutput); + } + + /** + * Writes as plain text. + */ + public void WriteToPlainTextStream(StreamWriter aOutput) + { + PlainTextOutput.Write(aOutput, iDatablocks); + } + + private void WriteReport(XmlWriter aOutput) + { + CXmlDataBlock datablock = iDatablocks[0]; + + aOutput.WriteStartElement(XmlConsts.Kxml_report); + + WriteDevice(aOutput, datablock); + WriteReportDetails(aOutput, datablock); + + aOutput.WriteEndElement(); + } + + + private static void WriteDevice(XmlWriter aOutput, CXmlDataBlock datablock) + { + // Device + aOutput.WriteStartElement(XmlConsts.Kxml_device); + + if (datablock.Platform().Equals(XmlConsts.Kxml_sos)) + { + aOutput.WriteAttributeString(XmlConsts.Kxml_platform, XmlConsts.Kxml_s60); + } + else + { + aOutput.WriteAttributeString(XmlConsts.Kxml_platform, datablock.Platform()); + } + + aOutput.WriteAttributeString(XmlConsts.Kxml_code, datablock.ProductType()); + aOutput.WriteAttributeString(XmlConsts.Kxml_version, datablock.SWVersion()); + + if (datablock.RomId() != null) + { + aOutput.WriteAttributeString(XmlConsts.Kxml_romid, datablock.RomId().ToString()); + } + + // variant is not written. + + if (datablock.Imei() != string.Empty) + { + aOutput.WriteAttributeString(XmlConsts.Kxml_imei, datablock.Imei()); + } + + // Write additional device details here if exist. + + aOutput.WriteEndElement(); + } + + private static void WriteHeader(XmlWriter aOutput) + { + aOutput.WriteStartDocument(); + aOutput.WriteDocType(XmlConsts.Kxml_report, null, XmlConsts.Kxml_doctype, null); + } + + private static void WriteFooter(XmlWriter aOutput) + { + aOutput.WriteEndDocument(); + } + + private static void WriteReportDetails(XmlWriter aOutput, CXmlDataBlock datablock) + { + // Device report details + aOutput.WriteStartElement(XmlConsts.Kxml_report_details); + aOutput.WriteAttributeString(XmlConsts.Kxml_timestamp, datablock.TimeStampText()); + + string crashtypestr = "Not found"; + if(datablock.FileType() == XmlConsts.MobileCrashFileType.ETypeBasicCrash) + { + crashtypestr = XmlConsts.Kxml_type_crash; + } + else if (datablock.FileType() == XmlConsts.MobileCrashFileType.ETypeAliveMessage) + { + crashtypestr = XmlConsts.Kxml_type_alivemsg; + } + else if (datablock.FileType() == XmlConsts.MobileCrashFileType.ETypeCrashAPIReport) + { + crashtypestr = XmlConsts.Kxml_type_report; + } + else if (datablock.FileType() == XmlConsts.MobileCrashFileType.ETypeRegistrationMessage) + { + crashtypestr = XmlConsts.Kxml_type_regmsg; + } + + aOutput.WriteAttributeString(XmlConsts.Kxml_type, crashtypestr); + + aOutput.WriteAttributeString(XmlConsts.Kxml_file_name, datablock.BinFilename()); + + if (crashtypestr.Equals(XmlConsts.Kxml_type_report)) + { + aOutput.WriteAttributeString(XmlConsts.Kxml_report_category, datablock.ReportCategory()); + } + + if (crashtypestr.Equals(XmlConsts.Kxml_type_report)) + { + aOutput.WriteAttributeString(XmlConsts.Kxml_report_type, datablock.ReportType()); + } + + if (datablock.CrashedModuleName() != string.Empty) + { + aOutput.WriteAttributeString(XmlConsts.Kxml_crashed_module, datablock.CrashedModuleName()); + } + + if (datablock.Hash() != string.Empty) + { + aOutput.WriteAttributeString(XmlConsts.Kxml_defect_hash, datablock.Hash()); + } + + // Child elements for report details + if (datablock.CodeSegs().Count > 0) + { + aOutput.WriteStartElement(XmlConsts.Kxml_loaded_dlls); + } + foreach (CXmlCodeSegItem codeseg in datablock.CodeSegs()) + { + aOutput.WriteStartElement(XmlConsts.Kxml_loaded_dll); + aOutput.WriteAttributeString(XmlConsts.Kxml_name, codeseg.Name); + aOutput.WriteAttributeString(XmlConsts.Kxml_start_address, codeseg.Start.ToString()); + aOutput.WriteAttributeString(XmlConsts.Kxml_end_address, codeseg.End.ToString()); + aOutput.WriteEndElement(); // loaded dll + } + + if (datablock.CodeSegs().Count > 0) + { + aOutput.WriteEndElement(); // loaded dlls + } + + // Traces + if(datablock.RegStorage().BasicRegs().Registers.Count > 0 || + datablock.CallStacks().Count > 0 || + datablock.OstTraces().Count > 0 || + datablock.Eventlog().Count > 0 || + datablock.RegStorage().OtherRegLists().Count > 0) + { + aOutput.WriteStartElement(XmlConsts.Kxml_traces); + } + + WriteDetail(aOutput, XmlConsts.Kxml_register, datablock.RegStorage().BasicRegs().ToString()); + + // Extra registers + System.Text.StringBuilder extraRegisters = new System.Text.StringBuilder(); + foreach (CXmlRegisterStorage.CCrashInfoRegisterList registerList in datablock.RegStorage().OtherRegLists()) + { + extraRegisters.AppendLine(registerList.ToPrettyString()); + } + WriteDetail(aOutput, XmlConsts.Kxml_register_extra, extraRegisters.ToString()); + + // Call stack + foreach (XmlFilePlugin.FileFormat.CXmlCallStack stack in datablock.CallStacks()) + { + WriteDetail(aOutput, XmlConsts.Kxml_call_stack_text, stack.ToString()); + } + + // OST traces + System.Text.StringBuilder ostTraces = new System.Text.StringBuilder(); + foreach (string line in datablock.OstTraces()) + { + ostTraces.AppendLine(line); + } + WriteDetail(aOutput, XmlConsts.Kxml_trace_data, ostTraces.ToString()); + + // Event log + System.Text.StringBuilder eventLog = new System.Text.StringBuilder(); + foreach (string line in datablock.Eventlog()) + { + eventLog.AppendLine(line); + } + WriteDetail(aOutput, XmlConsts.Kxml_eventlog, eventLog.ToString()); + + if (datablock.RegStorage().BasicRegs().Registers.Count > 0 || + datablock.CallStacks().Count > 0 || + datablock.OstTraces().Count > 0 || + datablock.Eventlog().Count > 0 || + datablock.RegStorage().OtherRegLists().Count > 0) + { + aOutput.WriteEndElement(); // traces + } + WriteDictionaryValues(aOutput, datablock); + WriteUniqueValues(aOutput, datablock); + + aOutput.WriteEndElement(); // report details + } + + + private static void WriteDictionaryValues(XmlWriter aOutput, CXmlDataBlock datablock) + { + // Dictionary values + aOutput.WriteStartElement(XmlConsts.Kxml_dictionary_values); + + WriteDetail(aOutput, XmlConsts.Kxml_panic_id, datablock.PanicId()); + WriteDetail(aOutput, XmlConsts.Kxml_panic_category, datablock.PanicCategory()); + WriteDetail(aOutput, XmlConsts.Kxml_panic_description, datablock.PanicDescription()); + WriteDetail(aOutput, XmlConsts.Kxml_language, datablock.Language()); + + if (!datablock.Process().Equals(XmlConsts.Kxml_unknown_process)) + { + WriteDetail(aOutput, XmlConsts.Kxml_panicked_process, datablock.Process()); + } + + WriteDetail(aOutput, XmlConsts.Kxml_network_country_code, datablock.NetworkCountry()); + WriteDetail(aOutput, XmlConsts.Kxml_network_identity, datablock.NetworkIdentity()); + WriteDetail(aOutput, XmlConsts.Kxml_s60version, datablock.S60Version()); + WriteDetail(aOutput, XmlConsts.Kxml_product_code, datablock.ProductCode()); + WriteDetail(aOutput, XmlConsts.Kxml_variant_version, datablock.VariantVersion()); + + aOutput.WriteStartElement(XmlConsts.Kxml_detail); + aOutput.WriteAttributeString(XmlConsts.Kxml_name, XmlConsts.Kxml_file_type); + if (datablock.ReportType() != string.Empty) + { + aOutput.WriteAttributeString(XmlConsts.Kxml_value, "1"); + } + else + { + aOutput.WriteAttributeString(XmlConsts.Kxml_value, "0"); + } + aOutput.WriteEndElement(); + + // Production mode + if (datablock.ProductionMode() != -1) + { + aOutput.WriteStartElement(XmlConsts.Kxml_detail); + aOutput.WriteAttributeString(XmlConsts.Kxml_name, XmlConsts.Kxml_production_mode); + if (datablock.ProductionMode() == 1) + { + aOutput.WriteAttributeString(XmlConsts.Kxml_value, XmlConsts.Kxml_production_mode_value); + } + else + { + aOutput.WriteAttributeString(XmlConsts.Kxml_value, XmlConsts.Kxml_rnd_mode_value); + } + aOutput.WriteEndElement(); + } + + // Crash source + if (datablock.CrashSource() != -1) + { + aOutput.WriteStartElement(XmlConsts.Kxml_detail); + aOutput.WriteAttributeString(XmlConsts.Kxml_name, XmlConsts.Kxml_crash_source); + if (datablock.CrashSource() == 1) + { + aOutput.WriteAttributeString(XmlConsts.Kxml_value, XmlConsts.Kxml_crash_source_user); + } + else + { + aOutput.WriteAttributeString(XmlConsts.Kxml_value, XmlConsts.Kxml_crash_source_kernel); + } + aOutput.WriteEndElement(); + } + + WriteSymbolFileNames(aOutput, datablock); + + + aOutput.WriteEndElement(); // dictionary values + } + + + private static void WriteUniqueValues(XmlWriter aOutput, CXmlDataBlock datablock) + { + // Unique values + aOutput.WriteStartElement(XmlConsts.Kxml_unique_values); + + // Hw version is not added because it doesn't exist. + + WriteDetail(aOutput, XmlConsts.Kxml_available_memory, datablock.FreeMemory()); + + if (datablock.RegStorage() != null && datablock.RegStorage().ProgramCounter() != null) + { + WriteDetail(aOutput, XmlConsts.Kxml_program_counter, datablock.RegStorage().ProgramCounter().Value); + WriteDetail(aOutput, XmlConsts.Kxml_program_counter_symbol, datablock.RegStorage().ProgramCounter().Symbol); + } + + WriteDetail(aOutput, XmlConsts.Kxml_misc_info, datablock.GetMiscInfo()); + + // Reporter not written. + // Resetreason not written. + + WriteDetail(aOutput, XmlConsts.Kxml_uptime, datablock.Uptime()); + WriteDetail(aOutput, XmlConsts.Kxml_siminfo, datablock.Imsi()); + WriteDetail(aOutput, XmlConsts.Kxml_locinfo, datablock.LocInfo()); + WriteDetail(aOutput, XmlConsts.Kxml_cellid, datablock.NetworkCell()); + WriteDetail(aOutput, XmlConsts.Kxml_psninfo, datablock.SerialNumber()); + WriteDetail(aOutput, XmlConsts.Kxml_uid, datablock.UID()); + WriteDetail(aOutput, XmlConsts.Kxml_testset, datablock.TestSet()); + WriteDetail(aOutput, XmlConsts.Kxml_diskinfo, datablock.DiskInfo()); + WriteDetail(aOutput, XmlConsts.Kxml_phone_number, datablock.PhoneNumber()); + + WriteDetail(aOutput, XmlConsts.Kxml_report_ok, datablock.ReportOK()); + WriteDetail(aOutput, XmlConsts.Kxml_report_fail, datablock.ReportFail()); + WriteDetail(aOutput, XmlConsts.Kxml_report_param_name1, datablock.ReportParamName1()); + WriteDetail(aOutput, XmlConsts.Kxml_report_param_value1, datablock.ReportParamValue1()); + WriteDetail(aOutput, XmlConsts.Kxml_report_param_name2, datablock.ReportParamName2()); + WriteDetail(aOutput, XmlConsts.Kxml_report_param_value2, datablock.ReportParamValue2()); + WriteDetail(aOutput, XmlConsts.Kxml_report_param_name3, datablock.ReportParamName3()); + WriteDetail(aOutput, XmlConsts.Kxml_report_param_value3, datablock.ReportParamValue3()); + WriteDetail(aOutput, XmlConsts.Kxml_report_comments, datablock.ReportComments()); + + aOutput.WriteEndElement(); // unique values + } + + + private static void WriteSymbolFileNames(XmlWriter aOutput, CXmlDataBlock datablock) + { + List symbolFiles = datablock.SymbolFiles(); + + string symbolfilenames = string.Empty; + foreach (string fileName in symbolFiles) + { + if (symbolfilenames != string.Empty) + { + symbolfilenames = symbolfilenames + ", "; + } + symbolfilenames = symbolfilenames + Path.GetFileName(fileName); + } + + WriteDetail(aOutput, XmlConsts.Kxml_symbol_file_name, symbolfilenames); + } + + private static void WriteDetail(XmlWriter aOutput, string name, ulong? value) + { + if (value != null) + { + aOutput.WriteStartElement(XmlConsts.Kxml_detail); + aOutput.WriteAttributeString(XmlConsts.Kxml_name, name); + aOutput.WriteAttributeString(XmlConsts.Kxml_value, value.ToString()); + aOutput.WriteEndElement(); + } + } + + private static void WriteDetail(XmlWriter aOutput, string name, double? value) + { + if (value != null) + { + aOutput.WriteStartElement(XmlConsts.Kxml_detail); + aOutput.WriteAttributeString(XmlConsts.Kxml_name, name); + aOutput.WriteAttributeString(XmlConsts.Kxml_value, value.ToString()); + aOutput.WriteEndElement(); + } + } + + private static void WriteDetail(XmlWriter aOutput, string name, string value) + { + if (value != string.Empty) + { + aOutput.WriteStartElement(XmlConsts.Kxml_detail); + aOutput.WriteAttributeString(XmlConsts.Kxml_name, name); + aOutput.WriteAttributeString(XmlConsts.Kxml_value, value); + aOutput.WriteEndElement(); + } + } + + private static void WriteDetail(XmlWriter aOutput, string name, int? value) + { + if (value != null) + { + aOutput.WriteStartElement(XmlConsts.Kxml_detail); + aOutput.WriteAttributeString(XmlConsts.Kxml_name, name); + aOutput.WriteAttributeString(XmlConsts.Kxml_value, value.ToString()); + aOutput.WriteEndElement(); + } + } + + #region Data members + private List iDatablocks = new List(); + #endregion + } +}