diff options
Diffstat (limited to 'src/manager/lib')
-rw-r--r-- | src/manager/lib/dict.c | 154 | ||||
-rw-r--r-- | src/manager/lib/dict.h | 73 | ||||
-rw-r--r-- | src/manager/lib/enumerator.h | 5 | ||||
-rw-r--r-- | src/manager/lib/request.c | 84 | ||||
-rw-r--r-- | src/manager/lib/template.c | 2 | ||||
-rw-r--r-- | src/manager/lib/xml.c | 169 | ||||
-rw-r--r-- | src/manager/lib/xml.h | 63 |
7 files changed, 480 insertions, 70 deletions
diff --git a/src/manager/lib/dict.c b/src/manager/lib/dict.c new file mode 100644 index 000000000..a5fdd52d5 --- /dev/null +++ b/src/manager/lib/dict.c @@ -0,0 +1,154 @@ +/** + * @file dict.c + * + * @brief Implementation of dict_t. + * + */ + +/* + * Copyright (C) 2007 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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 General Public License + * for more details. + */ + +#include "dict.h" + +#include <utils/linked_list.h> + + +typedef struct private_dict_t private_dict_t; + +/** + * private data of dict + */ +struct private_dict_t { + + /** + * public functions + */ + dict_t public; + + /** + * baaah, we really should have a hashtable for this + */ + linked_list_t *list; + + /** + * key comparator function + */ + bool(*key_comparator)(void*,void*); + + /** + * destructor function for key + */ + void(*key_destructor)(void*); + + /** + * destructor function for value + */ + void(*value_destructor)(void*); +}; + +/** + * key value pair to store entries + */ +typedef struct { + void *key; + void *value; +} key_value_t; + +/** + * Implementation of dict_t.get. + */ +static void* get(private_dict_t *this, void *key) +{ + key_value_t *kv; + iterator_t *iterator; + void *value = NULL; + + iterator = this->list->create_iterator(this->list, TRUE); + while (iterator->iterate(iterator, (void**)&kv)) + { + if (this->key_comparator(kv->key, key)) + { + value = kv->value; + break; + } + } + iterator->destroy(iterator); + return value; +} +/** + * Implementation of dict_t.set. + */ +static void set(private_dict_t *this, void *key, void *value) +{ + /* we don't overwrite, just prepend */ + key_value_t *kv = malloc_thing(key_value_t); + kv->key = key; + kv->value = value; + this->list->insert_first(this->list, kv); +} + + +/** + * comparator for strings + */ +bool dict_streq(void *a, void *b) +{ + return streq(a, b); +} + +/** + * Implementation of dict_t.destroy + */ +static void destroy(private_dict_t *this) +{ + key_value_t *kv; + + while (this->list->remove_last(this->list, (void**)&kv) == SUCCESS) + { + if (this->key_destructor) + { + this->key_destructor(kv->key); + } + if (this->value_destructor) + { + this->value_destructor(kv->value); + } + free(kv); + } + this->list->destroy(this->list); + free(this); +} + +/* + * see header file + */ +dict_t *dict_create(bool(*key_comparator)(void*,void*), + void(*key_destructor)(void*), + void(*value_destructor)(void*)) +{ + private_dict_t *this = malloc_thing(private_dict_t); + + this->public.set = (void(*)(dict_t*, void *key, void *value))set; + this->public.get = (void*(*)(dict_t*, void *key))get; + this->public.destroy = (void(*)(dict_t*))destroy; + + this->list = linked_list_create(); + this->key_comparator = key_comparator; + this->key_destructor = key_destructor; + this->value_destructor = value_destructor; + + return &this->public; +} + diff --git a/src/manager/lib/dict.h b/src/manager/lib/dict.h new file mode 100644 index 000000000..9a9e9036b --- /dev/null +++ b/src/manager/lib/dict.h @@ -0,0 +1,73 @@ +/** + * @file dict.h + * + * @brief Interface of dict_t. + * + */ + +/* + * Copyright (C) 2007 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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 General Public License + * for more details. + */ + +#ifndef DICT_H_ +#define DICT_H_ + +#include <library.h> + +typedef struct dict_t dict_t; + +/** + * @brief Dictionary type, key value stuff. + */ +struct dict_t { + + /** + * @brief Set a value in the dict. + * + * @param key key to set + * @param value value, NULL to unset key + * @return + */ + void (*set)(dict_t *this, void *key, void *value); + + /** + * @brief Get a value form the dict. + * + * @param key key to get value of + * @return assigned value, NULL if not found + */ + void* (*get)(dict_t *this, void *key); + + /** + * @brief Destroy a dict instance. + */ + void (*destroy)(dict_t *this); +}; + +/** + * @brief Key comparator function for strings + */ +bool dict_streq(void *a, void *b); + +/** + * @brief Create a dict instance. + * + * @param free_key TRUE to free() keys on destruction + * @param + */ +dict_t *dict_create(bool(*key_comparator)(void*,void*), + void(*key_destructor)(void*), + void(*value_destructor)(void*)); + +#endif /* DICT_H_ */ diff --git a/src/manager/lib/enumerator.h b/src/manager/lib/enumerator.h index de272f9c9..7321e2192 100644 --- a/src/manager/lib/enumerator.h +++ b/src/manager/lib/enumerator.h @@ -35,10 +35,11 @@ struct enumerator_t { /** * @brief Enumerate collection. * - * @param ... variable argument list of pointers, NULL terminated + * @param item first enumerated item + * @param ... additional items enumerated, depending in implementation * @return TRUE if pointers returned */ - bool (*enumerate)(enumerator_t *this, ...); + bool (*enumerate)(enumerator_t *this, void *item, ...); /** * @brief Destroy a enumerator instance. diff --git a/src/manager/lib/request.c b/src/manager/lib/request.c index 2e12d3643..704b25203 100644 --- a/src/manager/lib/request.c +++ b/src/manager/lib/request.c @@ -26,22 +26,7 @@ #include <stdlib.h> -#include <utils/linked_list.h> - -typedef struct { - char *name; - char *value; -} name_value_t; - -/** - * destroy a name value pair - */ -static void name_value_destroy(name_value_t *this) -{ - free(this->name); - free(this->value); - free(this); -} +#include <dict.h> typedef struct private_request_t private_request_t; @@ -61,14 +46,14 @@ struct private_request_t { FCGX_Request *req; /** - * list of cookies (name_value_t) + * list of cookies */ - linked_list_t *cookies; + dict_t *cookies; /** - * list of post data (name_value_t) + * list of post data */ - linked_list_t *posts; + dict_t *posts; }; /** @@ -76,21 +61,7 @@ struct private_request_t { */ static char* get_cookie(private_request_t *this, char *name) { - char *value = NULL; - name_value_t *cookie; - iterator_t *iterator; - - iterator = this->cookies->create_iterator(this->cookies, TRUE); - while (iterator->iterate(iterator, (void**)&cookie)) - { - if (streq(cookie->name, name)) - { - value = cookie->value; - break; - } - } - iterator->destroy(iterator); - return value; + return this->cookies->get(this->cookies, name); } /** @@ -107,21 +78,7 @@ static char* get_path(private_request_t *this) */ static char* get_post_data(private_request_t *this, char *name) { - char *value = NULL; - name_value_t *data; - iterator_t *iterator; - - iterator = this->posts->create_iterator(this->posts, TRUE); - while (iterator->iterate(iterator, (void**)&data)) - { - if (streq(data->name, name)) - { - value = data->value; - break; - } - } - iterator->destroy(iterator); - return value; + return this->posts->get(this->posts, name); } /** @@ -185,7 +142,6 @@ static char *unescape(char **pos, char delimiter) static void parse_post(private_request_t *this) { char buf[4096], *pos, *name, *value; - name_value_t *data; int len; if (!streq(FCGX_GetParam("REQUEST_METHOD", this->req->envp), "POST") || @@ -211,10 +167,7 @@ static void parse_post(private_request_t *this) value = unescape(&pos, '&'); if (value) { - data = malloc_thing(name_value_t); - data->name = name; - data->value = value; - this->posts->insert_last(this->posts, data); + this->posts->set(this->posts, name, value); continue; } else @@ -232,7 +185,7 @@ static void parse_post(private_request_t *this) static void parse_cookies(private_request_t *this) { char *str, *pos; - name_value_t *cookie; + char *name, *value; str = FCGX_GetParam("HTTP_COOKIE", this->req->envp); while (str) @@ -247,23 +200,22 @@ static void parse_cookies(private_request_t *this) { break; } - cookie = malloc_thing(name_value_t); - cookie->name = strndup(str, pos - str); - cookie->value = NULL; + name = strndup(str, pos - str); + value = NULL; str = pos + 1; if (str) { pos = strchr(str, ';'); if (pos) { - cookie->value = strndup(str, pos - str); + value = strndup(str, pos - str); } else { - cookie->value = strdup(str); + value = strdup(str); } } - this->cookies->insert_last(this->cookies, cookie); + this->cookies->set(this->cookies, name, value); if (pos == NULL) { break; @@ -277,8 +229,8 @@ static void parse_cookies(private_request_t *this) */ static void destroy(private_request_t *this) { - this->cookies->destroy_function(this->cookies, (void*)name_value_destroy); - this->posts->destroy_function(this->posts, (void*)name_value_destroy); + this->cookies->destroy(this->cookies); + this->posts->destroy(this->posts); free(this); } @@ -295,8 +247,8 @@ request_t *request_create(FCGX_Request *request) this->public.destroy = (void(*)(request_t*))destroy; this->req = request; - this->cookies = linked_list_create(); - this->posts = linked_list_create(); + this->cookies = dict_create(dict_streq, free, free); + this->posts = dict_create(dict_streq, free, free); parse_cookies(this); parse_post(this); diff --git a/src/manager/lib/template.c b/src/manager/lib/template.c index f168f9a56..3ae7c87a3 100644 --- a/src/manager/lib/template.c +++ b/src/manager/lib/template.c @@ -66,8 +66,6 @@ static void render(private_template_t *this, response_t *response) NEOERR* err; CSPARSE *parse; - hdf_remove_tree(this->hdf, ""); - err = cs_init(&parse, this->hdf); if (!err) { diff --git a/src/manager/lib/xml.c b/src/manager/lib/xml.c new file mode 100644 index 000000000..008235b69 --- /dev/null +++ b/src/manager/lib/xml.c @@ -0,0 +1,169 @@ +/** + * @file xml.c + * + * @brief Implementation of xml_t. + * + */ + +/* + * Copyright (C) 2007 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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 General Public License + * for more details. + */ + +#include "xml.h" + +#include <libxml/parser.h> +#include <libxml/tree.h> + + +typedef struct private_xml_t private_xml_t; + +/** + * private data of xml + */ +struct private_xml_t { + + /** + * public functions + */ + xml_t public; + + /** + * root node of this xml (part) + */ + xmlNode *node; + + /** + * document, only for root xml_t + */ + xmlDoc *doc; + + /** + * Root xml_t* + */ + private_xml_t *root; + + /** + * number of enumerator instances + */ + int enums; +}; + +/** + * child element enumerator + */ +typedef struct { + /** enumerator interface */ + enumerator_t e; + /** current child context (returned to enumerate() caller) */ + private_xml_t child; + /** currently processing node */ + xmlNode *node; +} child_enum_t; + +/** + * Implementation of xml_t.children().enumerate(). + */ +static bool child_enumerate(child_enum_t *e, private_xml_t **child, + char **name, char **value) +{ + while (e->node && e->node->type != XML_ELEMENT_NODE) + { + e->node = e->node->next; + } + if (e->node) + { + xmlNode *text; + + text = e->node->children; + *value = NULL; + + while (text && text->type != XML_TEXT_NODE) + { + text = text->next; + } + if (text) + { + *value = text->content; + } + *name = (char*)e->node->name; + *child = &e->child; + e->child.node = e->node->children; + e->node = e->node->next; + return TRUE; + } + return FALSE; +} + +/** + * Implementation of xml_t.get_attribute. + */ +static char* get_attribute(private_xml_t *this, char *name) +{ + return NULL; +} + +/** + * destroy enumerator, and complete tree if this was the last enumerator + */ +static void child_destroy(child_enum_t *this) +{ + if (--this->child.root->enums == 0) + { + xmlFreeDoc(this->child.root->doc); + free(this->child.root); + } + free(this); +} + +/** + * Implementation of xml_t.children. + */ +static enumerator_t* children(private_xml_t *this) +{ + child_enum_t *ce = malloc_thing(child_enum_t); + ce->e.enumerate = (void*)child_enumerate; + ce->e.destroy = (void*)child_destroy; + ce->node = this->node; + ce->child.public.children = (void*)children; + ce->child.public.get_attribute = (void*)get_attribute; + ce->child.node = NULL; + ce->child.doc = this->doc; + ce->child.root = this->root; + this->root->enums++; + return &ce->e; +} + +/* + * see header file + */ +xml_t *xml_create(char *xml) +{ + private_xml_t *this = malloc_thing(private_xml_t); + + this->public.get_attribute = (char*(*)(xml_t*,char*))get_attribute; + this->public.children = (enumerator_t*(*)(xml_t*))children; + + this->doc = xmlReadMemory(xml, strlen(xml), NULL, NULL, 0); + if (this->doc == NULL) + { + free(this); + return NULL; + } + this->node = xmlDocGetRootElement(this->doc); + this->root = this; + this->enums = 0; + + return &this->public; +} + diff --git a/src/manager/lib/xml.h b/src/manager/lib/xml.h new file mode 100644 index 000000000..b73ddf074 --- /dev/null +++ b/src/manager/lib/xml.h @@ -0,0 +1,63 @@ +/** + * @file xml.h + * + * @brief Interface of xml_t. + * + */ + +/* + * Copyright (C) 2007 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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 General Public License + * for more details. + */ + +#ifndef XML_H_ +#define XML_H_ + +#include <enumerator.h> + +typedef struct xml_t xml_t; + +/** + * @brief Simple enumerator based XML parser. + * + * An xml_t is a single node of the XML tree, but also serves as root node + * and therefore the document. + * This object has no destructor, the tree gets destroyed when all enumerator + * instances get destroyed. + */ +struct xml_t { + + /** + * @brief Create an enumerator over all children. + * + * Enumerated values must not be manipulated or freed. + * + * @return enumerator over (xml_t* child, char *name, char *value) + */ + enumerator_t* (*children)(xml_t *this); + + /** + * @brief Get an attribute value by its name. + * + * @param name name of the attribute + * @return attribute value, NULL if not found + */ + char *(*get_attribute)(xml_t *this, char *name); +}; + +/** + * @brief Create a xml instance. + */ +xml_t *xml_create(char *xml); + +#endif /* XML_H_ */ |