str_parms.c revision a603e40f9efa0239ea18c9e98a0ae0f437c057f1
10fad7d023f0229f763a58dd479f78397322baa6dDima Zavin/*
20fad7d023f0229f763a58dd479f78397322baa6dDima Zavin * Copyright (C) 2011 The Android Open Source Project
30fad7d023f0229f763a58dd479f78397322baa6dDima Zavin *
40fad7d023f0229f763a58dd479f78397322baa6dDima Zavin * Licensed under the Apache License, Version 2.0 (the "License");
50fad7d023f0229f763a58dd479f78397322baa6dDima Zavin * you may not use this file except in compliance with the License.
60fad7d023f0229f763a58dd479f78397322baa6dDima Zavin * You may obtain a copy of the License at
70fad7d023f0229f763a58dd479f78397322baa6dDima Zavin *
80fad7d023f0229f763a58dd479f78397322baa6dDima Zavin *      http://www.apache.org/licenses/LICENSE-2.0
90fad7d023f0229f763a58dd479f78397322baa6dDima Zavin *
100fad7d023f0229f763a58dd479f78397322baa6dDima Zavin * Unless required by applicable law or agreed to in writing, software
110fad7d023f0229f763a58dd479f78397322baa6dDima Zavin * distributed under the License is distributed on an "AS IS" BASIS,
120fad7d023f0229f763a58dd479f78397322baa6dDima Zavin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130fad7d023f0229f763a58dd479f78397322baa6dDima Zavin * See the License for the specific language governing permissions and
140fad7d023f0229f763a58dd479f78397322baa6dDima Zavin * limitations under the License.
150fad7d023f0229f763a58dd479f78397322baa6dDima Zavin */
160fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
170fad7d023f0229f763a58dd479f78397322baa6dDima Zavin#define LOG_TAG "str_params"
180fad7d023f0229f763a58dd479f78397322baa6dDima Zavin//#define LOG_NDEBUG 0
190fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
200fad7d023f0229f763a58dd479f78397322baa6dDima Zavin#define _GNU_SOURCE 1
210fad7d023f0229f763a58dd479f78397322baa6dDima Zavin#include <errno.h>
220fad7d023f0229f763a58dd479f78397322baa6dDima Zavin#include <stdint.h>
230fad7d023f0229f763a58dd479f78397322baa6dDima Zavin#include <stdio.h>
240fad7d023f0229f763a58dd479f78397322baa6dDima Zavin#include <stdlib.h>
250fad7d023f0229f763a58dd479f78397322baa6dDima Zavin#include <string.h>
260fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
270fad7d023f0229f763a58dd479f78397322baa6dDima Zavin#include <cutils/hashmap.h>
280fad7d023f0229f763a58dd479f78397322baa6dDima Zavin#include <cutils/log.h>
290fad7d023f0229f763a58dd479f78397322baa6dDima Zavin#include <cutils/memory.h>
300fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
310fad7d023f0229f763a58dd479f78397322baa6dDima Zavin#include <cutils/str_parms.h>
320fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
330fad7d023f0229f763a58dd479f78397322baa6dDima Zavinstruct str_parms {
340fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    Hashmap *map;
350fad7d023f0229f763a58dd479f78397322baa6dDima Zavin};
360fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
370fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
380fad7d023f0229f763a58dd479f78397322baa6dDima Zavinstatic bool str_eq(void *key_a, void *key_b)
390fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
400fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return !strcmp((const char *)key_a, (const char *)key_b);
410fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
420fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
430fad7d023f0229f763a58dd479f78397322baa6dDima Zavin/* use djb hash unless we find it inadequate */
440fad7d023f0229f763a58dd479f78397322baa6dDima Zavinstatic int str_hash_fn(void *str)
450fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
460fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    uint32_t hash = 5381;
470fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    char *p;
480fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
490fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    for (p = str; p && *p; p++)
500fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        hash = ((hash << 5) + hash) + *p;
510fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return (int)hash;
520fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
530fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
540fad7d023f0229f763a58dd479f78397322baa6dDima Zavinstruct str_parms *str_parms_create(void)
550fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
560fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    struct str_parms *str_parms;
570fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
580fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    str_parms = calloc(1, sizeof(struct str_parms));
590fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    if (!str_parms)
600fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        return NULL;
610fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
620fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    str_parms->map = hashmapCreate(5, str_hash_fn, str_eq);
630fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    if (!str_parms->map)
640fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        goto err;
650fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
660fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return str_parms;
670fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
680fad7d023f0229f763a58dd479f78397322baa6dDima Zavinerr:
690fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    free(str_parms);
700fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return NULL;
710fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
720fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
730fad7d023f0229f763a58dd479f78397322baa6dDima Zavinstatic bool remove_pair(void *key, void *value, void *context)
740fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
750fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    struct str_parms *str_parms = context;
760fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
770fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    hashmapRemove(str_parms->map, key);
780fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    free(key);
790fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    free(value);
800fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return true;
810fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
820fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
830fad7d023f0229f763a58dd479f78397322baa6dDima Zavinvoid str_parms_destroy(struct str_parms *str_parms)
840fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
850fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    hashmapForEach(str_parms->map, remove_pair, str_parms);
860fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    hashmapFree(str_parms->map);
870fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    free(str_parms);
880fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
890fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
900fad7d023f0229f763a58dd479f78397322baa6dDima Zavinstruct str_parms *str_parms_create_str(const char *_string)
910fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
920fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    struct str_parms *str_parms;
930fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    char *str;
940fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    char *kvpair;
950fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    char *tmpstr;
960fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    int items = 0;
970fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
980fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    str_parms = str_parms_create();
990fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    if (!str_parms)
1000fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        goto err_create_str_parms;
1010fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1020fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    str = strdup(_string);
1030fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    if (!str)
1040fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        goto err_strdup;
1050fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
10669f4cd7f5add7a7c7f5915e5292aab7eb2a42e9fSteve Block    ALOGV("%s: source string == '%s'\n", __func__, _string);
1070fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1080fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    kvpair = strtok_r(str, ";", &tmpstr);
1090fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    while (kvpair && *kvpair) {
1100fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        char *eq = strchr(kvpair, '='); /* would love strchrnul */
1110fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        char *value;
1120fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        char *key;
1130fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        void *old_val;
1140fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1150fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        if (eq == kvpair)
1160fad7d023f0229f763a58dd479f78397322baa6dDima Zavin            goto next_pair;
1170fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1180fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        if (eq) {
1190fad7d023f0229f763a58dd479f78397322baa6dDima Zavin            key = strndup(kvpair, eq - kvpair);
1200fad7d023f0229f763a58dd479f78397322baa6dDima Zavin            if (*(++eq))
1210fad7d023f0229f763a58dd479f78397322baa6dDima Zavin                value = strdup(eq);
1220fad7d023f0229f763a58dd479f78397322baa6dDima Zavin            else
1230fad7d023f0229f763a58dd479f78397322baa6dDima Zavin                value = strdup("");
1240fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        } else {
1250fad7d023f0229f763a58dd479f78397322baa6dDima Zavin            key = strdup(kvpair);
1260fad7d023f0229f763a58dd479f78397322baa6dDima Zavin            value = strdup("");
1270fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        }
1280fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1290fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        /* if we replaced a value, free it */
1300fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        old_val = hashmapPut(str_parms->map, key, value);
1310fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        if (old_val)
1320fad7d023f0229f763a58dd479f78397322baa6dDima Zavin            free(old_val);
1330fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1340fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        items++;
1350fad7d023f0229f763a58dd479f78397322baa6dDima Zavinnext_pair:
1360fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        kvpair = strtok_r(NULL, ";", &tmpstr);
1370fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    }
1380fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1390fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    if (!items)
14069f4cd7f5add7a7c7f5915e5292aab7eb2a42e9fSteve Block        ALOGV("%s: no items found in string\n", __func__);
1410fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1420fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    free(str);
1430fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1440fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return str_parms;
1450fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1460fad7d023f0229f763a58dd479f78397322baa6dDima Zavinerr_strdup:
1470fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    str_parms_destroy(str_parms);
1480fad7d023f0229f763a58dd479f78397322baa6dDima Zavinerr_create_str_parms:
1490fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return NULL;
1500fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
1510fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1520fad7d023f0229f763a58dd479f78397322baa6dDima Zavinvoid str_parms_del(struct str_parms *str_parms, const char *key)
1530fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
1540fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    hashmapRemove(str_parms->map, (void *)key);
1550fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
1560fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1570fad7d023f0229f763a58dd479f78397322baa6dDima Zavinint str_parms_add_str(struct str_parms *str_parms, const char *key,
1580fad7d023f0229f763a58dd479f78397322baa6dDima Zavin                      const char *value)
1590fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
1600fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    void *old_val;
16170b93034f3ce06404e9b042c80759da25dac99d8Dima Zavin    void *tmp_key;
16270b93034f3ce06404e9b042c80759da25dac99d8Dima Zavin    void *tmp_val;
1630fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
16470b93034f3ce06404e9b042c80759da25dac99d8Dima Zavin    tmp_key = strdup(key);
16570b93034f3ce06404e9b042c80759da25dac99d8Dima Zavin    tmp_val = strdup(value);
16670b93034f3ce06404e9b042c80759da25dac99d8Dima Zavin    old_val = hashmapPut(str_parms->map, tmp_key, tmp_val);
1670fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1680fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    if (old_val) {
1690fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        free(old_val);
1700fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    } else if (errno == ENOMEM) {
17170b93034f3ce06404e9b042c80759da25dac99d8Dima Zavin        free(tmp_key);
17270b93034f3ce06404e9b042c80759da25dac99d8Dima Zavin        free(tmp_val);
1730fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        return -ENOMEM;
1740fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    }
1750fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return 0;
1760fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
1770fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1780fad7d023f0229f763a58dd479f78397322baa6dDima Zavinint str_parms_add_int(struct str_parms *str_parms, const char *key, int value)
1790fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
1800fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    char val_str[12];
1810fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    int ret;
1820fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1830fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    ret = snprintf(val_str, sizeof(val_str), "%d", value);
1840fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    if (ret < 0)
1850fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        return -EINVAL;
1860fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1870fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    ret = str_parms_add_str(str_parms, key, val_str);
1880fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return ret;
1890fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
1900fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1910fad7d023f0229f763a58dd479f78397322baa6dDima Zavinint str_parms_add_float(struct str_parms *str_parms, const char *key,
1920fad7d023f0229f763a58dd479f78397322baa6dDima Zavin                        float value)
1930fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
1940fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    char val_str[23];
1950fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    int ret;
1960fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
1970fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    ret = snprintf(val_str, sizeof(val_str), "%.10f", value);
1980fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    if (ret < 0)
1990fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        return -EINVAL;
2000fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2010fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    ret = str_parms_add_str(str_parms, key, val_str);
2020fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return ret;
2030fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
2040fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2050fad7d023f0229f763a58dd479f78397322baa6dDima Zavinint str_parms_get_str(struct str_parms *str_parms, const char *key, char *val,
2060fad7d023f0229f763a58dd479f78397322baa6dDima Zavin                      int len)
2070fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
2080fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    char *value;
2090fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2100fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    value = hashmapGet(str_parms->map, (void *)key);
2110fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    if (value)
2120fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        return strlcpy(val, value, len);
2130fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2140fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return -ENOENT;
2150fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
2160fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2170fad7d023f0229f763a58dd479f78397322baa6dDima Zavinint str_parms_get_int(struct str_parms *str_parms, const char *key, int *val)
2180fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
2190fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    char *value;
2200fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    char *end;
2210fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2220fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    value = hashmapGet(str_parms->map, (void *)key);
2230fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    if (!value)
2240fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        return -ENOENT;
2250fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2260fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    *val = (int)strtol(value, &end, 0);
2270fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    if (*value != '\0' && *end == '\0')
2280fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        return 0;
2290fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2300fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return -EINVAL;
2310fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
2320fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2330fad7d023f0229f763a58dd479f78397322baa6dDima Zavinint str_parms_get_float(struct str_parms *str_parms, const char *key,
2340fad7d023f0229f763a58dd479f78397322baa6dDima Zavin                        float *val)
2350fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
2360fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    float out;
2370fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    char *value;
2380fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    char *end;
2390fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2400fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    value = hashmapGet(str_parms->map, (void *)key);
2410fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    if (!value)
2420fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        return -ENOENT;
2430fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2440fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    out = strtof(value, &end);
2450fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    if (*value != '\0' && *end == '\0')
2460fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        return 0;
2470fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2480fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return -EINVAL;
2490fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
2500fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2510fad7d023f0229f763a58dd479f78397322baa6dDima Zavinstatic bool combine_strings(void *key, void *value, void *context)
2520fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
2530fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    char **old_str = context;
2540fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    char *new_str;
2550fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    int ret;
2560fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2570fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    ret = asprintf(&new_str, "%s%s%s=%s",
2580fad7d023f0229f763a58dd479f78397322baa6dDima Zavin                   *old_str ? *old_str : "",
2590fad7d023f0229f763a58dd479f78397322baa6dDima Zavin                   *old_str ? ";" : "",
2600fad7d023f0229f763a58dd479f78397322baa6dDima Zavin                   (char *)key,
2610fad7d023f0229f763a58dd479f78397322baa6dDima Zavin                   (char *)value);
2620fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    if (*old_str)
2630fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        free(*old_str);
2640fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2650fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    if (ret >= 0) {
2660fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        *old_str = new_str;
2670fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        return true;
2680fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    }
2690fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2700fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    *old_str = NULL;
2710fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return false;
2720fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
2730fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2740fad7d023f0229f763a58dd479f78397322baa6dDima Zavinchar *str_parms_to_str(struct str_parms *str_parms)
2750fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
2760fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    char *str = NULL;
2770fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2780fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    if (hashmapSize(str_parms->map) > 0)
2790fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        hashmapForEach(str_parms->map, combine_strings, &str);
2800fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    else
2810fad7d023f0229f763a58dd479f78397322baa6dDima Zavin        str = strdup("");
2820fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return str;
2830fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
2840fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2850fad7d023f0229f763a58dd479f78397322baa6dDima Zavinstatic bool dump_entry(void *key, void *value, void *context)
2860fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
287fe71a61e5b0cb666675900d206251a7c18ed944bSteve Block    ALOGI("key: '%s' value: '%s'\n", (char *)key, (char *)value);
2880fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return true;
2890fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
2900fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2910fad7d023f0229f763a58dd479f78397322baa6dDima Zavinvoid str_parms_dump(struct str_parms *str_parms)
2920fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
2930fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    hashmapForEach(str_parms->map, dump_entry, str_parms);
2940fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
2950fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
2960fad7d023f0229f763a58dd479f78397322baa6dDima Zavin#ifdef TEST_STR_PARMS
2970fad7d023f0229f763a58dd479f78397322baa6dDima Zavinstatic void test_str_parms_str(const char *str)
2980fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
2990fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    struct str_parms *str_parms;
3000fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    char *out_str;
3010fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    int ret;
3020fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
3030fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    str_parms = str_parms_create_str(str);
304a603e40f9efa0239ea18c9e98a0ae0f437c057f1Dima Zavin    str_parms_add_str(str_parms, "dude", "woah");
3050fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    str_parms_dump(str_parms);
3060fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    out_str = str_parms_to_str(str_parms);
3070fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    str_parms_destroy(str_parms);
308fe71a61e5b0cb666675900d206251a7c18ed944bSteve Block    ALOGI("%s: '%s' stringified is '%s'", __func__, str, out_str);
3090fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    free(out_str);
3100fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
3110fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
3120fad7d023f0229f763a58dd479f78397322baa6dDima Zavinint main(void)
3130fad7d023f0229f763a58dd479f78397322baa6dDima Zavin{
3140fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    struct str_parms *str_parms;
3150fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
3160fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    test_str_parms_str("");
3170fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    test_str_parms_str(";");
3180fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    test_str_parms_str("=");
3190fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    test_str_parms_str("=;");
3200fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    test_str_parms_str("=bar");
3210fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    test_str_parms_str("=bar;");
3220fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    test_str_parms_str("foo=");
3230fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    test_str_parms_str("foo=;");
3240fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    test_str_parms_str("foo=bar");
3250fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    test_str_parms_str("foo=bar;");
3260fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    test_str_parms_str("foo=bar;baz");
3270fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    test_str_parms_str("foo=bar;baz=");
3280fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    test_str_parms_str("foo=bar;baz=bat");
3290fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    test_str_parms_str("foo=bar;baz=bat;");
3300fad7d023f0229f763a58dd479f78397322baa6dDima Zavin
3310fad7d023f0229f763a58dd479f78397322baa6dDima Zavin    return 0;
3320fad7d023f0229f763a58dd479f78397322baa6dDima Zavin}
3330fad7d023f0229f763a58dd479f78397322baa6dDima Zavin#endif
334