blob: 9b0b1e016ed3ad58adbc5cfd4b23dcc383550f52
1 | /* |
2 | * Copyright (c) 2014 Amlogic, Inc. All rights reserved. |
3 | * |
4 | * This source code is subject to the terms and conditions defined in the |
5 | * file 'LICENSE' which is part of this source code package. |
6 | * |
7 | * Description: |
8 | */ |
9 | |
10 | |
11 | /* |
12 | libplayer's configs. |
13 | changed to HASH and list for fast get,set... |
14 | |
15 | */ |
16 | #include "include/amconfigutils.h" |
17 | #include <stdio.h> |
18 | #include <string.h> |
19 | #include <stdlib.h> |
20 | #include <fcntl.h> |
21 | #include <pthread.h> |
22 | static char *amconfigs[MAX_CONFIG] = {0}; |
23 | static int amconfig_inited = 0; |
24 | #define lock_t pthread_mutex_t |
25 | #define lp_lock_init(x,v) pthread_mutex_init(x,v) |
26 | #define lp_lock(x) pthread_mutex_lock(x) |
27 | #define lp_unlock(x) pthread_mutex_unlock(x) |
28 | #define lp_trylock(x) pthread_mutex_trylock(x) |
29 | #ifdef ANDROID |
30 | #include <cutils/properties.h> |
31 | |
32 | #include <sys/system_properties.h> |
33 | #endif |
34 | //#define CONFIG_DEBUG |
35 | #ifdef CONFIG_DEBUG |
36 | #define DBGPRINT printf |
37 | #else |
38 | #define DBGPRINT(...) |
39 | #endif |
40 | static lock_t config_lock; |
41 | static char *malloc_config_item() |
42 | { |
43 | return malloc(CONFIG_PATH_MAX + CONFIG_VALUE_MAX + 8); |
44 | } |
45 | static void free_config_item(char *item) |
46 | { |
47 | free(item); |
48 | } |
49 | |
50 | static int get_matched_index(const char * path) |
51 | { |
52 | int len = strlen(path); |
53 | char *ppath; |
54 | int i; |
55 | |
56 | if (len >= CONFIG_PATH_MAX) { |
57 | return -40; |
58 | } |
59 | for (i = 0; i < MAX_CONFIG; i++) { |
60 | ppath = amconfigs[i]; |
61 | if (ppath) { |
62 | ; //DBGPRINT("check match [%d]=%s ?= %s \n",i,path,amconfigs[i]); |
63 | } |
64 | if (ppath != NULL && strncmp(path, ppath, len) == 0) { |
65 | return i; |
66 | } |
67 | } |
68 | return -10; |
69 | } |
70 | static int get_unused_index(const char * path) |
71 | { |
72 | int i; |
73 | for (i = 0; i < MAX_CONFIG; i++) { |
74 | if (amconfigs[i] == NULL) { |
75 | return i; |
76 | } |
77 | } |
78 | return -20; |
79 | } |
80 | int am_config_init(void) |
81 | { |
82 | lp_lock_init(&config_lock, NULL); |
83 | lp_lock(&config_lock); |
84 | //can do more init here. |
85 | memset(amconfigs, 0, sizeof(amconfigs)); |
86 | amconfig_inited = 1; |
87 | lp_unlock(&config_lock); |
88 | return 0; |
89 | } |
90 | int am_getconfig(const char * path, char *val, const char * def) |
91 | { |
92 | int i, ret; |
93 | if (!amconfig_inited) { |
94 | am_config_init(); |
95 | } |
96 | val[0] = 0x0;//"\0"; |
97 | lp_lock(&config_lock); |
98 | i = get_matched_index(path); |
99 | if (i >= 0) { |
100 | strcpy(val, amconfigs[i] + CONFIG_VALUE_OFF); |
101 | } else if (def != NULL) { |
102 | strcpy(val, def); |
103 | } |
104 | lp_unlock(&config_lock); |
105 | #ifdef ANDROID |
106 | if (i < 0) { |
107 | /*get failed,get from android prop settings*/ |
108 | ret = property_get(path, val, def); |
109 | if (ret > 0) { |
110 | i = 1; |
111 | } |
112 | } |
113 | #endif |
114 | return strlen(val) ; |
115 | } |
116 | |
117 | |
118 | int am_setconfig(const char * path, const char *val) |
119 | { |
120 | int i; |
121 | char **pppath, *pconfig; |
122 | char value[CONFIG_VALUE_MAX]; |
123 | char *setval = NULL; |
124 | int ret = -1; |
125 | if (!amconfig_inited) { |
126 | am_config_init(); |
127 | } |
128 | if (strlen(path) > CONFIG_PATH_MAX) { |
129 | return -1; /*too long*/ |
130 | } |
131 | if (val != NULL) { |
132 | setval = strdup(val); |
133 | if (strlen(setval) >= CONFIG_VALUE_MAX) { |
134 | setval[CONFIG_VALUE_MAX] = '\0'; /*maybe val is too long,cut it*/ |
135 | } |
136 | } |
137 | lp_lock(&config_lock); |
138 | i = get_matched_index(path); |
139 | if (i >= 0) { |
140 | pppath = &amconfigs[i]; |
141 | if (!setval || strlen(setval) == 0) { //del value |
142 | free_config_item(*pppath); |
143 | amconfigs[i] = NULL; |
144 | ret = 1; /*just not setting*/ |
145 | goto end_out; |
146 | } |
147 | } else { |
148 | i = get_unused_index(path); |
149 | if (i < 0) { |
150 | ret = i; |
151 | goto end_out; |
152 | } |
153 | if (!setval || strlen(setval) == 0) { //value is nothing.exit now; |
154 | ret = 1; /*just not setting*/ |
155 | goto end_out; |
156 | } |
157 | DBGPRINT("used config index=%d,path=%s,val=%s\n", i, path, setval); |
158 | pppath = &amconfigs[i]; |
159 | *pppath = malloc_config_item(); |
160 | if (!*pppath) { |
161 | ret = -4; /*no MEM ?*/ |
162 | goto end_out; |
163 | } |
164 | } |
165 | pconfig = *pppath; |
166 | strcpy(pconfig, path); |
167 | strcpy(pconfig + CONFIG_VALUE_OFF, setval); |
168 | ret = 0; |
169 | end_out: |
170 | if (setval != NULL) { |
171 | free(setval); |
172 | } |
173 | lp_unlock(&config_lock); |
174 | return ret; |
175 | } |
176 | |
177 | int am_dumpallconfigs(void) |
178 | { |
179 | int i; |
180 | char *config; |
181 | lp_lock(&config_lock); |
182 | for (i = 0; i < MAX_CONFIG; i++) { |
183 | config = amconfigs[i]; |
184 | if (config != NULL) { |
185 | fprintf(stderr, "[%d] %s=%s\n", i, config, config + CONFIG_VALUE_OFF); |
186 | } |
187 | } |
188 | lp_unlock(&config_lock); |
189 | return 0; |
190 | } |
191 | int am_setconfig_float(const char * path, float value) |
192 | { |
193 | char buf[CONFIG_VALUE_MAX]; |
194 | int len; |
195 | len = snprintf(buf, CONFIG_VALUE_MAX - 1, "%f", value); |
196 | buf[len] = '\0'; |
197 | return am_setconfig(path, buf); |
198 | } |
199 | int am_getconfig_float(const char * path, float *value) |
200 | { |
201 | char buf[CONFIG_VALUE_MAX]; |
202 | int ret = -1; |
203 | |
204 | *value = -1.0; |
205 | ret = am_getconfig(path, buf, NULL); |
206 | if (ret > 0) { |
207 | ret = sscanf(buf, "%f", value); |
208 | } |
209 | return ret > 0 ? 0 : -2; |
210 | } |
211 | |
212 | int am_getconfig_int_def(const char * path, int def) |
213 | { |
214 | char buf[CONFIG_VALUE_MAX]; |
215 | int ret = -1; |
216 | int value = 0; |
217 | |
218 | ret = am_getconfig(path, buf, NULL); |
219 | if (ret > 0) { |
220 | ret = sscanf(buf, "%d", &value); |
221 | } |
222 | |
223 | if (ret <= 0) { |
224 | value = def; |
225 | } |
226 | return value; |
227 | } |
228 | |
229 | float am_getconfig_float_def(const char * path, float defvalue) |
230 | { |
231 | char buf[CONFIG_VALUE_MAX]; |
232 | int ret = -1; |
233 | float value = defvalue; |
234 | ret = am_getconfig(path, buf, NULL); |
235 | if (ret > 0) { |
236 | ret = sscanf(buf, "%f", &value); |
237 | } |
238 | if (ret <= 0) { |
239 | value = defvalue; |
240 | } |
241 | return value; |
242 | } |
243 | |
244 | int am_getconfig_bool(const char * path) |
245 | { |
246 | char buf[CONFIG_VALUE_MAX]; |
247 | int ret = -1; |
248 | |
249 | ret = am_getconfig(path, buf, NULL); |
250 | if (ret > 0) { |
251 | if (strcasecmp(buf, "true") == 0 || strcmp(buf, "1") == 0) { |
252 | return 1; |
253 | } |
254 | } |
255 | return 0; |
256 | } |
257 | |
258 | int am_getconfig_bool_def(const char * path, int def) |
259 | { |
260 | char buf[CONFIG_VALUE_MAX]; |
261 | int ret = -1; |
262 | |
263 | ret = am_getconfig(path, buf, NULL); |
264 | if (ret > 0) { |
265 | if (strcasecmp(buf, "true") == 0 || strcmp(buf, "1") == 0) { |
266 | return 1; |
267 | } else { |
268 | return 0; |
269 | } |
270 | } |
271 | return def; |
272 | } |
273 | |
274 |