<<TableOfContents(2)>>
= CPlusPlus =
C++ programming language created by Bjarne Stroustrup

== Sample app for Linux ==
{{{#!highlight c++
/*
gcc test.cpp -lstdc++ -o test
cpp test.cpp -o test
g++ test.cpp -o test
*/

#include<vector>
#include<iostream>
#include<sstream>

class Teste{
  public:
    Teste(std::string xyz){
      std::cout << xyz << "\r\n";
    }
};

int main(){
  std::vector<int> listInst = std::vector<int>(); 
  std::cout <<"Hello world \r\n";
  std::ostringstream oss(std::ostringstream::out);
  int a = 1234;
  char xpto[16]="AAA BBB";
  oss << a << xpto << "\r\n";

  std::cout << oss.str();
  //std::ostringstream ost = std::ostringstream(ostringstream::out);
  Teste x1("Ola aaaaaaa");
  return 0;
}
}}}

{{{#!highlight c++
/*
To compile in gcc container
g++ test.cpp -o test

g++ (GCC) 8.2.0
*/
#include<vector>
#include<iostream>
#include<sstream>
#include<random>
#include<ctime>

class Teste{
  public:
    Teste(std::string xyz){
      std::cout << xyz << "\r\n";
    }
};

int main(){
  std::vector<int> listInst = std::vector<int>();
  std::cout <<"Hello world \r\n";
  std::ostringstream oss(std::ostringstream::out);
  int a = 1234;
  char xpto[16]="AAA BBB";
  oss << a << xpto << "\r\n";

  std::cout << oss.str();
  //std::ostringstream ost = std::ostringstream(ostringstream::out);
  Teste x1("Ola aaaaaaa");
  srand( (unsigned) time(0)  );
  std::cout << rand() <<"\n";
  std::cout << rand() <<"\n";
  std::cout << std::to_string(1234) << " " << std::to_string(34.56) << "\n";
  return 0;
}

}}}

== dummy1.cpp ==
{{{#!highlight cpp
/**
g++ dummy1.cpp -o dummy1
*/
#include <iostream>
#include <string>
using namespace std;

int main(){
  std::string input;
  std::cout <<"Hello world \r\n";
  cout << ">";
  std::cin >> input;
  std::cout << input << "!!!\n";
  char x[128];
  std::cout << ">";
  cin >> x;
  std::cout << x << "???\n";
  return 0;
}

}}}

