1 /****************************************************************************** 2 * 3 * Copyright (C) 2015 Google, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 #define LOG_TAG "hash_map_utils" 19 20 #include "osi/include/hash_map_utils.h" 21 22 #include <assert.h> 23 #include <string.h> 24 25 #include "osi/include/allocator.h" 26 #include "osi/include/hash_functions.h" 27 #include "osi/include/hash_map.h" 28 #include "osi/include/log.h" 29 #include "osi/include/osi.h" 30 31 static bool string_equals(const void *key_a, const void *key_b); 32 static bool dump_entry(hash_map_entry_t *entry, UNUSED_ATTR void *context); 33 34 static const size_t BUCKETS_NUM = 5; 35 36 hash_map_t *hash_map_utils_new_from_string_params(const char *params) { 37 assert(params != NULL); 38 39 hash_map_t *map = hash_map_new(BUCKETS_NUM, hash_function_string, osi_free, 40 osi_free, string_equals); 41 if (!map) 42 return NULL; 43 44 char *str = osi_strdup(params); 45 if (!str) 46 return NULL; 47 48 LOG_VERBOSE(LOG_TAG, "%s: source string: '%s'", __func__, str); 49 50 // Parse |str| and add extracted key-and-value pair(s) in |map|. 51 int items = 0; 52 char *tmpstr; 53 char *kvpair = strtok_r(str, ";", &tmpstr); 54 while (kvpair && *kvpair) { 55 char *eq = strchr(kvpair, '='); 56 57 if (eq == kvpair) 58 goto next_pair; 59 60 char *key; 61 char *value; 62 if (eq) { 63 key = osi_strndup(kvpair, eq - kvpair); 64 65 // The increment of |eq| moves |eq| to the beginning of the value. 66 ++eq; 67 value = (*eq != '\0') ? osi_strdup(eq) : osi_strdup(""); 68 } else { 69 key = osi_strdup(kvpair); 70 value = osi_strdup(""); 71 } 72 73 hash_map_set(map, key, value); 74 75 items++; 76 next_pair: 77 kvpair = strtok_r(NULL, ";", &tmpstr); 78 } 79 80 if (!items) 81 LOG_VERBOSE(LOG_TAG, "%s: no items found in string\n", __func__); 82 83 osi_free(str); 84 return map; 85 } 86 87 void hash_map_utils_dump_string_keys_string_values(hash_map_t *map) { 88 if (!map) { 89 LOG_VERBOSE( LOG_TAG, "%s: the given map is NULL\n", __func__); 90 return; 91 } 92 hash_map_foreach(map, dump_entry, NULL); 93 } 94 95 static bool string_equals(const void *key_a, const void *key_b) { 96 return !strcmp(key_a, key_b); 97 } 98 99 static bool dump_entry(hash_map_entry_t *entry, UNUSED_ATTR void *context) { 100 hash_map_entry_t *hash_map_entry = (hash_map_entry_t *)entry; 101 LOG_INFO(LOG_TAG, "key: '%s' value: '%s'\n", (char *)hash_map_entry->key, 102 (char *)hash_map_entry->data); 103 return true; 104 } 105