Fix naming mismatch of allocator functions.
[asterisk/asterisk.git] / main / datastore.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2007 - 2008, Digium, Inc.
5  *
6  * See http://www.asterisk.org for more information about
7  * the Asterisk project. Please do not directly contact
8  * any of the maintainers of this project for assistance;
9  * the project provides a web site, mailing lists and IRC
10  * channels for your use.
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License Version 2. See the LICENSE file
14  * at the top of the source tree.
15  */
16
17 /*! \file
18  *
19  * \brief Asterisk datastore objects
20  */
21
22 /*** MODULEINFO
23         <support_level>core</support_level>
24  ***/
25
26 #include "asterisk.h"
27
28 ASTERISK_REGISTER_FILE()
29
30 #include "asterisk/_private.h"
31
32 #include "asterisk/datastore.h"
33 #include "asterisk/utils.h"
34 #include "asterisk/astobj2.h"
35 #include "asterisk/uuid.h"
36
37 /*! \brief Number of buckets for datastore container */
38 #define DATASTORE_BUCKETS 53
39
40 struct ast_datastore *__ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid,
41                                             const char *file, int line, const char *function)
42 {
43         struct ast_datastore *datastore = NULL;
44
45         /* Make sure we at least have type so we can identify this */
46         if (!info) {
47                 return NULL;
48         }
49
50         if (!(datastore = __ast_calloc(1, sizeof(*datastore), file, line, function))) {
51                 return NULL;
52         }
53
54         datastore->info = info;
55
56         if (!ast_strlen_zero(uid) && !(datastore->uid = ast_strdup(uid))) {
57                 ast_free(datastore);
58                 datastore = NULL;
59         }
60
61         return datastore;
62 }
63
64 int ast_datastore_free(struct ast_datastore *datastore)
65 {
66         int res = 0;
67
68         /* Using the destroy function (if present) destroy the data */
69         if (datastore->info->destroy != NULL && datastore->data != NULL) {
70                 datastore->info->destroy(datastore->data);
71                 datastore->data = NULL;
72         }
73
74         /* Free allocated UID memory */
75         if (datastore->uid != NULL) {
76                 ast_free((void *) datastore->uid);
77                 datastore->uid = NULL;
78         }
79
80         /* Finally free memory used by ourselves */
81         ast_free(datastore);
82
83         return res;
84 }
85
86 AO2_STRING_FIELD_HASH_FN(ast_datastore, uid);
87 AO2_STRING_FIELD_CMP_FN(ast_datastore, uid);
88
89 struct ao2_container *ast_datastores_alloc(void)
90 {
91         return ao2_container_alloc(DATASTORE_BUCKETS, ast_datastore_hash_fn, ast_datastore_cmp_fn);
92 }
93
94 int ast_datastores_add(struct ao2_container *datastores, struct ast_datastore *datastore)
95 {
96         ast_assert(datastore != NULL);
97         ast_assert(datastore->info != NULL);
98         ast_assert(!ast_strlen_zero(datastore->uid));
99
100         if (!ao2_link(datastores, datastore)) {
101                 return -1;
102         }
103
104         return 0;
105 }
106
107 void ast_datastores_remove(struct ao2_container *datastores, const char *name)
108 {
109         ao2_find(datastores, name, OBJ_SEARCH_KEY | OBJ_UNLINK | OBJ_NODATA);
110 }
111
112 struct ast_datastore *ast_datastores_find(struct ao2_container *datastores, const char *name)
113 {
114         return ao2_find(datastores, name, OBJ_SEARCH_KEY);
115 }
116
117 static void datastore_destroy(void *obj)
118 {
119         struct ast_datastore *datastore = obj;
120
121         /* Using the destroy function (if present) destroy the data */
122         if (datastore->info->destroy != NULL && datastore->data != NULL) {
123                 datastore->info->destroy(datastore->data);
124                 datastore->data = NULL;
125         }
126
127         ast_free((void *) datastore->uid);
128         datastore->uid = NULL;
129 }
130
131 struct ast_datastore *ast_datastores_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
132 {
133         struct ast_datastore *datastore;
134         char uuid_buf[AST_UUID_STR_LEN];
135         const char *uid_ptr = uid;
136
137         if (!info) {
138                 return NULL;
139         }
140
141         datastore = ao2_alloc(sizeof(*datastore), datastore_destroy);
142         if (!datastore) {
143                 return NULL;
144         }
145
146         datastore->info = info;
147         if (ast_strlen_zero(uid)) {
148                 /* They didn't provide an ID so we'll provide one ourself */
149                 uid_ptr = ast_uuid_generate_str(uuid_buf, sizeof(uuid_buf));
150         }
151
152         datastore->uid = ast_strdup(uid_ptr);
153         if (!datastore->uid) {
154                 ao2_ref(datastore, -1);
155                 return NULL;
156         }
157
158         return datastore;
159 }