Parsee/src/XML/Elements.c
LDA ffc0679493 [MOD/WIP] Kill off the stanza sending function
The stanza sender is dead. All hail the Stanza Builder.
2024-08-13 20:24:32 +02:00

204 lines
3.7 KiB
C

#include <XML.h>
#include <Cytoplasm/Memory.h>
#include <Cytoplasm/Str.h>
#include <Cytoplasm/Log.h>
#include <string.h>
XMLElement *
XMLCreateTag(char *name)
{
XMLElement *elem;
if (!name)
{
return NULL;
}
elem = Malloc(sizeof(*elem));
elem->type = XML_ELEMENT_TAG;
elem->name = StrDuplicate(name);
elem->attrs = HashMapCreate();
elem->children = ArrayCreate();
elem->data = NULL;
return elem;
}
XMLElement *
XMLCreateText(char *data)
{
XMLElement *elem;
if (!data)
{
return NULL;
}
elem = Malloc(sizeof(*elem));
elem->type = XML_ELEMENT_DATA;
elem->name = NULL;
elem->attrs = NULL;
elem->children = NULL;
elem->data = StrDuplicate(data);
return elem;
}
void
XMLAddAttr(XMLElement *element, char *key, char *val)
{
if (!element || !key || !val)
{
return;
}
if (element->type != XML_ELEMENT_TAG || !element->attrs)
{
return;
}
Free(HashMapSet(element->attrs, key, StrDuplicate(val)));
}
void
XMLAddChild(XMLElement *element, XMLElement *child)
{
if (!element || !child)
{
return;
}
if (element->type != XML_ELEMENT_TAG)
{
return;
}
ArrayAdd(element->children, child);
}
void
XMLFreeElement(XMLElement *element)
{
if (!element)
{
return;
}
if (element->name)
{
Free(element->name);
}
if (element->data)
{
Free(element->data);
}
if (element->attrs)
{
char *key, *val;
while (HashMapIterate(element->attrs, &key, (void **) &val))
{
Free(val);
}
HashMapFree(element->attrs);
}
if (element->children)
{
size_t i;
for (i = 0; i < ArraySize(element->children); i++)
{
XMLFreeElement(ArrayGet(element->children, i));
}
ArrayFree(element->children);
}
Free(element);
}
XMLElement *
XMLookForUnique(XMLElement *parent, char *tag)
{
size_t i;
if (!parent || !tag)
{
return NULL;
}
for (i = 0; i < ArraySize(parent->children); i++)
{
XMLElement *child = ArrayGet(parent->children, i);
if (StrEquals(child->name, tag))
{
return child;
}
}
return NULL;
}
XMLElement *
XMLookForTKV(XMLElement *parent, char *tag, char *k, char *v)
{
size_t i;
if (!parent || !k || !v)
{
return NULL;
}
for (i = 0; i < ArraySize(parent->children); i++)
{
XMLElement *child = ArrayGet(parent->children, i);
HashMap *attrs = child->attrs;
char *value = HashMapGet(attrs, k);
if (StrEquals(child->name, tag) || !tag)
{
if (StrEquals(value, v))
{
return child;
}
}
}
return NULL;
}
XMLElement *
XMLCopy(XMLElement *original)
{
XMLElement *ret = NULL;
if (!original)
{
return NULL;
}
ret = Malloc(sizeof(*ret));
ret->type = original->type;
ret->name = StrDuplicate(original->name);
ret->data = StrDuplicate(original->data);
{
size_t i;
ret->children = ArrayCreate();
for (i = 0; i < ArraySize(original->children); i++)
{
XMLElement *child = ArrayGet(original->children, i);
ArrayAdd(
ret->children,
XMLCopy(child)
);
}
}
if (original->attrs)
{
char *name, *value;
ret->attrs = HashMapCreate();
while (HashMapIterate(original->attrs, &name, (void **) &value))
{
HashMapSet(ret->attrs, name, StrDuplicate(value));
}
}
return ret;
}