root/src/XsdWriter.cpp

////////////////////////////////////////////////////////////////////////
// Copyright (c) Nehmulos 2011-2014
// This file is part of N0 Strain Serialization Library.
//
// N0Strain-Serialization-Library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// N0Strain-Serialization-Library 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with N0Strain-Serialization-Library.  If not, see https://gnu.org/licenses/lgpl-3.0
////////////////////////////////////////////////////////////////////////




#include "XsdWriter.h"

namespace nw {

XsdWriter::XsdWriter(String path) : Describer()
{
        file.open(path.c_str(), std::fstream::out);
        currentTag = new Tag("xs:schema");
        currentTag->addNewChild("xmlns:xs", "http://www.w3.org/2001/XMLSchema");
        selectedTag = currentTag;
}

XsdWriter::~XsdWriter()
{
        if(file.is_open())
        {
                close();
        }
}

void XsdWriter::close()
{
        while(currentTag->getParent())
        {
                currentTag = currentTag->getParent();
        }

        Tag::writeXmlHeader(file);
        currentTag->writeAsXmlWithAttributes(file);
        file.close();
}

bool XsdWriter::isInWriteMode()
{
        return true;
}

bool XsdWriter::isSilentCrawler()
{
        return true;
}

bool XsdWriter::push(String tagName)
{
        currentTag->addNewChild("xs:complexType");
        currentTag = currentTag->getLastChild();
        currentTag->addNewChild("name", tagName); // TODO check if that's right
        currentTag->addNewChild("xs:sequence");
        currentTag = currentTag->getLastChild();
        return true;
}

void XsdWriter::pop()
{
        // pop sequence, complexType and the Tag itself
        for(unsigned int i=0; i < 3; ++i)
        {
                if(currentTag->getParent())
                {
                        // remove empty pushes
                        if(!currentTag->hasChildren())
                        {
                                Tag* emptyTag = currentTag;
                                simplePop();
                                currentTag->removeChild(emptyTag);
                                delete emptyTag;
                        }
                        else
                        {
                                simplePop();
                        }
                }
                else
                {
                        break;
                }
        }
}
void XsdWriter::describeArray(String arrayName, String ElementsName, unsigned int size)
{
        push(arrayName);
        didCheckArray.push(false);
}
void XsdWriter::describeValueArray(String arrayName, unsigned int size)
{
        describeArray(arrayName,"value",size);
}
bool XsdWriter::enterNextElement(unsigned int iterator)
{
        if(!didCheckArray.empty() && didCheckArray.top() == false)
        {
                didCheckArray.top() = true;
                return true;
        }
        else
        {
                pop();
                return false;
        }
}

/* Serialize functions */
void XsdWriter::describeName(String name)
{
        currentTag->addNewChild("xs:element");
        selectedTag = currentTag->getLastChild();
        selectedTag->addNewChild("name", name);
}
//1 byte
void XsdWriter::describeValue(bool& value)
{
        addXsdElement("xs:boolean");
}
void XsdWriter::describeValue(char& value)
{
        addXsdElement("xs:integer");
}
void XsdWriter::describeValue(unsigned char& value)
{
        addXsdElement("xs:integer");
}
void XsdWriter::describeValue(signed char& value)
{
        addXsdElement("xs:integer");
}
//2 byte
void XsdWriter::describeValue(short& value)
{
        addXsdElement("xs:integer");
}
void XsdWriter::describeValue(unsigned short& value)
{
        addXsdElement("xs:integer");
}
//4 byte
void XsdWriter::describeValue(int& value)
{
        addXsdElement("xs:integer");
}
void XsdWriter::describeValue(unsigned int& value)
{
        addXsdElement("xs:integer");
}
void XsdWriter::describeValue(long& value)
{
        addXsdElement("xs:float");
}
void XsdWriter::describeValue(unsigned long& value)
{
        addXsdElement("xs:float");
}
void XsdWriter::describeValue(float& value)
{
        addXsdElement("xs:float");
}
void XsdWriter::describeValue(Pointer value)
{
        addXsdElement("xs:integer");
}
//8 byte
void XsdWriter::describeValue(double& value)
{
        addXsdElement("xs:float");
}
void XsdWriter::describeValue(long long& value)
{
        addXsdElement("xs:float");
}
//12 byte
void XsdWriter::describeValue(long double& value)
{
        addXsdElement("xs:float");
}
//variable size
void XsdWriter::describeValue(String& value)
{
        addXsdElement("xs:string");
}
void XsdWriter::describeBlob(String blobName, nw::Pointer binaryBlob, unsigned int blobSize)
{
        //TODO
//              push(childName);
//               simplePush(N0Ware_BinaryToTextEncoding_EncodingTagName);
//                currentTag->addNewChild("xs:string, value);
//               simplePop();
//               currentTag->addNewChild(childName, value);
//              pop();
}
void XsdWriter::comment(const String text)
{
        currentTag->addComment(text);
}

void XsdWriter::simplePush(const String tagname)
{
        currentTag->addNewChild(tagname);
        currentTag = currentTag->getLastChild();
}
void XsdWriter::simplePop()
{
        if(currentTag->getParent() != NULL)
        {
                currentTag = currentTag->getParent();
        }
}

void XsdWriter::addXsdElement(const String type)
{
        selectedTag->addNewChild("type", type);
}

}  // namespace nw