diff options
author | Venkateshwarlu Domakonda <vdomak@codeaurora.org> | 2014-05-26 14:35:12 +0530 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2014-05-29 22:19:31 -0700 |
commit | 1c2c4355c22213cd1dffdda725e8b3e66fc4074a (patch) | |
tree | e440cf8133b9e361632d986673539dd200d2f567 /jni/ConfFileParser.cpp | |
parent | 360a450969d45c3633d0d319945fd70d8985da10 (diff) | |
download | android_vendor_qcom_opensource_fm-commonsys-1c2c4355c22213cd1dffdda725e8b3e66fc4074a.tar.gz android_vendor_qcom_opensource_fm-commonsys-1c2c4355c22213cd1dffdda725e8b3e66fc4074a.tar.bz2 android_vendor_qcom_opensource_fm-commonsys-1c2c4355c22213cd1dffdda725e8b3e66fc4074a.zip |
fm: Added support for configuring performance parameters
Add apis to configure fm performance related parameters.
CRs-Fixed: 671803
Change-Id: I37565c21a731023e42372be71fb28edc30154672
Diffstat (limited to 'jni/ConfFileParser.cpp')
-rw-r--r-- | jni/ConfFileParser.cpp | 917 |
1 files changed, 917 insertions, 0 deletions
diff --git a/jni/ConfFileParser.cpp b/jni/ConfFileParser.cpp new file mode 100644 index 0000000..103c240 --- /dev/null +++ b/jni/ConfFileParser.cpp @@ -0,0 +1,917 @@ +/* + * Copyright (c) 2014, 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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. + */ + +#include "ConfFileParser.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <limits.h> +#include <math.h> +#include <utils/Log.h> + +//declaration of functions only specific to this file +static char parse_line +( + group_table *key_file, + const char *line, + char **cur_grp +); + +static char parse_load_frm_fhandler +( + group_table *key_file, + FILE *fp +); + +static char line_is_grp +( + group_table *key_file, + const char *str, + char **cur_grp +); + +static void free_grp_list +( + group *a +); + +static void free_key_list +( + key_value_pair_list *a +); + +static char line_is_key_value_pair +( + group_table *key_file, + const char *str, + const char *cur_grp +); + +static char line_is_comment +( + const char *str +); + +static char grp_exist +( + const group_table *key_file, + const char *new_grp +); + +static char add_grp +( + group_table *key_file, + const char *new_grp +); + +static group *alloc_group +( + void +); + +static key_value_pair_list *alloc_key_value_pair +( + void +); + +static char add_key_value_pair +( + group_table *key_file, + const char *cur_grp, + const char *key, + const char *val +); + + +//Definitions +void free_strs +( + char **str_array +) +{ + char **str_array_cpy = str_array; + if(str_array != NULL) { + while(*str_array != NULL) { + free(*str_array); + str_array++; + } + } + free(str_array_cpy); +} +//ToDo: Come up with code hashing +//function +unsigned int get_hash_code +( + const char *str +) +{ + + unsigned len = strlen(str); + unsigned int i; + unsigned int hash_code = 0; + + for(i = 0; len > 0; len--, i++) { + hash_code += (int)((str[i] * pow(2, len))) % INT_MAX; + hash_code %= INT_MAX; + } + return hash_code; +} + +static key_value_pair_list *alloc_key_value_pair +( + void +) +{ + key_value_pair_list *key_list = NULL; + + key_list = (key_value_pair_list *)malloc( + sizeof(key_value_pair_list)); + if(key_list != NULL) { + key_list->key = NULL; + key_list->next = NULL; + key_list->value = NULL; + } + return key_list; +} + +static group * alloc_group +( + void +) +{ + group *grp = NULL; + unsigned int i; + + grp = (group *)malloc(sizeof(group)); + if(grp != NULL) { + grp->grp_name = NULL; + grp->grp_next = NULL; + grp->num_of_keys = 0; + grp->keys_hash_size = MAX_UNIQ_KEYS; + grp->list = (key_value_pair_list **)malloc + (sizeof(key_value_pair_list *) * grp->keys_hash_size); + if(grp->list == NULL) { + ALOGE("Could not alloc group\n"); + free(grp); + grp = NULL; + }else { + for(i = 0; i < grp->keys_hash_size; i++) { + grp->list[i] = NULL; + } + } + } + return grp; +} + +group_table *get_key_file +( +) +{ + group_table *t = NULL; + unsigned int i; + + t = (group_table *)malloc(sizeof(group_table)); + if (t != NULL) { + t->grps_hash_size = MAX_UNIQ_GRPS; + t->num_of_grps = 0; + t->grps_hash = (group **)malloc(sizeof(group *) + * t->grps_hash_size); + if (t->grps_hash == NULL) { + free(t); + return NULL; + } + for(i = 0; i < t->grps_hash_size; i++) { + t->grps_hash[i] = NULL; + } + } + return t; +} + +void free_key_file( + group_table *key_file +) +{ + unsigned int i; + + if(key_file != NULL) { + if(key_file->grps_hash != NULL) { + for(i = 0; i < key_file->grps_hash_size; i++) { + free_grp_list(key_file->grps_hash[i]); + } + } + free(key_file->grps_hash); + free(key_file); + } +} + +static void free_grp_list +( + group *a +) +{ + group *next; + unsigned int i; + + while(a != NULL) { + next = a->grp_next; + if(a->list != NULL) { + for(i = 0; i < a->keys_hash_size; i++) { + free_key_list(a->list[i]); + } + } + free(a->grp_name); + free(a->list); + free(a); + a = next; + } +} + +static void free_key_list +( + key_value_pair_list *a +) +{ + key_value_pair_list *next; + + while(a != NULL) { + next = a->next; + free(a->key); + free(a->value); + free(a); + a = next; + } +} +//return all the groups +//present in the file +char **get_grps +( + const group_table *key_file +) +{ + char **grps = NULL; + unsigned int i = 0; + unsigned int j = 0; + unsigned int grp_len; + group *grp_list; + + if((key_file == NULL) + || (key_file->grps_hash == NULL) + || (key_file->grps_hash_size == 0) + || (key_file->num_of_grps == 0)) { + return grps; + } + grps = (char **)calloc((key_file->num_of_grps + 1), + sizeof(char *)); + if(grps == NULL) { + return grps; + } + for(i = 0; i < key_file->grps_hash_size; i++) { + grp_list = key_file->grps_hash[i]; + while(grp_list != NULL) { + grp_len = strlen(grp_list->grp_name); + grps[j] = (char *)malloc(sizeof(char) * + (grp_len + 1)); + if(grps[j] == NULL) { + free_strs(grps); + grps = NULL; + return grps; + } + memcpy(grps[j], grp_list->grp_name, + (grp_len + 1)); + grp_list = grp_list->grp_next; + j++; + } + } + grps[j] = NULL; + return grps; +} + +//returns the list of keys +//associated with group name +char **get_keys +( + const group_table *key_file, + const char *grp_name +) +{ + unsigned int grp_hash_code; + unsigned int grp_index; + unsigned int num_of_keys; + unsigned int i; + unsigned int j = 0; + unsigned int key_len; + group *grp; + key_value_pair_list *key_val_list; + char **keys = NULL; + + if((key_file == NULL) || (grp_name == NULL) + || (key_file->num_of_grps == 0) || + (key_file->grps_hash_size == 0) || + (key_file->grps_hash == NULL) || + (!strcmp(grp_name, ""))) { + return keys; + } + grp_hash_code = get_hash_code(grp_name); + grp_index = (grp_hash_code % key_file->grps_hash_size); + grp = key_file->grps_hash[grp_index]; + while(grp != NULL) { + if(!strcmp(grp_name, grp->grp_name)) { + if((grp->num_of_keys == 0) + || (grp->keys_hash_size == 0) + || (grp->list == 0)) { + return keys; + } + keys = (char **)calloc((grp->num_of_keys + 1), + sizeof(char *)); + if(keys == NULL) { + return keys; + } + for(i = 0; i < grp->keys_hash_size; i++) { + key_val_list = grp->list[i]; + while(key_val_list != NULL) { + key_len = strlen(key_val_list->key); + keys[j] = (char *)malloc(sizeof(char) * + (key_len + 1)); + if(keys[j] == NULL) { + free_strs(keys); + keys = NULL; + return keys; + } + memcpy(keys[j], key_val_list->key, + (key_len + 1)); + j++; + key_val_list = key_val_list->next; + } + } + keys[j] = NULL; + return keys; + } + grp = grp->grp_next; + } + return keys; +} + +char *get_value +( + const group_table *key_file, + const char *grp_name, + const char *key +) +{ + unsigned int grp_hash_code; + unsigned int key_hash_code; + unsigned int grp_index; + unsigned int key_index; + unsigned val_len; + char *val = NULL; + group *grp; + key_value_pair_list *list; + + if((key_file == NULL) || (grp_name == NULL) + || (key == NULL) || (key_file->grps_hash == NULL) + || (key_file->grps_hash_size == 0) || !strcmp(grp_name, "") + ||(!strcmp(key, ""))) { + return NULL; + } + grp_hash_code = get_hash_code(grp_name); + key_hash_code = get_hash_code(key); + grp_index = (grp_hash_code % key_file->grps_hash_size); + grp = key_file->grps_hash[grp_index]; + while(grp != NULL) { + if(!strcmp(grp_name, grp->grp_name) && grp->keys_hash_size + && grp->list) { + key_index = (key_hash_code % grp->keys_hash_size); + list = grp->list[key_index]; + while((list != NULL) && (strcmp(list->key, key))) { + list = list->next; + } + if(list != NULL) { + val_len = strlen(list->value); + val = (char *)malloc(sizeof(char) * (val_len + 1)); + if(val != NULL) { + memcpy(val, list->value, val_len); + val[val_len] = '\0'; + } + } + return val; + } + grp = grp->grp_next; + } + return val; +} +//open the file, +//read, parse and load +//returns PARSE_SUCCESS if successfully +//loaded else PARSE_FAILED +char parse_load_file +( + group_table *key_file, + const char *file +) +{ + FILE *fp; + char ret = FALSE; + + if((file == NULL) || !strcmp(file, "")) { + ALOGE("File name is null or empty \n"); + return ret; + } + + fp = fopen(file, "r"); + if(fp == NULL) { + ALOGE("could not open file for read\n"); + return ret; + } + + ret = parse_load_frm_fhandler(key_file, fp); + fclose(fp); + + return ret; +} + +//Read block of data from file handler +//extract each line, check kind of line(comment, +//group, key value pair) +static char parse_load_frm_fhandler +( + group_table *key_file, + FILE *fp +) +{ + char buf[MAX_LINE_LEN]; + char ret = TRUE; + char *line = NULL; + void *new_line; + char *cur_grp = NULL; + unsigned line_len = 0; + unsigned line_allocated = 0; + unsigned int bytes_read = 0; + unsigned int i; + bool has_carriage_rtn = false; + + while((bytes_read = fread(buf, 1, MAX_LINE_LEN, fp))) { + for(i = 0; i < bytes_read; i++) { + if(line_len == line_allocated) { + line_allocated += 25; + new_line = realloc(line, line_allocated); + if(new_line == NULL) { + ret = FALSE; + ALOGE("memory allocation failed for line\n"); + break; + } + line = (char *)new_line; + } + if((buf[i] == '\n')) { + has_carriage_rtn = false; + line[line_len] = '\0'; + ret = parse_line(key_file, line, &cur_grp); + line_len = 0; + if(ret == FALSE) { + ALOGE("could not parse the line, line not proper\n"); + break; + } + }else if(buf[i] == '\r') { + ALOGE("File has carriage return\n"); + has_carriage_rtn = true; + }else if(has_carriage_rtn) { + ALOGE("File format is not proper, no line character\ + after carraige return\n"); + ret = FALSE; + break; + }else { + line[line_len] = buf[i]; + line_len++; + } + } + if (!ret) { + break; + } + } + free(line); + free(cur_grp); + + return ret; +} + +//checks whether a line is +//comment or grp or key pair value +//and accordingly adds to list +static char parse_line +( + group_table *key_file, + const char *line, + char **cur_grp +) +{ + const char *line_begin; + char *grp_name; + unsigned int len; + + if((line == NULL) || (key_file == NULL)) { + ALOGE("key file or line is null\n"); + return FALSE; + } + + for(line_begin = line; isspace(*line_begin); + line_begin++); + + if(line_is_comment(line_begin)) { + ALOGE("line is comment\n"); + return TRUE; + }else if(line_is_grp(key_file, line_begin, cur_grp)) { + ALOGE("line is grp\n"); + return TRUE; + }else if(line_is_key_value_pair(key_file, line_begin, *cur_grp)) { + ALOGE("line is key value pair\n"); + return TRUE; + }else { + ALOGE("line is neither comment, grp nor key value pair\n"); + return FALSE; + } +} + +static char line_is_comment +( + const char *str +) +{ + if(str == NULL) { + return FALSE; + }else if(((*str) == '#') || ((*str) == '\0') + || ((*str) == '\n')) { + return TRUE; + }else { + ALOGE("line is not comment\n"); + return FALSE; + } +} + +//return true if a group +//name already exist +//else false +static char grp_exist +( + const group_table *key_file, + const char *new_grp +) +{ + unsigned hash_code; + unsigned int index; + group *grp; + + if((key_file == NULL) || (new_grp == NULL) + || (!key_file->grps_hash_size)) { + return FALSE; + }else { + hash_code = get_hash_code(new_grp); + index = hash_code % key_file->grps_hash_size; + grp = key_file->grps_hash[index]; + while(grp != NULL) { + if (!strcmp(grp->grp_name, new_grp)) + return TRUE; + grp = grp->grp_next; + } + return FALSE; + } +} + +//Add a group to group +//table if it does not exist +static char add_grp +( + group_table *key_file, + const char *new_grp +) +{ + unsigned int hash_code; + unsigned int index; + unsigned int grp_name_len; + group *grp; + + if(!grp_exist(key_file, new_grp)) { + if((key_file == NULL) || (new_grp == NULL) + || !key_file->grps_hash_size) { + return FALSE; + } + hash_code = get_hash_code(new_grp); + ALOGE("group hash code is: %u\n", hash_code); + index = hash_code % key_file->grps_hash_size; + ALOGE("group index is: %u\n", index); + grp = alloc_group(); + if(grp == NULL) { + return FALSE; + } + grp_name_len = strlen(new_grp); + grp->grp_name = (char *)malloc( + sizeof(char) * (grp_name_len + 1)); + if(grp->grp_name == NULL) { + ALOGE("could not alloc memory for group name\n"); + ALOGE("Add group failed\n"); + free_grp_list(grp); + return FALSE; + }else { + memcpy(grp->grp_name, new_grp, (grp_name_len + 1)); + } + grp->grp_next = key_file->grps_hash[index]; + key_file->grps_hash[index] = grp; + key_file->num_of_grps++; + return TRUE; + }else { + return FALSE; + } +} + +//checks validity of a group +//a valid group is +//inside [] group name must be +//alphanumeric +//Example: [grpName] +static char line_is_grp +( + group_table *key_file, + const char *str, + char **cur_grp +) +{ + const char *g_start; + const char *g_end; + char *new_grp; + unsigned int grp_len; + + if ((str == NULL) || (key_file == NULL)) { + ALOGE("str is null or key file is null\n"); + return FALSE; + } + //checks start mark char ']' + if(((*str) != '[')) { + ALOGE("start mark is not '['\n"); + return FALSE; + }else { + str++; + g_start = str; + } + //checks the end char '[' + while((*str != '\0') && ((*str) != ']')) { + str++; + } + //if end mark group not found + if ((*str) != ']') { + ALOGE("grp end mark is not '['\n"); + return FALSE; + }else { + g_end = (str - 1); + } + + str++; + //if end mark found checks the rest chars as well + //rest chars should be space + while(((*str) == ' ') || ((*str) == '\t')) { + str++; + } + if(*str) { + ALOGE("after ']' there are some character\n"); + return FALSE; + } + + str = g_start; + while((*g_start != '\0') && (g_start != g_end) + && isalnum(*g_start)) { + g_start++; + } + if((g_start == g_end) && isalnum(*g_start)) { + //look up if already exist + //return false else insert the grp in grp table + grp_len = (g_end - str + 1); + new_grp = (char *)malloc(sizeof(char) * (grp_len + 1)); + if (new_grp == NULL) { + ALOGE("could not alloc memory for new group\n"); + return FALSE; + } + memcpy(new_grp, str, grp_len); + new_grp[grp_len] = '\0'; + + if(add_grp(key_file, new_grp)) { + free(*cur_grp); + *cur_grp = new_grp; + return TRUE; + }else { + ALOGE("could not add group to group table\n"); + return FALSE; + } + }else { + return FALSE; + } +} + +static char key_exist +( + const group_table *key_file, + const char *cur_grp, + const char *key +) +{ + unsigned int grp_hash_code; + unsigned int key_hash_code; + unsigned int grp_index; + unsigned int key_index; + group *grp = NULL; + key_value_pair_list *list = NULL; + + if((key_file != NULL) && (cur_grp != NULL) + && (key != NULL) && ((key_file->grps_hash != NULL)) + && (strcmp(key, ""))) { + grp_hash_code = get_hash_code(cur_grp); + grp_index = (grp_hash_code % key_file->grps_hash_size); + grp = key_file->grps_hash[grp_index]; + key_hash_code = get_hash_code(key); + while((grp != NULL)) { + if(!strcmp(cur_grp, grp->grp_name)) { + key_index = (key_hash_code % grp->keys_hash_size); + if(!grp->list) + list = grp->list[key_index]; + while((list != NULL) && strcmp(key, list->key)) { + list = list->next; + } + if(list != NULL){ + return TRUE; + }else{ + return FALSE; + } + } + grp = grp->grp_next; + } + if(!grp) { + return TRUE; + }else { + return FALSE; + } + }else { + return FALSE; + } +} + +//checks validity of key +//a valid key must start in +//a seperate line and key must +//be alphanumeric and before '=' +//there must not be any space +//Example: key=value +static char line_is_key_value_pair +( + group_table *key_file, + const char *str, + const char *cur_grp +) +{ + char *equal_start; + char *key; + char *val; + unsigned key_len; + unsigned val_len; + + if((str == NULL) || (cur_grp == NULL) || + !strcmp(cur_grp, "") || (key_file == NULL)) { + ALOGE("line is null or cur group or key file is null or empty\n"); + return FALSE; + } + equal_start = strchr(str, '='); + key_len = (equal_start - str); + if((equal_start == NULL) || (equal_start == str)) { + ALOGE("line does not have '=' character or no key\n"); + return FALSE; + } + while((str != equal_start) && isalnum(*str)) + str++; + if((str == equal_start)) { + key = (char *)malloc(sizeof(char) * (key_len + 1)); + if(key == NULL) { + ALOGE("could not alloc memory for new key\n"); + return FALSE; + } + equal_start++; + val_len = strlen(equal_start); + val = (char *)malloc(sizeof(char) * (val_len + 1)); + if(val == NULL) { + ALOGE("could not alloc memory for value\n"); + return FALSE; + } + memcpy(key, (str - key_len), key_len); + memcpy(val, equal_start, val_len); + key[key_len] = '\0'; + val[val_len] = '\0'; + ALOGE("Grp: %s, key: %s, value: %s\n", cur_grp, key, val); + return add_key_value_pair(key_file, + cur_grp, key, val); + }else { + ALOGE("key name doesnot have alpha numeric char\n"); + return FALSE; + } +} + +static char add_key_value_pair +( + group_table *key_file, + const char *cur_grp, + const char *key, + const char *val +) +{ + unsigned int grp_hash_code; + unsigned int key_hash_code; + unsigned int grp_index; + unsigned int key_index; + unsigned key_len, val_len; + group *grp = NULL; + key_value_pair_list *list = NULL; + + if((key_file != NULL) && (cur_grp != NULL) + && (key != NULL) && ((key_file->grps_hash != NULL)) + && (strcmp(key, ""))) { + grp_hash_code = get_hash_code(cur_grp); + ALOGE("grp hash code is %u\n", grp_hash_code); + grp_index = (grp_hash_code % key_file->grps_hash_size); + ALOGE("grp index is %u\n", grp_index); + grp = key_file->grps_hash[grp_index]; + key_hash_code = get_hash_code(key); + while((grp != NULL)) { + if(!strcmp(cur_grp, grp->grp_name)) { + key_index = (key_hash_code % grp->keys_hash_size); + if(grp->list) { + list = grp->list[key_index]; + }else { + ALOGE("group list is null\n"); + return FALSE; + } + while((list != NULL) && strcmp(key, list->key)) { + list = list->next; + } + if(list != NULL) { + ALOGE("group already contains the key\n"); + return FALSE; + }else{ + list = alloc_key_value_pair(); + if(list == NULL) { + ALOGE("add key value failed as could not alloc memory for key\ + val pair\n"); + return FALSE; + } + key_len = strlen(key); + list->key = (char *)malloc(sizeof(char) * + (key_len + 1)); + if(list->key == NULL) { + ALOGE("could not alloc memory for key\n"); + free(list); + return FALSE; + } + val_len = strlen(val); + list->value = (char *)malloc(sizeof(char) * + (val_len + 1)); + if(!list->value) { + free(list->key); + free(list); + return FALSE; + } + memcpy(list->key, key, key_len); + memcpy(list->value, val, val_len); + list->key[key_len] = '\0'; + list->value[val_len] = '\0'; + list->next = grp->list[key_index]; + grp->list[key_index] = list; + grp->num_of_keys++; + return TRUE; + } + } + grp = grp->grp_next; + } + ALOGE("group does not exist\n"); + return FALSE; + }else { + return FALSE; + } +} |