diff options
author | Guido Günther <agx@sigxcpu.org> | 2014-02-05 08:38:30 +0100 |
---|---|---|
committer | Guido Günther <agx@sigxcpu.org> | 2014-02-05 08:38:30 +0100 |
commit | 13ed135b9ae78c692dc359976eb8b54d0a3629b8 (patch) | |
tree | ae2ea713ad51d73980cf83db1411d6589dac5e8b /libwmc/src/result.c | |
parent | 14d771b90f5a7d3887e5e900d1fb4737477ad305 (diff) |
Imported Upstream version 0.7.991upstream/0.7.991
Diffstat (limited to 'libwmc/src/result.c')
-rw-r--r-- | libwmc/src/result.c | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/libwmc/src/result.c b/libwmc/src/result.c new file mode 100644 index 0000000..b66f864 --- /dev/null +++ b/libwmc/src/result.c @@ -0,0 +1,298 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2010 Red Hat, Inc. + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include <stdlib.h> + +#include "result.h" +#include "result-private.h" +#include "errors.h" + +/*********************************************************/ + +typedef struct Val Val; + +typedef enum { + VAL_TYPE_NONE = 0, + VAL_TYPE_STRING = 1, + VAL_TYPE_U8 = 2, + VAL_TYPE_U32 = 3 +} ValType; + +struct Val { + char *key; + ValType type; + union { + char *s; + u_int8_t u8; + u_int32_t u32; + } u; + Val *next; +}; + +static void +val_free (Val *v) +{ + if (v->type == VAL_TYPE_STRING) { + if (v->u.s) + free (v->u.s); + } + free (v->key); + memset (v, 0, sizeof (*v)); + free (v); +} + +static Val * +val_new_string (const char *key, const char *value) +{ + Val *v; + + wmc_return_val_if_fail (key != NULL, NULL); + wmc_return_val_if_fail (key[0] != '\0', NULL); + wmc_return_val_if_fail (value != NULL, NULL); + + v = calloc (sizeof (Val), 1); + if (v == NULL) + return NULL; + + v->key = strdup (key); + v->type = VAL_TYPE_STRING; + v->u.s = strdup (value); + return v; +} + +static Val * +val_new_u8 (const char *key, u_int8_t u) +{ + Val *v; + + wmc_return_val_if_fail (key != NULL, NULL); + wmc_return_val_if_fail (key[0] != '\0', NULL); + + v = calloc (sizeof (Val), 1); + if (v == NULL) + return NULL; + + v->key = strdup (key); + v->type = VAL_TYPE_U8; + v->u.u8 = u; + return v; +} + +static Val * +val_new_u32 (const char *key, u_int32_t u) +{ + Val *v; + + wmc_return_val_if_fail (key != NULL, NULL); + wmc_return_val_if_fail (key[0] != '\0', NULL); + + v = calloc (sizeof (Val), 1); + if (v == NULL) + return NULL; + + v->key = strdup (key); + v->type = VAL_TYPE_U32; + v->u.u32 = u; + return v; +} + +/*********************************************************/ + +struct WmcResult { + u_int32_t refcount; + Val *first; +}; + +WmcResult * +wmc_result_new (void) +{ + WmcResult *r; + + r = calloc (sizeof (WmcResult), 1); + if (r) + r->refcount = 1; + return r; +} + +WmcResult * +wmc_result_ref (WmcResult *r) +{ + wmc_return_val_if_fail (r != NULL, NULL); + wmc_return_val_if_fail (r->refcount > 0, NULL); + + r->refcount++; + return r; +} + +static void +wmc_result_free (WmcResult *r) +{ + Val *v, *n; + + v = r->first; + while (v) { + n = v->next; + val_free (v); + v = n; + } + memset (r, 0, sizeof (*r)); + free (r); +} + +void +wmc_result_unref (WmcResult *r) +{ + wmc_return_if_fail (r != NULL); + wmc_return_if_fail (r->refcount > 0); + + r->refcount--; + if (r->refcount == 0) + wmc_result_free (r); +} + +static Val * +find_val (WmcResult *r, const char *key, ValType expected_type) +{ + Val *v, *n; + + v = r->first; + while (v) { + n = v->next; + if (strcmp (v->key, key) == 0) { + /* Check type */ + wmc_return_val_if_fail (v->type == expected_type, NULL); + return v; + } + v = n; + } + return NULL; +} + +void +wmc_result_add_string (WmcResult *r, + const char *key, + const char *str) +{ + Val *v; + + wmc_return_if_fail (r != NULL); + wmc_return_if_fail (r->refcount > 0); + wmc_return_if_fail (key != NULL); + wmc_return_if_fail (str != NULL); + + v = val_new_string (key, str); + wmc_return_if_fail (v != NULL); + v->next = r->first; + r->first = v; +} + +int +wmc_result_get_string (WmcResult *r, + const char *key, + const char **out_val) +{ + Val *v; + + wmc_return_val_if_fail (r != NULL, -WMC_ERROR_INVALID_ARGUMENTS); + wmc_return_val_if_fail (r->refcount > 0, -WMC_ERROR_INVALID_ARGUMENTS); + wmc_return_val_if_fail (key != NULL, -WMC_ERROR_INVALID_ARGUMENTS); + wmc_return_val_if_fail (out_val != NULL, -WMC_ERROR_INVALID_ARGUMENTS); + wmc_return_val_if_fail (*out_val == NULL, -WMC_ERROR_INVALID_ARGUMENTS); + + v = find_val (r, key, VAL_TYPE_STRING); + if (v == NULL) + return -WMC_ERROR_VALUE_NOT_FOUND; + + *out_val = v->u.s; + return 0; +} + +void +wmc_result_add_u8 (WmcResult *r, + const char *key, + u_int8_t num) +{ + Val *v; + + wmc_return_if_fail (r != NULL); + wmc_return_if_fail (r->refcount > 0); + wmc_return_if_fail (key != NULL); + + v = val_new_u8 (key, num); + wmc_return_if_fail (v != NULL); + v->next = r->first; + r->first = v; +} + +int +wmc_result_get_u8 (WmcResult *r, + const char *key, + u_int8_t *out_val) +{ + Val *v; + + wmc_return_val_if_fail (r != NULL, -WMC_ERROR_INVALID_ARGUMENTS); + wmc_return_val_if_fail (r->refcount > 0, -WMC_ERROR_INVALID_ARGUMENTS); + wmc_return_val_if_fail (key != NULL, -WMC_ERROR_INVALID_ARGUMENTS); + wmc_return_val_if_fail (out_val != NULL, -WMC_ERROR_INVALID_ARGUMENTS); + + v = find_val (r, key, VAL_TYPE_U8); + if (v == NULL) + return -WMC_ERROR_VALUE_NOT_FOUND; + + *out_val = v->u.u8; + return 0; +} + +void +wmc_result_add_u32 (WmcResult *r, + const char *key, + u_int32_t num) +{ + Val *v; + + wmc_return_if_fail (r != NULL); + wmc_return_if_fail (r->refcount > 0); + wmc_return_if_fail (key != NULL); + + v = val_new_u32 (key, num); + wmc_return_if_fail (v != NULL); + v->next = r->first; + r->first = v; +} + +int +wmc_result_get_u32 (WmcResult *r, + const char *key, + u_int32_t *out_val) +{ + Val *v; + + wmc_return_val_if_fail (r != NULL, -WMC_ERROR_INVALID_ARGUMENTS); + wmc_return_val_if_fail (r->refcount > 0, -WMC_ERROR_INVALID_ARGUMENTS); + wmc_return_val_if_fail (key != NULL, -WMC_ERROR_INVALID_ARGUMENTS); + wmc_return_val_if_fail (out_val != NULL, -WMC_ERROR_INVALID_ARGUMENTS); + + v = find_val (r, key, VAL_TYPE_U32); + if (v == NULL) + return -WMC_ERROR_VALUE_NOT_FOUND; + + *out_val = v->u.u32; + return 0; +} + |