libfmjni: Implement hal layer
Implement HAL layer that can be plugged in with Android FM APP to get fm functionalities. Change-Id: Id16d37a320fdbacb505ba7ecc431622db17bd4d7
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
commit
6ff7436b7e
918
ConfFileParser.cpp
Normal file
918
ConfFileParser.cpp
Normal file
@@ -0,0 +1,918 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#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 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user