1 /*
2 * Copyright (c) 2017 - 2018, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #define LOG_TAG "ConfigParser"
31
32 #include <string.h>
33 #include <errno.h>
34 #include <utils/Log.h>
35 #include <sys/mman.h>
36 #include "PlatformConfig.h"
37 #include "ConfigParser.h"
38
39 namespace Platform {
40
41 #define BUF_SIZE 1024
42
processProperty(const XML_Char ** attr,ConfigMap & configMap)43 void ConfigParser::processProperty(const XML_Char **attr, ConfigMap &configMap) {
44 if (strcmp(attr[0], "name") != 0) {
45 VIDC_PLAT_LOGH("%s: Element 'name' not found!", __func__);
46 return;
47 }
48
49 std::string propName(attr[1]);
50
51 if (strcmp(attr[2], "value") != 0) {
52 VIDC_PLAT_LOGH("%s: Element 'value' not found for %s!", __func__, propName.c_str());
53 return;
54 }
55
56 std::string propValue(attr[3]);
57
58 configMap[propName] = propValue;
59
60 return;
61 }
62
startTag(void * userdata,const XML_Char * tagName,const XML_Char ** attr)63 void ConfigParser::startTag(void *userdata, const XML_Char *tagName,
64 const XML_Char **attr) {
65 if (strcmp(tagName, "property") == 0) {
66 processProperty(attr, *static_cast<ConfigMap *>(userdata));
67 }
68 return;
69 }
70
endTag(void * userdata __unused,const XML_Char * tagName __unused)71 void ConfigParser::endTag(void *userdata __unused, const XML_Char *tagName __unused) {
72 return;
73 }
74
initAndParse(std::string configFile,ConfigMap & configMap)75 int ConfigParser::initAndParse(std::string configFile, ConfigMap &configMap) {
76 int err = 1;
77 XML_Parser parser;
78 FILE *file;
79 file = fopen(configFile.c_str(), "r");
80 if (!file) {
81 VIDC_PLAT_LOGH("%s: Error: %d (%s). Using defaults!",
82 __func__, errno, strerror(errno));
83 return err;
84 }
85
86 // Create Parser
87 parser = XML_ParserCreate(NULL);
88 if (!parser) {
89 VIDC_PLAT_LOGH("%s: Failed to create XML parser!", __func__);
90 err = -ENODEV;
91 goto fileError;
92 }
93
94 // Set XML element handlers
95 XML_SetUserData(parser, &configMap);
96 XML_SetElementHandler(parser, startTag, endTag);
97 void *buf;
98 int bytesRead;
99
100 // Parse
101 while (1) {
102 buf = XML_GetBuffer(parser, BUF_SIZE);
103 if (buf == NULL) {
104 VIDC_PLAT_LOGH("%s: XML_GetBuffer failed", __func__);
105 err = -ENOMEM;
106 goto parserError;
107 }
108
109 bytesRead = fread(buf, 1, BUF_SIZE, file);
110 if (bytesRead < 0) {
111 VIDC_PLAT_LOGH("%s: fread failed, bytes read = %d", __func__, bytesRead);
112 err = bytesRead;
113 goto parserError;
114 }
115
116 if (XML_ParseBuffer(parser, bytesRead,
117 bytesRead == 0) == XML_STATUS_ERROR) {
118 VIDC_PLAT_LOGH("%s: XML_ParseBuffer failed, for %s",
119 __func__, configFile.c_str());
120 err = -EINVAL;
121 goto parserError;
122 }
123 if (bytesRead == 0)
124 break;
125 }
126
127 // Free parser and close file in error/ at exit
128 parserError:
129 XML_ParserFree(parser);
130 fileError:
131 fclose(file);
132 return err;
133 }
134
135 }
136