Skip to content
xml_converters.cc 5.76 KiB
Newer Older
YannGarcia's avatar
YannGarcia committed
/*!
 * \file      xml_converters.cc
 * \brief     Source file for the xml_converters functionality.
 * \author    ETSI STF637
 * \copyright ETSI Copyright Notification
 *            No part may be reproduced except as authorized by written permission.
 *            The copyright and the foregoing restriction extend to reproduction in all media.
 *            All rights reserved.
 * \version   0.1
 */
#include "xml_converters.hh"

#include "loggers.hh"

#include <libxml/parser.h>
#include <libxml/c14n.h>
YannGarcia's avatar
YannGarcia committed
#include <libxml/xpath.h>
#include <libxml/tree.h>
YannGarcia's avatar
YannGarcia committed
//#include <libxslt/transform.h>
//#include <libxslt/xsltutils.h>
YannGarcia's avatar
YannGarcia committed

xml_converters* xml_converters::_instance = nullptr;

YannGarcia's avatar
YannGarcia committed
// FIXME Use libxslt
int xml_converters::xml_transform(const std::string& p_to_transform, std::string& p_transformed) const {
  loggers::get_instance().log(">>> xml_converters::xml_transform: '%s'", p_to_transform.c_str());


  xmlDocPtr doc = xmlReadMemory(p_to_transform.c_str(), p_to_transform.length(), "noname.xml", NULL, 0);
  xmlChar *xmlbuff;
  int buffersize;
  xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1);
  loggers::get_instance().log("xml_converters::xml_transform: tree dump: '%s'", (char *) xmlbuff);
  //"\\n\\t<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:s=\"http://www.w3.org/2000/09/xmldsig#\">\\n\\t\\t<xsl:strip-space elements=\"*\"/>\\n\\t\\t<xsl:output indent=\"false\" method=\"xml\" omit-xml-declaration=\"yes\"/>\\n\\t\\t\\t<xsl:template match=\"*[not(self::s:Signature)]\">\\n\\t\\t\\t<xsl:element name=\"{local-name()}\">\\n\\t\\t\\t<xsl:apply-templates select=\"*|text()\"/>\\n\\t\\t</xsl:element></xsl:template><xsl:template match=\"s:Signature\"/>\\n\\t</xsl:stylesheet>\\n\\t"
  
  //xsltApplyStylesheet(cur, doc, params);
  xmlFree(xmlbuff);
  xmlFreeDoc(doc);


  int first = p_to_transform.find('>');
  int next = 0;
  while ((first != -1) && (first < p_to_transform.length())) {
    //loggers::get_instance().log("xml_converters::xml_transform: first: '%d'", first);
    //loggers::get_instance().log("xml_converters::xml_transform: next: '%d'", next);
    p_transformed += p_to_transform.substr(next, first - next + 1);
    //loggers::get_instance().log("xml_converters::xml_transform: p_to_transform: '%s'", p_to_transform.c_str());
    //loggers::get_instance().log("xml_converters::xml_transform: p_transformed: '%s'", p_transformed.c_str());
    next = first + 1;
    while (
      (p_to_transform[next] == '\r') || 
      (p_to_transform[next] == '\n') || 
      (p_to_transform[next] == '\t') || 
      (p_to_transform[next] == ' ')
    ) { // Skip CR, LF, TAG and SPACE
      next += 1;
    } // End of 'while'statement
    first = p_to_transform.find('>', next);
  } // End of 'while'statement

  //<ns4:PullRequest xmlns:ns4="http://www.cise.eu/servicemodel/v1/message/">
  first = p_transformed.find("ns4:");
  while ((first != -1) && (first < p_to_transform.length())) {
    p_transformed = p_transformed.substr(0, first) + p_transformed.substr(first + 4,  p_transformed.length() - 4 - 1);
    loggers::get_instance().log("xml_converters::xml_transform: New p_transformed (1): '%s'", p_transformed.c_str());
    first = p_transformed.find("ns4:");
  } // End of 'while'statement

  first = p_transformed.find("xmlns:ns4");
  while ((first != -1) && (first < p_to_transform.length())) {
    next = p_transformed.find("\">", first + 1);
    p_transformed = p_transformed.substr(0, first - 1) + p_transformed.substr(next + 1,  p_transformed.length() - next - 1);
    loggers::get_instance().log("xml_converters::xml_transform: New p_transformed (2): '%s'", p_transformed.c_str());
    first = p_transformed.find("xmlns:ns4");
  } // End of 'while'statement

  // <Payload xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="XmlEntityPayload">
  first = p_transformed.find("<Payload");
  if ((first != -1) && (first < p_to_transform.length())) {
    next = p_transformed.find("\">", first + 8 + 1);
    p_transformed = p_transformed.substr(0, first + 8) + p_transformed.substr(next + 1,  p_transformed.length() - next - 1);
  }
  
  loggers::get_instance().log("<<< xml_converters::xml_transform: '%s'", p_transformed.c_str());
  return 0;
}

YannGarcia's avatar
YannGarcia committed
int xml_converters::xml_canonicalization(const std::string& p_to_canonical, std::string& p_canonicalized) const {
YannGarcia's avatar
YannGarcia committed
  loggers::get_instance().log(">>> xml_converters::xml_canonicalization: '%s'", p_to_canonical.c_str());
YannGarcia's avatar
YannGarcia committed

  xmlDocPtr doc = xmlParseMemory(p_to_canonical.c_str(), p_to_canonical.length());
  if (doc == nullptr) {
    loggers::get_instance().log("xml_converters::xml_canonicalization: Failed to read XML input");
    return -1;
  }

  xmlOutputBufferPtr buffer = xmlAllocOutputBuffer(nullptr);
  if (buffer == nullptr) {
    loggers::get_instance().log("xml_converters::xml_canonicalization: Failed to read XML input");
    xmlFreeDoc(doc);
    return -1;
  }

  // Do canonicalization
YannGarcia's avatar
YannGarcia committed
  if (xmlC14NExecute(doc, nullptr/*(xmlC14NIsVisibleCallback)&xml_converters::xml_node_set_contains_callback*/, nullptr,  XML_C14N_EXCLUSIVE_1_0, nullptr, 1, buffer) == -1) {
YannGarcia's avatar
YannGarcia committed
    loggers::get_instance().log("xml_converters::xml_canonicalization: Failed to read XML input");
    xmlFreeDoc(doc);
    xmlOutputBufferClose(buffer);
    return -1;
  }

  // Retrieve the canonicalization XML document
  const char* data = (const char*)xmlOutputBufferGetContent(buffer);
  size_t size = xmlOutputBufferGetSize(buffer);
  p_canonicalized.assign(data, data + size);

  // Free resources
  xmlOutputBufferClose(buffer);
  xmlFreeDoc(doc);

YannGarcia's avatar
YannGarcia committed
  loggers::get_instance().log("<<< xml_converters::xml_canonicalization: '%s'", p_canonicalized.c_str());
YannGarcia's avatar
YannGarcia committed
  return 0;
}

int xml_converters::xml_node_set_contains_callback(void* p_user_data, xmlNodePtr p_node, xmlNodePtr p_parent) {
YannGarcia's avatar
YannGarcia committed
  //loggers::get_instance().log("xml_converters::xml_node_set_contains_callback");
YannGarcia's avatar
YannGarcia committed
  return 1;
}