#include "xml.h" #include "input_buffer.h" #include kit_xml_parse_result_t kit_xml_parse(kit_is_handle_t is, kit_allocator_t *alloc) { xml_parse_result_t res; memset(&res, 0, sizeof res); ib_t begin = ib_wrap(is, alloc); ib_t tag_before = ib_until(begin, SZ("<")); ib_t tag_open = ib_exact(tag_before, SZ("<")); ib_t tag_name = ib_until(tag_open, SZ(">")); ib_t tag_name_empty = ib_until(tag_open, SZ("/")); #define return_ \ ib_destroy(begin); \ ib_destroy(tag_before); \ ib_destroy(tag_open); \ ib_destroy(tag_name); \ ib_destroy(tag_name_empty); \ ib_destroy(tag_close); \ return if (tag_name_empty.offset < tag_name.offset) { ib_t tag_close = ib_exact(tag_name_empty, SZ("/>")); if (tag_close.status != KIT_OK) { res.status = KIT_ERROR_INTERNAL; return_ res; } // move res.xml.tag = tag_name_empty.data; memset(&tag_name_empty.data, 0, sizeof tag_name_empty.data); while (res.xml.tag.size > 0 && res.xml.tag.values[res.xml.tag.size - 1] == ' ') --res.xml.tag.size; DA_INIT(res.xml.text, 0, alloc); DA_INIT(res.xml.tail, 0, alloc); DA_INIT(res.xml.properties, 0, alloc); DA_INIT(res.xml.children, 0, alloc); res.status = KIT_OK; return_ res; } ib_t tag_close = ib_exact(tag_name, SZ(">")); ib_t tag_text = ib_until(tag_close, SZ("<")); ib_t tagend_open = ib_exact(tag_text, SZ("")); #undef return_ #define return_ \ ib_destroy(begin); \ ib_destroy(tag_before); \ ib_destroy(tag_open); \ ib_destroy(tag_name); \ ib_destroy(tag_name_empty); \ ib_destroy(tag_close); \ ib_destroy(tag_text); \ ib_destroy(tagend_open); \ ib_destroy(tagend_name); \ ib_destroy(tagend_close); \ return if (tagend_close.status != KIT_OK) { res.status = KIT_ERROR_INTERNAL; return_ res; } // move res.xml.tag = tag_name.data; memset(&tag_name.data, 0, sizeof tag_name.data); // move res.xml.text = tag_text.data; memset(&tag_text.data, 0, sizeof tag_text.data); DA_INIT(res.xml.tail, 0, alloc); DA_INIT(res.xml.properties, 0, alloc); DA_INIT(res.xml.children, 0, alloc); res.status = KIT_OK; return_ res; #undef return_ } kit_xml_print_result_t kit_xml_print(kit_xml_t *xml, kit_allocator_t *alloc) { assert(xml != NULL); kit_xml_print_result_t result; memset(&result, 0, sizeof result); result.status = KIT_ERROR_NOT_IMPLEMENTED; return result; } void kit_xml_destroy(kit_xml_t *xml) { assert(xml != NULL); if (xml == NULL) return; for (i64 i = 0; i < xml->properties.size; i++) { DA_DESTROY(xml->properties.values[i].name); DA_DESTROY(xml->properties.values[i].value); } for (i64 i = 0; i < xml->children.size; i++) kit_xml_destroy(xml->children.values + i); DA_DESTROY(xml->tag); DA_DESTROY(xml->text); DA_DESTROY(xml->tail); DA_DESTROY(xml->properties); DA_DESTROY(xml->children); }