aboutsummaryrefslogtreecommitdiff
path: root/daemon/CapturedXML.cpp
blob: 1854c77dcb0eb709438b830a32481015d52cb86e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/**
 * Copyright (C) ARM Limited 2010-2015. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include "CapturedXML.h"

#include <stdlib.h>
#include <string.h>
#include <dirent.h>

#include "SessionData.h"
#include "Logging.h"
#include "OlyUtility.h"

CapturedXML::CapturedXML() {
}

CapturedXML::~CapturedXML() {
}

mxml_node_t* CapturedXML::getTree(bool includeTime) {
	mxml_node_t *xml;
	mxml_node_t *captured;
	mxml_node_t *target;
	int x;

	xml = mxmlNewXML("1.0");

	captured = mxmlNewElement(xml, "captured");
	mxmlElementSetAttr(captured, "version", "1");
	if (gSessionData->perf.isSetup()) {
		mxmlElementSetAttr(captured, "type", "Perf");
	}
	mxmlElementSetAttrf(captured, "protocol", "%d", PROTOCOL_VERSION);
	if (includeTime) { // Send the following only after the capture is complete
		if (time(NULL) > 1267000000) { // If the time is reasonable (after Feb 23, 2010)
			mxmlElementSetAttrf(captured, "created", "%lu", time(NULL)); // Valid until the year 2038
		}
	}

	target = mxmlNewElement(captured, "target");
	mxmlElementSetAttr(target, "name", gSessionData->mCoreName);
	mxmlElementSetAttrf(target, "sample_rate", "%d", gSessionData->mSampleRate);
	mxmlElementSetAttrf(target, "cores", "%d", gSessionData->mCores);
	mxmlElementSetAttrf(target, "cpuid", "0x%x", gSessionData->mMaxCpuId);

	if (!gSessionData->mOneShot && (gSessionData->mSampleRate > 0)) {
		mxmlElementSetAttr(target, "supports_live", "yes");
	}

	if (gSessionData->mLocalCapture) {
		mxmlElementSetAttr(target, "local_capture", "yes");
	}

	mxml_node_t *counters = NULL;
	for (x = 0; x < MAX_PERFORMANCE_COUNTERS; x++) {
		const Counter & counter = gSessionData->mCounters[x];
		if (counter.isEnabled()) {
			if (counters == NULL) {
				counters = mxmlNewElement(captured, "counters");
			}
			mxml_node_t *const node = mxmlNewElement(counters, "counter");
			mxmlElementSetAttrf(node, "key", "0x%x", counter.getKey());
			mxmlElementSetAttr(node, "type", counter.getType());
			if (counter.getEvent() != -1) {
				mxmlElementSetAttrf(node, "event", "0x%x", counter.getEvent());
			}
			if (counter.getCount() > 0) {
				mxmlElementSetAttrf(node, "count", "%d", counter.getCount());
			}
			if (counter.getCores() > 0) {
				mxmlElementSetAttrf(node, "cores", "%d", counter.getCores());
			}
		}
	}

	return xml;
}

char* CapturedXML::getXML(bool includeTime) {
	char* xml_string;
	mxml_node_t *xml = getTree(includeTime);
	xml_string = mxmlSaveAllocString(xml, mxmlWhitespaceCB);
	mxmlDelete(xml);
	return xml_string;
}

void CapturedXML::write(char* path) {
	char file[PATH_MAX];

	// Set full path
	snprintf(file, PATH_MAX, "%s/captured.xml", path);

	char* xml = getXML(true);
	if (util->writeToDisk(file, xml) < 0) {
		logg->logError("Error writing %s\nPlease verify the path.", file);
		handleException();
	}

	free(xml);
}

// whitespace callback utility function used with mini-xml
const char * mxmlWhitespaceCB(mxml_node_t *node, int loc) {
	const char *name;

	name = mxmlGetElement(node);

	if (loc == MXML_WS_BEFORE_OPEN) {
		// Single indentation
		if (!strcmp(name, "target") || !strcmp(name, "counters"))
			return "\n  ";

		// Double indentation
		if (!strcmp(name, "counter"))
			return "\n    ";

		// Avoid a carriage return on the first line of the xml file
		if (!strncmp(name, "?xml", 4))
			return NULL;

		// Default - no indentation
		return "\n";
	}

	if (loc == MXML_WS_BEFORE_CLOSE) {
		// No indentation
		if (!strcmp(name, "captured"))
			return "\n";

		// Single indentation
		if (!strcmp(name, "counters"))
			return "\n  ";

		// Default - no carriage return
		return NULL;
	}

	return NULL;
}