summaryrefslogtreecommitdiffstats
path: root/jni/ConfFileParser.cpp
diff options
context:
space:
mode:
authorVenkateshwarlu Domakonda <vdomak@codeaurora.org>2014-05-26 14:35:12 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2014-05-29 22:19:31 -0700
commit1c2c4355c22213cd1dffdda725e8b3e66fc4074a (patch)
treee440cf8133b9e361632d986673539dd200d2f567 /jni/ConfFileParser.cpp
parent360a450969d45c3633d0d319945fd70d8985da10 (diff)
downloadandroid_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.cpp917
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;
+ }
+}