Remove ASTERISK_REGISTER_FILE.
[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 #include "asterisk/_private.h"
29
30 #include "asterisk/datastore.h"
31 #include "asterisk/utils.h"
32 #include "asterisk/astobj2.h"
33 #include "asterisk/uuid.h"
34
35 /*! \brief Number of buckets for datastore container */
36 #define DATASTORE_BUCKETS 53
37
38 struct ast_datastore *__ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid,
39                                             const char *file, int line, const char *function)
40 {
41         struct ast_datastore *datastore = NULL;
42
43         /* Make sure we at least have type so we can identify this */
44         if (!info) {
45                 return NULL;
46         }
47
48         if (!(datastore = __ast_calloc(1, sizeof(*datastore), file, line, function))) {
49                 return NULL;
50         }
51
52         datastore->info = info;
53
54         if (!ast_strlen_zero(uid) && !(datastore->uid = ast_strdup(uid))) {
55                 ast_free(datastore);
56                 datastore = NULL;
57         }
58
59         return datastore;
60 }
61
62 int ast_datastore_free(struct ast_datastore *datastore)
63 {
64         int res = 0;
65
66         /* Using the destroy function (if present) destroy the data */
67         if (datastore->info->destroy != NULL && datastore->data != NULL) {
68                 datastore->info->destroy(datastore->data);
69                 datastore->data = NULL;
70         }
71
72         /* Free allocated UID memory */
73         if (datastore->uid != NULL) {
74                 ast_free((void *) datastore->uid);
75                 datastore->uid = NULL;
76         }
77
78         /* Finally free memory used by ourselves */
79         ast_free(datastore);
80
81         return res;
82 }
83
84 AO2_STRING_FIELD_HASH_FN(ast_datastore, uid);
85 AO2_STRING_FIELD_CMP_FN(ast_datastore, uid);
86
87 struct ao2_container *ast_datastores_alloc(void)
88 {
89         return ao2_container_alloc(DATASTORE_BUCKETS, ast_datastore_hash_fn, ast_datastore_cmp_fn);
90 }
91
92 int ast_datastores_add(struct ao2_container *datastores, struct ast_datastore *datastore)
93 {
94         ast_assert(datastore != NULL);
95         ast_assert(datastore->info != NULL);
96         ast_assert(!ast_strlen_zero(datastore->uid));
97
98         if (!ao2_link(datastores, datastore)) {
99                 return -1;
100         }
101
102         return 0;
103 }
104
105 void ast_datastores_remove(struct ao2_container *datastores, const char *name)
106 {
107         ao2_find(datastores, name, OBJ_SEARCH_KEY | OBJ_UNLINK | OBJ_NODATA);
108 }
109
110 struct ast_datastore *ast_datastores_find(struct ao2_container *datastores, const char *name)
111 {
112         return ao2_find(datastores, name, OBJ_SEARCH_KEY);
113 }
114
115 static void datastore_destroy(void *obj)
116 {
117         struct ast_datastore *datastore = obj;
118
119         /* Using the destroy function (if present) destroy the data */
120         if (datastore->info->destroy != NULL && datastore->data != NULL) {
121                 datastore->info->destroy(datastore->data);
122                 datastore->data = NULL;
123         }
124
125         ast_free((void *) datastore->uid);
126         datastore->uid = NULL;
127 }
128
129 struct ast_datastore *ast_datastores_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
130 {
131         struct ast_datastore *datastore;
132         char uuid_buf[AST_UUID_STR_LEN];
133         const char *uid_ptr = uid;
134
135         if (!info) {
136                 return NULL;
137         }
138
139         datastore = ao2_alloc(sizeof(*datastore), datastore_destroy);
140         if (!datastore) {
141                 return NULL;
142         }
143
144         datastore->info = info;
145         if (ast_strlen_zero(uid)) {
146                 /* They didn't provide an ID so we'll provide one ourself */
147                 uid_ptr = ast_uuid_generate_str(uuid_buf, sizeof(uuid_buf));
148         }
149
150         datastore->uid = ast_strdup(uid_ptr);
151         if (!datastore->uid) {
152                 ao2_ref(datastore, -1);
153                 return NULL;
154         }
155
156         return datastore;
157 }