* libfm_jni/ConfFileParser.cpp:480:21:
error: using the result of an assignment
as a condition without parentheses
Change-Id: Ib9526734ec96e029f89801ec9b008296a7e2c0fc
879 lines
21 KiB
C++
879 lines
21 KiB
C++
/*
|
|
Copyright (c) 2015, 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 "android_hardware_fm"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <limits.h>
|
|
#include <math.h>
|
|
#include <utils/Log.h>
|
|
#include "ConfFileParser.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 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;
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
//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
|
|
)
|
|
{
|
|
const char *equal_start;
|
|
char *key = NULL;
|
|
char *val = NULL;
|
|
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");
|
|
if(key){
|
|
free(key);
|
|
key = NULL;
|
|
}
|
|
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");
|
|
goto err;
|
|
}
|
|
while((list != NULL) && strcmp(key, list->key)) {
|
|
list = list->next;
|
|
}
|
|
if(list != NULL) {
|
|
ALOGE("group already contains the key\n");
|
|
goto err;
|
|
}else{
|
|
list = alloc_key_value_pair();
|
|
if(list == NULL) {
|
|
ALOGE("add key value failed as could not alloc memory for key\
|
|
val pair\n");
|
|
goto err;
|
|
}
|
|
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);
|
|
goto err;
|
|
}
|
|
val_len = strlen(val);
|
|
list->value = (char *)malloc(sizeof(char) *
|
|
(val_len + 1));
|
|
if(!list->value) {
|
|
free(list->key);
|
|
free(list);
|
|
goto err;
|
|
}
|
|
memcpy(list->key, key, key_len);
|
|
memcpy(list->value, val, val_len);
|
|
if (key) free((char*)key);
|
|
if (val) free((char*)val);
|
|
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");
|
|
goto err;
|
|
}
|
|
err:
|
|
if (key) free((char*)key);
|
|
if (val) free((char*)val);
|
|
return FALSE;
|
|
}
|