You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
5.7 KiB
C
227 lines
5.7 KiB
C
9 years ago
|
/*
|
||
|
* Yet another daemon library especially designed to be used
|
||
|
* with libsxmp based daemons.
|
||
|
*
|
||
|
* (c) Alexander Vdolainen 2016 <avdolainen@zoho.com>
|
||
|
*
|
||
|
* libsxmp is free software: you can redistribute it and/or modify it
|
||
|
* under the terms of the GNU Lesser General Public License as published
|
||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||
|
* (at your option) any later version.
|
||
|
*
|
||
|
* libsxmp 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 Lesser General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Lesser General Public License
|
||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include <ydaemon/dataobject.h>
|
||
|
|
||
|
static long __cmp_uint8(const void *a, const void *b)
|
||
|
{
|
||
|
return *(uint8_t *)a - *(uint8_t *)b;
|
||
|
}
|
||
|
|
||
|
static long __cmp_cstr(const void *a, const void *b)
|
||
|
{
|
||
|
return strcmp((const char *)a, (const char *)b);
|
||
|
}
|
||
|
|
||
|
dataobject_t *dotr_create(const char *name)
|
||
|
{
|
||
|
dataobject_t *dtr = malloc(sizeof(dataobject_t));
|
||
|
|
||
|
if(!dtr) return NULL;
|
||
|
else memset(dtr, 0, sizeof(dataobject_t));
|
||
|
|
||
|
/* init name, indexes etc ... */
|
||
|
strncpy(dtr->name, name, MAX_ITEM_NAME - sizeof(char));
|
||
|
|
||
|
list_init_head(&dtr->description);
|
||
|
usrtc_init(&dtr->id_index, USRTC_REDBLACK, MAX_ITEMS, __cmp_uint8);
|
||
|
usrtc_init(&dtr->name_index, USRTC_REDBLACK, MAX_ITEMS, __cmp_cstr);
|
||
|
|
||
|
return dtr;
|
||
|
}
|
||
|
|
||
|
int dotr_set_item(dataobject_t *dotr, uint8_t type, uint64_t len,
|
||
|
const char *name)
|
||
|
{
|
||
|
dataobject_item_t *ditem = malloc(sizeof(dataobject_item_t));
|
||
|
char *indexes = malloc(2*sizeof(item_idx_t));
|
||
|
item_idx_t *iidx, *nidx;
|
||
|
|
||
|
if(!ditem || !indexes) {
|
||
|
if(ditem) free(ditem);
|
||
|
if(indexes) free(indexes);
|
||
|
return ENOMEM;
|
||
|
} else {
|
||
|
iidx = (item_idx_t *)indexes;
|
||
|
nidx = (item_idx_t *)(indexes + sizeof(item_idx_t));
|
||
|
}
|
||
|
|
||
|
/* init items */
|
||
|
strncpy(ditem->name, name, MAX_ITEM_NAME - sizeof(char));
|
||
|
ditem->id = usrtc_count(&dotr->id_index);
|
||
|
ditem->type = type;
|
||
|
ditem->len = len;
|
||
|
list_init_node(&ditem->node);
|
||
|
|
||
|
iidx->key = &ditem->id;
|
||
|
iidx->dtr = ditem;
|
||
|
usrtc_node_init(&iidx->node, iidx);
|
||
|
|
||
|
nidx->key = ditem->name;
|
||
|
nidx->dtr = ditem;
|
||
|
usrtc_node_init(&nidx->node, nidx);
|
||
|
|
||
|
/* now insert all */
|
||
|
list_add2tail(&dotr->description, &ditem->node);
|
||
|
usrtc_insert(&dotr->id_index, &iidx->node, iidx->key);
|
||
|
usrtc_insert(&dotr->name_index, &nidx->node, nidx->key);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void dotr_destroy(dataobject_t *dotr)
|
||
|
{
|
||
|
usrtc_t *tree = &dotr->id_index;
|
||
|
usrtc_node_t *node = NULL;
|
||
|
item_idx_t *idx;
|
||
|
list_node_t *iter, *save;
|
||
|
dataobject_item_t *ditem;
|
||
|
|
||
|
if(usrtc_count(tree)) { /* we can free only index, since it was allocated as one memory chunk */
|
||
|
for(node = usrtc_first(tree); node != NULL; node = usrtc_first(tree)) {
|
||
|
idx = (item_idx_t *)usrtc_node_getdata(node);
|
||
|
usrtc_delete(tree, node);
|
||
|
free(idx);
|
||
|
}
|
||
|
|
||
|
/* free description */
|
||
|
list_for_each_safe(&dotr->description, iter, save) {
|
||
|
ditem = container_of(iter, dataobject_item_t, node);
|
||
|
list_del(&ditem->node);
|
||
|
free(ditem);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
free(dotr);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
uint8_t dotr_item_type(dataobject_t *obj, const char *name, uint64_t *len)
|
||
|
{
|
||
|
usrtc_node_t *node = usrtc_lookup(&obj->name_index, name);
|
||
|
item_idx_t *idxnode;
|
||
|
dataobject_item_t *dtr = NULL;
|
||
|
|
||
|
if(!node) { /* not found ! */
|
||
|
__failed:
|
||
|
*len = 0;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
idxnode = (item_idx_t *)usrtc_node_getdata(node);
|
||
|
if(!idxnode) goto __failed;
|
||
|
else dtr = idxnode->dtr;
|
||
|
|
||
|
if(!dtr) goto __failed;
|
||
|
|
||
|
*len = dtr->len;
|
||
|
return dtr->type;
|
||
|
}
|
||
|
|
||
|
char *dotr_item_nameptr(dataobject_t *obj, const char *name)
|
||
|
{
|
||
|
usrtc_node_t *node = usrtc_lookup(&obj->name_index, name);
|
||
|
item_idx_t *idxnode;
|
||
|
dataobject_item_t *dtr = NULL;
|
||
|
|
||
|
if(!node) /* not found ! */ return NULL;
|
||
|
|
||
|
idxnode = (item_idx_t *)usrtc_node_getdata(node);
|
||
|
if(!idxnode) return NULL;
|
||
|
else dtr = idxnode->dtr;
|
||
|
|
||
|
if(!dtr) return NULL;
|
||
|
|
||
|
return dtr->name;
|
||
|
}
|
||
|
|
||
|
int dotr_item_nameidx(dataobject_t *obj, const char *name)
|
||
|
{
|
||
|
usrtc_node_t *node = usrtc_lookup(&obj->name_index, name);
|
||
|
item_idx_t *idxnode;
|
||
|
dataobject_item_t *dtr = NULL;
|
||
|
|
||
|
if(!node) /* not found ! */ return -1;
|
||
|
|
||
|
idxnode = (item_idx_t *)usrtc_node_getdata(node);
|
||
|
if(!idxnode) return -1;
|
||
|
else dtr = idxnode->dtr;
|
||
|
|
||
|
if(!dtr) return -1;
|
||
|
|
||
|
return dtr->id;
|
||
|
}
|
||
|
|
||
|
static inline int __itemcmp(const dataobject_item_t *s1,
|
||
|
const dataobject_item_t *s2)
|
||
|
{
|
||
|
int r = 0;
|
||
|
if((r = strcmp(s1->name, s2->name))) return r;
|
||
|
if((r = s1->len - s2->len)) return r;
|
||
|
if((r = s1->type - s2->type)) return r;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int dtocmp(const dataobject_t *src, const dataobject_t *dst)
|
||
|
{
|
||
|
int r = 0;
|
||
|
list_node_t *iter, *siter;
|
||
|
dataobject_item_t *ditem, *sitem;
|
||
|
usrtc_node_t *unode;
|
||
|
item_idx_t *iidx;
|
||
|
|
||
|
/* check name */
|
||
|
if((r = strcmp(src->name, dst->name))) return r;
|
||
|
/* check amount of items */
|
||
|
if((r = usrtc_count((usrtc_t *)&src->id_index) - usrtc_count((usrtc_t *)&dst->id_index)))
|
||
|
return r;
|
||
|
|
||
|
/* check items itself */
|
||
|
list_for_each_safe(&src->description, iter, siter) {
|
||
|
ditem = container_of(iter, dataobject_item_t, node);
|
||
|
if(!(unode = usrtc_lookup((usrtc_t *)&dst->id_index, (const void *)&ditem->id)))
|
||
|
return 100*ditem->id;
|
||
|
|
||
|
iidx = (item_idx_t *)usrtc_node_getdata(unode);
|
||
|
sitem = iidx->dtr;
|
||
|
|
||
|
if((r = __itemcmp(ditem, sitem))) return r*ditem->id;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
size_t dtolen(const dataobject_t *src)
|
||
|
{
|
||
|
size_t len = 0;
|
||
|
list_node_t *iter, *siter;
|
||
|
dataobject_item_t *ditem;
|
||
|
|
||
|
list_for_each_safe(&src->description, iter, siter) {
|
||
|
ditem = container_of(iter, dataobject_item_t, node);
|
||
|
len += ditem->len;
|
||
|
}
|
||
|
|
||
|
return len;
|
||
|
}
|