From bad939f9d6f4b335aff3c52806b05f5d0eb5a6bb Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Thu, 4 Apr 2024 23:01:00 +0200 Subject: [PATCH] src/model.c: integrating within actual parsing --- src/model.c | 81 ++++++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/src/model.c b/src/model.c index 08d5ec5..3fecbc5 100644 --- a/src/model.c +++ b/src/model.c @@ -38,27 +38,25 @@ struct model_t *knownModels = NULL; -static xmlHashTablePtr hashTable == NULL; - /* -------------------------------------------------------------------------- */ /** * Recursively populates a hash table with XML nodes, using the node paths as keys. * + * @param self The self structure containing hash table containing + * nodes indexed by their paths to populate * @param node The current node being processed. - * @param hashTable The hash table to populate. * @param currentPath The path to the current node. */ -void model_populate_hashtable (xmlNode *node, - char *currentPath) +void model_populate_hashTable (struct model_t *self, xmlNode *node, char *currentPath) { if (node == NULL) return; - assert(hashTable == NULL); + assert(self->hashTable == NULL); // Skip text nodes and others that are not element nodes if (node->type != XML_ELEMENT_NODE) { - model_populate_hashtable (node->next, hashTable, currentPath); + model_populate_hashTable (node->next, self->hashTable, currentPath); return; } @@ -71,43 +69,46 @@ void model_populate_hashtable (xmlNode *node, } // Add current node to hash table with its path as the key - xmlHashAddEntry (hashTable, (const xmlChar *)newPath, node); + xmlHashAddEntry (self->hashTable, (const xmlChar *)newPath, node); // Recurse into child nodes with the updated path - model_populate_hashtable (node->children, hashTable, newPath); + model_populate_hashTable (self, node->children, newPath); // Continue with the next sibling - model_populate_hashtable (node->next, hashTable, currentPath); + model_populate_hashTable (self, node->next, currentPath); } /* * Finds a node by a path of tags. * - * @param node The starting node for the search. + * @param self The self structure containing hash table containing + * nodes indexed by their paths. * @param path The path to the tag, with '/' as the delimiter. * @return The content of the tag at the end of the path, or NULL if not found. */ -char* model_find_node_by_path (xmlNode *node, const char *path) +xmlNodePtr model_get_node (struct model_t *self, const char *path) { - assert(hashTable != NULL); + assert(self->hashTable != NULL); - return (xmlNodePtr)xmlHashLookup(hashTable, (const xmlChar *)path); + return (xmlNodePtr)xmlHashLookup (self->hashTable, (const xmlChar *)path); } /** * Modifies the content of an XML node identified by its path in the hash table. * - * @param hashTable The hash table containing the XML nodes. + * @param self The self structure containing hash table containing + * nodes indexed by their paths. * @param path The path to the node to modify. * @param newContent The new content to set for the node. * @return 1 if the node was found and modified, 0 otherwise. */ -int model_modify_node (const char *path, - const char *newContent) +int model_modify_node (struct model_t *self, + const char *path, + const char *newContent) { - assert(hashTable != NULL); + assert(self->hashTable != NULL); - xmlNodePtr node = model_find_node_by_path(hashTable, path); + xmlNodePtr node = model_get_node (self, path); if (node) { // Free the current content of the node, if any xmlNodeSetContent (node, (const xmlChar *)""); // Clear existing content @@ -121,17 +122,19 @@ int model_modify_node (const char *path, /** * Retrieves the value of an attribute for a node identified by its path. * - * @param hashTable The hash table containing nodes indexed by their paths. + * @param self The self structure containing hash table containing + * nodes indexed by their paths. * @param nodePath The path to the node. * @param attributeName The name of the attribute. * @return The value of the attribute, or NULL if not found. */ -char* model_get_attribute (const char* nodePath, +char *model_get_attribute (struct model_t *self, + const char* nodePath, const char* attributeName) { - assert(hashTable != NULL); + assert(self->hashTable != NULL); - xmlNodePtr node = (xmlNodePtr)xmlHashLookup (hashTable, (const xmlChar*)nodePath); + xmlNodePtr node = (xmlNodePtr)xmlHashLookup (self->hashTable, (const xmlChar*)nodePath); if (node) { return getAttributeValue (node, attributeName); } else { @@ -142,19 +145,21 @@ char* model_get_attribute (const char* nodePath, /** * Sets or updates the value of an attribute for a node identified by its path. * - * @param hashTable The hash table containing nodes indexed by their paths. + * @param self The self structure containing hash table containing + * nodes indexed by their paths. * @param nodePath The path to the node. * @param attributeName The name of the attribute to set. * @param attributeValue The value to set for the attribute. * @return 1 on success, 0 on failure. */ -int model_set_attribute (const char* nodePath, +int model_set_attribute (struct model_t *self, + const char* nodePath, const char* attributeName, const char* attributeValue) { - assert(hashTable != NULL); + assert(self->hashTable != NULL); - xmlNodePtr node = (xmlNodePtr)xmlHashLookup (hashTable, (const xmlChar*)nodePath); + xmlNodePtr node = (xmlNodePtr)xmlHashLookup (self->hashTable, (const xmlChar*)nodePath); if (node) { return setAttributeValue (node, attributeName, attributeValue); } else { @@ -163,12 +168,11 @@ int model_set_attribute (const char* nodePath, } /** - * Copies a node recursively to a new sibling node with a modified attribute and updates the hashtable. + * Copies a node recursively to a new sibling node with a modified attribute and updates the self->hashTable. * - * @param doc The document to which the nodes belong. * @param node The node to copy. - * @param hashTable The hashtable for tracking nodes by path. - * @param originalNodePath The path of the original node in the hashtable. + * @param self The self structure for tracking nodes by path. + * @param originalNodePath The path of the original node in the self->hashTable. * @param attributeName The name of the attribute to modify in the copied node. * @param newAttributeValue The new value for the specified attribute in the copied node. * @return The copied node with the modified attribute, or NULL on failure. @@ -179,7 +183,7 @@ xmlNodePtr model_copy_node(struct model_t *self, const char* attributeName, const char* newAttributeValue) { - assert(hashTable != NULL); + assert(self->hashTable != NULL); // Deep copy the node xmlNodePtr copiedNode = xmlDocCopyNode(node, self->doc, 1); @@ -197,8 +201,8 @@ xmlNodePtr model_copy_node(struct model_t *self, char newPath[1024]; snprintf (newPath, sizeof(newPath), "%s_copy", originalNodePath); - // Update the hashtable with the new node's path - xmlHashAddEntry (hashTable, (const xmlChar*)newPath, copiedNode); + // Update the self->hashTable with the new node's path + xmlHashAddEntry (self->hashTable, (const xmlChar*)newPath, copiedNode); return copiedNode; } @@ -224,7 +228,8 @@ xmlNodePtr model_copy_node(struct model_t *self, * additional information to the callback function. It is passed * directly through to the callback function as its second argument. */ -void model_iterate_node(xmlNodePtr node, +void model_iterate_node(struct model_t *self, + xmlNodePtr node, void (*processNode)(xmlNodePtr node, void* userData), void* userData) { for (xmlNodePtr curNode = node->children; curNode; curNode = curNode->next) { @@ -308,9 +313,9 @@ static bool model_init(struct model_t *self) return false; } - self->hashtable = xmlHashCreate(0); + model_populate_hashTable(self, node, "/"); - if (self->hashtable == NULL) { + if (self->hashTable == NULL) { printerr("Can't create model hash table !\n"); xmlFreeDoc(self->doc); return false; @@ -322,7 +327,7 @@ static bool model_init(struct model_t *self) static bool model_shutdown(struct model_t *self) { xmlFreeDoc(self->doc); - xmlHashFree(self->hashtable, NULL); + xmlHashFree(self->hashTable, NULL); // This is to debug memory for regression tests //xmlMemoryDump();