diff options
Diffstat (limited to 'libcutils/properties.c')
-rw-r--r-- | libcutils/properties.c | 84 |
1 files changed, 82 insertions, 2 deletions
diff --git a/libcutils/properties.c b/libcutils/properties.c index 28d8b2f..bfbd1b8 100644 --- a/libcutils/properties.c +++ b/libcutils/properties.c @@ -15,17 +15,94 @@ */ #define LOG_TAG "properties" +// #define LOG_NDEBUG 0 #include <stdlib.h> #include <string.h> +#include <ctype.h> #include <unistd.h> #include <cutils/sockets.h> #include <errno.h> #include <assert.h> #include <cutils/properties.h> +#include <stdbool.h> +#include <inttypes.h> #include "loghack.h" +int8_t property_get_bool(const char *key, int8_t default_value) { + if (!key) { + return default_value; + } + + int8_t result = default_value; + char buf[PROPERTY_VALUE_MAX] = {'\0',}; + + int len = property_get(key, buf, ""); + if (len == 1) { + char ch = buf[0]; + if (ch == '0' || ch == 'n') { + result = false; + } else if (ch == '1' || ch == 'y') { + result = true; + } + } else if (len > 1) { + if (!strcmp(buf, "no") || !strcmp(buf, "false") || !strcmp(buf, "off")) { + result = false; + } else if (!strcmp(buf, "yes") || !strcmp(buf, "true") || !strcmp(buf, "on")) { + result = true; + } + } + + return result; +} + +// Convert string property to int (default if fails); return default value if out of bounds +static intmax_t property_get_imax(const char *key, intmax_t lower_bound, intmax_t upper_bound, + intmax_t default_value) { + if (!key) { + return default_value; + } + + intmax_t result = default_value; + char buf[PROPERTY_VALUE_MAX] = {'\0',}; + char *end = NULL; + + int len = property_get(key, buf, ""); + if (len > 0) { + int tmp = errno; + errno = 0; + + // Infer base automatically + result = strtoimax(buf, &end, /*base*/0); + if ((result == INTMAX_MIN || result == INTMAX_MAX) && errno == ERANGE) { + // Over or underflow + result = default_value; + ALOGV("%s(%s,%lld) - overflow", __FUNCTION__, key, default_value); + } else if (result < lower_bound || result > upper_bound) { + // Out of range of requested bounds + result = default_value; + ALOGV("%s(%s,%lld) - out of range", __FUNCTION__, key, default_value); + } else if (end == buf) { + // Numeric conversion failed + result = default_value; + ALOGV("%s(%s,%lld) - numeric conversion failed", __FUNCTION__, key, default_value); + } + + errno = tmp; + } + + return result; +} + +int64_t property_get_int64(const char *key, int64_t default_value) { + return (int64_t)property_get_imax(key, INT64_MIN, INT64_MAX, default_value); +} + +int32_t property_get_int32(const char *key, int32_t default_value) { + return (int32_t)property_get_imax(key, INT32_MIN, INT32_MAX, default_value); +} + #ifdef HAVE_LIBC_SYSTEM_PROPERTIES #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ @@ -44,10 +121,13 @@ int property_get(const char *key, char *value, const char *default_value) if(len > 0) { return len; } - if(default_value) { len = strlen(default_value); - memcpy(value, default_value, len + 1); + if (len >= PROPERTY_VALUE_MAX) { + len = PROPERTY_VALUE_MAX - 1; + } + memcpy(value, default_value, len); + value[len] = '\0'; } return len; } |