/* * Copyright (c) 2017, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #define LOG_TAG "ConfigParser" #include #include #include #include "vidc_debug.h" #include "PlatformConfig.h" #include "ConfigParser.h" namespace Platform { #define BUF_SIZE 1024 void ConfigParser::processProperty(const XML_Char **attr, ConfigMap &configMap) { if (strcmp(attr[0], "name") != 0) { DEBUG_PRINT_HIGH("%s: Element 'name' not found!", __func__); return; } std::string propName(attr[1]); if (strcmp(attr[2], "value") != 0) { DEBUG_PRINT_HIGH("%s: Element 'value' not found for %s!", __func__, propName.c_str()); return; } std::string propValue(attr[3]); configMap[propName] = propValue; return; } void ConfigParser::startTag(void *userdata, const XML_Char *tagName, const XML_Char **attr) { if (strcmp(tagName, "property") == 0) { processProperty(attr, *static_cast(userdata)); } return; } void ConfigParser::endTag(void *userdata __unused, const XML_Char *tagName __unused) { return; } int ConfigParser::initAndParse(std::string configFile, ConfigMap &configMap) { int err = 1; XML_Parser parser; FILE *file; file = fopen(configFile.c_str(), "r"); if (!file) { DEBUG_PRINT_HIGH("%s: Error: %d (%s). Using defaults!", __func__, errno, strerror(errno)); return err; } // Create Parser parser = XML_ParserCreate(NULL); if (!parser) { DEBUG_PRINT_HIGH("%s: Failed to create XML parser!", __func__); err = -ENODEV; goto fileError; } // Set XML element handlers XML_SetUserData(parser, &configMap); XML_SetElementHandler(parser, startTag, endTag); void *buf; int bytesRead; // Parse while (1) { buf = XML_GetBuffer(parser, BUF_SIZE); if (buf == NULL) { DEBUG_PRINT_HIGH("%s: XML_GetBuffer failed", __func__); err = -ENOMEM; goto parserError; } bytesRead = fread(buf, 1, BUF_SIZE, file); if (bytesRead < 0) { DEBUG_PRINT_HIGH("%s: fread failed, bytes read = %d", __func__, bytesRead); err = bytesRead; goto parserError; } if (XML_ParseBuffer(parser, bytesRead, bytesRead == 0) == XML_STATUS_ERROR) { DEBUG_PRINT_HIGH("%s: XML_ParseBuffer failed, for %s", __func__, configFile.c_str()); err = -EINVAL; goto parserError; } if (bytesRead == 0) break; } // Free parser and close file in error/ at exit parserError: XML_ParserFree(parser); fileError: fclose(file); return err; } }