• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/corennnnn


Commit MetaInfo

Revisão14c2823a631b444687b9d26b7baf4c864091c07b (tree)
Hora2011-06-19 03:56:48
AutorJean-Baptiste Queru <jbq@goog...>
CommiterAndroid Code Review

Mensagem de Log

Merge "add strutils"

Mudança Sumário

Diff

--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -46,7 +46,8 @@ commonSources := \
4646 properties.c \
4747 threads.c \
4848 sched_policy.c \
49- iosched_policy.c
49+ iosched_policy.c \
50+ str_parms.c
5051
5152 commonHostSources := \
5253 ashmem-host.c
--- /dev/null
+++ b/libcutils/str_parms.c
@@ -0,0 +1,329 @@
1+/*
2+ * Copyright (C) 2011 The Android Open Source Project
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+#define LOG_TAG "str_params"
18+//#define LOG_NDEBUG 0
19+
20+#define _GNU_SOURCE 1
21+#include <errno.h>
22+#include <stdint.h>
23+#include <stdio.h>
24+#include <stdlib.h>
25+#include <string.h>
26+
27+#include <cutils/hashmap.h>
28+#include <cutils/log.h>
29+#include <cutils/memory.h>
30+
31+#include <cutils/str_parms.h>
32+
33+struct str_parms {
34+ Hashmap *map;
35+};
36+
37+
38+static bool str_eq(void *key_a, void *key_b)
39+{
40+ return !strcmp((const char *)key_a, (const char *)key_b);
41+}
42+
43+/* use djb hash unless we find it inadequate */
44+static int str_hash_fn(void *str)
45+{
46+ uint32_t hash = 5381;
47+ char *p;
48+
49+ for (p = str; p && *p; p++)
50+ hash = ((hash << 5) + hash) + *p;
51+ return (int)hash;
52+}
53+
54+struct str_parms *str_parms_create(void)
55+{
56+ struct str_parms *str_parms;
57+
58+ str_parms = calloc(1, sizeof(struct str_parms));
59+ if (!str_parms)
60+ return NULL;
61+
62+ str_parms->map = hashmapCreate(5, str_hash_fn, str_eq);
63+ if (!str_parms->map)
64+ goto err;
65+
66+ return str_parms;
67+
68+err:
69+ free(str_parms);
70+ return NULL;
71+}
72+
73+static bool remove_pair(void *key, void *value, void *context)
74+{
75+ struct str_parms *str_parms = context;
76+
77+ hashmapRemove(str_parms->map, key);
78+ free(key);
79+ free(value);
80+ return true;
81+}
82+
83+void str_parms_destroy(struct str_parms *str_parms)
84+{
85+ hashmapForEach(str_parms->map, remove_pair, str_parms);
86+ hashmapFree(str_parms->map);
87+ free(str_parms);
88+}
89+
90+struct str_parms *str_parms_create_str(const char *_string)
91+{
92+ struct str_parms *str_parms;
93+ char *str;
94+ char *kvpair;
95+ char *tmpstr;
96+ int items = 0;
97+
98+ str_parms = str_parms_create();
99+ if (!str_parms)
100+ goto err_create_str_parms;
101+
102+ str = strdup(_string);
103+ if (!str)
104+ goto err_strdup;
105+
106+ LOGV("%s: source string == '%s'\n", __func__, _string);
107+
108+ kvpair = strtok_r(str, ";", &tmpstr);
109+ while (kvpair && *kvpair) {
110+ char *eq = strchr(kvpair, '='); /* would love strchrnul */
111+ char *value;
112+ char *key;
113+ void *old_val;
114+
115+ if (eq == kvpair)
116+ goto next_pair;
117+
118+ if (eq) {
119+ key = strndup(kvpair, eq - kvpair);
120+ if (*(++eq))
121+ value = strdup(eq);
122+ else
123+ value = strdup("");
124+ } else {
125+ key = strdup(kvpair);
126+ value = strdup("");
127+ }
128+
129+ /* if we replaced a value, free it */
130+ old_val = hashmapPut(str_parms->map, key, value);
131+ if (old_val)
132+ free(old_val);
133+
134+ items++;
135+next_pair:
136+ kvpair = strtok_r(NULL, ";", &tmpstr);
137+ }
138+
139+ if (!items)
140+ LOGV("%s: no items found in string\n", __func__);
141+
142+ free(str);
143+
144+ return str_parms;
145+
146+err_strdup:
147+ str_parms_destroy(str_parms);
148+err_create_str_parms:
149+ return NULL;
150+}
151+
152+void str_parms_del(struct str_parms *str_parms, const char *key)
153+{
154+ hashmapRemove(str_parms->map, (void *)key);
155+}
156+
157+int str_parms_add_str(struct str_parms *str_parms, const char *key,
158+ const char *value)
159+{
160+ void *old_val;
161+ char *tmp;
162+
163+ tmp = strdup(value);
164+ old_val = hashmapPut(str_parms->map, (void *)key, tmp);
165+
166+ if (old_val) {
167+ free(old_val);
168+ } else if (errno == ENOMEM) {
169+ free(tmp);
170+ return -ENOMEM;
171+ }
172+ return 0;
173+}
174+
175+int str_parms_add_int(struct str_parms *str_parms, const char *key, int value)
176+{
177+ char val_str[12];
178+ int ret;
179+
180+ ret = snprintf(val_str, sizeof(val_str), "%d", value);
181+ if (ret < 0)
182+ return -EINVAL;
183+
184+ ret = str_parms_add_str(str_parms, key, val_str);
185+ return ret;
186+}
187+
188+int str_parms_add_float(struct str_parms *str_parms, const char *key,
189+ float value)
190+{
191+ char val_str[23];
192+ int ret;
193+
194+ ret = snprintf(val_str, sizeof(val_str), "%.10f", value);
195+ if (ret < 0)
196+ return -EINVAL;
197+
198+ ret = str_parms_add_str(str_parms, key, val_str);
199+ return ret;
200+}
201+
202+int str_parms_get_str(struct str_parms *str_parms, const char *key, char *val,
203+ int len)
204+{
205+ char *value;
206+
207+ value = hashmapGet(str_parms->map, (void *)key);
208+ if (value)
209+ return strlcpy(val, value, len);
210+
211+ return -ENOENT;
212+}
213+
214+int str_parms_get_int(struct str_parms *str_parms, const char *key, int *val)
215+{
216+ char *value;
217+ char *end;
218+
219+ value = hashmapGet(str_parms->map, (void *)key);
220+ if (!value)
221+ return -ENOENT;
222+
223+ *val = (int)strtol(value, &end, 0);
224+ if (*value != '\0' && *end == '\0')
225+ return 0;
226+
227+ return -EINVAL;
228+}
229+
230+int str_parms_get_float(struct str_parms *str_parms, const char *key,
231+ float *val)
232+{
233+ float out;
234+ char *value;
235+ char *end;
236+
237+ value = hashmapGet(str_parms->map, (void *)key);
238+ if (!value)
239+ return -ENOENT;
240+
241+ out = strtof(value, &end);
242+ if (*value != '\0' && *end == '\0')
243+ return 0;
244+
245+ return -EINVAL;
246+}
247+
248+static bool combine_strings(void *key, void *value, void *context)
249+{
250+ char **old_str = context;
251+ char *new_str;
252+ int ret;
253+
254+ ret = asprintf(&new_str, "%s%s%s=%s",
255+ *old_str ? *old_str : "",
256+ *old_str ? ";" : "",
257+ (char *)key,
258+ (char *)value);
259+ if (*old_str)
260+ free(*old_str);
261+
262+ if (ret >= 0) {
263+ *old_str = new_str;
264+ return true;
265+ }
266+
267+ *old_str = NULL;
268+ return false;
269+}
270+
271+char *str_parms_to_str(struct str_parms *str_parms)
272+{
273+ char *str = NULL;
274+
275+ if (hashmapSize(str_parms->map) > 0)
276+ hashmapForEach(str_parms->map, combine_strings, &str);
277+ else
278+ str = strdup("");
279+ return str;
280+}
281+
282+static bool dump_entry(void *key, void *value, void *context)
283+{
284+ LOGI("key: '%s' value: '%s'\n", (char *)key, (char *)value);
285+ return true;
286+}
287+
288+void str_parms_dump(struct str_parms *str_parms)
289+{
290+ hashmapForEach(str_parms->map, dump_entry, str_parms);
291+}
292+
293+#ifdef TEST_STR_PARMS
294+static void test_str_parms_str(const char *str)
295+{
296+ struct str_parms *str_parms;
297+ char *out_str;
298+ int ret;
299+
300+ str_parms = str_parms_create_str(str);
301+ str_parms_dump(str_parms);
302+ out_str = str_parms_to_str(str_parms);
303+ str_parms_destroy(str_parms);
304+ LOGI("%s: '%s' stringified is '%s'", __func__, str, out_str);
305+ free(out_str);
306+}
307+
308+int main(void)
309+{
310+ struct str_parms *str_parms;
311+
312+ test_str_parms_str("");
313+ test_str_parms_str(";");
314+ test_str_parms_str("=");
315+ test_str_parms_str("=;");
316+ test_str_parms_str("=bar");
317+ test_str_parms_str("=bar;");
318+ test_str_parms_str("foo=");
319+ test_str_parms_str("foo=;");
320+ test_str_parms_str("foo=bar");
321+ test_str_parms_str("foo=bar;");
322+ test_str_parms_str("foo=bar;baz");
323+ test_str_parms_str("foo=bar;baz=");
324+ test_str_parms_str("foo=bar;baz=bat");
325+ test_str_parms_str("foo=bar;baz=bat;");
326+
327+ return 0;
328+}
329+#endif