blob: 30c4c44c5d92dc6cdc9f87cc23d8ed53fafd83e7 [file] [log] [blame]
Jon Medhurstaaf37a32013-06-11 12:10:56 +01001/**
2 * Copyright (C) ARM Limited 2010-2013. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <stdlib.h>
10#include <string.h>
11#include <dirent.h>
12#include "SessionData.h"
13#include "CapturedXML.h"
14#include "Logging.h"
15#include "OlyUtility.h"
16
17CapturedXML::CapturedXML() {
18}
19
20CapturedXML::~CapturedXML() {
21}
22
23mxml_node_t* CapturedXML::getTree(bool includeTime) {
24 mxml_node_t *xml;
25 mxml_node_t *captured;
26 mxml_node_t *target;
27 int x;
28
29 xml = mxmlNewXML("1.0");
30
31 captured = mxmlNewElement(xml, "captured");
32 mxmlElementSetAttr(captured, "version", "1");
33 mxmlElementSetAttrf(captured, "protocol", "%d", PROTOCOL_VERSION);
34 if (includeTime) { // Send the following only after the capture is complete
35 if (time(NULL) > 1267000000) { // If the time is reasonable (after Feb 23, 2010)
36 mxmlElementSetAttrf(captured, "created", "%lu", time(NULL)); // Valid until the year 2038
37 }
38 }
39
40 target = mxmlNewElement(captured, "target");
41 mxmlElementSetAttr(target, "name", gSessionData->mCoreName);
42 mxmlElementSetAttrf(target, "sample_rate", "%d", gSessionData->mSampleRate);
43 mxmlElementSetAttrf(target, "cores", "%d", gSessionData->mCores);
44 mxmlElementSetAttrf(target, "cpuid", "0x%x", gSessionData->mCpuId);
45
Jon Medhurstd3698592013-10-10 16:48:56 +010046 if (!gSessionData->mOneShot && (gSessionData->mSampleRate > 0)) {
47 mxmlElementSetAttr(target, "supports_live", "yes");
48 }
49
50 if (gSessionData->mLocalCapture) {
51 mxmlElementSetAttr(target, "local_capture", "yes");
52 }
53
Jon Medhurstaaf37a32013-06-11 12:10:56 +010054 mxml_node_t *counters = NULL;
55 for (x = 0; x < MAX_PERFORMANCE_COUNTERS; x++) {
56 const Counter & counter = gSessionData->mCounters[x];
57 if (counter.isEnabled()) {
58 if (counters == NULL) {
59 counters = mxmlNewElement(captured, "counters");
60 }
61 mxml_node_t *const node = mxmlNewElement(counters, "counter");
62 mxmlElementSetAttrf(node, "key", "0x%x", counter.getKey());
63 mxmlElementSetAttr(node, "type", counter.getType());
64 mxmlElementSetAttrf(node, "event", "0x%x", counter.getEvent());
65 if (counter.getCount() > 0) {
66 mxmlElementSetAttrf(node, "count", "%d", counter.getCount());
67 }
68 }
69 }
70
71 return xml;
72}
73
74char* CapturedXML::getXML(bool includeTime) {
75 char* xml_string;
76 mxml_node_t *xml = getTree(includeTime);
77 xml_string = mxmlSaveAllocString(xml, mxmlWhitespaceCB);
78 mxmlDelete(xml);
79 return xml_string;
80}
81
82void CapturedXML::write(char* path) {
83 char file[PATH_MAX];
84
85 // Set full path
86 snprintf(file, PATH_MAX, "%s/captured.xml", path);
87
88 char* xml = getXML(true);
89 if (util->writeToDisk(file, xml) < 0) {
90 logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file);
91 handleException();
92 }
93
94 free(xml);
95}
96
97// whitespace callback utility function used with mini-xml
98const char * mxmlWhitespaceCB(mxml_node_t *node, int loc) {
99 const char *name;
100
101 name = mxmlGetElement(node);
102
103 if (loc == MXML_WS_BEFORE_OPEN) {
104 // Single indentation
105 if (!strcmp(name, "target") || !strcmp(name, "counters"))
106 return("\n ");
107
108 // Double indentation
109 if (!strcmp(name, "counter"))
110 return("\n ");
111
112 // Avoid a carriage return on the first line of the xml file
113 if (!strncmp(name, "?xml", 4))
114 return(NULL);
115
116 // Default - no indentation
117 return("\n");
118 }
119
120 if (loc == MXML_WS_BEFORE_CLOSE) {
121 // No indentation
122 if (!strcmp(name, "captured"))
123 return("\n");
124
125 // Single indentation
126 if (!strcmp(name, "counters"))
127 return("\n ");
128
129 // Default - no carriage return
130 return(NULL);
131 }
132
133 return(NULL);
134}