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 <errno.h>
33 #include <utils/Log.h>
34 #include <sys/mman.h>
35 #include "PlatformConfig.h"
36 #include "ConfigParser.h"
37
38 namespace Platform {
39
40 #define BUF_SIZE 1024
41
processProperty(const XML_Char ** attr,ConfigMap & configMap)42 void ConfigParser::processProperty(const XML_Char **attr, ConfigMap &configMap) {
43 if (strcmp(attr[0], "name") != 0) {
44 VIDC_PLAT_LOGH("%s: Element 'name' not found!", __func__);
45 return;
46 }
47
48 std::string propName(attr[1]);
49
50 if (strcmp(attr[2], "value") != 0) {
51 VIDC_PLAT_LOGH("%s: Element 'value' not found for %s!", __func__, propName.c_str());
52 return;
53 }
54
55 std::string propValue(attr[3]);
56
57 configMap[propName] = propValue;
58
59 return;
60 }
61
startTag(void * userdata,const XML_Char * tagName,const XML_Char ** attr)62 void ConfigParser::startTag(void *userdata, const XML_Char *tagName,
63 const XML_Char **attr) {
64 if (strcmp(tagName, "property") == 0) {
65 processProperty(attr, *static_cast<ConfigMap *>(userdata));
66 }
67 return;
68 }
69
endTag(void * userdata __unused,const XML_Char * tagName __unused)70 void ConfigParser::endTag(void *userdata __unused, const XML_Char *tagName __unused) {
71 return;
72 }
73
initAndParse(std::string configFile,ConfigMap & configMap)74 int ConfigParser::initAndParse(std::string configFile, ConfigMap &configMap) {
75 int err = 1;
76 XML_Parser parser;
77 FILE *file;
78 file = fopen(configFile.c_str(), "r");
79 if (!file) {
80 VIDC_PLAT_LOGH("%s: Error: %d (%s). Using defaults!",
81 __func__, errno, strerror(errno));
82 return err;
83 }
84
85 // Create Parser
86 parser = XML_ParserCreate(NULL);
87 if (!parser) {
88 VIDC_PLAT_LOGH("%s: Failed to create XML parser!", __func__);
89 err = -ENODEV;
90 goto fileError;
91 }
92
93 // Set XML element handlers
94 XML_SetUserData(parser, &configMap);
95 XML_SetElementHandler(parser, startTag, endTag);
96 void *buf;
97 int bytesRead;
98
99 // Parse
100 while (1) {
101 buf = XML_GetBuffer(parser, BUF_SIZE);
102 if (buf == NULL) {
103 VIDC_PLAT_LOGH("%s: XML_GetBuffer failed", __func__);
104 err = -ENOMEM;
105 goto parserError;
106 }
107
108 bytesRead = fread(buf, 1, BUF_SIZE, file);
109 if (bytesRead < 0) {
110 VIDC_PLAT_LOGH("%s: fread failed, bytes read = %d", __func__, bytesRead);
111 err = bytesRead;
112 goto parserError;
113 }
114
115 if (XML_ParseBuffer(parser, bytesRead,
116 bytesRead == 0) == XML_STATUS_ERROR) {
117 VIDC_PLAT_LOGH("%s: XML_ParseBuffer failed, for %s",
118 __func__, configFile.c_str());
119 err = -EINVAL;
120 goto parserError;
121 }
122 if (bytesRead == 0)
123 break;
124 }
125
126 // Free parser and close file in error/ at exit
127 parserError:
128 XML_ParserFree(parser);
129 fileError:
130 fclose(file);
131 return err;
132 }
133
134 }
135