<commit_before>/***********************************************************************
    filename:   CEGUIRapidXMLParser.cpp
    created:    Mar 27 2010
    author:     Jay Sprenkle
 *************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2010 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "rapidxml.hpp"

#include "CEGUI/XMLParserModules/RapidXML/XMLParser.h"
#include "CEGUI/ResourceProvider.h"
#include "CEGUI/System.h"
#include "CEGUI/XMLHandler.h"
#include "CEGUI/XMLAttributes.h"
#include "CEGUI/Logger.h"
#include "CEGUI/Exceptions.h"

// Start of CEGUI namespace section
namespace CEGUI
{

//----------------------------------------------------------------------------//
class RapidXMLDocument : public rapidxml::xml_document<>
{
public:
    RapidXMLDocument(XMLHandler& handler, const RawDataContainer& source,
                     const String& schemaName);

    ~RapidXMLDocument()
    {
    }

protected:
    void processElement(const rapidxml::xml_node<>* element);

private:
    XMLHandler* d_handler;
};

//----------------------------------------------------------------------------//
RapidXMLDocument::RapidXMLDocument(XMLHandler& handler,
                                   const RawDataContainer& source,
                                   const String& /*schemaName*/)
{
    d_handler = &handler;

    // Create a buffer with extra bytes for a newline and a terminating null
    size_t size = source.getSize();
    char* buf = new char[size + 2];
    memcpy(buf, source.getDataPtr(), size);
    // PDT: The addition of the newline is a kludge to resolve an issue
    // whereby parse returns 0 if the xml file has no newline at the end but
    // is otherwise well formed.
    buf[size] = '\n';
    buf[size + 1] = 0;

    // Parse the document
    rapidxml::xml_document<> doc;    // character type defaults to char

    try
    {
        doc.parse<0>(buf);          // 0 means default parse flags
    }
    catch (...)
    {
        // error detected, cleanup out buffers
        delete[] buf;
        CEGUI_THROW(FileIOException("an error occurred while "
                              "parsing the XML data - check it for "
                              "potential errors!."));
    }

    rapidxml::xml_node<>* currElement = doc.first_node();

    if (currElement)
    {
        try
        {
            // function called recursively to parse xml data
            processElement(currElement);
        }
        catch (...)
        {
            delete[] buf;
            throw;
        }
    }

    // Free memory
    delete[] buf;
}

//----------------------------------------------------------------------------//
void RapidXMLDocument::processElement(const rapidxml::xml_node<>* element)
{
    // build attributes block for the element
    XMLAttributes attrs;

    rapidxml::xml_attribute<>* currAttr = element->first_attribute(0);

    while (currAttr)
    {
        attrs.add((utf8*)currAttr->name(), (utf8*)currAttr->value());
        currAttr = currAttr->next_attribute();
    }

    // start element
    d_handler->elementStart((utf8*)element->name(), attrs);

    // do children
    rapidxml::xml_node<>* childNode = element->first_node();

    while (childNode)
    {
        switch (childNode->type())
        {
        case rapidxml::node_element:
            processElement(childNode);
            break;

        case rapidxml::node_data:
            if (childNode->value() != '\0')
                d_handler->text((utf8*)childNode->value());

            break;

            // Silently ignore unhandled node type
        };

        childNode = childNode->next_sibling();
    }

    // end element
    d_handler->elementEnd((utf8*)element->name());
}

//----------------------------------------------------------------------------//
RapidXMLParser::RapidXMLParser(void)
{
    // set ID string
    d_identifierString = "CEGUI::RapidXMLParser - "
                         "Official RapidXML based parser module for CEGUI";
}

//----------------------------------------------------------------------------//
RapidXMLParser::~RapidXMLParser(void)
{
}

//----------------------------------------------------------------------------//
void RapidXMLParser::parseXML(XMLHandler& handler,
                              const RawDataContainer& source,
                              const String& schemaName)
{
    RapidXMLDocument doc(handler, source, schemaName);
}

//----------------------------------------------------------------------------//
bool RapidXMLParser::initialiseImpl(void)
{
    // This used to prevent deletion of line ending in the middle of a text.
    // WhiteSpace cleaning will be available throught the use of String methods
    // directly: rapidxml::xml_document<>::SetCondenseWhiteSpace(false);
    return true;
}

//----------------------------------------------------------------------------//
void RapidXMLParser::cleanupImpl(void)
{
}

//----------------------------------------------------------------------------//

} // End of  CEGUI namespace section

<commit_msg>FIX: RapidXML based parser compile errors using std::string as CEGUI::String<commit_after>/***********************************************************************
    filename:   CEGUIRapidXMLParser.cpp
    created:    Mar 27 2010
    author:     Jay Sprenkle
 *************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2010 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "rapidxml.hpp"

#include "CEGUI/XMLParserModules/RapidXML/XMLParser.h"
#include "CEGUI/ResourceProvider.h"
#include "CEGUI/System.h"
#include "CEGUI/XMLHandler.h"
#include "CEGUI/XMLAttributes.h"
#include "CEGUI/Logger.h"
#include "CEGUI/Exceptions.h"

// Start of CEGUI namespace section
namespace CEGUI
{

//----------------------------------------------------------------------------//
class RapidXMLDocument : public rapidxml::xml_document<>
{
public:
    RapidXMLDocument(XMLHandler& handler, const RawDataContainer& source,
                     const String& schemaName);

    ~RapidXMLDocument()
    {
    }

protected:
    void processElement(const rapidxml::xml_node<>* element);

private:
    XMLHandler* d_handler;
};

//----------------------------------------------------------------------------//
RapidXMLDocument::RapidXMLDocument(XMLHandler& handler,
                                   const RawDataContainer& source,
                                   const String& /*schemaName*/)
{
    d_handler = &handler;

    // Create a buffer with extra bytes for a newline and a terminating null
    size_t size = source.getSize();
    char* buf = new char[size + 2];
    memcpy(buf, source.getDataPtr(), size);
    // PDT: The addition of the newline is a kludge to resolve an issue
    // whereby parse returns 0 if the xml file has no newline at the end but
    // is otherwise well formed.
    buf[size] = '\n';
    buf[size + 1] = 0;

    // Parse the document
    rapidxml::xml_document<> doc;    // character type defaults to char

    try
    {
        doc.parse<0>(buf);          // 0 means default parse flags
    }
    catch (...)
    {
        // error detected, cleanup out buffers
        delete[] buf;
        CEGUI_THROW(FileIOException("an error occurred while "
                              "parsing the XML data - check it for "
                              "potential errors!."));
    }

    rapidxml::xml_node<>* currElement = doc.first_node();

    if (currElement)
    {
        try
        {
            // function called recursively to parse xml data
            processElement(currElement);
        }
        catch (...)
        {
            delete[] buf;
            throw;
        }
    }

    // Free memory
    delete[] buf;
}

//----------------------------------------------------------------------------//
void RapidXMLDocument::processElement(const rapidxml::xml_node<>* element)
{
    // build attributes block for the element
    XMLAttributes attrs;

    rapidxml::xml_attribute<>* currAttr = element->first_attribute(0);

    while (currAttr)
    {
        attrs.add(reinterpret_cast<encoded_char*>(currAttr->name()),
                  reinterpret_cast<encoded_char*>(currAttr->value()));
        currAttr = currAttr->next_attribute();
    }

    // start element
    d_handler->elementStart(reinterpret_cast<encoded_char*>(element->name()),
                            attrs);

    // do children
    rapidxml::xml_node<>* childNode = element->first_node();

    while (childNode)
    {
        switch (childNode->type())
        {
        case rapidxml::node_element:
            processElement(childNode);
            break;

        case rapidxml::node_data:
            if (childNode->value() != '\0')
                d_handler->text(
                    reinterpret_cast<encoded_char*>(childNode->value()));

            break;

            // Silently ignore unhandled node type
        };

        childNode = childNode->next_sibling();
    }

    // end element
    d_handler->elementEnd(reinterpret_cast<encoded_char*>(element->name()));
}

//----------------------------------------------------------------------------//
RapidXMLParser::RapidXMLParser(void)
{
    // set ID string
    d_identifierString = "CEGUI::RapidXMLParser - "
                         "Official RapidXML based parser module for CEGUI";
}

//----------------------------------------------------------------------------//
RapidXMLParser::~RapidXMLParser(void)
{
}

//----------------------------------------------------------------------------//
void RapidXMLParser::parseXML(XMLHandler& handler,
                              const RawDataContainer& source,
                              const String& schemaName)
{
    RapidXMLDocument doc(handler, source, schemaName);
}

//----------------------------------------------------------------------------//
bool RapidXMLParser::initialiseImpl(void)
{
    // This used to prevent deletion of line ending in the middle of a text.
    // WhiteSpace cleaning will be available throught the use of String methods
    // directly: rapidxml::xml_document<>::SetCondenseWhiteSpace(false);
    return true;
}

//----------------------------------------------------------------------------//
void RapidXMLParser::cleanupImpl(void)
{
}

//----------------------------------------------------------------------------//

} // End of  CEGUI namespace section

<|endoftext|>


<commit_before>/* Copyright (C) 2012, 2013
   Daniel Mosquera Villanueva (daniel.m.v@terra.es)
   This file is part of LFC Library.

   LFC 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 2.1 of the License, or (at your option) any later version.

   LFC 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 LFC Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA. or see http://www.gnu.org/licenses/. */

#include "serializator.h"
#include "filesystemexception.h"
#include "../Text/text.h"
#include "../nobjectregistry.h"
#include "../Devices/stdout.h"
#include <string.h>
#include <typeinfo>
#include <unistd.h>

Serializator::Serializator(const IFile &file)
{
	this->file = (IFile *)&file;
	readTimeout = 60000000;
}

Serializator::~Serializator()
{

}

void Serializator::Put(char *buffer, int lonBuffer)
{
	int escrito = 0;
	while (escrito < lonBuffer) {
		int res = file->Write(buffer + escrito, lonBuffer - escrito > 1000 ? 1000 : lonBuffer - escrito);
		if (res == 0)
			throw new FileSystemException("It seems that the stream has suddently been closed.", __FILE__, __LINE__, __func__);
		escrito += res;
	}
}

void Serializator::Put(const NObject &o)
{
	char strName[1000];
	strcpy(strName, typeid(o).name());
	unsigned char namelen = strlen(strName);
	unsigned char signature = 0x000000CC;

	file->Write((char *)&signature, sizeof(signature));
	file->Write((char *)&namelen, sizeof(namelen));
	file->Write(strName, namelen);
	((NObject *)&o)->Serialize(*this);
}

void Serializator::Put(bool b)
{
	file->Write((char *)&b, sizeof(b));
}

