1 /**
2 * Copyright (C) ARM Limited 2010-2012. 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 */
9 #include <string.h>
10 #include <stdlib.h>
11 #include <limits.h>
12 #include "SessionXML.h"
13 #include "Logging.h"
14 #include "OlyUtility.h"
16 extern void handleException();
18 static const char* TAG_SESSION = "session";
19 static const char* TAG_IMAGE = "image";
21 static const char* ATTR_VERSION = "version";
22 static const char* ATTR_TITLE = "title";
23 static const char* ATTR_UUID = "uuid";
24 static const char* ATTR_CALL_STACK_UNWINDING = "call_stack_unwinding";
25 static const char* ATTR_BUFFER_MODE = "buffer_mode";
26 static const char* ATTR_SAMPLE_RATE = "sample_rate";
27 static const char* ATTR_TARGET_PATH = "target_path";
28 static const char* ATTR_OUTPUT_PATH = "output_path";
29 static const char* ATTR_DURATION = "duration";
30 static const char* ATTR_PATH = "path";
32 SessionXML::SessionXML(const char* str) {
33 parameters.title = 0;
34 parameters.uuid[0] = 0;
35 parameters.target_path = 0;
36 parameters.output_path = 0;
37 parameters.buffer_mode[0] = 0;
38 parameters.sample_rate[0] = 0;
39 parameters.duration = 0;
40 parameters.call_stack_unwinding = false;
41 parameters.images = NULL;
42 mPath = 0;
43 mSessionXML = (char*)str;
44 logg->logMessage(mSessionXML);
45 }
47 SessionXML::~SessionXML() {
48 if (mPath != 0) {
49 free(mSessionXML);
50 }
51 }
53 void SessionXML::parse() {
54 mxml_node_t *tree;
55 mxml_node_t *node;
57 tree = mxmlLoadString(NULL, mSessionXML, MXML_NO_CALLBACK);
58 node = mxmlFindElement(tree, tree, TAG_SESSION, NULL, NULL, MXML_DESCEND);
60 if (node) {
61 sessionTag(tree, node);
62 mxmlDelete(tree);
63 return;
64 }
66 logg->logError(__FILE__, __LINE__, "No session tag found in the session.xml file");
67 handleException();
68 }
70 void SessionXML::sessionTag(mxml_node_t *tree, mxml_node_t *node) {
71 int version = 0;
72 if (mxmlElementGetAttr(node, ATTR_VERSION)) version = strtol(mxmlElementGetAttr(node, ATTR_VERSION), NULL, 10);
73 if (version != 1) {
74 logg->logError(__FILE__, __LINE__, "Invalid session.xml version: %d", version);
75 handleException();
76 }
78 // allocate strings
79 if (mxmlElementGetAttr(node, ATTR_TITLE)) {
80 parameters.title = strdup(mxmlElementGetAttr(node, ATTR_TITLE)); // freed when the child process exits
81 if (parameters.title == NULL) {
82 logg->logError(__FILE__, __LINE__, "failed to allocate parameters.title");
83 handleException();
84 }
85 }
86 if (mxmlElementGetAttr(node, ATTR_TARGET_PATH)) {
87 parameters.target_path = strdup(mxmlElementGetAttr(node, ATTR_TARGET_PATH)); // freed when the child process exits
88 if (parameters.target_path == NULL) {
89 logg->logError(__FILE__, __LINE__, "failed to allocate parameters.target_path");
90 handleException();
91 }
92 }
93 if (mxmlElementGetAttr(node, ATTR_OUTPUT_PATH)) {
94 parameters.output_path = strdup(mxmlElementGetAttr(node, ATTR_OUTPUT_PATH)); // freed when the child process exits
95 if (parameters.output_path == NULL) {
96 logg->logError(__FILE__, __LINE__, "failed to allocate parameters.output_path");
97 handleException();
98 }
99 }
101 // copy to pre-allocated strings
102 if (mxmlElementGetAttr(node, ATTR_UUID)) {
103 strncpy(parameters.uuid, mxmlElementGetAttr(node, ATTR_UUID), sizeof(parameters.uuid));
104 parameters.uuid[sizeof(parameters.uuid) - 1] = 0; // strncpy does not guarantee a null-terminated string
105 }
106 if (mxmlElementGetAttr(node, ATTR_BUFFER_MODE)) {
107 strncpy(parameters.buffer_mode, mxmlElementGetAttr(node, ATTR_BUFFER_MODE), sizeof(parameters.buffer_mode));
108 parameters.buffer_mode[sizeof(parameters.buffer_mode) - 1] = 0; // strncpy does not guarantee a null-terminated string
109 }
110 if (mxmlElementGetAttr(node, ATTR_SAMPLE_RATE)) {
111 strncpy(parameters.sample_rate, mxmlElementGetAttr(node, ATTR_SAMPLE_RATE), sizeof(parameters.sample_rate));
112 parameters.sample_rate[sizeof(parameters.sample_rate) - 1] = 0; // strncpy does not guarantee a null-terminated string
113 }
115 // integers/bools
116 parameters.call_stack_unwinding = util->stringToBool(mxmlElementGetAttr(node, ATTR_CALL_STACK_UNWINDING), false);
117 if (mxmlElementGetAttr(node, ATTR_DURATION)) parameters.duration = strtol(mxmlElementGetAttr(node, ATTR_DURATION), NULL, 10);
119 // parse subtags
120 node = mxmlGetFirstChild(node);
121 while (node) {
122 if (mxmlGetType(node) != MXML_ELEMENT) {
123 node = mxmlWalkNext(node, tree, MXML_NO_DESCEND);
124 continue;
125 }
126 if (strcmp(TAG_IMAGE, mxmlGetElement(node)) == 0) {
127 sessionImage(node);
128 }
129 node = mxmlWalkNext(node, tree, MXML_NO_DESCEND);
130 }
131 }
133 void SessionXML::sessionImage(mxml_node_t *node) {
134 int length = strlen(mxmlElementGetAttr(node, ATTR_PATH));
135 struct ImageLinkList *image;
137 image = (struct ImageLinkList *)malloc(sizeof(struct ImageLinkList));
138 image->path = (char*)malloc(length + 1);
139 image->path = strdup(mxmlElementGetAttr(node, ATTR_PATH));
140 image->next = parameters.images;
141 parameters.images = image;
142 }