== challenge.cpp ==
{{{#!highlight cpp
/**
g++ challenge.cpp -o challenge -lxml2
g++ challenge.cpp -o challenge -lstdc++ -lxml2 -I/usr/include/libxml2
g++ challenge.cpp -o challenge -lstdc++ -lxerces-c 
// added random ...
g++ challenge.cpp -o challenge -lstdc++ -lxerces-c -std=c++11
indent -kr -nut challenge.cpp 
*/
#include <iostream>
#include <string>
#include <typeinfo>
#include <exception>
#include <fstream>
#include <random>
#include <ctime>
#include <cstdlib>
#include <cstdio>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/sax/SAXParseException.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMNodeList.hpp>
#include <xercesc/dom/DOMNode.hpp>
using namespace std;
using namespace xercesc;

const int NO_OPTION=-1;
const int GEN_XML=1;
const int GEN_JSON=2;
const int EXIT=3;
const char* OUT_XML="out.xml";

class ErrorLoadXSDException:public exception {
  public:
    virtual const char *what() const throw() {
        return "Error loading XSD";
    }
};

class OutOfRangeException:public exception {
  public:
      
    OutOfRangeException(int value){
        this->value = value;  
        this->message = new char[128];
    }
    
    virtual const char *what() const throw() {
        char ret[128];
        sprintf(this->message,"%d out of range!",this->value);
        return this->message;
    }
    
  private:
    int value;
    char* message;
};

class Data {
  public:
      
      Data(){
          this->b = "";    
      }  
    
      virtual void set_string(string value) {
          this->b = value;
      } 
    
      virtual string get_string() {
          return this->b;
      }

      virtual string to_xml(const char* xsd_file) {
          string ret = "";
          ret += "<bit:a xmlns:bit=\"http://bitarus.allowed.org/types\" ";
          ret += "xsi:schemaLocation=\"http://bitarus.allowed.org/types " + string(xsd_file) + "\" ";
          ret += "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n";
          ret += "<bit:b>";
          ret += this->b;
          ret += "</bit:b>\n";
          ret += "</bit:a>\n";
          return ret;
      }

      virtual string to_json() {
          string ret = "";
          ret += "{\"a\": \n";
          ret += "  {\"b\":\"";
          ret += this->b;
          ret += "\"} \n"; 
          ret += "} ";  
          return ret;
      }      
    
      static Data* from_xml(const char* xml_file){
          Data* ret = new Data();
          try{
              XercesDOMParser *parser = new XercesDOMParser;
              parser->setValidationScheme(XercesDOMParser::Val_Never);
              parser->parse(xml_file);
              DOMDocument *doc = parser->getDocument();        
              DOMElement* root = doc->getDocumentElement();        
              DOMNodeList* nl = root->getElementsByTagName( XMLString::transcode("bit:b") );
            
              if(nl->getLength() > 0){ 
                  DOMNode* dn = nl->item(0);
                  string v = string(XMLString::transcode(dn->getLastChild()->getNodeValue()) );
                  ret->set_string(v);
              }            
          }
          catch(const DOMException& toCatch) {
              char *message = XMLString::transcode(toCatch.msg);
              cout << "DOMException message is:" << message << endl;
              XMLString::release(&message);
          }
          catch(...){
              cout << "Ups" << endl;
          }
        
          return ret;
    }
    
  private:
    string b;
};

class MyErrorHandler:public HandlerBase {
  public:
    void warning(const SAXParseException& exc) {
        throw exc;
    } 
    
    void error(const SAXParseException& exc) {
        throw exc;
    }
    
    void fatalError(const SAXParseException & exc) {
        throw exc;
    }

    void resetErrors() {
    }
};

void check_xml(const char* xsd_file, const char* out_file){
    XercesDOMParser *parser = new XercesDOMParser();
    MyErrorHandler *errorHandler = new MyErrorHandler();

    try {
        Grammar *g = parser->loadGrammar(xsd_file, Grammar::SchemaGrammarType);
        if (g == NULL) {
            throw new ErrorLoadXSDException();
        }

        parser->setErrorHandler(errorHandler);
        parser->setDoSchema(true);
        parser->setDoNamespaces(true);
        parser->setValidationSchemaFullChecking(true);
        parser->setValidationScheme(XercesDOMParser::Val_Always);
        parser->parse(out_file);
        cout << "XML is okay !" << endl;
    }
    catch(const XMLException& toCatch) {
        char *message = XMLString::transcode(toCatch.getMessage());
        cout << "XMLException message is: " << message << endl;
        XMLString::release(&message);
    }
    catch(const DOMException& toCatch) {
        char *message = XMLString::transcode(toCatch.msg);
        cout << "DOMException message is: " << message << endl;
        XMLString::release(&message);
    }
    catch(const SAXParseException& toCatch) {
        char *message = XMLString::transcode(toCatch.getMessage());
        cout << "SAXParseException message is: " << message << endl;
        XMLString::release(&message);
    }
    catch(const ErrorLoadXSDException* toCatch) {
        cout << "ErrorLoadXSDException message is: " << toCatch->what() << endl;
    }
    catch(...) {
        cout << "Unexpected Exception \n";
    }

    delete errorHandler;
    delete parser;    
}

void gen_xml(const char*xsd_file, const char* out_file, Data* d){
    int ret;
    cout << "XSD file " << xsd_file << endl;
    ofstream xml_out;
    xml_out.open(out_file);
    xml_out << d->to_xml(xsd_file) << endl;
    xml_out.close();
    cout << "Generated XML file " << out_file << endl; 
    check_xml(xsd_file,out_file);
}

void gen_json(const char* out_file, Data* d) {
    ofstream json_out;
    json_out.open(out_file);
    json_out << d->to_json() << endl;
    json_out.close();
    cout << "Generated JSON file " << out_file << endl; 
}

int menu(char* file_xsd) {
    cout << endl << "Using " << file_xsd << endl;
    std::cout << "1) Generate XML" << endl;
    std::cout << "2) Generate JSON" << endl;
    std::cout << "3) Quit" << std::endl;
    std::cout << ">";
    string option;
    std::cin >> option;
    int ret=-1;
    try{
        ret = std::stoi(option.c_str());
        if(ret<GEN_XML || ret >EXIT){            
            throw OutOfRangeException(ret);
        }
    }
    catch(OutOfRangeException ex){
        cout << ex.what() <<"\n"; 
    }
    catch(...){
        std::cout << "Invalid option selected!" << endl;
    }
    return ret;
}

int main(int argc, char** argv) {
    try {
        XMLPlatformUtils::Initialize();
    }
    catch(const XMLException& toCatch) {
        return 1;
    }

    if (argc == 2) {
        int res = NO_OPTION;
        while (res != EXIT) {
            
            res = menu(argv[1]);
            
            if (res == GEN_XML){
                Data d = Data();
                srand(time(0));
                int val = rand();                
                d.set_string("xml" + std::to_string(val) );
                gen_xml(argv[1],OUT_XML,&d);                
            }
            
            if (res == GEN_JSON){
                Data* d=Data::from_xml(OUT_XML);
                gen_json("out.json",d);                
            }           
        }
    }

    XMLPlatformUtils::Terminate();
    return 0;
}

}}}

== hello.cpp ==
{{{#!highlight cpp
/*
g++ hello.cpp -o hello-cpp
clang++  hello.cpp -o hello-cpp
./hello-cpp aaa bbb
*/
#include<iostream>
using namespace std;

int main(int argc, char** argv){
  if(argc==2)  cout << "Hello " << argc << " " <<  argv[1] << "\n";
  if(argc==3)  cout << "Hello " << argc << " " << argv[1] << " " << argv[2] << "\n";
}
}}}