|
26 | 26 | #include <libxml/parser.h>
|
27 | 27 | #include <stdexcept>
|
28 | 28 | #include <string>
|
| 29 | +#include <cstring> |
29 | 30 |
|
30 | 31 | #include "configuration_XML.hpp"
|
31 | 32 |
|
@@ -216,6 +217,41 @@ void readConfiguration(const std::string &filename, const std::string &rootname,
|
216 | 217 | xmlCleanupParser();
|
217 | 218 | }
|
218 | 219 |
|
| 220 | +/*! |
| 221 | + Read xml information from a plain xml-formatted std::string and fill the Config tree. |
| 222 | + The method is meant for general-purpose xml info absorbing. So no version checking |
| 223 | + is done in this context, nor rootname one. |
| 224 | + \param source string containing all the info formatted in XML style. |
| 225 | + \param rootConfig pointer to Config tree to store data parsed from the string. |
| 226 | +*/ |
| 227 | +void readBufferConfiguration(const std::string &source, Config *rootConfig) |
| 228 | +{ |
| 229 | + if (!rootConfig) { |
| 230 | + throw std::runtime_error("XML::readConfiguration Null Config tree structure passed"); |
| 231 | + } |
| 232 | + |
| 233 | + // Macro to check API for match with the DLL we are using |
| 234 | + LIBXML_TEST_VERSION |
| 235 | + |
| 236 | + // Read the XML string |
| 237 | + const char * cstr = source.c_str(); |
| 238 | + xmlDoc *doc = xmlParseMemory(cstr, strlen(cstr)); |
| 239 | + if (doc == nullptr) { |
| 240 | + throw std::runtime_error("Could not parse XML configuration string: \"" + source + "\""); |
| 241 | + } |
| 242 | + |
| 243 | + // Get the root element |
| 244 | + xmlNode * rootElement = xmlDocGetRootElement(doc); |
| 245 | + |
| 246 | + //read it as usual |
| 247 | + readNode(rootElement->children, rootConfig); |
| 248 | + |
| 249 | + // Clean-up |
| 250 | + xmlFreeDoc(doc); |
| 251 | + xmlCleanupParser(); |
| 252 | +} |
| 253 | + |
| 254 | + |
219 | 255 | /*!
|
220 | 256 | Write the configuration to the specified file.
|
221 | 257 |
|
@@ -283,6 +319,75 @@ void writeConfiguration(const std::string &filename, const std::string &rootname
|
283 | 319 | xmlFreeTextWriter(writer);
|
284 | 320 | }
|
285 | 321 |
|
| 322 | +/*! |
| 323 | + Write the Config Tree to a c++ string (xml-stringfication). All contents will |
| 324 | + be appended to the target source string. |
| 325 | + The method is meant for general-purpose xml info flushing. |
| 326 | + \param source string to write to |
| 327 | + \param rootConfig pointer to the Config tree to be stringfied. |
| 328 | + \param rootname (optional) name of the root section. Default is "root". |
| 329 | +*/ |
| 330 | +void writeBufferConfiguration(std::string &source, const Config *rootConfig, const std::string &rootname) |
| 331 | +{ |
| 332 | + if (!rootConfig) { |
| 333 | + throw std::runtime_error("XML::writeConfiguration Null Config tree structure passed"); |
| 334 | + } |
| 335 | + |
| 336 | + int status; |
| 337 | + |
| 338 | + xmlBufferPtr buffer = xmlBufferCreate(); |
| 339 | + if (buffer == NULL) { |
| 340 | + throw std::runtime_error("Error creating the writing buffer"); |
| 341 | + } |
| 342 | + // Create a new XmlWriter for DOM tree acting on memory buffer, with no compression |
| 343 | + xmlTextWriterPtr writer = xmlNewTextWriterMemory(buffer, 0); |
| 344 | + if (writer == NULL) { |
| 345 | + throw std::runtime_error("Error creating the xml buffer writer"); |
| 346 | + } |
| 347 | + //no indent. |
| 348 | + xmlTextWriterSetIndent(writer, 0); |
| 349 | + |
| 350 | + // Start the document |
| 351 | + status = xmlTextWriterStartDocument(writer, NULL, DEFAULT_ENCODING.c_str(), NULL); |
| 352 | + if (status < 0) { |
| 353 | + throw std::runtime_error("Error at xmlTextWriterStartDocument"); |
| 354 | + } |
| 355 | + |
| 356 | + // Start the root element |
| 357 | + xmlChar *elementName = encodeString(rootname, DEFAULT_ENCODING); |
| 358 | + status = xmlTextWriterStartElement(writer, BAD_CAST elementName); |
| 359 | + if (status < 0) { |
| 360 | + throw std::runtime_error("Error at xmlTextWriterStartElement"); |
| 361 | + } |
| 362 | + |
| 363 | + // Attribute version is not relevant in this context. |
| 364 | + |
| 365 | + // Write the configuration |
| 366 | + writeNode(writer, rootConfig, DEFAULT_ENCODING); |
| 367 | + |
| 368 | + // End section |
| 369 | + status = xmlTextWriterEndElement(writer); |
| 370 | + if (status < 0) { |
| 371 | + throw std::runtime_error("Error at xmlTextWriterEndElement"); |
| 372 | + } |
| 373 | + |
| 374 | + // Close the document |
| 375 | + status = xmlTextWriterEndDocument(writer); |
| 376 | + if (status < 0) { |
| 377 | + throw std::runtime_error("Error at xmlTextWriterEndDocument"); |
| 378 | + } |
| 379 | + |
| 380 | + // free the XML writer |
| 381 | + xmlFreeTextWriter(writer); |
| 382 | + |
| 383 | + //buffer is still hanging on, append its contents to the output string |
| 384 | + //xmlChar (aka unsigned char) simple casting to char should be enough |
| 385 | + source += std::string(reinterpret_cast<char*>(buffer->content)); |
| 386 | + |
| 387 | + //free the buffer |
| 388 | + xmlBufferFree(buffer); |
| 389 | +} |
| 390 | + |
286 | 391 | }
|
287 | 392 |
|
288 | 393 | }
|
|
0 commit comments