2021-09-16 21:30:43 +02:00
|
|
|
//=-------------------------------------------------------------------------=//
|
|
|
|
// XML parsing module //
|
|
|
|
// //
|
|
|
|
// Copyright © 2021 The Gem-graph Project //
|
|
|
|
// //
|
|
|
|
// This file is part of gem-graph. //
|
|
|
|
// //
|
|
|
|
// This program is free software: you can redistribute it and/or modify //
|
|
|
|
// it under the terms of the GNU Affero General Public License as //
|
|
|
|
// published by the Free Software Foundation, either version 3 of the //
|
|
|
|
// License, or (at your option) any later version. //
|
|
|
|
// //
|
|
|
|
// 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 Affero General Public License for more details. //
|
|
|
|
// //
|
|
|
|
// You should have received a copy of the GNU Affero General Public License //
|
|
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>. //
|
|
|
|
//=-------------------------------------------------------------------------=//
|
|
|
|
|
|
|
|
#include "../include/base.h"
|
2021-09-17 16:14:04 +02:00
|
|
|
#include "../include/model.h"
|
2021-09-16 21:30:43 +02:00
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
2021-09-17 16:14:04 +02:00
|
|
|
#include <libxml/parser.h>
|
2021-09-16 21:30:43 +02:00
|
|
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
|
2021-09-17 16:14:04 +02:00
|
|
|
#define NO_DESTINATION NULL
|
2021-09-16 21:30:43 +02:00
|
|
|
|
2021-09-17 16:14:04 +02:00
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
struct ModelParserTableXML_t;
|
|
|
|
|
|
|
|
struct ParserTableXML_t
|
|
|
|
{
|
2021-09-16 21:30:43 +02:00
|
|
|
const xmlChar *tag;
|
2021-09-17 16:14:04 +02:00
|
|
|
int (*parse) (xmlDoc*,
|
|
|
|
struct ModelParserTableXML_t*,
|
|
|
|
int currentParser,
|
|
|
|
xmlNode*);
|
|
|
|
void *destination;
|
2021-09-16 21:30:43 +02:00
|
|
|
} typedef ParserTableXML_t;
|
|
|
|
|
2021-09-17 16:14:04 +02:00
|
|
|
struct ModelParserTableXML_t
|
2021-09-16 21:30:43 +02:00
|
|
|
{
|
2021-09-17 16:14:04 +02:00
|
|
|
size_t len;
|
|
|
|
ParserTableXML_t *table;
|
|
|
|
} typedef ModelParserTableXML_t;
|
2021-09-16 21:30:43 +02:00
|
|
|
|
2021-09-17 16:14:04 +02:00
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
int parseParentFieldXML(xmlDocPtr,
|
|
|
|
ModelParserTableXML_t*,
|
|
|
|
int,
|
|
|
|
xmlNodePtr);
|
|
|
|
|
|
|
|
int parseTextField(xmlDocPtr,
|
|
|
|
ModelParserTableXML_t*,
|
|
|
|
int,
|
|
|
|
xmlNodePtr);
|
2021-09-16 21:30:43 +02:00
|
|
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
|
2021-09-17 16:14:04 +02:00
|
|
|
// -------------------------------------------------------------------------- //
|
|
|
|
// Parsing NOTHING //
|
|
|
|
// -------------------------------------------------------------------------- //
|
|
|
|
int parseStubFieldXML (xmlDocPtr doc,
|
|
|
|
ModelParserTableXML_t *ModelTable,
|
|
|
|
int currentParser,
|
|
|
|
xmlNodePtr currentNode)
|
2021-09-16 21:30:43 +02:00
|
|
|
{
|
2021-09-17 16:14:04 +02:00
|
|
|
xmlChar *content;
|
|
|
|
content = xmlNodeListGetString(doc, currentNode->xmlChildrenNode, 1);
|
|
|
|
|
|
|
|
printLog("%s (stub): %s\n",
|
|
|
|
ModelTable->table[currentParser].tag,
|
|
|
|
content);
|
|
|
|
|
|
|
|
xmlFree(content);
|
2021-09-16 21:30:43 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-09-17 16:14:04 +02:00
|
|
|
// -------------------------------------------------------------------------- //
|
|
|
|
// Parsing a text field //
|
|
|
|
// -------------------------------------------------------------------------- //
|
|
|
|
int parseTextFieldXML (xmlDocPtr doc,
|
|
|
|
ModelParserTableXML_t *ModelTable,
|
|
|
|
int currentParser,
|
|
|
|
xmlNodePtr currentNode)
|
2021-09-16 21:30:43 +02:00
|
|
|
{
|
2021-09-17 16:14:04 +02:00
|
|
|
xmlChar *content;
|
|
|
|
content = xmlNodeListGetString(doc, currentNode->xmlChildrenNode, 1);
|
|
|
|
|
|
|
|
printLog("%s: %s\n", ModelTable->table[currentParser].tag,
|
|
|
|
content);
|
|
|
|
|
|
|
|
strncpy((char *)ModelTable->table[currentParser].destination,
|
|
|
|
(char *)content, MODEL_STRING_SIZE);
|
|
|
|
xmlFree(content);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-09-17 16:22:51 +02:00
|
|
|
// -------------------------------------------------------------------------- //
|
|
|
|
// Parsing a field that contains children fields //
|
|
|
|
// -------------------------------------------------------------------------- //
|
2021-09-17 16:14:04 +02:00
|
|
|
int parseParentFieldXML (xmlDocPtr doc,
|
|
|
|
ModelParserTableXML_t *ModelTable,
|
|
|
|
int currentParser,
|
|
|
|
xmlNodePtr currentNode)
|
|
|
|
{
|
|
|
|
currentNode = currentNode->xmlChildrenNode;
|
|
|
|
while (currentNode != NULL) {
|
|
|
|
for (int i = 0; i < ModelTable->len; i++) {
|
2021-09-16 21:30:43 +02:00
|
|
|
if ((!xmlStrcmp(currentNode->name,
|
2021-09-17 16:14:04 +02:00
|
|
|
ModelTable->table[i].tag))) {
|
|
|
|
ModelTable->table[i].parse(doc,
|
|
|
|
ModelTable,
|
|
|
|
i,
|
|
|
|
currentNode);
|
2021-09-16 21:30:43 +02:00
|
|
|
}
|
|
|
|
}
|
2021-09-17 16:14:04 +02:00
|
|
|
currentNode = currentNode->next;
|
|
|
|
}
|
2021-09-16 21:30:43 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-09-17 16:22:51 +02:00
|
|
|
// -------------------------------------------------------------------------- //
|
|
|
|
// Parsing a model file //
|
|
|
|
// -------------------------------------------------------------------------- //
|
2021-09-16 21:30:43 +02:00
|
|
|
int ParseModelXML(Model_t *model)
|
|
|
|
{
|
2021-09-17 16:14:04 +02:00
|
|
|
ParserTableXML_t table[] =
|
|
|
|
{
|
2021-09-17 16:22:51 +02:00
|
|
|
{(const xmlChar *)"identity", parseParentFieldXML, model},
|
|
|
|
{(const xmlChar *)"name", parseTextFieldXML, model->name},
|
|
|
|
{(const xmlChar *)"owner", parseTextFieldXML, model->owner},
|
|
|
|
{(const xmlChar *)"owner_id", parseStubFieldXML, model->owner_id},
|
|
|
|
{(const xmlChar *)"date", parseStubFieldXML, &model->date},
|
|
|
|
{(const xmlChar *)"version", parseTextFieldXML, model->version},
|
2021-09-17 16:14:04 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
ModelParserTableXML_t modelParserTable =
|
|
|
|
{
|
|
|
|
LEN(table),
|
|
|
|
&table[0]
|
|
|
|
};
|
|
|
|
|
2021-09-16 21:30:43 +02:00
|
|
|
printLog("Parsing model %s\n", model->name);
|
|
|
|
xmlDocPtr xmlDocument;
|
|
|
|
xmlNodePtr currentNode;
|
|
|
|
|
|
|
|
xmlDocument = xmlParseFile(model->filename);
|
|
|
|
|
|
|
|
if (xmlDocument == NULL) {
|
|
|
|
printLog("Can't parse model file at '%s'.\n", model->filename);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
currentNode = xmlDocGetRootElement(xmlDocument);
|
|
|
|
|
|
|
|
if (currentNode == NULL) {
|
|
|
|
printLog("Invalid model file at '%s', document empty !\n",
|
|
|
|
model->filename);
|
|
|
|
xmlFreeDoc(xmlDocument);
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xmlStrcmp(currentNode->name, (const xmlChar *) "gem-graph-model")) {
|
|
|
|
printLog("Invalid model file at '%s', "
|
|
|
|
"root node is not <gem-graph-model> !\n",
|
|
|
|
model->filename);
|
|
|
|
xmlFreeDoc(xmlDocument);
|
|
|
|
return -3;
|
|
|
|
}
|
|
|
|
|
|
|
|
currentNode = currentNode->xmlChildrenNode;
|
|
|
|
while (currentNode != NULL) {
|
2021-09-17 16:14:04 +02:00
|
|
|
for (int i = 0; i < modelParserTable.len; i++) {
|
2021-09-16 21:30:43 +02:00
|
|
|
if ((!xmlStrcmp(currentNode->name,
|
2021-09-17 16:14:04 +02:00
|
|
|
modelParserTable.table[i].tag))) {
|
|
|
|
modelParserTable.table[i].parse(xmlDocument,
|
|
|
|
&modelParserTable,
|
|
|
|
i,
|
|
|
|
currentNode);
|
2021-09-16 21:30:43 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
currentNode = currentNode->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
xmlFreeDoc(xmlDocument);
|
|
|
|
|
|
|
|
// Interpret what needs to be
|
|
|
|
//model->date = strtol(date, NULL, 0);
|
|
|
|
|
|
|
|
// validate when we're finished
|
|
|
|
// model->validated = true;
|
|
|
|
return 0;
|
|
|
|
}
|