void Serializator::Put(char n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(short n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(int n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(long n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(long long n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(unsigned char n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(unsigned short n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(unsigned int n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(unsigned long n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(unsigned long long n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(float n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(double n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(long double n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Get(char *buffer, int lonBuffer)
{
	int timecount = readTimeout;
	int leido = 0;
	while (leido < lonBuffer) {
		int res = file->Read(buffer + leido, lonBuffer - leido);
		if (res == 0) {	// Waits until timeout goes
			timecount -= READ_TIMEOUT_STEP;
			if (timecount < 0)
				throw new FileSystemException("Read timeout exception", __FILE__, __LINE__, __func__);
			usleep(READ_TIMEOUT_STEP);
		} else {
			leido += res;
		}
	}
}

NObject *Serializator::GetNObject()
{
	char strName[1000];
	unsigned char namelen = 0;
	unsigned char signature = 0;

	Get((char *)&signature, sizeof(signature));
	if (signature != 0x00CC)
		throw new FileSystemException((Text)"No valid class found in file.", __FILE__, __LINE__, __func__);
	Get((char *)&namelen, sizeof(namelen));
	Get(strName, namelen);
	strName[namelen] = 0;

	NObject *o = NObjectRegistry::GetInstance(strName);
	o->Deserialize(*this);
	return o;
}

bool Serializator::GetBool()
{
	bool n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

char Serializator::GetChar()
{
	char n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

short Serializator::GetShort()
{
	short n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

int Serializator::GetInt()
{
	int n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

long Serializator::GetLong()
{
	long n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

long long Serializator::GetLongLong()
{
	long long n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

unsigned char Serializator::GetUChar()
{
	unsigned char n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

unsigned short Serializator::GetUShort()
{
	unsigned short n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

unsigned int Serializator::GetUInt()
{
	unsigned int n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

unsigned long Serializator::GetULong()
{
	unsigned long n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

unsigned long long Serializator::GetULongLong()
{
	unsigned long long n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

float Serializator::GetFloat()
{
	float n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

double Serializator::GetDouble()
{
	double n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

long double Serializator::GetLongDouble()
{
	long double n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}
<commit_msg>Now serializator wakes up sooner when data avaliable<commit_after>/* Copyright (C) 2012, 2013
   Daniel Mosquera Villanueva (daniel.m.v@terra.es)
   This file is part of LFC Library.

   LFC 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 2.1 of the License, or (at your option) any later version.

   LFC 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 LFC Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA. or see http://www.gnu.org/licenses/. */

#include "serializator.h"
#include "filesystemexception.h"
#include "../Text/text.h"
#include "../nobjectregistry.h"
#include "../Devices/stdout.h"
#include <string.h>
#include <typeinfo>
#include <unistd.h>

Serializator::Serializator(const IFile &file)
{
	this->file = (IFile *)&file;
	readTimeout = 60000000;
}

Serializator::~Serializator()
{

}

void Serializator::Put(char *buffer, int lonBuffer)
{
	int escrito = 0;
	while (escrito < lonBuffer) {
		int res = file->Write(buffer + escrito, lonBuffer - escrito > 1000 ? 1000 : lonBuffer - escrito);
		if (res == 0)
			throw new FileSystemException("It seems that the stream has suddently been closed.", __FILE__, __LINE__, __func__);
		escrito += res;
	}
}

void Serializator::Put(const NObject &o)
{
	char strName[1000];
	strcpy(strName, typeid(o).name());
	unsigned char namelen = strlen(strName);
	unsigned char signature = 0x000000CC;

	file->Write((char *)&signature, sizeof(signature));
	file->Write((char *)&namelen, sizeof(namelen));
	file->Write(strName, namelen);
	((NObject *)&o)->Serialize(*this);
}

void Serializator::Put(bool b)
{
	file->Write((char *)&b, sizeof(b));
}

void Serializator::Put(char n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(short n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(int n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(long n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(long long n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(unsigned char n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(unsigned short n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(unsigned int n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(unsigned long n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(unsigned long long n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(float n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(double n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Put(long double n)
{
	file->Write((char *)&n, sizeof(n));
}

void Serializator::Get(char *buffer, int lonBuffer)
{
	int timecount = readTimeout;
	int leido = 0;
	while (leido < lonBuffer) {
		int res = file->Read(buffer + leido, lonBuffer - leido);
		if (res == 0) {	// Waits until timeout goes
			timecount -= READ_TIMEOUT_STEP;
			if (timecount < 0)
				throw new FileSystemException("Read timeout exception", __FILE__, __LINE__, __func__);
			file->WaitForDataComming(READ_TIMEOUT_STEP);
		} else {
			leido += res;
		}
	}
}

NObject *Serializator::GetNObject()
{
	char strName[1000];
	unsigned char namelen = 0;
	unsigned char signature = 0;

	Get((char *)&signature, sizeof(signature));
	if (signature != 0x00CC)
		throw new FileSystemException((Text)"No valid class found in file.", __FILE__, __LINE__, __func__);
	Get((char *)&namelen, sizeof(namelen));
	Get(strName, namelen);
	strName[namelen] = 0;

	NObject *o = NObjectRegistry::GetInstance(strName);
	o->Deserialize(*this);
	return o;
}

bool Serializator::GetBool()
{
	bool n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

char Serializator::GetChar()
{
	char n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

short Serializator::GetShort()
{
	short n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

int Serializator::GetInt()
{
	int n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

long Serializator::GetLong()
{
	long n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

long long Serializator::GetLongLong()
{
	long long n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

unsigned char Serializator::GetUChar()
{
	unsigned char n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

unsigned short Serializator::GetUShort()
{
	unsigned short n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

unsigned int Serializator::GetUInt()
{
	unsigned int n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

unsigned long Serializator::GetULong()
{
	unsigned long n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

unsigned long long Serializator::GetULongLong()
{
	unsigned long long n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

float Serializator::GetFloat()
{
	float n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

double Serializator::GetDouble()
{
	double n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}

long double Serializator::GetLongDouble()
{
	long double n = 0;
	Get((char *)&n, sizeof(n));
	return n;
}
<|endoftext|>


<commit_before>#include "Scene.h"
#include "Director.h"

#include "EngineShaderFactory.hpp"
#include "FontLoader.h"

using namespace Core;
using namespace std;
using namespace Structure;
using namespace Math;
using namespace Rendering;
using namespace Rendering::Manager;
using namespace Rendering::PostProcessing;
using namespace Rendering::TBDR;
using namespace Rendering::Shader;
using namespace UI::Manager;
using namespace Rendering::Camera;
using namespace Rendering::Texture;
using namespace Rendering::Shadow;

Scene::Scene(void) :
	_cameraMgr(nullptr), _uiManager(nullptr),
	_renderMgr(nullptr), _backBufferMaker(nullptr),
	_shadowRenderer(nullptr)
{
	_state = State::Init;
}

Scene::~Scene(void)
{
	Destroy();
}

void Scene::Initialize()
{
	_cameraMgr		= new CameraManager;

	_renderMgr		= new RenderManager;
	_renderMgr->Initialize();

	_uiManager		= new UIManager;

	_dx				= Device::Director::GetInstance()->GetDirectX();

	_lightManager	= new LightManager;
	_lightManager->InitializeAllShaderResourceBuffer();

	_materialMgr	= new MaterialManager;

	_backBufferMaker = new BackBufferMaker;
	_backBufferMaker->Initialize(false);

	_shadowRenderer = new ShadowRenderer;
	_shadowRenderer->Initialize();

	uint value = 0xff7fffff;
	float fltMin = (*(float*)&value);

	value = 0x7f7fffff;
	float fltMax = (*(float*)&value);

	_boundBox.SetMinMax(Vector3(fltMax, fltMax, fltMax), Vector3(fltMin, fltMin, fltMin));

	NextState();
	OnInitialize();
}

void Scene::Update(float dt)
{
	OnUpdate(dt);

	auto end = _rootObjects.GetVector().end();
	for(auto iter = _rootObjects.GetVector().begin(); iter != end; ++iter)
		(*iter)->Update(dt);
}

void Scene::RenderPreview()
{
	OnRenderPreview();

	Vector3 boundBoxMin = _boundBox.GetMin();
	Vector3 boundBoxMax = _boundBox.GetMax();

	const auto& objectVector = _rootObjects.GetVector();
	for(auto iter = objectVector.begin(); iter != objectVector.end(); ++iter)
		(*iter)->UpdateTransformCB_With_ComputeSceneMinMaxPos(_dx, boundBoxMin, boundBoxMax);

	_boundBox.SetMinMax(boundBoxMin, boundBoxMax);
	_shadowRenderer->UpdateConstBuffer(_dx);

	auto materials = _materialMgr->GetMaterials().GetVector();
	for(auto iter = materials.begin(); iter != materials.end(); ++iter)
		(*iter)->UpdateConstBuffer(_dx);

	_lightManager->ComputeAllLightViewProj(_boundBox);
	_lightManager->UpdateBuffer(_dx);

	const std::vector<CameraForm*>& cameras = _cameraMgr->GetVector();
	for(auto iter = cameras.begin(); iter != cameras.end(); ++iter)
		(*iter)->CullingWithUpdateCB(_dx, _rootObjects.GetVector(), _lightManager);
}

void Scene::Render()
{
	_dx->ClearDeviceContext();
	const RenderManager* renderMgr = _renderMgr;
	_shadowRenderer->RenderShadowMap(_dx, renderMgr);

	_dx->ClearDeviceContext();
	const std::vector<CameraForm*>& cameras = _cameraMgr->GetVector();
	for(auto iter = cameras.begin(); iter != cameras.end(); ++iter)
	{
		if( (*iter)->GetUsage() == CameraForm::Usage::MeshRender )
		{
			const Buffer::ConstBuffer* shadowCB = _shadowRenderer->IsWorking() ? _shadowRenderer->GetShadowGlobalParamConstBuffer() : nullptr;
			dynamic_cast<MeshCamera*>(*iter)->Render(_dx, _renderMgr, _lightManager, shadowCB);
		}
		else if( (*iter)->GetUsage() == CameraForm::Usage::UI )
			dynamic_cast<UICamera*>(*iter)->Render(_dx);
	}
	CameraForm* firstCam = _cameraMgr->GetFirstCamera();
	if(firstCam)
	{
		ID3D11RenderTargetView* backBufferRTV = _dx->GetBackBufferRTV();
		const RenderTexture* camRT = firstCam->GetRenderTarget();

		MeshCamera* mainFirstCam = dynamic_cast<MeshCamera*>(firstCam);
		_backBufferMaker->Render(backBufferRTV, camRT, nullptr, mainFirstCam->GetTBRParamConstBuffer());
	}

	_dx->GetSwapChain()->Present(0, 0);
	OnRenderPost();
}

void Scene::Destroy()
{
	UI::FontLoader::GetInstance()->Destroy();

	SAFE_DELETE(_cameraMgr);
	SAFE_DELETE(_renderMgr);
	SAFE_DELETE(_uiManager);
	SAFE_DELETE(_lightManager);
	SAFE_DELETE(_materialMgr);
	SAFE_DELETE(_backBufferMaker);
	SAFE_DELETE(_shadowRenderer);

	OnDestroy();
}

void Scene::NextState()
{
	_state = (State)(((int)_state + 1) % (int)State::Num);
}

void Scene::AddObject(Core::Object* object)
{
	_rootObjects.Add(object->GetName(), object);
}

Core::Object* Scene::FindObject(const std::string& key)
{
	Core::Object** objAddr = _rootObjects.Find(key);
	return objAddr ? (*objAddr) : nullptr;
}

void Scene::DeleteObject(Core::Object* object)
{
	std::string key = object->GetName();
	Core::Object** objectAddr = _rootObjects.Find(key);
	if(objectAddr)
	{
		Core::Object* object = (*objectAddr);
		SAFE_DELETE(object);

		_rootObjects.Delete(key);
	}
}

void Scene::DeleteAllObject()
{
	auto& objects = _rootObjects.GetVector();
	for(auto iter = objects.begin(); iter != objects.end(); ++iter)
	{
		Core::Object* object = (*iter);
		SAFE_DELETE(object);
	}

	_rootObjects.DeleteAll();
}

void Scene::Input(const Device::Win32::Mouse& mouse, const  Device::Win32::Keyboard& keyboard)
{
	if(_state == State::Loop)
		OnInput(mouse, keyboard);
}<commit_msg>Scene - 에러 수정<commit_after>#include "Scene.h"
#include "Director.h"

#include "EngineShaderFactory.hpp"
#include "FontLoader.h"

using namespace Core;
using namespace std;
using namespace Structure;
using namespace Math;
using namespace Rendering;
using namespace Rendering::Manager;
using namespace Rendering::PostProcessing;
using namespace Rendering::TBDR;
using namespace Rendering::Shader;
using namespace UI::Manager;
using namespace Rendering::Camera;
using namespace Rendering::Texture;
using namespace Rendering::Shadow;

Scene::Scene(void) :
	_cameraMgr(nullptr), _uiManager(nullptr),
	_renderMgr(nullptr), _backBufferMaker(nullptr),
	_shadowRenderer(nullptr)
{
	_state = State::Init;
}

Scene::~Scene(void)
{
	Destroy();
}

void Scene::Initialize()
{
	_cameraMgr		= new CameraManager;

	_renderMgr		= new RenderManager;
	_renderMgr->Initialize();

	_uiManager		= new UIManager;

	_dx				= Device::Director::GetInstance()->GetDirectX();

	_lightManager	= new LightManager;
	_lightManager->InitializeAllShaderResourceBuffer();

	_materialMgr	= new MaterialManager;

	_backBufferMaker = new BackBufferMaker;
	_backBufferMaker->Initialize(false);

	_shadowRenderer = new ShadowRenderer;
	_shadowRenderer->Initialize(false);

	uint value = 0xff7fffff;
	float fltMin = (*(float*)&value);

	value = 0x7f7fffff;
	float fltMax = (*(float*)&value);

	_boundBox.SetMinMax(Vector3(fltMax, fltMax, fltMax), Vector3(fltMin, fltMin, fltMin));

	NextState();
	OnInitialize();
}

void Scene::Update(float dt)
{
	OnUpdate(dt);

	auto end = _rootObjects.GetVector().end();
	for(auto iter = _rootObjects.GetVector().begin(); iter != end; ++iter)
		(*iter)->Update(dt);
}

void Scene::RenderPreview()
{
	OnRenderPreview();

	Vector3 boundBoxMin = _boundBox.GetMin();
	Vector3 boundBoxMax = _boundBox.GetMax();

	const auto& objectVector = _rootObjects.GetVector();
	for(auto iter = objectVector.begin(); iter != objectVector.end(); ++iter)
		(*iter)->UpdateTransformCB_With_ComputeSceneMinMaxPos(_dx, boundBoxMin, boundBoxMax);

	_boundBox.SetMinMax(boundBoxMin, boundBoxMax);
	_shadowRenderer->UpdateConstBuffer(_dx);

	auto materials = _materialMgr->GetMaterials().GetVector();
	for(auto iter = materials.begin(); iter != materials.end(); ++iter)
		(*iter)->UpdateConstBuffer(_dx);

	_lightManager->ComputeAllLightViewProj(_boundBox);
	_lightManager->UpdateBuffer(_dx);

	const std::vector<CameraForm*>& cameras = _cameraMgr->GetVector();
	for(auto iter = cameras.begin(); iter != cameras.end(); ++iter)
		(*iter)->CullingWithUpdateCB(_dx, _rootObjects.GetVector(), _lightManager);
}

void Scene::Render()
{
	_dx->ClearDeviceContext();
	const RenderManager* renderMgr = _renderMgr;
	_shadowRenderer->RenderShadowMap(_dx, renderMgr);

	_dx->ClearDeviceContext();
	const std::vector<CameraForm*>& cameras = _cameraMgr->GetVector();
	for(auto iter = cameras.begin(); iter != cameras.end(); ++iter)
	{
		if( (*iter)->GetUsage() == CameraForm::Usage::MeshRender )
		{
			const Buffer::ConstBuffer* shadowCB = _shadowRenderer->IsWorking() ? _shadowRenderer->GetShadowGlobalParamConstBuffer() : nullptr;
			dynamic_cast<MeshCamera*>(*iter)->Render(_dx, _renderMgr, _lightManager, shadowCB);
		}
		else if( (*iter)->GetUsage() == CameraForm::Usage::UI )
			dynamic_cast<UICamera*>(*iter)->Render(_dx);
	}
	CameraForm* firstCam = _cameraMgr->GetFirstCamera();
	if(firstCam)
	{
		ID3D11RenderTargetView* backBufferRTV = _dx->GetBackBufferRTV();
		const RenderTexture* camRT = firstCam->GetRenderTarget();

		MeshCamera* mainFirstCam = dynamic_cast<MeshCamera*>(firstCam);
		_backBufferMaker->Render(backBufferRTV, camRT, nullptr, mainFirstCam->GetTBRParamConstBuffer());
	}

	_dx->GetSwapChain()->Present(0, 0);
	OnRenderPost();
}

void Scene::Destroy()
{
	UI::FontLoader::GetInstance()->Destroy();

	SAFE_DELETE(_cameraMgr);
	SAFE_DELETE(_renderMgr);
	SAFE_DELETE(_uiManager);
	SAFE_DELETE(_lightManager);
	SAFE_DELETE(_materialMgr);
	SAFE_DELETE(_backBufferMaker);
	SAFE_DELETE(_shadowRenderer);

	OnDestroy();
}

void Scene::NextState()
{
	_state = (State)(((int)_state + 1) % (int)State::Num);
}

void Scene::AddObject(Core::Object* object)
{
	_rootObjects.Add(object->GetName(), object);
}

Core::Object* Scene::FindObject(const std::string& key)
{
	Core::Object** objAddr = _rootObjects.Find(key);
	return objAddr ? (*objAddr) : nullptr;
}

void Scene::DeleteObject(Core::Object* object)
{
	std::string key = object->GetName();
	Core::Object** objectAddr = _rootObjects.Find(key);
	if(objectAddr)
	{
		Core::Object* object = (*objectAddr);
		SAFE_DELETE(object);

		_rootObjects.Delete(key);
	}
}

void Scene::DeleteAllObject()
{
	auto& objects = _rootObjects.GetVector();
	for(auto iter = objects.begin(); iter != objects.end(); ++iter)
	{
		Core::Object* object = (*iter);
		SAFE_DELETE(object);
	}

	_rootObjects.DeleteAll();
}

void Scene::Input(const Device::Win32::Mouse& mouse, const  Device::Win32::Keyboard& keyboard)
{
	if(_state == State::Loop)
		OnInput(mouse, keyboard);
}<|endoftext|>


<commit_before>#include "tentacle-pseudopod.h"
#include "pin-array.h"
#include <stddef.h>
#include "Arduino.h"

Pseudopod::Pseudopod(Stream &input, Print &output) {
  pb_ostream_from_stream(output, pbOutput);
  pb_istream_from_stream(input, pbInput);
}

size_t Pseudopod::sendPins(Pin *pins, size_t length) {
  PinArray pinArray(pins, length);
  pbOutput.bytes_written = 0;

  protobuf::TentacleMessage protobufMsg = {};
  protobufMsg.topic = protobuf::TentacleMessageTopic_action;
  protobufMsg.has_topic = true;
  protobufMsg.response = true;
  protobufMsg.has_response = true;
  protobufMsg.pins.funcs.encode = &Pseudopod::pinEncode;
  protobufMsg.pins.arg = (void*)&pinArray;

  Serial.println("about to encode message");
  Serial.flush();

  bool status = pb_encode_delimited(&pbOutput, protobuf::TentacleMessage_fields, &protobufMsg);

  Serial.println("encoded message");
  Serial.flush();

  return pbOutput.bytes_written;
}

size_t Pseudopod::authenticate(const char *uuid, const char *token) {
  Serial.print(F("uuid in string:\t"));
  Serial.println(uuid);

  Serial.print(F("token in string:\t"));
  Serial.println(token);
  Serial.flush();

  pbOutput.bytes_written = 0;

  protobuf::TentacleMessage protobufMsg = {};
  protobufMsg.topic = protobuf::TentacleMessageTopic_authentication;
  protobufMsg.has_topic = true;
  protobufMsg.authentication = {};
  protobufMsg.has_authentication = true;

  strncpy(protobufMsg.authentication.uuid, uuid, 36);
  protobufMsg.authentication.has_uuid = true;

  strncpy(protobufMsg.authentication.token, token, 40);
  protobufMsg.authentication.has_token = true;

  Serial.print(F("uuid:\t"));
  Serial.println(protobufMsg.authentication.uuid);

  Serial.print(F("token:\t"));
  Serial.println(protobufMsg.authentication.token);

  Serial.flush();
  bool status = pb_encode_delimited(&pbOutput, protobuf::TentacleMessage_fields, &protobufMsg);

  return pbOutput.bytes_written;
}

size_t Pseudopod::registerDevice() {
  // pbOutput.bytes_written = 0;
  //
  // protobuf::MeshbluAuthentication protobufMsg = {};
  // bool status = pb_encode_delimited(&pbOutput, protobuf::TentacleMessage_fields, &protobufMsg);
  //
  // return pbOutput.bytes_written;
}

size_t Pseudopod::processMessage(Tentacle &tentacle) {
  Pin msgPins[tentacle.getNumPins()];

  protobuf::TentacleMessage protobufMsg = {};

  protobufMsg.pins.funcs.decode = &Pseudopod::pinDecode;
  protobufMsg.pins.arg = (void*) &msgPins;

  bool status = pb_decode_delimited(&pbInput, protobuf::TentacleMessage_fields, &protobufMsg);
  switch(protobufMsg.topic) {

    case protobuf::TentacleMessageTopic_action:
      Serial.println(F("Got an ACTION topic!"));
      tentacle.processPins(msgPins);
    break;

    case protobuf::TentacleMessageTopic_config:
      Serial.println(F("Got an CONFIG topic!"));
      tentacle.configurePins(msgPins);
    break;

  }

  Serial.println(F("Printing what I think my pins are: "));
  for(int i = 0; i < tentacle.getNumPins(); i++) {
    Pin &pin = tentacle.getPin(i);
    Serial.print("#");
    Serial.print(pin.getNumber());
    Serial.print(" mode: ");
    Serial.print(pin.getAction());
    Serial.print(" value: ");
    Serial.println(pin.getValue());
    Serial.flush();
  }

  return 0;
}

Pin::Action Pseudopod::getPinAction(protobuf::Action action) {
  switch(action) {
    case protobuf::Action_digitalRead :
      return Pin::digitalRead;

    case protobuf::Action_digitalWrite:
      return Pin::digitalWrite;

    case protobuf::Action_analogRead  :
      return Pin::analogRead;

    case protobuf::Action_analogWrite :
      return Pin::analogWrite;

    case protobuf::Action_servoWrite  :
      return Pin::servoWrite;

    case protobuf::Action_pwmWrite    :
      return Pin::pwmWrite;

    case protobuf::Action_i2cWrite    :
      return Pin::i2cWrite;

    case protobuf::Action_i2cRead     :
      return Pin::i2cRead;

    case protobuf::Action_ignore      :
    default:
      return Pin::ignore;
    break;
  }
}

protobuf::Action Pseudopod::getProtoBufAction(Pin::Action action) {
  switch(action) {
    case Pin::digitalRead :
      return protobuf::Action_digitalRead;

    case Pin::digitalWrite:
      return protobuf::Action_digitalWrite;

    case Pin::analogRead  :
      return protobuf::Action_analogRead;

    case Pin::analogWrite :
      return protobuf::Action_analogWrite;

    case Pin::servoWrite  :
      return protobuf::Action_servoWrite;

    case Pin::pwmWrite    :
      return protobuf::Action_pwmWrite;

    case Pin::i2cWrite    :
      return protobuf::Action_i2cWrite;

    case Pin::i2cRead     :
      return protobuf::Action_i2cRead;

    case Pin::ignore      :
    default:
      return protobuf::Action_ignore;
    break;
  }
}

bool Pseudopod::pinEncode(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) {
  PinArray *pinArray = (PinArray*) *arg;
  bool fail = false;
  for(int i = 0; i < pinArray->length; i++) {

    Pin &pin = pinArray->elements[i];

    if(pin.getAction() == Pin::ignore) {
      continue;
    }

    protobuf::Pin protoBufPin = {};

    protoBufPin.number = pin.getNumber();
    protoBufPin.has_number = true;

    protoBufPin.value = pin.getValue();
    protoBufPin.has_value = true;

    protoBufPin.action = getProtoBufAction(pin.getAction());
    protoBufPin.has_action = true;

    if (!pb_encode_tag_for_field(stream, field)) {
      return false;
    }

    if(!pb_encode_submessage(stream, protobuf::Pin_fields, &protoBufPin)) {
      return false;
    }
  }

  return true;
}

bool Pseudopod::pinDecode(pb_istream_t *stream, const pb_field_t *field, void **arg) {
  Pin *pins = (Pin*) *arg;

  protobuf::Pin protoBufPin = {};

  if (!pb_decode(stream, protobuf::Pin_fields, &protoBufPin)) {
    return false;
  }

  Pin pin((int)protoBufPin.number, getPinAction(protoBufPin.action), protoBufPin.value);

  pins[pin.getNumber()] = pin;

  return true;
}
<commit_msg>introduced this cool new feature where, if you try to write to a pin, it causes an awesome buffer overflow and starts sending you nonsense<commit_after>#include "tentacle-pseudopod.h"
#include "pin-array.h"
#include <stddef.h>
#include "Arduino.h"

Pseudopod::Pseudopod(Stream &input, Print &output) {
  pb_ostream_from_stream(output, pbOutput);
  pb_istream_from_stream(input, pbInput);
}

size_t Pseudopod::sendPins(Pin *pins, size_t length) {
  PinArray pinArray(pins, length);
  pbOutput.bytes_written = 0;

  protobuf::TentacleMessage protobufMsg = {};
  protobufMsg.topic = protobuf::TentacleMessageTopic_action;
  protobufMsg.has_topic = true;
  protobufMsg.response = true;
  protobufMsg.has_response = true;
  protobufMsg.pins.funcs.encode = &Pseudopod::pinEncode;
  protobufMsg.pins.arg = (void*)&pinArray;

  Serial.println("about to encode message");
  Serial.flush();

  bool status = pb_encode_delimited(&pbOutput, protobuf::TentacleMessage_fields, &protobufMsg);

  Serial.println("encoded message");
  Serial.flush();

  return pbOutput.bytes_written;
}

size_t Pseudopod::authenticate(const char *uuid, const char *token) {
  Serial.print(F("uuid in string:\t"));
  Serial.println(uuid);

  Serial.print(F("token in string:\t"));
  Serial.println(token);
  Serial.flush();

  pbOutput.bytes_written = 0;

  protobuf::TentacleMessage protobufMsg = {};
  protobufMsg.topic = protobuf::TentacleMessageTopic_authentication;
  protobufMsg.has_topic = true;
  protobufMsg.authentication = {};
  protobufMsg.has_authentication = true;

  strncpy(protobufMsg.authentication.uuid, uuid, 36);
  protobufMsg.authentication.has_uuid = true;

  strncpy(protobufMsg.authentication.token, token, 40);
  protobufMsg.authentication.has_token = true;

  Serial.print(F("uuid:\t"));
  Serial.println(protobufMsg.authentication.uuid);

  Serial.print(F("token:\t"));
  Serial.println(protobufMsg.authentication.token);

  Serial.flush();
  bool status = pb_encode_delimited(&pbOutput, protobuf::TentacleMessage_fields, &protobufMsg);

  return pbOutput.bytes_written;
}

size_t Pseudopod::registerDevice() {
  // pbOutput.bytes_written = 0;
  //
  // protobuf::MeshbluAuthentication protobufMsg = {};
  // bool status = pb_encode_delimited(&pbOutput, protobuf::TentacleMessage_fields, &protobufMsg);
  //
  // return pbOutput.bytes_written;
}

size_t Pseudopod::processMessage(Tentacle &tentacle) {
  Pin msgPins[tentacle.getNumPins()];

  protobuf::TentacleMessage protobufMsg = {};

  protobufMsg.pins.funcs.decode = &Pseudopod::pinDecode;
  protobufMsg.pins.arg = (void*) &msgPins;

  bool status = pb_decode_delimited(&pbInput, protobuf::TentacleMessage_fields, &protobufMsg);

  Serial.println(F("I received the following pins: "));
  for(int i = 0; i < tentacle.getNumPins(); i++) {
    Pin &pin = msgPins[i];
    Serial.print("#");
    Serial.print(pin.getNumber());
    Serial.print(" mode: ");
    Serial.print(pin.getAction());
    Serial.print(" value: ");
    Serial.println(pin.getValue());
    Serial.flush();
  }

  switch(protobufMsg.topic) {

    case protobuf::TentacleMessageTopic_action:
      Serial.println(F("Got an ACTION topic!"));
      tentacle.processPins(msgPins);

      sendPins(msgPins, tentacle.getNumPins());
    break;

    case protobuf::TentacleMessageTopic_config:
      Serial.println(F("Got an CONFIG topic!"));
      tentacle.configurePins(msgPins);
    break;

  }

  return 0;
}

Pin::Action Pseudopod::getPinAction(protobuf::Action action) {
  switch(action) {
    case protobuf::Action_digitalRead :
      return Pin::digitalRead;

    case protobuf::Action_digitalWrite:
      return Pin::digitalWrite;

    case protobuf::Action_analogRead  :
      return Pin::analogRead;

    case protobuf::Action_analogWrite :
      return Pin::analogWrite;

    case protobuf::Action_servoWrite  :
      return Pin::servoWrite;

    case protobuf::Action_pwmWrite    :
      return Pin::pwmWrite;

    case protobuf::Action_i2cWrite    :
      return Pin::i2cWrite;

    case protobuf::Action_i2cRead     :
      return Pin::i2cRead;

    case protobuf::Action_ignore      :
    default:
      return Pin::ignore;
    break;
  }
}

protobuf::Action Pseudopod::getProtoBufAction(Pin::Action action) {
  switch(action) {
    case Pin::digitalRead :
      return protobuf::Action_digitalRead;

    case Pin::digitalWrite:
      return protobuf::Action_digitalWrite;

    case Pin::analogRead  :
      return protobuf::Action_analogRead;

    case Pin::analogWrite :
      return protobuf::Action_analogWrite;

    case Pin::servoWrite  :
      return protobuf::Action_servoWrite;

    case Pin::pwmWrite    :
      return protobuf::Action_pwmWrite;

    case Pin::i2cWrite    :
      return protobuf::Action_i2cWrite;

    case Pin::i2cRead     :
      return protobuf::Action_i2cRead;

    case Pin::ignore      :
    default:
      return protobuf::Action_ignore;
    break;
  }
}

bool Pseudopod::pinEncode(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) {
  PinArray *pinArray = (PinArray*) *arg;
  bool fail = false;
  for(int i = 0; i < pinArray->length; i++) {

    Pin &pin = pinArray->elements[i];

    if(pin.getAction() == Pin::ignore) {
      continue;
    }

    protobuf::Pin protoBufPin = {};

    protoBufPin.number = pin.getNumber();
    protoBufPin.has_number = true;

    protoBufPin.value = pin.getValue();
    protoBufPin.has_value = true;

    protoBufPin.action = getProtoBufAction(pin.getAction());
    protoBufPin.has_action = true;

    if (!pb_encode_tag_for_field(stream, field)) {
      return false;
    }

    if(!pb_encode_submessage(stream, protobuf::Pin_fields, &protoBufPin)) {
      return false;
    }
  }

  return true;
}

bool Pseudopod::pinDecode(pb_istream_t *stream, const pb_field_t *field, void **arg) {
  Pin *pins = (Pin*) *arg;

  protobuf::Pin protoBufPin = {};

  if (!pb_decode(stream, protobuf::Pin_fields, &protoBufPin)) {
    return false;
  }

  Pin pin((int)protoBufPin.number, getPinAction(protoBufPin.action), protoBufPin.value);

  pins[pin.getNumber()] = pin;

  return true;
}
<|endoftext|>


<commit_before>// FitsRequestHandler.cc

// This file is part of fits_handler, a data handler for the OPeNDAP data
// server.

// Copyright (c) 2004,2005 University Corporation for Atmospheric Research
// Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
//
// This 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 2.1 of the License, or (at your option) any later version.
//
// This 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 this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// You can contact University Corporation for Atmospheric Research at
// 3080 Center Green Drive, Boulder, CO 80301

// (c) COPYRIGHT University Corporation for Atmostpheric Research 2004-2005
// Please read the full copyright statement in the file COPYRIGHT_UCAR.
//
// Authors:
//      pwest       Patrick West <pwest@ucar.edu>
//      jgarcia     Jose Garcia <jgarcia@ucar.edu>

#include "config.h"

#include <DAS.h>
#include <DDS.h>
#include <DMR.h>
#include <D4BaseTypeFactory.h>
#include <Ancillary.h>
#include <InternalErr.h>
#include <mime_util.h>

#include <BESResponseHandler.h>
#include <BESDapError.h>

#include <BESDapNames.h>
#include <BESResponseNames.h>
#include <BESDASResponse.h>
#include <BESDDSResponse.h>
#include <BESDataDDSResponse.h>
#include <BESDMRResponse.h>

#include <BESVersionInfo.h>
#include <BESConstraintFuncs.h>
#include <BESServiceRegistry.h>
#include <BESUtil.h>

#include <fitsio.h>

#include "FitsRequestHandler.h"
#include "fits_read_attributes.h"
#include "fits_read_descriptors.h"

#define FITS_NAME "fits"

FitsRequestHandler::FitsRequestHandler(const string &name) :
		BESRequestHandler(name)
{
	add_handler(DAS_RESPONSE, FitsRequestHandler::fits_build_das);
	add_handler(DDS_RESPONSE, FitsRequestHandler::fits_build_dds);
	add_handler(DATA_RESPONSE, FitsRequestHandler::fits_build_data);

	add_handler(DMR_RESPONSE, FitsRequestHandler::fits_build_dmr);
	add_handler(DAP4DATA_RESPONSE, FitsRequestHandler::fits_build_dmr);

	add_handler(VERS_RESPONSE, FitsRequestHandler::fits_build_vers);
	add_handler(HELP_RESPONSE, FitsRequestHandler::fits_build_help);
}

FitsRequestHandler::~FitsRequestHandler()
{
}

bool FitsRequestHandler::fits_build_das(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDASResponse *bdas = dynamic_cast<BESDASResponse *>(response);
	if (!bdas) throw BESInternalError("cast error", __FILE__, __LINE__);

	try {
		bdas->set_container(dhi.container->get_symbolic_name());
		DAS *das = bdas->get_das();
		string accessed = dhi.container->access();
		string fits_error;
		if (!fits_handler::fits_read_attributes(*das, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}
		Ancillary::read_ancillary_das(*das, accessed);
		bdas->clear_container();
	}
	catch( InternalErr &e ) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( Error &e ) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( ... ) {
		throw BESDapError("Unknown exception caught building FITS das response", true, unknown_error, __FILE__, __LINE__);
	}
	return true;
}

bool FitsRequestHandler::fits_build_dds(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDDSResponse *bdds = dynamic_cast<BESDDSResponse *>(response);
	if (!bdds) throw BESInternalError("cast error", __FILE__, __LINE__);

	try {
		bdds->set_container(dhi.container->get_symbolic_name());
		DDS *dds = bdds->get_dds();
		string accessed = dhi.container->access();
		string fits_error;

		if (!fits_handler::fits_read_descriptors(*dds, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}

		Ancillary::read_ancillary_dds(*dds, accessed);
		DAS *das = new DAS;
		BESDASResponse bdas(das);
		bdas.set_container(dhi.container->get_symbolic_name());
		if (!fits_handler::fits_read_attributes(*das, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}
		Ancillary::read_ancillary_das(*das, accessed);

		dds->transfer_attributes(das);

		bdds->set_constraint(dhi);

		bdds->clear_container();
	}
	catch( InternalErr &e ) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( Error &e ) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( ... ) {
		string err = "Unknown exception caught building FITS dds response";
		throw BESDapError(err, true, unknown_error, __FILE__, __LINE__);
	}

	return true;
}

bool FitsRequestHandler::fits_build_data(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDataDDSResponse *bdds = dynamic_cast<BESDataDDSResponse *>(response);
	if (!bdds) throw BESInternalError("cast error", __FILE__, __LINE__);

	try {
		bdds->set_container(dhi.container->get_symbolic_name());
		DataDDS *dds = bdds->get_dds();
		string accessed = dhi.container->access();
		string fits_error;
		if (!fits_handler::fits_read_descriptors(*dds, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}
		Ancillary::read_ancillary_dds(*dds, accessed);

		DAS *das = new DAS;
		BESDASResponse bdas(das);
		bdas.set_container(dhi.container->get_symbolic_name());
		if (!fits_handler::fits_read_attributes(*das, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}
		Ancillary::read_ancillary_das(*das, accessed);

		dds->transfer_attributes(das);

		bdds->set_constraint(dhi);

		bdds->clear_container();
	}
	catch( InternalErr &e ) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( Error &e ) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( ... ) {
		string err = "Unknown exception caught building FITS data response";
		throw BESDapError(err, true, unknown_error, __FILE__, __LINE__);
	}

	return true;
}

/**
 * Build a DMR object. This method builds a DMR by first building a DDS
 * that is loaded with attributes and then using that to make a DMR. This
 * method can be used by both the DAP4 metadata and data responses - because
 * the DMR is the C++ object used for both by libdap.
 *
 * @note The CSV handler has a version of this method that contains some
 * more commentary.
 *
 * @param dhi
 * @return true or throws an exception on error
 */
bool FitsRequestHandler::fits_build_dmr(BESDataHandlerInterface &dhi)
{
	string data_path = dhi.container->access();

	BaseTypeFactory factory;
	DDS dds(&factory, name_path(data_path), "3.2");
	dds.filename(data_path);

	try {
		string fits_error;

		if (!fits_handler::fits_read_descriptors(dds, data_path, fits_error))
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);

		DAS das;
		if (!fits_handler::fits_read_attributes(das, data_path, fits_error))
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		Ancillary::read_ancillary_das(das, data_path);

		dds.transfer_attributes(&das);
	}
	catch( InternalErr &e ) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( Error &e ) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( ... ) {
		throw BESDapError("Unknown exception caught building FITS DMR response", true, unknown_error, __FILE__, __LINE__);
	}

	// Make a DMR using the DDS
	DMR *built_dmr = new DMR(new D4BaseTypeFactory, dds);

	// Extract the DMR Response object - this holds the DMR used by the
	// other parts of the framework.
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDMRResponse &bdmr = dynamic_cast<BESDMRResponse &>(*response);

	// Remove the existing DMR and set the newly made one
	DMR *dmr = bdmr.get_dmr();
	delete dmr->factory();
	delete dmr;
	bdmr.set_dmr(built_dmr);	// BESDMRResponse will delete this object

	bdmr.set_dap4_constraint(dhi);
	bdmr.set_dap4_function(dhi);

	return true;
}

bool FitsRequestHandler::fits_build_vers(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESVersionInfo *info = dynamic_cast<BESVersionInfo *>(response);
	if (!info) throw BESInternalError("cast error", __FILE__, __LINE__);

	info->add_module(PACKAGE_NAME, PACKAGE_VERSION);

	return true;
}

bool FitsRequestHandler::fits_build_help(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESInfo *info = dynamic_cast<BESInfo *>(response);
	if (!info) throw BESInternalError("cast error", __FILE__, __LINE__);

	map<string, string> attrs;
	attrs["name"] = PACKAGE_NAME;
	attrs["version"] = PACKAGE_VERSION;
	list<string> services;
	BESServiceRegistry::TheRegistry()->services_handled(FITS_NAME, services);
	if (services.size() > 0) {
		string handles = BESUtil::implode(services, ',');
		attrs["handles"] = handles;
	}
	info->begin_tag("module", &attrs);
	info->end_tag("module");

	return true;
}

/** @brief dumps information about this object
 *
 * Displays the pointer value of this instance, the name of the request
 * handler, and the names of all registered handler functions
 *
 * @param strm C++ i/o stream to dump the information to
 */
void FitsRequestHandler::dump(ostream &strm) const
{
	strm << BESIndent::LMarg << "FitsRequestHandler::dump - (" << (void *) this << ")" << endl;
	BESIndent::Indent();
	BESRequestHandler::dump(strm);
	BESIndent::UnIndent();
}

<commit_msg>Added support for xml:base<commit_after>// FitsRequestHandler.cc

// This file is part of fits_handler, a data handler for the OPeNDAP data
// server.

// Copyright (c) 2004,2005 University Corporation for Atmospheric Research
// Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
//
// This 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 2.1 of the License, or (at your option) any later version.
//
// This 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 this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// You can contact University Corporation for Atmospheric Research at
// 3080 Center Green Drive, Boulder, CO 80301

// (c) COPYRIGHT University Corporation for Atmostpheric Research 2004-2005
// Please read the full copyright statement in the file COPYRIGHT_UCAR.
//
// Authors:
//      pwest       Patrick West <pwest@ucar.edu>
//      jgarcia     Jose Garcia <jgarcia@ucar.edu>

#include "config.h"

#include <DAS.h>
#include <DDS.h>
#include <DMR.h>
#include <D4BaseTypeFactory.h>
#include <Ancillary.h>
#include <InternalErr.h>
#include <mime_util.h>

#include <BESResponseHandler.h>
#include <BESDapError.h>

#include <BESDapNames.h>
#include <BESResponseNames.h>
#include <BESDASResponse.h>
#include <BESDDSResponse.h>
#include <BESDataDDSResponse.h>
#include <BESDMRResponse.h>

#include <BESVersionInfo.h>
#include <BESConstraintFuncs.h>
#include <BESServiceRegistry.h>
#include <BESUtil.h>

#include <fitsio.h>

#include "FitsRequestHandler.h"
#include "fits_read_attributes.h"
#include "fits_read_descriptors.h"

#define FITS_NAME "fits"

FitsRequestHandler::FitsRequestHandler(const string &name) :
		BESRequestHandler(name)
{
	add_handler(DAS_RESPONSE, FitsRequestHandler::fits_build_das);
	add_handler(DDS_RESPONSE, FitsRequestHandler::fits_build_dds);
	add_handler(DATA_RESPONSE, FitsRequestHandler::fits_build_data);

	add_handler(DMR_RESPONSE, FitsRequestHandler::fits_build_dmr);
	add_handler(DAP4DATA_RESPONSE, FitsRequestHandler::fits_build_dmr);

	add_handler(VERS_RESPONSE, FitsRequestHandler::fits_build_vers);
	add_handler(HELP_RESPONSE, FitsRequestHandler::fits_build_help);
}

FitsRequestHandler::~FitsRequestHandler()
{
}

bool FitsRequestHandler::fits_build_das(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDASResponse *bdas = dynamic_cast<BESDASResponse *>(response);
	if (!bdas) throw BESInternalError("cast error", __FILE__, __LINE__);

	try {
		bdas->set_container(dhi.container->get_symbolic_name());
		DAS *das = bdas->get_das();
		string accessed = dhi.container->access();
		string fits_error;
		if (!fits_handler::fits_read_attributes(*das, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}
		Ancillary::read_ancillary_das(*das, accessed);
		bdas->clear_container();
	}
	catch( InternalErr &e ) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( Error &e ) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( ... ) {
		throw BESDapError("Unknown exception caught building FITS das response", true, unknown_error, __FILE__, __LINE__);
	}
	return true;
}

bool FitsRequestHandler::fits_build_dds(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDDSResponse *bdds = dynamic_cast<BESDDSResponse *>(response);
	if (!bdds) throw BESInternalError("cast error", __FILE__, __LINE__);

	try {
		bdds->set_container(dhi.container->get_symbolic_name());
		DDS *dds = bdds->get_dds();
		string accessed = dhi.container->access();
		string fits_error;

		if (!fits_handler::fits_read_descriptors(*dds, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}

		Ancillary::read_ancillary_dds(*dds, accessed);
		DAS *das = new DAS;
		BESDASResponse bdas(das);
		bdas.set_container(dhi.container->get_symbolic_name());
		if (!fits_handler::fits_read_attributes(*das, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}
		Ancillary::read_ancillary_das(*das, accessed);

		dds->transfer_attributes(das);

		bdds->set_constraint(dhi);

		bdds->clear_container();
	}
	catch( InternalErr &e ) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( Error &e ) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( ... ) {
		string err = "Unknown exception caught building FITS dds response";
		throw BESDapError(err, true, unknown_error, __FILE__, __LINE__);
	}

	return true;
}

bool FitsRequestHandler::fits_build_data(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDataDDSResponse *bdds = dynamic_cast<BESDataDDSResponse *>(response);
	if (!bdds) throw BESInternalError("cast error", __FILE__, __LINE__);

	try {
		bdds->set_container(dhi.container->get_symbolic_name());
		DataDDS *dds = bdds->get_dds();
		string accessed = dhi.container->access();
		string fits_error;
		if (!fits_handler::fits_read_descriptors(*dds, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}
		Ancillary::read_ancillary_dds(*dds, accessed);

		DAS *das = new DAS;
		BESDASResponse bdas(das);
		bdas.set_container(dhi.container->get_symbolic_name());
		if (!fits_handler::fits_read_attributes(*das, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}
		Ancillary::read_ancillary_das(*das, accessed);

		dds->transfer_attributes(das);

		bdds->set_constraint(dhi);

		bdds->clear_container();
	}
	catch( InternalErr &e ) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( Error &e ) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( ... ) {
		string err = "Unknown exception caught building FITS data response";
		throw BESDapError(err, true, unknown_error, __FILE__, __LINE__);
	}

	return true;
}

/**
 * Build a DMR object. This method builds a DMR by first building a DDS
 * that is loaded with attributes and then using that to make a DMR. This
 * method can be used by both the DAP4 metadata and data responses - because
 * the DMR is the C++ object used for both by libdap.
 *
 * @note The CSV handler has a version of this method that contains some
 * more commentary.
 *
 * @param dhi
 * @return true or throws an exception on error
 */
bool FitsRequestHandler::fits_build_dmr(BESDataHandlerInterface &dhi)
{
	string data_path = dhi.container->access();

	BaseTypeFactory factory;
	DDS dds(&factory, name_path(data_path), "3.2");
	dds.filename(data_path);

	try {
		string fits_error;

		if (!fits_handler::fits_read_descriptors(dds, data_path, fits_error))
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);

		DAS das;
		if (!fits_handler::fits_read_attributes(das, data_path, fits_error))
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		Ancillary::read_ancillary_das(das, data_path);

		dds.transfer_attributes(&das);
	}
	catch( InternalErr &e ) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( Error &e ) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( ... ) {
		throw BESDapError("Unknown exception caught building FITS DMR response", true, unknown_error, __FILE__, __LINE__);
	}

	// Extract the DMR Response object - this holds the DMR used by the
	// other parts of the framework.
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDMRResponse &bdmr = dynamic_cast<BESDMRResponse &>(*response);

	// Remove the existing DMR and set the newly made one
	DMR *dmr = bdmr.get_dmr();
	dmr->set_factory(new D4BaseTypeFactory);
	dmr->build_using_dds(dds);

	bdmr.set_dap4_constraint(dhi);
	bdmr.set_dap4_function(dhi);

	return true;
}

bool FitsRequestHandler::fits_build_vers(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESVersionInfo *info = dynamic_cast<BESVersionInfo *>(response);
	if (!info) throw BESInternalError("cast error", __FILE__, __LINE__);

	info->add_module(PACKAGE_NAME, PACKAGE_VERSION);

	return true;
}

bool FitsRequestHandler::fits_build_help(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESInfo *info = dynamic_cast<BESInfo *>(response);
	if (!info) throw BESInternalError("cast error", __FILE__, __LINE__);

	map<string, string> attrs;
	attrs["name"] = PACKAGE_NAME;
	attrs["version"] = PACKAGE_VERSION;
	list<string> services;
	BESServiceRegistry::TheRegistry()->services_handled(FITS_NAME, services);
	if (services.size() > 0) {
		string handles = BESUtil::implode(services, ',');
		attrs["handles"] = handles;
	}
	info->begin_tag("module", &attrs);
	info->end_tag("module");

	return true;
}

/** @brief dumps information about this object
 *
 * Displays the pointer value of this instance, the name of the request
 * handler, and the names of all registered handler functions
 *
 * @param strm C++ i/o stream to dump the information to
 */
void FitsRequestHandler::dump(ostream &strm) const
{
	strm << BESIndent::LMarg << "FitsRequestHandler::dump - (" << (void *) this << ")" << endl;
	BESIndent::Indent();
	BESRequestHandler::dump(strm);
	BESIndent::UnIndent();
}

<|endoftext|>


<commit_before>// Copyright © 2014 German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.
//
// Author: Christian Kellner <kellner@bio.lmu.de>

#include "TestDataArray.hpp"

#include <nix/util/util.hpp>
#include <nix/valid/validate.hpp>

#include <cstdint>

using namespace nix;
using namespace valid;

void TestDataArray::setUp()
{
    startup_time = time(NULL);
    file = nix::File::open("test_DataArray.h5", nix::FileMode::Overwrite);

    block = file.createBlock("block_one", "dataset");
    array1 = block.createDataArray("array_one",
                                   "testdata",
                                   nix::DataType::Double,
                                   nix::NDSize({ 0, 0, 0 }));
    array2 = block.createDataArray("random",
                                   "double",
                                   nix::DataType::Double,
                                   nix::NDSize({ 20, 20 }));
}

void TestDataArray::tearDown()
{
    file.close();
}

void TestDataArray::testValidate() {
    // dims are not equal data dims: 1 warning
    valid::Result result = validate(array1);
    CPPUNIT_ASSERT(result.getErrors().size() == 0);
    CPPUNIT_ASSERT(result.getWarnings().size() == 1);
}

void TestDataArray::testId() {
    CPPUNIT_ASSERT(array1.id().size() == 36);
}

void TestDataArray::testName() {
    CPPUNIT_ASSERT(array1.name() == "array_one");
}

void TestDataArray::testType() {
    CPPUNIT_ASSERT(array1.type() == "testdata");
    std::string typ = nix::util::createId();
    array1.type(typ);
    CPPUNIT_ASSERT(array1.type() == typ);
}

void TestDataArray::testDefinition() {
    std::string def = nix::util::createId();
    array1.definition(def);
    CPPUNIT_ASSERT(*array1.definition() == def);
    array1.definition(boost::none);
    CPPUNIT_ASSERT(array1.definition() == nix::none);
}

void TestDataArray::testData()
{
    typedef boost::multi_array<double, 3> array_type;
    typedef array_type::index index;
    array_type A(boost::extents[3][4][2]);

    int values = 0;
    for(index i = 0; i != 3; ++i)
        for(index j = 0; j != 4; ++j)
            for(index k = 0; k != 2; ++k)
                A[i][j][k] = values++;

    CPPUNIT_ASSERT_EQUAL(array1.dataType(), nix::DataType::Double);
    CPPUNIT_ASSERT_EQUAL(array1.dataExtent(), nix::NDSize({0, 0, 0}));
    CPPUNIT_ASSERT(array1.getDimension(1) == false);

    array1.setData(A);

    array_type B(boost::extents[1][1][1]);
    array1.getData(B);

    int verify = 0;
    int errors = 0;
    for(index i = 0; i != 3; ++i) {
        for(index j = 0; j != 4; ++j) {
            for(index k = 0; k != 2; ++k) {
                int v = verify++;
                errors += B[i][j][k] != v;
            }
        }
    }

    CPPUNIT_ASSERT_EQUAL(errors, 0);

    DataArray direct = block.createDataArray("da_direct", "double", A);
    array_type Adirect(boost::extents[3][4][2]);
    direct.getData(Adirect);

    errors = 0;
    verify = 0;
    for(index i = 0; i != 3; ++i) {
        for(index j = 0; j != 4; ++j) {
            for(index k = 0; k != 2; ++k) {
                int v = verify++;
                errors += Adirect[i][j][k] != v;
            }
        }
    }

    CPPUNIT_ASSERT_EQUAL(0, errors);

    typedef boost::multi_array<double, 2> array2D_type;
    typedef array_type::index index;
    array2D_type C(boost::extents[5][5]);

    for(index i = 0; i != 5; ++i)
        for(index j = 0; j != 5; ++j)
            C[i][j] = 42.0;

    CPPUNIT_ASSERT_EQUAL(array2.dataExtent(), nix::NDSize({20, 20}));

    array2.setData(C, nix::NDSize({0, 0}));
    array2.dataExtent(nix::NDSize({40, 40}));
    CPPUNIT_ASSERT_EQUAL(array2.dataExtent(), nix::NDSize({40, 40}));

    array2D_type D(boost::extents[5][5]);
    for(index i = 0; i != 5; ++i)
        for(index j = 0; j != 5; ++j)
            D[i][j] = 42.0;

        array2.setData(D, nix::NDSize({ 20, 20 }));

    array2D_type E(boost::extents[1][1]);
    array2.getData(E, nix::NDSize({ 5, 5 }), nix::NDSize({ 20, 20 }));

    for(index i = 0; i != 5; ++i)
        for(index j = 0; j != 5; ++j)
            CPPUNIT_ASSERT_DOUBLES_EQUAL(D[i][j], E[i][j],
                std::numeric_limits<double>::epsilon());

    array2D_type F(boost::extents[5][5]);

    array2.getData(F, nix::NDSize({ 20, 20 }));

    for(index i = 0; i != 5; ++i)
        for(index j = 0; j != 5; ++j)
            CPPUNIT_ASSERT_DOUBLES_EQUAL(D[i][j], F[i][j],
                std::numeric_limits<double>::epsilon());

    nix::DataArray da3 = block.createDataArray("direct-vector",
                                               "double",
                                               nix::DataType::Double,
                                               nix::NDSize({5}));

    CPPUNIT_ASSERT(da3.dataExtent() == nix::NDSize{5});
    CPPUNIT_ASSERT(da3.getDimension(1) == false);

    std::vector<double> dv = {1.0, 2.0, 3.0, 4.0, 5.0};
    da3.setData(nix::DataType::Double, dv.data(), nix::NDSize({ 5 }), nix::NDSize({ 0 }));

    std::vector<double> dvin;
    dvin.resize(5);
    da3.getData(nix::DataType::Double, dvin.data(), nix::NDSize({ 5 }), nix::NDSize({ 0 }));

    for(size_t i = 0; i < dvin.size(); i++) {
        CPPUNIT_ASSERT_DOUBLES_EQUAL(dv[i], dvin[i],
                                     std::numeric_limits<double>::epsilon());
    }
}

void TestDataArray::testPolynomial()
{
    double PI = boost::math::constants::pi<double>();
    boost::array<double, 10> coefficients1;
    std::vector<double> coefficients2;
    for(int i=0; i<10; i++) {
        coefficients1[i] = i;
        coefficients2.push_back(i);
    }

    double res1 = util::applyPolynomial(coefficients2, 0, PI);
    double res2 = boost::math::tools::evaluate_polynomial(coefficients1, PI);

    //evalutate_polynomial from boost might use a different algorithm
    //therefore we raise the allowed detlta to 10e-10
    CPPUNIT_ASSERT_DOUBLES_EQUAL(res1, res2, 10e-10);

    array2.polynomCoefficients(coefficients2);
    std::vector<double> ret = array2.polynomCoefficients();
    for(size_t i=0; i<ret.size(); i++) {
        CPPUNIT_ASSERT(ret[i] == coefficients2[i]);
    }

    array2.polynomCoefficients(nix::none);
    CPPUNIT_ASSERT(array2.polynomCoefficients().size() == 0);

    array2.expansionOrigin(3);
    boost::optional<double> retval = array2.expansionOrigin();
    CPPUNIT_ASSERT(*retval == 3);
    array2.expansionOrigin(nix::none);
    CPPUNIT_ASSERT(array2.expansionOrigin() == nix::none);

    //test IO with a polynomial set
    nix::DataArray dap = block.createDataArray("polyio",
                                               "double",
                                               nix::DataType::Double,
                                               nix::NDSize({2, 3}));

    std::vector<double> dv = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};
    dap.setData(nix::DataType::Double, dv.data(), nix::NDSize({2, 3}), nix::NDSize({0, 0}));

    std::vector<double> poly = {1.0, 2.0, 3.0};
    dap.polynomCoefficients(poly);

    std::vector<int32_t> dvin_poly;
    dvin_poly.resize(2*3);
    dap.getData(DataType::Int32, dvin_poly.data(), nix::NDSize({2, 3}), nix::NDSize({0, 0}));

    // reference data generated with MATLAB(c) as folows:
    // p = [3, 2, 1]
    // polyval(p, [1, 2, 3, 4, 5, 6])
    // ans =
    // 6    17    34    57    86   121
    std::vector<int32_t> ref = {6, 17, 34, 57, 86, 121};

    CPPUNIT_ASSERT_EQUAL(ref.size(), dvin_poly.size());
    for (size_t i = 0; i < dvin_poly.size(); i++) {
        CPPUNIT_ASSERT_EQUAL(ref[i], dvin_poly[i]);
    }

}

void TestDataArray::testLabel()
{
    std::string testStr = "somestring";

    array1.label(testStr);
    CPPUNIT_ASSERT(*array1.label() == testStr);
    array1.label(boost::none);
    CPPUNIT_ASSERT(array1.label() == nix::none);
}

void TestDataArray::testUnit()
{
    std::string testStr = "somestring";
    std::string validUnit = "mV^2";

    CPPUNIT_ASSERT_THROW(array1.unit(testStr), nix::InvalidUnit);
    CPPUNIT_ASSERT_NO_THROW(array1.unit(validUnit));
    CPPUNIT_ASSERT(array1.unit() == validUnit);
    CPPUNIT_ASSERT_NO_THROW(array1.unit(boost::none));
    CPPUNIT_ASSERT(array1.unit() == nix::none);
}

void TestDataArray::testDimension()
{
    std::vector<nix::Dimension> dims;
    std::vector<double> ticks;
    double samplingInterval = boost::math::constants::pi<double>();

    for(size_t i = 0; i < 5; i++) {
        ticks.push_back(i * boost::math::constants::pi<double>());
    }

    dims.push_back(array2.createSampledDimension(1, samplingInterval));
    dims.push_back(array2.createSetDimension(2));
    dims.push_back(array2.createRangeDimension(3, ticks));
    dims.push_back(array2.appendSampledDimension(samplingInterval));
    dims.push_back(array2.appendSetDimension());
    dims[3] = array2.createRangeDimension(4, ticks);

    // have some explicit dimension types
    nix::RangeDimension dim_range = array1.appendRangeDimension(ticks);
    nix::SampledDimension dim_sampled = array1.appendSampledDimension(samplingInterval);
    nix::SetDimension dim_set = array1.appendSetDimension();

    CPPUNIT_ASSERT(array2.getDimension(dims[0].index()).dimensionType() == nix::DimensionType::Sample);
    CPPUNIT_ASSERT(array2.getDimension(dims[1].index()).dimensionType() == nix::DimensionType::Set);
    CPPUNIT_ASSERT(array2.getDimension(dims[2].index()).dimensionType() == nix::DimensionType::Range);
    CPPUNIT_ASSERT(array2.getDimension(dims[3].index()).dimensionType() == nix::DimensionType::Range);
    CPPUNIT_ASSERT(array2.getDimension(dims[4].index()).dimensionType() == nix::DimensionType::Set);

    CPPUNIT_ASSERT(array2.dimensionCount() == 5);

    dims = array2.dimensions([](nix::Dimension dim) { return dim.dimensionType() == nix::DimensionType::Sample; });
    CPPUNIT_ASSERT(dims.size() == 1);
    CPPUNIT_ASSERT(dims[0].dimensionType() == nix::DimensionType::Sample);
    dims = array2.dimensions([](nix::Dimension dim) { return dim.dimensionType() == nix::DimensionType::Set; });
    CPPUNIT_ASSERT(dims.size() == 2);
    CPPUNIT_ASSERT(dims[0].dimensionType() == nix::DimensionType::Set);
    CPPUNIT_ASSERT(dims[1].dimensionType() == nix::DimensionType::Set);
    dims = array2.dimensions([](nix::Dimension dim) { return dim.dimensionType() == nix::DimensionType::Range; });
    CPPUNIT_ASSERT(dims.size() == 2);
    CPPUNIT_ASSERT(dims[0].dimensionType() == nix::DimensionType::Range);
    CPPUNIT_ASSERT(dims[1].dimensionType() == nix::DimensionType::Range);
    dims = array2.dimensions();
    CPPUNIT_ASSERT(dims.size() == 5);
    CPPUNIT_ASSERT(dims[0].dimensionType() == nix::DimensionType::Sample);
    CPPUNIT_ASSERT(dims[1].dimensionType() == nix::DimensionType::Set);
    CPPUNIT_ASSERT(dims[2].dimensionType() == nix::DimensionType::Range);
    CPPUNIT_ASSERT(dims[3].dimensionType() == nix::DimensionType::Range);
    CPPUNIT_ASSERT(dims[4].dimensionType() == nix::DimensionType::Set);

    // since deleteDimension renumbers indices to be continuous we test that too
    array2.deleteDimension(5);
    array2.deleteDimension(4);
    array2.deleteDimension(1);
    array2.deleteDimension(1);
    array2.deleteDimension(1);

    dims = array2.dimensions();
    CPPUNIT_ASSERT(array2.dimensionCount() == 0);
    CPPUNIT_ASSERT(dims.size() == 0);
}

void TestDataArray::testOperator()
{
    std::stringstream mystream;
    mystream << array1;

    array1 = none;
    CPPUNIT_ASSERT(array1 == false);
    CPPUNIT_ASSERT(array1 == none);
}
<commit_msg>[test] checks for expansionOrigin (+ polynomial)<commit_after>// Copyright © 2014 German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.
//
// Author: Christian Kellner <kellner@bio.lmu.de>

#include "TestDataArray.hpp"

#include <nix/util/util.hpp>
#include <nix/valid/validate.hpp>

#include <cstdint>

using namespace nix;
using namespace valid;

void TestDataArray::setUp()
{
    startup_time = time(NULL);
    file = nix::File::open("test_DataArray.h5", nix::FileMode::Overwrite);

    block = file.createBlock("block_one", "dataset");
    array1 = block.createDataArray("array_one",
                                   "testdata",
                                   nix::DataType::Double,
                                   nix::NDSize({ 0, 0, 0 }));
    array2 = block.createDataArray("random",
                                   "double",
                                   nix::DataType::Double,
                                   nix::NDSize({ 20, 20 }));
}

void TestDataArray::tearDown()
{
    file.close();
}

void TestDataArray::testValidate() {
    // dims are not equal data dims: 1 warning
    valid::Result result = validate(array1);
    CPPUNIT_ASSERT(result.getErrors().size() == 0);
    CPPUNIT_ASSERT(result.getWarnings().size() == 1);
}

void TestDataArray::testId() {
    CPPUNIT_ASSERT(array1.id().size() == 36);
}

void TestDataArray::testName() {
    CPPUNIT_ASSERT(array1.name() == "array_one");
}

void TestDataArray::testType() {
    CPPUNIT_ASSERT(array1.type() == "testdata");
    std::string typ = nix::util::createId();
    array1.type(typ);
    CPPUNIT_ASSERT(array1.type() == typ);
}

void TestDataArray::testDefinition() {
    std::string def = nix::util::createId();
    array1.definition(def);
    CPPUNIT_ASSERT(*array1.definition() == def);
    array1.definition(boost::none);
    CPPUNIT_ASSERT(array1.definition() == nix::none);
}

void TestDataArray::testData()
{
    typedef boost::multi_array<double, 3> array_type;
    typedef array_type::index index;
    array_type A(boost::extents[3][4][2]);

    int values = 0;
    for(index i = 0; i != 3; ++i)
        for(index j = 0; j != 4; ++j)
            for(index k = 0; k != 2; ++k)
                A[i][j][k] = values++;

    CPPUNIT_ASSERT_EQUAL(array1.dataType(), nix::DataType::Double);
    CPPUNIT_ASSERT_EQUAL(array1.dataExtent(), nix::NDSize({0, 0, 0}));
    CPPUNIT_ASSERT(array1.getDimension(1) == false);

    array1.setData(A);

    array_type B(boost::extents[1][1][1]);
    array1.getData(B);

    int verify = 0;
    int errors = 0;
    for(index i = 0; i != 3; ++i) {
        for(index j = 0; j != 4; ++j) {
            for(index k = 0; k != 2; ++k) {
                int v = verify++;
                errors += B[i][j][k] != v;
            }
        }
    }

    CPPUNIT_ASSERT_EQUAL(errors, 0);

    DataArray direct = block.createDataArray("da_direct", "double", A);
    array_type Adirect(boost::extents[3][4][2]);
    direct.getData(Adirect);

    errors = 0;
    verify = 0;
    for(index i = 0; i != 3; ++i) {
        for(index j = 0; j != 4; ++j) {
            for(index k = 0; k != 2; ++k) {
                int v = verify++;
                errors += Adirect[i][j][k] != v;
            }
        }
    }

    CPPUNIT_ASSERT_EQUAL(0, errors);

    typedef boost::multi_array<double, 2> array2D_type;
    typedef array_type::index index;
    array2D_type C(boost::extents[5][5]);

    for(index i = 0; i != 5; ++i)
        for(index j = 0; j != 5; ++j)
            C[i][j] = 42.0;

    CPPUNIT_ASSERT_EQUAL(array2.dataExtent(), nix::NDSize({20, 20}));

    array2.setData(C, nix::NDSize({0, 0}));
    array2.dataExtent(nix::NDSize({40, 40}));
    CPPUNIT_ASSERT_EQUAL(array2.dataExtent(), nix::NDSize({40, 40}));

    array2D_type D(boost::extents[5][5]);
    for(index i = 0; i != 5; ++i)
        for(index j = 0; j != 5; ++j)
            D[i][j] = 42.0;

        array2.setData(D, nix::NDSize({ 20, 20 }));

    array2D_type E(boost::extents[1][1]);
    array2.getData(E, nix::NDSize({ 5, 5 }), nix::NDSize({ 20, 20 }));

    for(index i = 0; i != 5; ++i)
        for(index j = 0; j != 5; ++j)
            CPPUNIT_ASSERT_DOUBLES_EQUAL(D[i][j], E[i][j],
                std::numeric_limits<double>::epsilon());

    array2D_type F(boost::extents[5][5]);

    array2.getData(F, nix::NDSize({ 20, 20 }));

    for(index i = 0; i != 5; ++i)
        for(index j = 0; j != 5; ++j)
            CPPUNIT_ASSERT_DOUBLES_EQUAL(D[i][j], F[i][j],
                std::numeric_limits<double>::epsilon());

    nix::DataArray da3 = block.createDataArray("direct-vector",
                                               "double",
                                               nix::DataType::Double,
                                               nix::NDSize({5}));

    CPPUNIT_ASSERT(da3.dataExtent() == nix::NDSize{5});
    CPPUNIT_ASSERT(da3.getDimension(1) == false);

    std::vector<double> dv = {1.0, 2.0, 3.0, 4.0, 5.0};
    da3.setData(nix::DataType::Double, dv.data(), nix::NDSize({ 5 }), nix::NDSize({ 0 }));

    std::vector<double> dvin;
    dvin.resize(5);
    da3.getData(nix::DataType::Double, dvin.data(), nix::NDSize({ 5 }), nix::NDSize({ 0 }));

    for(size_t i = 0; i < dvin.size(); i++) {
        CPPUNIT_ASSERT_DOUBLES_EQUAL(dv[i], dvin[i],
                                     std::numeric_limits<double>::epsilon());
    }
}

void TestDataArray::testPolynomial()
{
    double PI = boost::math::constants::pi<double>();
    boost::array<double, 10> coefficients1;
    std::vector<double> coefficients2;
    for(int i=0; i<10; i++) {
        coefficients1[i] = i;
        coefficients2.push_back(i);
    }

    double res1 = util::applyPolynomial(coefficients2, 0, PI);
    double res2 = boost::math::tools::evaluate_polynomial(coefficients1, PI);

    //evalutate_polynomial from boost might use a different algorithm
    //therefore we raise the allowed detlta to 10e-10
    CPPUNIT_ASSERT_DOUBLES_EQUAL(res1, res2, 10e-10);

    array2.polynomCoefficients(coefficients2);
    std::vector<double> ret = array2.polynomCoefficients();
    for(size_t i=0; i<ret.size(); i++) {
        CPPUNIT_ASSERT(ret[i] == coefficients2[i]);
    }

    array2.polynomCoefficients(nix::none);
    CPPUNIT_ASSERT(array2.polynomCoefficients().size() == 0);

    array2.expansionOrigin(3);
    boost::optional<double> retval = array2.expansionOrigin();
    CPPUNIT_ASSERT(*retval == 3);
    array2.expansionOrigin(nix::none);
    CPPUNIT_ASSERT(array2.expansionOrigin() == nix::none);

    //test IO with a polynomial set
    nix::DataArray dap = block.createDataArray("polyio",
                                               "double",
                                               nix::DataType::Double,
                                               nix::NDSize({2, 3}));

    std::vector<double> dv = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};
    dap.setData(nix::DataType::Double, dv.data(), nix::NDSize({2, 3}), nix::NDSize({0, 0}));

    std::vector<double> poly = {1.0, 2.0, 3.0};
    dap.polynomCoefficients(poly);

    std::vector<int32_t> dvin_poly;
    dvin_poly.resize(2*3);
    dap.getData(DataType::Int32, dvin_poly.data(), nix::NDSize({2, 3}), nix::NDSize({0, 0}));

    // reference data generated with MATLAB(c) as folows:
    // p = [3, 2, 1]
    // polyval(p, [1, 2, 3, 4, 5, 6])
    // ans =
    // 6    17    34    57    86   121
    std::vector<int32_t> ref = {6, 17, 34, 57, 86, 121};

    CPPUNIT_ASSERT_EQUAL(ref.size(), dvin_poly.size());
    for (size_t i = 0; i < dvin_poly.size(); i++) {
        CPPUNIT_ASSERT_EQUAL(ref[i], dvin_poly[i]);
    }

    //poly + expansionOrigin
    const double origin = 4.0;
    dap.expansionOrigin(origin);
    dap.getData(DataType::Int32, dvin_poly.data(), nix::NDSize({2, 3}), nix::NDSize({0, 0}));
    // polyval(p, [1,2,3,4,5,6]-4)
    // ans =  22     9     2     1     6    17
    std::vector<int32_t> ref_eop = {22, 9, 2, 1, 6, 17};

    CPPUNIT_ASSERT_EQUAL(ref_eop.size(), dvin_poly.size());
    for (size_t i = 0; i < dvin_poly.size(); i++) {
        CPPUNIT_ASSERT_EQUAL(ref_eop[i], dvin_poly[i]);
    }

    // expansionOrigin alone
    dap.polynomCoefficients(boost::none);
    dap.getData(DataType::Int32, dvin_poly.data(), nix::NDSize({2, 3}), nix::NDSize({0, 0}));
    CPPUNIT_ASSERT_EQUAL(dv.size(), dvin_poly.size());
    for (size_t i = 0; i < dvin_poly.size(); i++) {
        CPPUNIT_ASSERT_EQUAL(static_cast<int32_t >(dv[i]-origin), dvin_poly[i]);
    }
}

void TestDataArray::testLabel()
{
    std::string testStr = "somestring";

    array1.label(testStr);
    CPPUNIT_ASSERT(*array1.label() == testStr);
    array1.label(boost::none);
    CPPUNIT_ASSERT(array1.label() == nix::none);
}

void TestDataArray::testUnit()
{
    std::string testStr = "somestring";
    std::string validUnit = "mV^2";

    CPPUNIT_ASSERT_THROW(array1.unit(testStr), nix::InvalidUnit);
    CPPUNIT_ASSERT_NO_THROW(array1.unit(validUnit));
    CPPUNIT_ASSERT(array1.unit() == validUnit);
    CPPUNIT_ASSERT_NO_THROW(array1.unit(boost::none));
    CPPUNIT_ASSERT(array1.unit() == nix::none);
}

void TestDataArray::testDimension()
{
    std::vector<nix::Dimension> dims;
    std::vector<double> ticks;
    double samplingInterval = boost::math::constants::pi<double>();

    for(size_t i = 0; i < 5; i++) {
        ticks.push_back(i * boost::math::constants::pi<double>());
    }

    dims.push_back(array2.createSampledDimension(1, samplingInterval));
    dims.push_back(array2.createSetDimension(2));
    dims.push_back(array2.createRangeDimension(3, ticks));
    dims.push_back(array2.appendSampledDimension(samplingInterval));
    dims.push_back(array2.appendSetDimension());
    dims[3] = array2.createRangeDimension(4, ticks);

    // have some explicit dimension types
    nix::RangeDimension dim_range = array1.appendRangeDimension(ticks);
    nix::SampledDimension dim_sampled = array1.appendSampledDimension(samplingInterval);
    nix::SetDimension dim_set = array1.appendSetDimension();

    CPPUNIT_ASSERT(array2.getDimension(dims[0].index()).dimensionType() == nix::DimensionType::Sample);
    CPPUNIT_ASSERT(array2.getDimension(dims[1].index()).dimensionType() == nix::DimensionType::Set);
    CPPUNIT_ASSERT(array2.getDimension(dims[2].index()).dimensionType() == nix::DimensionType::Range);
    CPPUNIT_ASSERT(array2.getDimension(dims[3].index()).dimensionType() == nix::DimensionType::Range);
    CPPUNIT_ASSERT(array2.getDimension(dims[4].index()).dimensionType() == nix::DimensionType::Set);

    CPPUNIT_ASSERT(array2.dimensionCount() == 5);

    dims = array2.dimensions([](nix::Dimension dim) { return dim.dimensionType() == nix::DimensionType::Sample; });
    CPPUNIT_ASSERT(dims.size() == 1);
    CPPUNIT_ASSERT(dims[0].dimensionType() == nix::DimensionType::Sample);
    dims = array2.dimensions([](nix::Dimension dim) { return dim.dimensionType() == nix::DimensionType::Set; });
    CPPUNIT_ASSERT(dims.size() == 2);
    CPPUNIT_ASSERT(dims[0].dimensionType() == nix::DimensionType::Set);
    CPPUNIT_ASSERT(dims[1].dimensionType() == nix::DimensionType::Set);
    dims = array2.dimensions([](nix::Dimension dim) { return dim.dimensionType() == nix::DimensionType::Range; });
    CPPUNIT_ASSERT(dims.size() == 2);
    CPPUNIT_ASSERT(dims[0].dimensionType() == nix::DimensionType::Range);
    CPPUNIT_ASSERT(dims[1].dimensionType() == nix::DimensionType::Range);
    dims = array2.dimensions();
    CPPUNIT_ASSERT(dims.size() == 5);
    CPPUNIT_ASSERT(dims[0].dimensionType() == nix::DimensionType::Sample);
    CPPUNIT_ASSERT(dims[1].dimensionType() == nix::DimensionType::Set);
    CPPUNIT_ASSERT(dims[2].dimensionType() == nix::DimensionType::Range);
    CPPUNIT_ASSERT(dims[3].dimensionType() == nix::DimensionType::Range);
    CPPUNIT_ASSERT(dims[4].dimensionType() == nix::DimensionType::Set);

    // since deleteDimension renumbers indices to be continuous we test that too
    array2.deleteDimension(5);
    array2.deleteDimension(4);
    array2.deleteDimension(1);
    array2.deleteDimension(1);
    array2.deleteDimension(1);

    dims = array2.dimensions();
    CPPUNIT_ASSERT(array2.dimensionCount() == 0);
    CPPUNIT_ASSERT(dims.size() == 0);
}

void TestDataArray::testOperator()
{
    std::stringstream mystream;
    mystream << array1;

    array1 = none;
    CPPUNIT_ASSERT(array1 == false);
    CPPUNIT_ASSERT(array1 == none);
}
<|endoftext|>


<commit_before>#include "PythonParser.h"

PythonParser::PythonParser(std::shared_ptr<StorageInterface> storage, std::shared_ptr<const std::vector<ColumnMeta> > metadatas) {
    this->metas = metadatas;
    this->parsers = std::vector<UnitParser*>(metadatas->size());
    uint32_t meta_i = 0;
    for (const ColumnMeta CM : *metadatas) {
        if (CM.type && CASS_VALUE_TYPE_INT) {
            parsers[meta_i] = new Int32Parser(CM);
        }
        else if (CM.type && (CASS_VALUE_TYPE_BIGINT || CASS_VALUE_TYPE_BIGINT )) {
            parsers[meta_i] = new Int64Parser(CM);
        }
        else if (CM.type && CASS_VALUE_TYPE_BOOLEAN) {
            parsers[meta_i] = new BoolParser(CM);
        }
        else if (CM.type && (CASS_VALUE_TYPE_TEXT || CASS_VALUE_TYPE_VARCHAR ||  CASS_VALUE_TYPE_ASCII)) {
            parsers[meta_i] = new TextParser(CM);
        }
        else if (CM.type && CASS_VALUE_TYPE_BLOB) {
            parsers[meta_i] = new BytesParser(CM);
        }
        else if (CM.type && (CASS_VALUE_TYPE_DOUBLE||CASS_VALUE_TYPE_FLOAT)) {
            parsers[meta_i] = new DoubleParser(CM);
        }
        else if (CM.type && CASS_VALUE_TYPE_UUID) {
            parsers[meta_i] = new UuidParser(CM);
        }
        else if (CM.type && CASS_VALUE_TYPE_SMALL_INT) {
            parsers[meta_i] = new Int16Parser(CM);
        }
        else if (CM.type && CASS_VALUE_TYPE_TINY_INT) {
            parsers[meta_i] = new Int8Parser(CM);
        }
        else if (CM.info.find("table") != CM.info.end()) {
            NumpyParser *NP = new NumpyParser(CM);
            NP->setStorage(storage);
            parsers[meta_i] = NP;
        }
        else parsers[meta_i]= new UnitParser(CM);
        ++meta_i;
    }
}

PythonParser::~PythonParser() {
    for (UnitParser *parser : this->parsers) {
        delete(parser);
    }
}
/*** TUPLE BUILDERS ***/

/***
 * Build a tuple from the given Python object using the stored metadata
 * @param obj Python List containing exactly the same number of objects that parsers/metadata sued
 * to setup the PythonParser
 * @return TupleRow with a copy of the values in obj
 * @post The python object can be garbage collected
 */
TupleRow *PythonParser::make_tuple(PyObject* obj) const {
    if (!PyList_Check(obj)) throw ModuleException("PythonParser: Make tuple: Expected python list");
    if (size_t(PyList_Size(obj))!=parsers.size())
        throw ModuleException("PythonParser: Got less python elements than columns configured");

    uint32_t total_bytes = metas->at(metas->size()-1).position+metas->at(metas->size()-1).size;
    char *buffer = (char *) malloc(total_bytes);
    TupleRow *new_tuple = new TupleRow(metas, total_bytes, buffer);

    for (uint32_t i = 0; i < PyList_Size(obj); ++i) {
        PyObject* some = PyList_GetItem(obj, i);
        if (this->parsers[i]->py_to_c(some, buffer+metas->at(i).position)<0) new_tuple->setNull(i);
    }
    return new_tuple;
}

/***
 * Builds a Python list from the data being held inside the TupleRow
 * @param tuple
 * @return A list with the information from tuple preserving its order
 */
PyObject *PythonParser::make_pylist(std::vector<const TupleRow *> &values) const {
    //TODO design behaviour, should we expect N tuples or just one?
    const TupleRow *tuple = values[0];
    if (tuple == nullptr)
        throw ModuleException("PythonParser: Marshalling from c to python a NULL tuple, unsupported");
    if (tuple->n_elem() != parsers.size())
        throw ModuleException("PythonParser: Found " + std::to_string(tuple->n_elem()) +
                              " elements from a max of " + std::to_string(parsers.size()));

    PyObject *list = PyList_New(tuple->n_elem());
    for (uint16_t i = 0; i < tuple->n_elem(); i++) {
        PyList_SetItem(list, i, this->parsers[i]->c_to_py(tuple->get_element(i)));
    }
    return list;
}
<commit_msg>Ammend PythonParser assignations of UnitParsers<commit_after>#include "PythonParser.h"

PythonParser::PythonParser(std::shared_ptr<StorageInterface> storage, std::shared_ptr<const std::vector<ColumnMeta> > metadatas) {
    this->metas = metadatas;
    this->parsers = std::vector<UnitParser*>(metadatas->size());
    uint32_t meta_i = 0;
    for (const ColumnMeta CM : *metadatas) {
        if (CM.type == CASS_VALUE_TYPE_INT) {
            parsers[meta_i] = new Int32Parser(CM);
        }
        else if (CM.type == CASS_VALUE_TYPE_BIGINT || CM.type == CASS_VALUE_TYPE_VARINT) {
            parsers[meta_i] = new Int64Parser(CM);
        }
        else if (CM.type == CASS_VALUE_TYPE_BOOLEAN) {
            parsers[meta_i] = new BoolParser(CM);
        }
        else if (CM.type == CASS_VALUE_TYPE_TEXT || CM.type == CASS_VALUE_TYPE_VARCHAR || CM.type ==  CASS_VALUE_TYPE_ASCII) {
            parsers[meta_i] = new TextParser(CM);
        }
        else if (CM.type == CASS_VALUE_TYPE_BLOB) {
            parsers[meta_i] = new BytesParser(CM);
        }
        else if (CM.type == CASS_VALUE_TYPE_DOUBLE || CM.type == CASS_VALUE_TYPE_FLOAT) {
            parsers[meta_i] = new DoubleParser(CM);
        }
        else if (CM.type == CASS_VALUE_TYPE_UUID) {
            parsers[meta_i] = new UuidParser(CM);
        }
        else if (CM.type == CASS_VALUE_TYPE_SMALL_INT) {
            parsers[meta_i] = new Int16Parser(CM);
        }
        else if (CM.type == CASS_VALUE_TYPE_TINY_INT) {
            parsers[meta_i] = new Int8Parser(CM);
        }
        else if (CM.type == CASS_VALUE_TYPE_UDT && CM.info.find("table") != CM.info.end()) {
            NumpyParser *NP = new NumpyParser(CM);
            NP->setStorage(storage);
            parsers[meta_i] = NP;
        }
        else parsers[meta_i]= new UnitParser(CM);
        ++meta_i;
    }
}

PythonParser::~PythonParser() {
    for (UnitParser *parser : this->parsers) {
        delete(parser);
    }
}
/*** TUPLE BUILDERS ***/

/***
 * Build a tuple from the given Python object using the stored metadata
 * @param obj Python List containing exactly the same number of objects that parsers/metadata sued
 * to setup the PythonParser
 * @return TupleRow with a copy of the values in obj
 * @post The python object can be garbage collected
 */
TupleRow *PythonParser::make_tuple(PyObject* obj) const {
    if (!PyList_Check(obj)) throw ModuleException("PythonParser: Make tuple: Expected python list");
    if (size_t(PyList_Size(obj))!=parsers.size())
        throw ModuleException("PythonParser: Got less python elements than columns configured");

    uint32_t total_bytes = metas->at(metas->size()-1).position+metas->at(metas->size()-1).size;
    char *buffer = (char *) malloc(total_bytes);
    TupleRow *new_tuple = new TupleRow(metas, total_bytes, buffer);

    for (uint32_t i = 0; i < PyList_Size(obj); ++i) {
        PyObject* some = PyList_GetItem(obj, i);
        if (this->parsers[i]->py_to_c(some, buffer+metas->at(i).position)<0) new_tuple->setNull(i);
    }
    return new_tuple;
}

/***
 * Builds a Python list from the data being held inside the TupleRow
 * @param tuple
 * @return A list with the information from tuple preserving its order
 */
PyObject *PythonParser::make_pylist(std::vector<const TupleRow *> &values) const {
    //TODO design behaviour, should we expect N tuples or just one?
    const TupleRow *tuple = values[0];
    if (tuple == nullptr)
        throw ModuleException("PythonParser: Marshalling from c to python a NULL tuple, unsupported");
    if (tuple->n_elem() != parsers.size())
        throw ModuleException("PythonParser: Found " + std::to_string(tuple->n_elem()) +
                              " elements from a max of " + std::to_string(parsers.size()));

    PyObject *list = PyList_New(tuple->n_elem());
    for (uint16_t i = 0; i < tuple->n_elem(); i++) {
        PyList_SetItem(list, i, this->parsers[i]->c_to_py(tuple->get_element(i)));
    }
    return list;
}
<|endoftext|>