<commit_before>/*
 * bacteria-core, core for cellular automaton
 * Copyright (C) 2016 Pavel Dolgov
 *
 * See the LICENSE file for terms of use.
 */

#include <boost/test/unit_test.hpp>

#include "Model.hpp"

typedef void (Implementation::Model::*OneArgMethod) (
    const Abstract::Point& coordinates
);

typedef void (Implementation::Model::*TwoArgsMethod) (
    const Abstract::Point& coordinates,
    int change
);

typedef void (Implementation::Model::*MultiArgsMethod) (
    const Abstract::Point& coordinates,
    int mass,
    int direction,
    int team,
    int instruction
);

template<typename Func>
void checkModelMethodForThrow(
    Implementation::Model* model,
    Func model_method,
    int arg1,
    int arg2
) {
    BOOST_REQUIRE_THROW(
        ((*model).*model_method)(arg1, arg2), Exception
    );
}

template<>
void checkModelMethodForThrow<OneArgMethod>(
    Implementation::Model* model,
    OneArgMethod model_method,
    int arg1,
    int arg2
) {
    Abstract::Point coordinates(arg1, arg2);
    BOOST_REQUIRE_THROW(
        ((*model).*model_method)(coordinates), Exception
    );
}

template<typename Func>
static void checkErrorHandling(
    Implementation::Model* model,
    Func model_method
) {
    // range errors: test all combinations of
    // "wrong" (outside of correct range) arguments
    // Max_index: 0; min_index: 0
    for (int arg1 = -1; arg1 <= 1; arg1++) {
        for (int arg2 = -1; arg2 <= 1; arg2++) {
            if ((arg1 != 0) || (arg2 != 0)) {
                // (0, 0) is correct
                BOOST_REQUIRE_THROW(
                    ((*model).*model_method)(arg1, arg2), Exception
                );
            }
        }
    }
    // "dead" error
    // (attempt to do something with dead bacterium)
    model->kill(0, 0);
    BOOST_REQUIRE_THROW(
        ((*model).*model_method)(0, 0), Exception
    );
}

#define CREATE_NEW \
    model->createNewByCoordinates( \
        coordinates, \
        DEFAULT_MASS, \
        0, \
        0, \
        0 \
    );

static Abstract::Point createInBaseCoordinates(
    Implementation::Model* model
) {
    Abstract::Point coordinates(0, 0);
    CREATE_NEW
    return coordinates;
}

static void createByCoordinates(
    Implementation::Model* model,
    Abstract::Point coordinates
) {
    CREATE_NEW
}

#undef CREATE_NEW

static Implementation::Model* createBaseModel(
    int bacteria = 0,
    int teams = 1
) {
    Implementation::Model* model =
        Abstract::makeModel<Implementation::Model>(
            MIN_WIDTH,
            MIN_HEIGHT,
            bacteria,
            teams
        );
    return model;
}

BOOST_AUTO_TEST_CASE (bacteria_number_test) {
    Implementation::Model* model = createBaseModel();
    int bacteria_number = model->getBacteriaNumber(0);
    BOOST_REQUIRE(bacteria_number == 0);
    createInBaseCoordinates(model);
    bacteria_number = model->getBacteriaNumber(0);
    BOOST_REQUIRE(bacteria_number == 1);
    // range errors
    BOOST_REQUIRE_THROW(model->getBacteriaNumber(-1), Exception);
    BOOST_REQUIRE_THROW(model->getBacteriaNumber(1), Exception);
    delete model;
}

BOOST_AUTO_TEST_CASE (get_mass_test) {
    Implementation::Model* model = createBaseModel(1, 1);
    int mass = model->getMass(0, 0);
    BOOST_REQUIRE(mass == DEFAULT_MASS);
    checkErrorHandling(model, &Implementation::Model::getMass);
    delete model;
}

BOOST_AUTO_TEST_CASE (height_test) {
    Implementation::Model* model = createBaseModel();
    BOOST_REQUIRE(model->getHeight() == MIN_HEIGHT);
    delete model;
}

BOOST_AUTO_TEST_CASE (width_test) {
    Implementation::Model* model = createBaseModel();
    BOOST_REQUIRE(model->getWidth() == MIN_WIDTH);
    delete model;
}

BOOST_AUTO_TEST_CASE (kill_test) {
    Implementation::Model* model = createBaseModel();
    Abstract::Point coordinates = createInBaseCoordinates(model);
    model->kill(0, 0);
    Abstract::CellState state = model->cellState(coordinates);
    BOOST_REQUIRE(state == Abstract::EMPTY);
    // error handling checks
    createInBaseCoordinates(model);
    // FIXME test doesn't work correctly without this function call.
    // The solution is to use set instead of vector in model.
    model->clearBeforeMove(0);
    checkErrorHandling(model, &Implementation::Model::kill);
    delete model;
}

BOOST_AUTO_TEST_CASE (create_coordinates_test) {
    Implementation::Model* model = createBaseModel();
    Abstract::Point coordinates = createInBaseCoordinates(model);
    Abstract::CellState state = model->cellState(coordinates);
    BOOST_REQUIRE(state == Abstract::BACTERIUM);
    delete model;
}

BOOST_AUTO_TEST_CASE (kill_coordinates_test) {
    Implementation::Model* model = createBaseModel();
    Abstract::Point coordinates = createInBaseCoordinates(model);
    model->killByCoordinates(coordinates);
    Abstract::CellState state = model->cellState(coordinates);
    BOOST_REQUIRE(state == Abstract::EMPTY);
    delete model;
}
<commit_msg>Implement checkModelMethodForThrow <TwoArgsMethod><commit_after>/*
 * bacteria-core, core for cellular automaton
 * Copyright (C) 2016 Pavel Dolgov
 *
 * See the LICENSE file for terms of use.
 */

#include <boost/test/unit_test.hpp>

#include "Model.hpp"

typedef void (Implementation::Model::*OneArgMethod) (
    const Abstract::Point& coordinates
);

typedef void (Implementation::Model::*TwoArgsMethod) (
    const Abstract::Point& coordinates,
    int change
);

typedef void (Implementation::Model::*MultiArgsMethod) (
    const Abstract::Point& coordinates,
    int mass,
    int direction,
    int team,
    int instruction
);

template<typename Func>
void checkModelMethodForThrow(
    Implementation::Model* model,
    Func model_method,
    int arg1,
    int arg2
) {
    BOOST_REQUIRE_THROW(
        ((*model).*model_method)(arg1, arg2), Exception
    );
}

template<>
void checkModelMethodForThrow<OneArgMethod>(
    Implementation::Model* model,
    OneArgMethod model_method,
    int arg1,
    int arg2
) {
    Abstract::Point coordinates(arg1, arg2);
    BOOST_REQUIRE_THROW(
        ((*model).*model_method)(coordinates), Exception
    );
}

template<>
void checkModelMethodForThrow<TwoArgsMethod>(
    Implementation::Model* model,
    TwoArgsMethod model_method,
    int arg1,
    int arg2
) {
    Abstract::Point coordinates(arg1, arg2);
    BOOST_REQUIRE_THROW(
        ((*model).*model_method)(coordinates, 0), Exception
    );
}

template<typename Func>
static void checkErrorHandling(
    Implementation::Model* model,
    Func model_method
) {
    // range errors: test all combinations of
    // "wrong" (outside of correct range) arguments
    // Max_index: 0; min_index: 0
    for (int arg1 = -1; arg1 <= 1; arg1++) {
        for (int arg2 = -1; arg2 <= 1; arg2++) {
            if ((arg1 != 0) || (arg2 != 0)) {
                // (0, 0) is correct
                BOOST_REQUIRE_THROW(
                    ((*model).*model_method)(arg1, arg2), Exception
                );
            }
        }
    }
    // "dead" error
    // (attempt to do something with dead bacterium)
    model->kill(0, 0);
    BOOST_REQUIRE_THROW(
        ((*model).*model_method)(0, 0), Exception
    );
}

#define CREATE_NEW \
    model->createNewByCoordinates( \
        coordinates, \
        DEFAULT_MASS, \
        0, \
        0, \
        0 \
    );

static Abstract::Point createInBaseCoordinates(
    Implementation::Model* model
) {
    Abstract::Point coordinates(0, 0);
    CREATE_NEW
    return coordinates;
}

static void createByCoordinates(
    Implementation::Model* model,
    Abstract::Point coordinates
) {
    CREATE_NEW
}

#undef CREATE_NEW

static Implementation::Model* createBaseModel(
    int bacteria = 0,
    int teams = 1
) {
    Implementation::Model* model =
        Abstract::makeModel<Implementation::Model>(
            MIN_WIDTH,
            MIN_HEIGHT,
            bacteria,
            teams
        );
    return model;
}

BOOST_AUTO_TEST_CASE (bacteria_number_test) {
    Implementation::Model* model = createBaseModel();
    int bacteria_number = model->getBacteriaNumber(0);
    BOOST_REQUIRE(bacteria_number == 0);
    createInBaseCoordinates(model);
    bacteria_number = model->getBacteriaNumber(0);
    BOOST_REQUIRE(bacteria_number == 1);
    // range errors
    BOOST_REQUIRE_THROW(model->getBacteriaNumber(-1), Exception);
    BOOST_REQUIRE_THROW(model->getBacteriaNumber(1), Exception);
    delete model;
}

BOOST_AUTO_TEST_CASE (get_mass_test) {
    Implementation::Model* model = createBaseModel(1, 1);
    int mass = model->getMass(0, 0);
    BOOST_REQUIRE(mass == DEFAULT_MASS);
    checkErrorHandling(model, &Implementation::Model::getMass);
    delete model;
}

BOOST_AUTO_TEST_CASE (height_test) {
    Implementation::Model* model = createBaseModel();
    BOOST_REQUIRE(model->getHeight() == MIN_HEIGHT);
    delete model;
}

BOOST_AUTO_TEST_CASE (width_test) {
    Implementation::Model* model = createBaseModel();
    BOOST_REQUIRE(model->getWidth() == MIN_WIDTH);
    delete model;
}

BOOST_AUTO_TEST_CASE (kill_test) {
    Implementation::Model* model = createBaseModel();
    Abstract::Point coordinates = createInBaseCoordinates(model);
    model->kill(0, 0);
    Abstract::CellState state = model->cellState(coordinates);
    BOOST_REQUIRE(state == Abstract::EMPTY);
    // error handling checks
    createInBaseCoordinates(model);
    // FIXME test doesn't work correctly without this function call.
    // The solution is to use set instead of vector in model.
    model->clearBeforeMove(0);
    checkErrorHandling(model, &Implementation::Model::kill);
    delete model;
}

BOOST_AUTO_TEST_CASE (create_coordinates_test) {
    Implementation::Model* model = createBaseModel();
    Abstract::Point coordinates = createInBaseCoordinates(model);
    Abstract::CellState state = model->cellState(coordinates);
    BOOST_REQUIRE(state == Abstract::BACTERIUM);
    delete model;
}

BOOST_AUTO_TEST_CASE (kill_coordinates_test) {
    Implementation::Model* model = createBaseModel();
    Abstract::Point coordinates = createInBaseCoordinates(model);
    model->killByCoordinates(coordinates);
    Abstract::CellState state = model->cellState(coordinates);
    BOOST_REQUIRE(state == Abstract::EMPTY);
    delete model;
}
<|endoftext|>


<commit_before>#include "AmsFont.h"
#include "constants.h"

const int CHAR_SIZE  = 24;
const int MAX_COLUMN = SCREEN_W / CHAR_SIZE;
const int MAX_LINE   = SCREEN_H / CHAR_SIZE;

AmsFont::AmsFont(char* fileName) {
	font = SDL_LoadBMP(fileName);
	SDL_Surface* surface = SDL_CreateRGBSurface(0, SCREEN_W, SCREEN_H, 32, 0, 0, 0, 0);
	ctx = new RenderingContext(surface);
	_x = 0;
	_y = 0;
	_clearRect = SDL_CreateRGBSurface(SDL_HWSURFACE, CHAR_SIZE, CHAR_SIZE, 32, 0, 0, 0, 0);
}

AmsFont::~AmsFont() {
	delete ctx;
	SDL_FreeSurface(_clearRect);
}

SDL_Surface* AmsFont::get() {
	SDL_SetColorKey(ctx->getContext(), SDL_SRCCOLORKEY, SDL_MapRGB(ctx->getContext()->format, 0, 0, 0));
	return ctx->getContext();
};

void AmsFont::locate(int x, int y) {
	_x = x;
	_y = y;
}

void AmsFont::print(char* text) {
	while (*text) {
		int c = *text;
		text++;

		if (c == '\n') {
			_x = 0;
			_y++;
			continue;
		}

		int sourceX = (c % 16) * CHAR_SIZE;
		int sourceY = (c / 16) * CHAR_SIZE;
		int destX = _x * CHAR_SIZE;
		int destY = _y * CHAR_SIZE;

		// clear character background
		_clearPos.x = destX;
		_clearPos.y = destY;
		SDL_BlitSurface(_clearRect, NULL, ctx->getContext(), &_clearPos);
		ctx->drawImage(font, sourceX, sourceY, CHAR_SIZE, CHAR_SIZE, destX, destY);

		if (++_x >= MAX_COLUMN) {
			_x = 0;
			if (++_y > MAX_LINE) {
				_y--;
				scroll(1);
			}
		}
	}
}

void AmsFont::scroll(int) {
	// save current
	// TODO
}
<commit_msg>colored paper<commit_after>#include "AmsFont.h"
#include "constants.h"

const int CHAR_SIZE  = 24;
const int MAX_COLUMN = SCREEN_W / CHAR_SIZE;
const int MAX_LINE   = SCREEN_H / CHAR_SIZE;

AmsFont::AmsFont(char* fileName) {
	font = SDL_LoadBMP(fileName);
	SDL_Surface* surface = SDL_CreateRGBSurface(0, SCREEN_W, SCREEN_H, 32, 0, 0, 0, 0);
	ctx = new RenderingContext(surface);
	_x = 0;
	_y = 0;
	_clearRect = SDL_CreateRGBSurface(SDL_HWSURFACE, CHAR_SIZE, CHAR_SIZE, 32, 0, 0, 0, 0);
}

AmsFont::~AmsFont() {
	delete ctx;
	SDL_FreeSurface(_clearRect);
}

SDL_Surface* AmsFont::get() {
	SDL_SetColorKey(ctx->getContext(), SDL_SRCCOLORKEY, SDL_MapRGB(ctx->getContext()->format, 0, 0, 0));
	return ctx->getContext();
};

void AmsFont::locate(int x, int y) {
	_x = x;
	_y = y;
}

void AmsFont::print(char* text) {
	while (*text) {
		int c = *text;
		text++;

		if (c == '\n') {
			_x = 0;
			_y++;
			continue;
		}

		int sourceX = (c % 16) * CHAR_SIZE;
		int sourceY = (c / 16) * CHAR_SIZE;
		int destX = _x * CHAR_SIZE;
		int destY = _y * CHAR_SIZE;

		// clear character background
		_clearPos.x = destX;
		_clearPos.y = destY;
		SDL_FillRect(_clearRect, NULL, SDL_MapRGB(ctx->getContext()->format, 255, 5, 5));
		SDL_BlitSurface(_clearRect, NULL, ctx->getContext(), &_clearPos);
		ctx->drawImage(font, sourceX, sourceY, CHAR_SIZE, CHAR_SIZE, destX, destY);

		if (++_x >= MAX_COLUMN) {
			_x = 0;
			if (++_y > MAX_LINE) {
				_y--;
				scroll(1);
			}
		}
	}
}

void AmsFont::scroll(int) {
	// save current
	// TODO
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2015 Stefan Tröger <stefantroeger@gmx.net>              *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 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 Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# include <QMessageBox>
#include <QMenu>
#endif

#include "ViewProviderPipe.h"
//#include "TaskPipeParameters.h"
#include "TaskPipeParameters.h"
#include <Mod/PartDesign/App/Body.h>
#include <Mod/PartDesign/App/FeaturePipe.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Gui/Control.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
#include <Gui/BitmapFactory.h>
#include <TopExp.hxx>
#include <TopTools_IndexedMapOfShape.hxx>

using namespace PartDesignGui;

PROPERTY_SOURCE(PartDesignGui::ViewProviderPipe,PartDesignGui::ViewProvider)

ViewProviderPipe::ViewProviderPipe()
{
}

ViewProviderPipe::~ViewProviderPipe()
{
}

std::vector<App::DocumentObject*> ViewProviderPipe::claimChildren(void)const
{
    std::vector<App::DocumentObject*> temp;

    PartDesign::Pipe* pcPipe = static_cast<PartDesign::Pipe*>(getObject());

    App::DocumentObject* sketch = pcPipe->getVerifiedSketch(true);
    if (sketch != NULL)
        temp.push_back(sketch);

    App::DocumentObject* spine = pcPipe->Spine.getValue();
    if (spine != NULL)
        temp.push_back(spine);

    App::DocumentObject* auxspine = pcPipe->AuxillerySpine.getValue();
    if (auxspine != NULL)
        temp.push_back(auxspine);

    return temp;
}

void ViewProviderPipe::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
{
    QAction* act;
    act = menu->addAction(QObject::tr("Edit pipe"), receiver, member);
    act->setData(QVariant((int)ViewProvider::Default));
}

bool ViewProviderPipe::doubleClicked(void)
{
    Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().setEdit('%s',0)",this->pcObject->getNameInDocument());
    return true;
}

bool ViewProviderPipe::setEdit(int ModNum) {
    if (ModNum == ViewProvider::Default )
        setPreviewDisplayMode(true);

    return PartDesignGui::ViewProvider::setEdit(ModNum);
}

void ViewProviderPipe::unsetEdit(int ModNum) {
    setPreviewDisplayMode(false);
    PartDesignGui::ViewProvider::unsetEdit(ModNum);
}

TaskDlgFeatureParameters* ViewProviderPipe::getEditDialog() {
    return new TaskDlgPipeParameters(this, false);
}

bool ViewProviderPipe::onDelete(const std::vector<std::string> &s)
{/*
    PartDesign::Pipe* pcPipe = static_cast<PartDesign::Pipe*>(getObject());

    // get the Sketch
    Sketcher::SketchObject *pcSketch = 0;
    if (pcPipe->Sketch.getValue())
        pcSketch = static_cast<Sketcher::SketchObject*>(pcPipe->Sketch.getValue());

    // if abort command deleted the object the sketch is visible again
    if (pcSketch && Gui::Application::Instance->getViewProvider(pcSketch))
        Gui::Application::Instance->getViewProvider(pcSketch)->show();
*/
    return ViewProvider::onDelete(s);
}

void ViewProviderPipe::highlightReferences(const bool on, bool auxillery)
{
    PartDesign::Pipe* pcPipe = static_cast<PartDesign::Pipe*>(getObject());
    Part::Feature* base;
    if(!auxillery)
        base = static_cast<Part::Feature*>(pcPipe->Spine.getValue());
    else
        base = static_cast<Part::Feature*>(pcPipe->AuxillerySpine.getValue());

    if (base == NULL) return;
    PartGui::ViewProviderPart* svp = dynamic_cast<PartGui::ViewProviderPart*>(
                Gui::Application::Instance->getViewProvider(base));
    if (svp == NULL) return;

    std::vector<std::string> edges;
    if(!auxillery)
        edges = pcPipe->Spine.getSubValuesStartsWith("Edge");
    else
        edges = pcPipe->AuxillerySpine.getSubValuesStartsWith("Edge");

    if (on) {
         if (!edges.empty() && originalLineColors.empty()) {
            TopTools_IndexedMapOfShape eMap;
            TopExp::MapShapes(base->Shape.getValue(), TopAbs_EDGE, eMap);
            originalLineColors = svp->LineColorArray.getValues();
            std::vector<App::Color> colors = originalLineColors;
            colors.resize(eMap.Extent(), svp->LineColor.getValue());

            for (std::string e : edges) {
                int idx = std::stoi(e.substr(4)) - 1;
                assert ( idx >= 0 );
                if ( idx < (ssize_t) colors.size() )
                    colors[idx] = App::Color(1.0,0.0,1.0); // magenta
            }
            svp->LineColorArray.setValues(colors);
        }
    } else {
        if (!edges.empty() && !originalLineColors.empty()) {
            svp->LineColorArray.setValues(originalLineColors);
            originalLineColors.clear();
        }
    }
}

QIcon ViewProviderPipe::getIcon(void) const {
    QString str = QString::fromLatin1("PartDesign_");
    auto* prim = static_cast<PartDesign::Pipe*>(getObject());
    if(prim->getAddSubType() == PartDesign::FeatureAddSub::Additive)
        str += QString::fromLatin1("Additive_");
    else
        str += QString::fromLatin1("Subtractive_");

    str += QString::fromLatin1("Pipe.svg");
    return Gui::BitmapFactory().pixmap(str.toStdString().c_str());
}

<commit_msg>PDN: Fix Pipe claimChildren to only grab sketches<commit_after>/***************************************************************************
 *   Copyright (c) 2015 Stefan Tröger <stefantroeger@gmx.net>              *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 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 Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# include <QMessageBox>
#include <QMenu>
#endif

#include "ViewProviderPipe.h"
//#include "TaskPipeParameters.h"
#include "TaskPipeParameters.h"
#include <Mod/PartDesign/App/Body.h>
#include <Mod/PartDesign/App/FeaturePipe.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Gui/Control.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
#include <Gui/BitmapFactory.h>
#include <TopExp.hxx>
#include <TopTools_IndexedMapOfShape.hxx>

using namespace PartDesignGui;

PROPERTY_SOURCE(PartDesignGui::ViewProviderPipe,PartDesignGui::ViewProvider)

ViewProviderPipe::ViewProviderPipe()
{
}

ViewProviderPipe::~ViewProviderPipe()
{
}

std::vector<App::DocumentObject*> ViewProviderPipe::claimChildren(void)const
{
    std::vector<App::DocumentObject*> temp;

    PartDesign::Pipe* pcPipe = static_cast<PartDesign::Pipe*>(getObject());

    App::DocumentObject* sketch = pcPipe->getVerifiedSketch(true);
    if (sketch != NULL)
        temp.push_back(sketch);

    App::DocumentObject* spine = pcPipe->Spine.getValue();
    if (spine != NULL && spine->isDerivedFrom(Part::Part2DObject::getClassTypeId()))
        temp.push_back(spine);

    App::DocumentObject* auxspine = pcPipe->AuxillerySpine.getValue();
    if (auxspine != NULL && auxspine->isDerivedFrom(Part::Part2DObject::getClassTypeId()))
        temp.push_back(auxspine);

    return temp;
}

void ViewProviderPipe::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
{
    QAction* act;
    act = menu->addAction(QObject::tr("Edit pipe"), receiver, member);
    act->setData(QVariant((int)ViewProvider::Default));
}

bool ViewProviderPipe::doubleClicked(void)
{
    Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().setEdit('%s',0)",this->pcObject->getNameInDocument());
    return true;
}

bool ViewProviderPipe::setEdit(int ModNum) {
    if (ModNum == ViewProvider::Default )
        setPreviewDisplayMode(true);

    return PartDesignGui::ViewProvider::setEdit(ModNum);
}

void ViewProviderPipe::unsetEdit(int ModNum) {
    setPreviewDisplayMode(false);
    PartDesignGui::ViewProvider::unsetEdit(ModNum);
}

TaskDlgFeatureParameters* ViewProviderPipe::getEditDialog() {
    return new TaskDlgPipeParameters(this, false);
}

bool ViewProviderPipe::onDelete(const std::vector<std::string> &s)
{/*
    PartDesign::Pipe* pcPipe = static_cast<PartDesign::Pipe*>(getObject());

    // get the Sketch
    Sketcher::SketchObject *pcSketch = 0;
    if (pcPipe->Sketch.getValue())
        pcSketch = static_cast<Sketcher::SketchObject*>(pcPipe->Sketch.getValue());

    // if abort command deleted the object the sketch is visible again
    if (pcSketch && Gui::Application::Instance->getViewProvider(pcSketch))
        Gui::Application::Instance->getViewProvider(pcSketch)->show();
*/
    return ViewProvider::onDelete(s);
}

void ViewProviderPipe::highlightReferences(const bool on, bool auxillery)
{
    PartDesign::Pipe* pcPipe = static_cast<PartDesign::Pipe*>(getObject());
    Part::Feature* base;
    if(!auxillery)
        base = static_cast<Part::Feature*>(pcPipe->Spine.getValue());
    else
        base = static_cast<Part::Feature*>(pcPipe->AuxillerySpine.getValue());

    if (base == NULL) return;
    PartGui::ViewProviderPart* svp = dynamic_cast<PartGui::ViewProviderPart*>(
                Gui::Application::Instance->getViewProvider(base));
    if (svp == NULL) return;

    std::vector<std::string> edges;
    if(!auxillery)
        edges = pcPipe->Spine.getSubValuesStartsWith("Edge");
    else
        edges = pcPipe->AuxillerySpine.getSubValuesStartsWith("Edge");

    if (on) {
         if (!edges.empty() && originalLineColors.empty()) {
            TopTools_IndexedMapOfShape eMap;
            TopExp::MapShapes(base->Shape.getValue(), TopAbs_EDGE, eMap);
            originalLineColors = svp->LineColorArray.getValues();
            std::vector<App::Color> colors = originalLineColors;
            colors.resize(eMap.Extent(), svp->LineColor.getValue());

            for (std::string e : edges) {
                int idx = std::stoi(e.substr(4)) - 1;
                assert ( idx >= 0 );
                if ( idx < (ssize_t) colors.size() )
                    colors[idx] = App::Color(1.0,0.0,1.0); // magenta
            }
            svp->LineColorArray.setValues(colors);
        }
    } else {
        if (!edges.empty() && !originalLineColors.empty()) {
            svp->LineColorArray.setValues(originalLineColors);
            originalLineColors.clear();
        }
    }
}

QIcon ViewProviderPipe::getIcon(void) const {
    QString str = QString::fromLatin1("PartDesign_");
    auto* prim = static_cast<PartDesign::Pipe*>(getObject());
    if(prim->getAddSubType() == PartDesign::FeatureAddSub::Additive)
        str += QString::fromLatin1("Additive_");
    else
        str += QString::fromLatin1("Subtractive_");

    str += QString::fromLatin1("Pipe.svg");
    return Gui::BitmapFactory().pixmap(str.toStdString().c_str());
}

<|endoftext|>


<commit_before>//
// Copyright 2016 Giovanni Mels
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "NTriplesWriter.hh"

#include <utility> // std::move

namespace turtle {

	std::unique_ptr<BlankNode> NTriplesWriter::triples(const RDFList &list)
	{
		std::string id = m_idgen.generate();

		std::unique_ptr<BlankNode> head(new BlankNode(id));

		for (std::size_t i = 0; i < list.size(); i++) {
			const N3Node *node = list[i];

			std::unique_ptr<BlankNode> nestedList;
			if (const RDFList *rl = dynamic_cast<const RDFList *>(node)) {
				nestedList = triples(*rl);
				node = nestedList.get();
			}

			rawTriple(*head, RDF::first, *node);

			if (i == list.size() - 1) {
				rawTriple(*head, RDF::rest, RDF::nil);
			} else {
				std::unique_ptr<BlankNode> rest(new BlankNode(m_idgen.generate()));
				rawTriple(*head, RDF::rest, *rest);
				head = std::move(rest);
			}
		}

		return std::unique_ptr<BlankNode>(new BlankNode(id));
	}

	void NTriplesWriter::triple(const Resource &subject, const URIResource &property, const N3Node &object)
	{
		std::unique_ptr<BlankNode> sp; // prevent sp.get() getting deleted
		const Resource *s = &subject;
		if (const RDFList *list = dynamic_cast<const RDFList *>(s)) {
			if (list->empty()) {
				s = &RDF::nil;
			} else {
				sp = triples(*list);
				s = sp.get();
			}
		}

		std::unique_ptr<BlankNode> op; // prevent op.get() getting deleted
		const N3Node *o = &object;
		if (const RDFList *list = dynamic_cast<const RDFList *>(o)) {
			if (list->empty()) {
				o = &RDF::nil;
			} else {
				op = triples(*list);
				o = op.get();
			}
		}

		rawTriple(*s, property, *o);
	}

	inline void NTriplesWriter::rawTriple(const Resource &subject, const URIResource &property, const N3Node &object)
	{
		m_count++;
		subject.visit(m_formatter);
		m_outbuf->sputc(' ');
		property.visit(m_formatter);
		m_outbuf->sputc(' ');
		object.visit(m_formatter);
		m_outbuf->sputc(' ');
		m_outbuf->sputc('.');

#ifdef CTURTLE_CRLF
		m_outbuf->sputc('\r');
#endif
		m_outbuf->sputc('\n');
	}

}
<commit_msg>Fix for issue #5.<commit_after>//
// Copyright 2016 Giovanni Mels
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "NTriplesWriter.hh"

#include <utility> // std::move

namespace turtle {

	std::unique_ptr<BlankNode> NTriplesWriter::triples(const RDFList &list)
	{
		std::string id = m_idgen.generate();

		std::unique_ptr<BlankNode> head(new BlankNode(id));

		for (std::size_t i = 0; i < list.size(); i++) {
			const N3Node *node = list[i];

			std::unique_ptr<BlankNode> nestedList;
			if (const RDFList *rl = dynamic_cast<const RDFList *>(node)) {
				if (rl->empty()) {
					node = &RDF::nil;
				} else {
					nestedList = triples(*rl);
					node = nestedList.get();
				}
			}

			rawTriple(*head, RDF::first, *node);

			if (i == list.size() - 1) {
				rawTriple(*head, RDF::rest, RDF::nil);
			} else {
				std::unique_ptr<BlankNode> rest(new BlankNode(m_idgen.generate()));
				rawTriple(*head, RDF::rest, *rest);
				head = std::move(rest);
			}
		}

		return std::unique_ptr<BlankNode>(new BlankNode(id));
	}

	void NTriplesWriter::triple(const Resource &subject, const URIResource &property, const N3Node &object)
	{
		std::unique_ptr<BlankNode> sp; // prevent sp.get() getting deleted
		const Resource *s = &subject;
		if (const RDFList *list = dynamic_cast<const RDFList *>(s)) {
			if (list->empty()) {
				s = &RDF::nil;
			} else {
				sp = triples(*list);
				s = sp.get();
			}
		}

		std::unique_ptr<BlankNode> op; // prevent op.get() getting deleted
		const N3Node *o = &object;
		if (const RDFList *list = dynamic_cast<const RDFList *>(o)) {
			if (list->empty()) {
				o = &RDF::nil;
			} else {
				op = triples(*list);
				o = op.get();
			}
		}

		rawTriple(*s, property, *o);
	}

	inline void NTriplesWriter::rawTriple(const Resource &subject, const URIResource &property, const N3Node &object)
	{
		m_count++;
		subject.visit(m_formatter);
		m_outbuf->sputc(' ');
		property.visit(m_formatter);
		m_outbuf->sputc(' ');
		object.visit(m_formatter);
		m_outbuf->sputc(' ');
		m_outbuf->sputc('.');

#ifdef CTURTLE_CRLF
		m_outbuf->sputc('\r');
#endif
		m_outbuf->sputc('\n');
	}

}
<|endoftext|>


<commit_before>/*
 NUI3 - C++ cross-platform GUI framework for OpenGL based applications
 Copyright (C) 2002-2003 Sebastien Metrot

 licence: see nui3/LICENCE.TXT
 */

#include "nui.h"
#include "nuiSocket.h"
#include "nuiNetworkHost.h"

#ifdef WIN32
#include <Ws2tcpip.h>
#undef GetAddrInfo
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#endif

nuiSocket::nuiSocket(nuiSocket::SocketType Socket)
: mSocket(Socket)
{
#if (!defined _LINUX_)
  int n = 0;
  setsockopt(mSocket, SOL_SOCKET, SO_NOSIGPIPE, &n, sizeof(n));
#endif
  mNonBlocking = false;
}

bool nuiSocket::Init(int domain, int type, int protocol)
{
  mSocket = socket(domain, type, protocol);
#if (!defined _LINUX_)
  int n = 0;
  setsockopt(mSocket, SOL_SOCKET, SO_NOSIGPIPE, &n, sizeof(n));
#endif
  return mSocket >= 0;
}

nuiSocket::~nuiSocket()
{
#ifdef WIN32
  //DisconnectEx(mSocket, NULL, 0, 0);
  closesocket(mSocket);
#else
  close(mSocket);
#endif
}

nuiSocket::SocketType nuiSocket::GetSocket() const
{
  return mSocket;
}

bool nuiSocket::GetLocalHost(nuiNetworkHost& rHost) const
{
  struct sockaddr_in addr;
  socklen_t addrlen = sizeof(addr);
  int res = getsockname(mSocket, (struct sockaddr*)&addr, &addrlen);
  if (res != 0)
    return false;

  nuiNetworkHost h(addr.sin_addr.s_addr, addr.sin_port, rHost.mProtocol);
  rHost = h;
  return true;
}

bool nuiSocket::GetDistantHost(nuiNetworkHost& rHost) const
{
  struct sockaddr_in addr;
  socklen_t addrlen = sizeof(addr);
  int res = getpeername(mSocket, (struct sockaddr*)&addr, &addrlen);
  if (res != 0)
    return false;

  nuiNetworkHost h(ntohl(addr.sin_addr.s_addr), addr.sin_port, rHost.mProtocol);
  rHost = h;
  return true;
}

bool nuiSocket::IsValid() const
{
  return mSocket != -1;
}

struct addrinfo* nuiSocket::GetAddrInfo(const nuiNetworkHost& rHost) const
{
  return rHost.GetAddrInfo();
}

void nuiSocket::SetNonBlocking(bool set)
{
  if (mNonBlocking == set)
    return;

  int flags;
  mNonBlocking = set;

  /* If they have O_NONBLOCK, use the Posix way to do it */
#if defined(O_NONBLOCK)
  /* Fixme: O_NONBLOCK is defined but broken on SunOS 4.1.x and AIX 3.2.5. */
  if (-1 == (flags = fcntl(mSocket, F_GETFL, 0)))
    flags = 0;
  if (set)
    flags |= O_NONBLOCK;
  else
    flags &= ~O_NONBLOCK;
  fcntl(mSocket, F_SETFL, flags);
#else
  /* Otherwise, use the old way of doing it */
  flags = set ? 1 : 0;
  ioctl(mSocket, FIOBIO, &flags);
#endif
}

bool nuiSocket::IsNonBlocking() const
{
  return mNonBlocking;
}

void nuiSocket::SetCanReadDelegate(const EventDelegate& rDelegate)
{
  mReadDelegate = rDelegate;
}

void nuiSocket::SetCanWriteDelegate(const EventDelegate& rDelegate)
{
  mWriteDelegate = rDelegate;
}

void nuiSocket::SetReadClosedDelegate(const EventDelegate& rDelegate)
{
  mReadCloseDelegate = rDelegate;
}

void nuiSocket::SetWriteClosedDelegate(const EventDelegate& rDelegate)
{
  mWriteCloseDelegate = rDelegate;
}

void nuiSocket::OnCanRead()
{
  if (mReadDelegate)
    mReadDelegate(*this);
}

void nuiSocket::OnCanWrite()
{
  if (mWriteDelegate)
    mWriteDelegate(*this);
}

void nuiSocket::OnReadClosed()
{
  if (mReadCloseDelegate)
    mReadCloseDelegate(*this);
}

void nuiSocket::OnWriteClosed()
{
  if (mWriteCloseDelegate)
    mWriteCloseDelegate(*this);
}

#ifdef WIN32
#define W(X) WSA##X
#else
#define W(X) X
#endif

void nuiSocket::DumpError(int err) const
{
  if (!err)
    return;

  nglString error;

  switch (err)
  {
    case EACCES: error = "The destination address is a broadcast address and the socket option SO_BROADCAST is not set."; break;
    case W(EADDRINUSE): error = "The address is already in use."; break;
    case W(EADDRNOTAVAIL): error = "The specified address is not available on this machine."; break;
    case W(EAFNOSUPPORT): error = "Addresses in the specified address family cannot be used with this socket."; break;
    case W(EALREADY): error = "The socket is non-blocking and a previous connection attempt has not yet been completed."; break;
    case W(EBADF): error = "socket is not a valid descriptor."; break;
    case W(ECONNREFUSED): error = "The attempt to connect was ignored (because the target is not listening for connections) or explicitly rejected."; break;
    case W(EFAULT): error = "The address parameter specifies an area outside the process address space."; break;
    case W(EHOSTUNREACH): error = "The target host cannot be reached (e.g., down, disconnected)."; break;
    case W(EINPROGRESS): error = "The socket is non-blocking and the connection cannot be completed immediately.  It is possible to select(2) for completion by selecting the socket for writing."; break;
    case W(EINTR): error = "Its execution was interrupted by a signal."; break;
    case W(EINVAL): error = "An invalid argument was detected (e.g., address_len is not valid for the address family, the specified address family is invalid)."; break;
    case W(EISCONN): error = "The socket is already connected."; break;
    case W(ENETDOWN): error = "The local network interface is not functioning."; break;
    case W(ENETUNREACH): error = "The network isn't reachable from this host."; break;
    case W(ENOBUFS): error = "The system call was unable to allocate a needed memory buffer."; break;
    case W(ENOTSOCK): error = "socket is not a file descriptor for a socket."; break;
    case W(EOPNOTSUPP): error = "Because socket is listening, no connection is allowed."; break;
    case W(EPROTOTYPE): error = "address has a different type than the socket that is bound to the specified peer address."; break;
    case W(ETIMEDOUT): error = " Connection establishment timed out without establishing a connection."; break;
    case W(ECONNRESET): error = "Remote host reset the connection request."; break;
    default: error = "Unknown error "; error.Add(err); break;
  }

  NGL_OUT(_T("Socket Error: %s\n"), error.GetChars());
}

//////////////////////////////////////////////////////////////////
//class nuiSocketPool
#ifdef NGL_KQUEUE
nuiSocketPool::nuiSocketPool()
{
  mQueue = kqueue();
}

nuiSocketPool::~nuiSocketPool()
{
  ///
}

void nuiSocketPool::Add(nuiSocket* pSocket, TriggerMode ReadMode, TriggerMode WriteMode)
{
  struct kevent ev;
  memset(&ev, 0, sizeof(struct kevent));
  ev.ident = pSocket->GetSocket();
  ev.filter = EVFILT_READ;
  ev.flags = EV_ADD | EV_ENABLE | EV_CLEAR;
  ev.udata = pSocket;

  mChangeset.push_back(ev);
  ev.filter = EVFILT_WRITE;
  mChangeset.push_back(ev);

  mEvents.resize(mEvents.size() + 2);
}

void nuiSocketPool::Del(nuiSocket* pSocket)
{
  struct kevent ev;
  memset(&ev, 0, sizeof(struct kevent));
  ev.ident = pSocket->GetSocket();
  ev.filter = EVFILT_READ;
  ev.flags = EV_DELETE;
  ev.udata = pSocket;

  mChangeset.push_back(ev);
  ev.filter = EVFILT_WRITE;
  mChangeset.push_back(ev);

  mEvents.resize(mEvents.size() - 2);
}

int nuiSocketPool::DispatchEvents(int timeout_millisec)
{
	struct timespec to;

	if (timeout_millisec >= 0)
  {
		to.tv_sec = timeout_millisec / 1000;
		to.tv_nsec = (timeout_millisec % 1000) * 1000000;	// nanosec
	}

	int res = kevent(mQueue, &mChangeset[0], mChangeset.size(), &mEvents[0], mEvents.size(), (timeout_millisec >= 0) ? &to : (struct timespec *) 0);

  mChangeset.clear();
	if(res == -1)
  {
		int err = errno;
		NGL_LOG("socket", NGL_LOG_ERROR, "kqueue::waitForEvents : kevent : %s (errno %d)\n", strerror(err), err);
		return err;
	}

	if (res == 0)
		return EWOULDBLOCK;

  for (int i = 0; i < res; i++)
  {
    nuiSocket* pSocket = (nuiSocket*)mEvents[i].udata;
    // dispatch events:
    switch (mEvents[i].filter)
    {
      case EVFILT_READ:
        if (mEvents[i].flags == EV_EOF)
          pSocket->OnReadClosed();
        else
          pSocket->OnCanRead();
        break;

      case EVFILT_WRITE:
        if (mEvents[i].flags == EV_EOF)
          pSocket->OnWriteClosed();
        else
          pSocket->OnCanWrite();
        break;
    };
  }

	return 0;
}

#endif //NGL_KQUEUE

#ifdef NGL_EPOLL
nuiSocketPool::nuiSocketPool()
{
  mEPoll = epoll_create(100);
}

nuiSocketPool::~nuiSocketPool()
{
  ///
}

void nuiSocketPool::Add(nuiSocket* pSocket, TriggerMode ReadMode, TriggerMode WriteMode)
{
  struct epoll_event ev;
  ev.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP;
  ev.data.ptr = pSocket;
  ev.data.fd = pSocket->GetSocket();
  ev.data.u32 = 0;
  ev.data.u64 = 0;

  epoll_ctl(mEPoll, EPOLL_CTL_ADD, pSocket->GetSocket(), &ev);
  mEvents.resize(mEvents.size() + 2);
}

void nuiSocketPool::Del(nuiSocket* pSocket)
{
  epoll_ctl(mEPoll, EPOLL_CTL_DEL, pSocket->GetSocket(), NULL);
  mEvents.resize(mEvents.size() - 2);
}

int nuiSocketPool::DispatchEvents(int timeout_millisec)
{
  int res = epoll_wait(mEPoll, &mEvents[0], mEvents.size(), timeout_millisec);

	if(res == -1)
  {
		int err = errno;
		NGL_LOG("socket", NGL_LOG_ERROR, "epoll::WaitForEvents : %s (errno %d)\n", strerror(err), err);
		return err;
	}

	if (res == 0)
		return EWOULDBLOCK;

  for (int i = 0; i < res; i++)
  {
    nuiSocket* pSocket = (nuiSocket*)mEvents[i].data.ptr;
    // dispatch events:
    switch (mEvents[i].events)
    {
      case EPOLLIN:
        pSocket->OnCanRead();
        break;

      case EPOLLOUT:
        pSocket->OnCanWrite();
        break;

      case EPOLLRDHUP:
      default:
        pSocket->OnReadClosed();
        pSocket->OnWriteClosed();
        break;
    };
  }

	return 0;
}

#endif //NGL_EPOLL

<commit_msg>fixed ntohl missing<commit_after>/*
 NUI3 - C++ cross-platform GUI framework for OpenGL based applications
 Copyright (C) 2002-2003 Sebastien Metrot

 licence: see nui3/LICENCE.TXT
 */

#include "nui.h"
#include "nuiSocket.h"
#include "nuiNetworkHost.h"

#ifdef WIN32
#include <Ws2tcpip.h>
#undef GetAddrInfo
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#endif

nuiSocket::nuiSocket(nuiSocket::SocketType Socket)
: mSocket(Socket)
{
#if (!defined _LINUX_)
  int n = 0;
  setsockopt(mSocket, SOL_SOCKET, SO_NOSIGPIPE, &n, sizeof(n));
#endif
  mNonBlocking = false;
}

bool nuiSocket::Init(int domain, int type, int protocol)
{
  mSocket = socket(domain, type, protocol);
#if (!defined _LINUX_)
  int n = 0;
  setsockopt(mSocket, SOL_SOCKET, SO_NOSIGPIPE, &n, sizeof(n));
#endif
  return mSocket >= 0;
}

nuiSocket::~nuiSocket()
{
#ifdef WIN32
  //DisconnectEx(mSocket, NULL, 0, 0);
  closesocket(mSocket);
#else
  close(mSocket);
#endif
}

nuiSocket::SocketType nuiSocket::GetSocket() const
{
  return mSocket;
}

bool nuiSocket::GetLocalHost(nuiNetworkHost& rHost) const
{
  struct sockaddr_in addr;
  socklen_t addrlen = sizeof(addr);
  int res = getsockname(mSocket, (struct sockaddr*)&addr, &addrlen);
  if (res != 0)
    return false;

  nuiNetworkHost h(ntohl(addr.sin_addr.s_addr), addr.sin_port, rHost.mProtocol);
  rHost = h;
  return true;
}

bool nuiSocket::GetDistantHost(nuiNetworkHost& rHost) const
{
  struct sockaddr_in addr;
  socklen_t addrlen = sizeof(addr);
  int res = getpeername(mSocket, (struct sockaddr*)&addr, &addrlen);
  if (res != 0)
    return false;

  nuiNetworkHost h(ntohl(addr.sin_addr.s_addr), addr.sin_port, rHost.mProtocol);
  rHost = h;
  return true;
}

bool nuiSocket::IsValid() const
{
  return mSocket != -1;
}

struct addrinfo* nuiSocket::GetAddrInfo(const nuiNetworkHost& rHost) const
{
  return rHost.GetAddrInfo();
}

void nuiSocket::SetNonBlocking(bool set)
{
  if (mNonBlocking == set)
    return;

  int flags;
  mNonBlocking = set;

  /* If they have O_NONBLOCK, use the Posix way to do it */
#if defined(O_NONBLOCK)
  /* Fixme: O_NONBLOCK is defined but broken on SunOS 4.1.x and AIX 3.2.5. */
  if (-1 == (flags = fcntl(mSocket, F_GETFL, 0)))
    flags = 0;
  if (set)
    flags |= O_NONBLOCK;
  else
    flags &= ~O_NONBLOCK;
  fcntl(mSocket, F_SETFL, flags);
#else
  /* Otherwise, use the old way of doing it */
  flags = set ? 1 : 0;
  ioctl(mSocket, FIOBIO, &flags);
#endif
}

bool nuiSocket::IsNonBlocking() const
{
  return mNonBlocking;
}

void nuiSocket::SetCanReadDelegate(const EventDelegate& rDelegate)
{
  mReadDelegate = rDelegate;
}

void nuiSocket::SetCanWriteDelegate(const EventDelegate& rDelegate)
{
  mWriteDelegate = rDelegate;
}

void nuiSocket::SetReadClosedDelegate(const EventDelegate& rDelegate)
{
  mReadCloseDelegate = rDelegate;
}

void nuiSocket::SetWriteClosedDelegate(const EventDelegate& rDelegate)
{
  mWriteCloseDelegate = rDelegate;
}

void nuiSocket::OnCanRead()
{
  if (mReadDelegate)
    mReadDelegate(*this);
}

void nuiSocket::OnCanWrite()
{
  if (mWriteDelegate)
    mWriteDelegate(*this);
}

void nuiSocket::OnReadClosed()
{
  if (mReadCloseDelegate)
    mReadCloseDelegate(*this);
}

void nuiSocket::OnWriteClosed()
{
  if (mWriteCloseDelegate)
    mWriteCloseDelegate(*this);
}

#ifdef WIN32
#define W(X) WSA##X
#else
#define W(X) X
#endif

void nuiSocket::DumpError(int err) const
{
  if (!err)
    return;

  nglString error;

  switch (err)
  {
    case EACCES: error = "The destination address is a broadcast address and the socket option SO_BROADCAST is not set."; break;
    case W(EADDRINUSE): error = "The address is already in use."; break;
    case W(EADDRNOTAVAIL): error = "The specified address is not available on this machine."; break;
    case W(EAFNOSUPPORT): error = "Addresses in the specified address family cannot be used with this socket."; break;
    case W(EALREADY): error = "The socket is non-blocking and a previous connection attempt has not yet been completed."; break;
    case W(EBADF): error = "socket is not a valid descriptor."; break;
    case W(ECONNREFUSED): error = "The attempt to connect was ignored (because the target is not listening for connections) or explicitly rejected."; break;
    case W(EFAULT): error = "The address parameter specifies an area outside the process address space."; break;
    case W(EHOSTUNREACH): error = "The target host cannot be reached (e.g., down, disconnected)."; break;
    case W(EINPROGRESS): error = "The socket is non-blocking and the connection cannot be completed immediately.  It is possible to select(2) for completion by selecting the socket for writing."; break;
    case W(EINTR): error = "Its execution was interrupted by a signal."; break;
    case W(EINVAL): error = "An invalid argument was detected (e.g., address_len is not valid for the address family, the specified address family is invalid)."; break;
    case W(EISCONN): error = "The socket is already connected."; break;
    case W(ENETDOWN): error = "The local network interface is not functioning."; break;
    case W(ENETUNREACH): error = "The network isn't reachable from this host."; break;
    case W(ENOBUFS): error = "The system call was unable to allocate a needed memory buffer."; break;
    case W(ENOTSOCK): error = "socket is not a file descriptor for a socket."; break;
    case W(EOPNOTSUPP): error = "Because socket is listening, no connection is allowed."; break;
    case W(EPROTOTYPE): error = "address has a different type than the socket that is bound to the specified peer address."; break;
    case W(ETIMEDOUT): error = " Connection establishment timed out without establishing a connection."; break;
    case W(ECONNRESET): error = "Remote host reset the connection request."; break;
    default: error = "Unknown error "; error.Add(err); break;
  }

  NGL_OUT(_T("Socket Error: %s\n"), error.GetChars());
}

//////////////////////////////////////////////////////////////////
//class nuiSocketPool
#ifdef NGL_KQUEUE
nuiSocketPool::nuiSocketPool()
{
  mQueue = kqueue();
}

nuiSocketPool::~nuiSocketPool()
{
  ///
}

void nuiSocketPool::Add(nuiSocket* pSocket, TriggerMode ReadMode, TriggerMode WriteMode)
{
  struct kevent ev;
  memset(&ev, 0, sizeof(struct kevent));
  ev.ident = pSocket->GetSocket();
  ev.filter = EVFILT_READ;
  ev.flags = EV_ADD | EV_ENABLE | EV_CLEAR;
  ev.udata = pSocket;

  mChangeset.push_back(ev);
  ev.filter = EVFILT_WRITE;
  mChangeset.push_back(ev);

  mEvents.resize(mEvents.size() + 2);
}

void nuiSocketPool::Del(nuiSocket* pSocket)
{
  struct kevent ev;
  memset(&ev, 0, sizeof(struct kevent));
  ev.ident = pSocket->GetSocket();
  ev.filter = EVFILT_READ;
  ev.flags = EV_DELETE;
  ev.udata = pSocket;

  mChangeset.push_back(ev);
  ev.filter = EVFILT_WRITE;
  mChangeset.push_back(ev);

  mEvents.resize(mEvents.size() - 2);
}

int nuiSocketPool::DispatchEvents(int timeout_millisec)
{
	struct timespec to;

	if (timeout_millisec >= 0)
  {
		to.tv_sec = timeout_millisec / 1000;
		to.tv_nsec = (timeout_millisec % 1000) * 1000000;	// nanosec
	}

	int res = kevent(mQueue, &mChangeset[0], mChangeset.size(), &mEvents[0], mEvents.size(), (timeout_millisec >= 0) ? &to : (struct timespec *) 0);

  mChangeset.clear();
	if(res == -1)
  {
		int err = errno;
		NGL_LOG("socket", NGL_LOG_ERROR, "kqueue::waitForEvents : kevent : %s (errno %d)\n", strerror(err), err);
		return err;
	}

	if (res == 0)
		return EWOULDBLOCK;

  for (int i = 0; i < res; i++)
  {
    nuiSocket* pSocket = (nuiSocket*)mEvents[i].udata;
    // dispatch events:
    switch (mEvents[i].filter)
    {
      case EVFILT_READ:
        if (mEvents[i].flags == EV_EOF)
          pSocket->OnReadClosed();
        else
          pSocket->OnCanRead();
        break;

      case EVFILT_WRITE:
        if (mEvents[i].flags == EV_EOF)
          pSocket->OnWriteClosed();
        else
          pSocket->OnCanWrite();
        break;
    };
  }

	return 0;
}

#endif //NGL_KQUEUE

#ifdef NGL_EPOLL
nuiSocketPool::nuiSocketPool()
{
  mEPoll = epoll_create(100);
}

nuiSocketPool::~nuiSocketPool()
{
  ///
}

void nuiSocketPool::Add(nuiSocket* pSocket, TriggerMode ReadMode, TriggerMode WriteMode)
{
  struct epoll_event ev;
  ev.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP;
  ev.data.ptr = pSocket;
  ev.data.fd = pSocket->GetSocket();
  ev.data.u32 = 0;
  ev.data.u64 = 0;

  epoll_ctl(mEPoll, EPOLL_CTL_ADD, pSocket->GetSocket(), &ev);
  mEvents.resize(mEvents.size() + 2);
}

void nuiSocketPool::Del(nuiSocket* pSocket)
{
  epoll_ctl(mEPoll, EPOLL_CTL_DEL, pSocket->GetSocket(), NULL);
  mEvents.resize(mEvents.size() - 2);
}

int nuiSocketPool::DispatchEvents(int timeout_millisec)
{
  int res = epoll_wait(mEPoll, &mEvents[0], mEvents.size(), timeout_millisec);

	if(res == -1)
  {
		int err = errno;
		NGL_LOG("socket", NGL_LOG_ERROR, "epoll::WaitForEvents : %s (errno %d)\n", strerror(err), err);
		return err;
	}

	if (res == 0)
		return EWOULDBLOCK;

  for (int i = 0; i < res; i++)
  {
    nuiSocket* pSocket = (nuiSocket*)mEvents[i].data.ptr;
    // dispatch events:
    switch (mEvents[i].events)
    {
      case EPOLLIN:
        pSocket->OnCanRead();
        break;

      case EPOLLOUT:
        pSocket->OnCanWrite();
        break;

      case EPOLLRDHUP:
      default:
        pSocket->OnReadClosed();
        pSocket->OnWriteClosed();
        break;
    };
  }

	return 0;
}

#endif //NGL_EPOLL

<|endoftext|>


<commit_before>// Copyright 2010-2012 UT-Battelle, LLC.  See LICENSE.txt for more information.
#include "eavlVTKExporter.h"
#include <iostream>

void
eavlVTKExporter::Export(ostream &out)
{
    out<<"# vtk DataFile Version 3.0"<<endl;
    out<<"vtk output"<<endl;
    out<<"ASCII"<<endl;

    ExportUnstructured(out);
}

void
eavlVTKExporter::ExportUnstructured(ostream &out)
{
    out<<"DATASET UNSTRUCTURED_GRID"<<endl;
    ExportPoints(out);

    ExportCells(out);
    ExportFields(out);
}

void
eavlVTKExporter::ExportCells(ostream &out)
{
    if (data->GetNumCellSets() == 0)
        return;

    int nCells = data->GetCellSet(cellSetIndex)->GetNumCells();

    int sz = 0;
    for (int i = 0; i < nCells; i++)
    {
        sz += data->GetCellSet(cellSetIndex)->GetCellNodes(i).numIndices;
        sz += 1;
    }

    out<<"CELLS "<<nCells<<" "<<sz<<endl;
    for (int i = 0; i < nCells; i++)
    {
        int nVerts = data->GetCellSet(cellSetIndex)->GetCellNodes(i).numIndices;
        eavlCell cell = data->GetCellSet(cellSetIndex)->GetCellNodes(i);
        out<<nVerts<<" ";
        for (int j = 0; j < nVerts; j++)
            out<<cell.indices[j]<<" ";
        out<<endl;
    }
    out<<"CELL_TYPES "<<nCells<<endl;
    for (int i = 0; i < nCells; i++)
    {
        eavlCell cell = data->GetCellSet(cellSetIndex)->GetCellNodes(i);
        out<<CellTypeToVTK(cell.type)<<endl;
    }
}

void
eavlVTKExporter::ExportFields(ostream &out)
{
    // do point data
    bool wrote_point_header = false;
    for (unsigned int f = 0; f < data->GetNumFields(); f++)
    {
        int ntuples = data->GetField(f)->GetArray()->GetNumberOfTuples();
        int ncomp = data->GetField(f)->GetArray()->GetNumberOfComponents();

        if (ncomp > 4)
            continue;

        if (data->GetField(f)->GetAssociation() == eavlField::ASSOC_POINTS)
        {
            if (!wrote_point_header)
                out<<"POINT_DATA "<<ntuples<<endl;
            wrote_point_header = true;
            out<<"SCALARS "<<data->GetField(f)->GetArray()->GetName()<<" float "<< ncomp<<endl;
            out<<"LOOKUP_TABLE default"<<endl;
            for (int i = 0; i < ntuples; i++)
            {
                for (int j = 0; j < ncomp; j++)
                    out<<data->GetField(f)->GetArray()->GetComponentAsDouble(i,j)<<endl;
            }
        }
    }

    // do cell data
    bool wrote_cell_header = false;
    for (unsigned int f = 0; f < data->GetNumFields(); f++)
    {
        int ntuples = data->GetField(f)->GetArray()->GetNumberOfTuples();
        int ncomp = data->GetField(f)->GetArray()->GetNumberOfComponents();

        if (ncomp > 4)
            continue;

        if (data->GetField(f)->GetAssociation() == eavlField::ASSOC_CELL_SET &&
            data->GetField(f)->GetAssocCellSet() == cellSetIndex)
        {
            if (!wrote_cell_header)
                out<<"CELL_DATA "<<ntuples<<endl;
            wrote_cell_header = true;
            out<<"SCALARS "<<data->GetField(f)->GetArray()->GetName()<<" float "<< ncomp<<endl;
            out<<"LOOKUP_TABLE default"<<endl;
            for (int i = 0; i < ntuples; i++)
            {
                for (int j = 0; j < ncomp; j++)
                    out<<data->GetField(f)->GetArray()->GetComponentAsDouble(i,j)<<endl;
            }
        }
    }
}

void
eavlVTKExporter::ExportPoints(ostream &out)
{
    out<<"POINTS "<<data->GetNumPoints()<<" float"<<endl;

    int dim = data->GetCoordinateSystem(0)->GetDimension();
    int npts = data->GetNumPoints();
    for (int i = 0; i < npts; i++)
    {
        out<<(float)data->GetPoint(i, 0)<<" ";
        out<<(dim >=2 ? (float)data->GetPoint(i, 1) : 0.0)<<" ";
        out<<(dim >=3 ? (float)data->GetPoint(i, 2) : 0.0)<<endl;
    }
}

#define VTK_EMPTY_CELL     0
#define VTK_VERTEX         1
#define VTK_POLY_VERTEX    2
#define VTK_LINE           3
#define VTK_POLY_LINE      4
#define VTK_TRIANGLE       5
#define VTK_TRIANGLE_STRIP 6
#define VTK_POLYGON        7
#define VTK_PIXEL          8
#define VTK_QUAD           9
#define VTK_TETRA         10
#define VTK_VOXEL         11
#define VTK_HEXAHEDRON    12
#define VTK_WEDGE         13
#define VTK_PYRAMID       14
#define VTK_PENTAGONAL_PRISM 15
#define VTK_HEXAGONAL_PRISM  16

int
eavlVTKExporter::CellTypeToVTK(eavlCellShape &type)
{
    int vtkType = -1;
    switch(type)
    {
      case EAVL_POINT:
        vtkType = VTK_VERTEX;
        break;
      case EAVL_BEAM:
        vtkType = VTK_LINE;
        break;
      case EAVL_TRI:
        vtkType = VTK_TRIANGLE;
        break;
      case EAVL_QUAD:
        vtkType = VTK_QUAD;
        break;
      case EAVL_PIXEL:
        vtkType = VTK_PIXEL;
        break;
      case EAVL_TET:
        vtkType = VTK_TETRA;
        break;
      case EAVL_PYRAMID:
        vtkType = VTK_PYRAMID;
        break;
      case EAVL_WEDGE:
        vtkType = VTK_WEDGE;
        break;
      case EAVL_HEX:
        vtkType = VTK_HEXAHEDRON;
        break;
      case EAVL_VOXEL:
        vtkType = VTK_VOXEL;
        break;
      case EAVL_TRISTRIP:
        vtkType = VTK_TRIANGLE_STRIP;
        break;
      case EAVL_POLYGON:
        vtkType = VTK_POLYGON;
        break;
      case EAVL_OTHER:
        break;
    }

    return vtkType;
}
<commit_msg>fixing bug exporting rgrids to vtk.<commit_after>// Copyright 2010-2012 UT-Battelle, LLC.  See LICENSE.txt for more information.
#include "eavlVTKExporter.h"
#include <iostream>

void
eavlVTKExporter::Export(ostream &out)
{
    out<<"# vtk DataFile Version 3.0"<<endl;
    out<<"vtk output"<<endl;
    out<<"ASCII"<<endl;

    ExportUnstructured(out);
}

void
eavlVTKExporter::ExportUnstructured(ostream &out)
{
    out<<"DATASET UNSTRUCTURED_GRID"<<endl;
    ExportPoints(out);

    ExportCells(out);
    ExportFields(out);
}

void
eavlVTKExporter::ExportCells(ostream &out)
{
    if (data->GetNumCellSets() == 0)
        return;

    int nCells = data->GetCellSet(cellSetIndex)->GetNumCells();

    int sz = 0;
    for (int i = 0; i < nCells; i++)
    {
        sz += data->GetCellSet(cellSetIndex)->GetCellNodes(i).numIndices;
        sz += 1;
    }

    out<<"CELLS "<<nCells<<" "<<sz<<endl;
    for (int i = 0; i < nCells; i++)
    {
        int nVerts = data->GetCellSet(cellSetIndex)->GetCellNodes(i).numIndices;
        eavlCell cell = data->GetCellSet(cellSetIndex)->GetCellNodes(i);
        out<<nVerts<<" ";
        for (int j = 0; j < nVerts; j++)
            out<<cell.indices[j]<<" ";
        out<<endl;
    }
    out<<"CELL_TYPES "<<nCells<<endl;
    for (int i = 0; i < nCells; i++)
    {
        eavlCell cell = data->GetCellSet(cellSetIndex)->GetCellNodes(i);
        out<<CellTypeToVTK(cell.type)<<endl;
    }
}

void
eavlVTKExporter::ExportFields(ostream &out)
{
    // do point data
    bool wrote_point_header = false;
    for (unsigned int f = 0; f < data->GetNumFields(); f++)
    {
        int ntuples = data->GetField(f)->GetArray()->GetNumberOfTuples();
        int ncomp = data->GetField(f)->GetArray()->GetNumberOfComponents();

        if (ncomp > 4)
            continue;

        if (data->GetField(f)->GetAssociation() == eavlField::ASSOC_POINTS)
        {
            if (!wrote_point_header)
                out<<"POINT_DATA "<<ntuples<<endl;
            wrote_point_header = true;
            out<<"SCALARS "<<data->GetField(f)->GetArray()->GetName()<<" float "<< ncomp<<endl;
            out<<"LOOKUP_TABLE default"<<endl;
            for (int i = 0; i < ntuples; i++)
            {
                for (int j = 0; j < ncomp; j++)
                    out<<data->GetField(f)->GetArray()->GetComponentAsDouble(i,j)<<endl;
            }
        }
    }

    // do cell data
    bool wrote_cell_header = false;
    for (unsigned int f = 0; f < data->GetNumFields(); f++)
    {
        int ntuples = data->GetField(f)->GetArray()->GetNumberOfTuples();
        int ncomp = data->GetField(f)->GetArray()->GetNumberOfComponents();

        if (ncomp > 4)
            continue;

        if (data->GetField(f)->GetAssociation() == eavlField::ASSOC_CELL_SET &&
            data->GetField(f)->GetAssocCellSet() == cellSetIndex)
        {
            if (!wrote_cell_header)
                out<<"CELL_DATA "<<ntuples<<endl;
            wrote_cell_header = true;
            out<<"SCALARS "<<data->GetField(f)->GetArray()->GetName()<<" float "<< ncomp<<endl;
            out<<"LOOKUP_TABLE default"<<endl;
            for (int i = 0; i < ntuples; i++)
            {
                for (int j = 0; j < ncomp; j++)
                    out<<data->GetField(f)->GetArray()->GetComponentAsDouble(i,j)<<endl;
            }
        }
    }
}

void
eavlVTKExporter::ExportPoints(ostream &out)
{
    out<<"POINTS "<<data->GetNumPoints()<<" float"<<endl;

    int dim = data->GetCoordinateSystem(0)->GetDimension();
    int npts = data->GetNumPoints();
    for (int i = 0; i < npts; i++)
    {
        out<<(float)data->GetPoint(i, 0)<<" ";
        out<<(float)data->GetPoint(i, 1)<<" ";
        out<<(float)data->GetPoint(i, 2)<<endl;
    }
}

#define VTK_EMPTY_CELL     0
#define VTK_VERTEX         1
#define VTK_POLY_VERTEX    2
#define VTK_LINE           3
#define VTK_POLY_LINE      4
#define VTK_TRIANGLE       5
#define VTK_TRIANGLE_STRIP 6
#define VTK_POLYGON        7
#define VTK_PIXEL          8
#define VTK_QUAD           9
#define VTK_TETRA         10
#define VTK_VOXEL         11
#define VTK_HEXAHEDRON    12
#define VTK_WEDGE         13
#define VTK_PYRAMID       14
#define VTK_PENTAGONAL_PRISM 15
#define VTK_HEXAGONAL_PRISM  16

int
eavlVTKExporter::CellTypeToVTK(eavlCellShape &type)
{
    int vtkType = -1;
    switch(type)
    {
      case EAVL_POINT:
        vtkType = VTK_VERTEX;
        break;
      case EAVL_BEAM:
        vtkType = VTK_LINE;
        break;
      case EAVL_TRI:
        vtkType = VTK_TRIANGLE;
        break;
      case EAVL_QUAD:
        vtkType = VTK_QUAD;
        break;
      case EAVL_PIXEL:
        vtkType = VTK_PIXEL;
        break;
      case EAVL_TET:
        vtkType = VTK_TETRA;
        break;
      case EAVL_PYRAMID:
        vtkType = VTK_PYRAMID;
        break;
      case EAVL_WEDGE:
        vtkType = VTK_WEDGE;
        break;
      case EAVL_HEX:
        vtkType = VTK_HEXAHEDRON;
        break;
      case EAVL_VOXEL:
        vtkType = VTK_VOXEL;
        break;
      case EAVL_TRISTRIP:
        vtkType = VTK_TRIANGLE_STRIP;
        break;
      case EAVL_POLYGON:
        vtkType = VTK_POLYGON;
        break;
      case EAVL_OTHER:
        break;
    }

    return vtkType;
}
<|endoftext|>


<commit_before>#ifndef RESULT_BENCHMARK_HPP_
#define RESULT_BENCHMARK_HPP_

#include <math.h>
#include <iostream>
#include <array>
#include <vector>
#include <assert.h>
#include <regex>

namespace gearshifft
{
/** Result data generated after a benchmark has completed the runs
 */
  template<int T_NumberRuns, int T_NumberValues>
  class ResultBenchmark  {
  public:
    using ValuesT = std::array<std::array<double, T_NumberValues >, T_NumberRuns >;

    template<bool isComplex, bool isInplace, size_t T_NDim>
    void init(const std::array<unsigned, T_NDim>& ce, const char* precision) {
      total_ = 1;
      for(auto i=0; i<T_NDim; ++i) {
        extents_[i] = ce[i];
        total_ *= ce[i];
      }
      dim_ = T_NDim;
      dimkind_ = computeDimkind();
      run_ = 0;
      isInplace_ = isInplace;
      isComplex_ = isComplex;
      precision_.assign(precision);
      error_.clear();
      errorRun_ = -1;
    }

    /**
     * @retval 1 arbitrary extents
     * @retval 2 power-of-two extents
     * @retval 3 last dim: combination of powers of (3,5,7) {3^r * 5^s * 7^t}
     */
    size_t computeDimkind() {
      bool p2=true;
      for( unsigned k=0; k<dim_; ++k)
        p2 &= powerOf(extents_[k], 2.0);
      if(p2)
        return 2;
      unsigned e = extents_[dim_-1];
      unsigned sqr = static_cast<unsigned>(sqrt(e));
      for( unsigned k=2; k<=sqr; k+=1 ) {
        while( e%k == 0 ) {
          e /= k;
        }
      }
      if(e>7)
        return 1;
      else
        return 3;
    }

    /* setters */

    void setRun(int run) {
      run_ = run;
    }

    template<typename T_Index>
    void setValue(T_Index idx_val, double val) {
      int idx = static_cast<int>(idx_val);
      assert(idx<T_NumberValues);
      values_[run_][idx] = val;
    }

    void setError(int run, const std::string& what) {
      assert(errorRun_<T_NumberRuns);
      errorRun_ = run;
      error_ = what;
      // remove path informations of source file location
      std::regex e ("([^ ]*/|[^ ]*\\\\)([^/\\\\]*)(hpp|cpp)");
      error_ = std::regex_replace(error_,e,"$2$3");
    }

    /* getters */

    template<typename T_Index>
    double getValue(T_Index idx_val) const {
      int idx = static_cast<int>(idx_val);
      assert(idx<T_NumberValues);
      return values_[run_][idx];
    }
    std::string getPrecision() const { return precision_; }
    size_t getDim() const { return dim_; }
    size_t getDimKind() const { return dimkind_; }
    std::array<unsigned,3> getExtents() const { return extents_; }
    size_t getExtentsTotal() const { return total_; }
    bool isInplace() const { return isInplace_; }
    bool isComplex() const { return isComplex_; }
    bool hasError() const { return error_.empty()==false; }
    const std::string& getError() const { return error_; }
    int getErrorRun() const { return errorRun_; }

  private:
    /// result object id
    //size_t id_ = 0;
    int run_ = 0;
    /// fft dimension
    size_t dim_ = 0;
    /// extents are 1=Arbitrary, 2=PowerOfTwo, 3=PowerOfOther
    size_t dimkind_ = 0;
    /// fft extents
    std::array<unsigned,3> extents_ = { {1} };
    /// all extents multiplied
    size_t total_ = 1;
    /// each run w values ( data[idx_run][idx_val] )
    ValuesT values_ = { {{ {0.0} }} };
    /// FFT Kind Inplace
    bool isInplace_ = false;
    /// FFT Kind Complex
    bool isComplex_ = false;
    /// Precision as string
    std::string precision_;
    /// Error message
    std::string error_;
    /// Run where error occurred
    int errorRun_;

  private:
    bool powerOf(unsigned e, double b) {
      if(e==0)
        return false;
      double a = static_cast<double>(e);
      double p = floor(log(a)/log(b)+0.5);
      return fabs(pow(b,p)-a)<0.0001;
    }

  };
}

#endif
<commit_msg>computeDimKind fixed.<commit_after>#ifndef RESULT_BENCHMARK_HPP_
#define RESULT_BENCHMARK_HPP_

#include <math.h>
#include <iostream>
#include <array>
#include <vector>
#include <assert.h>
#include <regex>

namespace gearshifft
{
/** Result data generated after a benchmark has completed the runs
 */
  template<int T_NumberRuns, int T_NumberValues>
  class ResultBenchmark  {
  public:
    using ValuesT = std::array<std::array<double, T_NumberValues >, T_NumberRuns >;

    template<bool isComplex, bool isInplace, size_t T_NDim>
    void init(const std::array<unsigned, T_NDim>& ce, const char* precision) {
      total_ = 1;
      for(auto i=0; i<T_NDim; ++i) {
        extents_[i] = ce[i];
        total_ *= ce[i];
      }
      dim_ = T_NDim;
      dimkind_ = computeDimkind();
      run_ = 0;
      isInplace_ = isInplace;
      isComplex_ = isComplex;
      precision_.assign(precision);
      error_.clear();
      errorRun_ = -1;
    }

    /**
     * @retval 1 arbitrary extents
     * @retval 2 power-of-two extents
     * @retval 3 combination of powers of (3,5,7) {3^r * 5^s * 7^t}
     */
    size_t computeDimkind() {
      bool p2=true;
      for( unsigned k=0; k<dim_; ++k)
        p2 &= powerOf(extents_[k], 2.0);
      if(p2)
        return 2;
      for(unsigned k=0; k<dim_; ++k) {
        unsigned e = extents_[k];
        unsigned sqr = static_cast<unsigned>(sqrt(e));
        for( unsigned k=2; k<=sqr; k+=1 ) {
          while( e%k == 0 ) {
            e /= k;
          }
        }
        if(e>7)
          return 1;
      }
      return 3;
    }
    /* setters */

    void setRun(int run) {
      run_ = run;
    }

    template<typename T_Index>
    void setValue(T_Index idx_val, double val) {
      int idx = static_cast<int>(idx_val);
      assert(idx<T_NumberValues);
      values_[run_][idx] = val;
    }

    void setError(int run, const std::string& what) {
      assert(errorRun_<T_NumberRuns);
      errorRun_ = run;
      error_ = what;
      // remove path informations of source file location
      std::regex e ("([^ ]*/|[^ ]*\\\\)([^/\\\\]*)(hpp|cpp)");
      error_ = std::regex_replace(error_,e,"$2$3");
    }

    /* getters */

    template<typename T_Index>
    double getValue(T_Index idx_val) const {
      int idx = static_cast<int>(idx_val);
      assert(idx<T_NumberValues);
      return values_[run_][idx];
    }
    std::string getPrecision() const { return precision_; }
    size_t getDim() const { return dim_; }
    size_t getDimKind() const { return dimkind_; }
    std::array<unsigned,3> getExtents() const { return extents_; }
    size_t getExtentsTotal() const { return total_; }
    bool isInplace() const { return isInplace_; }
    bool isComplex() const { return isComplex_; }
    bool hasError() const { return error_.empty()==false; }
    const std::string& getError() const { return error_; }
    int getErrorRun() const { return errorRun_; }

  private:
    /// result object id
    //size_t id_ = 0;
    int run_ = 0;
    /// fft dimension
    size_t dim_ = 0;
    /// extents are 1=Arbitrary, 2=PowerOfTwo, 3=PowerOfOther
    size_t dimkind_ = 0;
    /// fft extents
    std::array<unsigned,3> extents_ = { {1} };
    /// all extents multiplied
    size_t total_ = 1;
    /// each run w values ( data[idx_run][idx_val] )
    ValuesT values_ = { {{ {0.0} }} };
    /// FFT Kind Inplace
    bool isInplace_ = false;
    /// FFT Kind Complex
    bool isComplex_ = false;
    /// Precision as string
    std::string precision_;
    /// Error message
    std::string error_;
    /// Run where error occurred
    int errorRun_;

  private:
    bool powerOf(unsigned e, double b) {
      if(e==0)
        return false;
      double a = static_cast<double>(e);
      double p = floor(log(a)/log(b)+0.5);
      return fabs(pow(b,p)-a)<0.0001;
    }

  };
}

#endif
<|endoftext|>


<commit_before>#include <string>
#include <vector>
#include <fstream>

#include <windows.h>

#include "simple/string.h"

typedef struct tagHEADER {
    WORD idReserved;
    WORD idType;
    WORD idCount;
} HEADER, *LPHEADER;

typedef struct tagICONDIRENTRY {
    BYTE bWidth;
    BYTE bHeight;
    BYTE bColorCount;
    BYTE bReserved;
    WORD wPlanes;
    WORD wBitCount;
    DWORD dwBytesInRes;
    DWORD dwImageOffset;
} ICONDIRENTRY, *LPICONDIRENTRY;

#pragma pack( push )
#pragma pack( 2 )
typedef struct tagGRPICONDIRENTRY {
    BYTE bWidth;
    BYTE bHeight;
    BYTE bColorCount;
    BYTE bReserved;
    WORD wPlanes;
    WORD wBitCount;
    DWORD dwBytesInRes;
    WORD nID;
} GRPICONDIRENTRY, *LPGRPICONDIRENTRY;;

typedef struct tagGRPICONDIR {
    WORD idReserved;
    WORD idType;
    WORD idCount;
    GRPICONDIRENTRY idEntries[1];
} GRPICONDIR, *LPGRPICONDIR;
#pragma pack( pop )

bool Res_ReplaceICO(const char* lpExeName, const char* sResID, const char* lpIconFile) {
    LPICONDIRENTRY pIconDirEntry(NULL);
    LPGRPICONDIR pGrpIconDir(NULL);
    HEADER header;
    LPBYTE pIconBytes(NULL);
    HANDLE hIconFile(NULL);
    DWORD dwRet(0), nSize(0), nGSize(0), dwReserved(0);
    HANDLE hUpdate(NULL);
    BOOL ret(FALSE);
    WORD i(0);

    //打开图标文件
    hIconFile = CreateFile(lpIconFile, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hIconFile == INVALID_HANDLE_VALUE) {
        return	false;
    }
    //读取文件头部信息
    ret=ReadFile(hIconFile, &header, sizeof(HEADER), &dwReserved, NULL);
    if (!ret) {
        CloseHandle(hIconFile);
        return	false;
    }
    //建立每一个图标的目录信息存放区域
    pIconDirEntry = (LPICONDIRENTRY)new BYTE[header.idCount*sizeof(ICONDIRENTRY)];
    if (pIconDirEntry==NULL) {
        CloseHandle(hIconFile);
        return	false;
    }
    //从Icon文件中读取每一个图标的目录信息
    ret = ReadFile(hIconFile, pIconDirEntry, header.idCount*sizeof(ICONDIRENTRY), &dwReserved, NULL);
    if (!ret) {
        delete[] pIconDirEntry;
        CloseHandle(hIconFile);
        return	false;
    }
    //建立EXE文件中RT_GROUP_ICON所需的数据结构存放区域
    nGSize=sizeof(GRPICONDIR)+header.idCount*sizeof(ICONDIRENTRY);
    pGrpIconDir=(LPGRPICONDIR)new BYTE[nGSize];
    ZeroMemory(pGrpIconDir, nSize);
    //填充信息，这里相当于一个转换的过程
    pGrpIconDir->idReserved=header.idReserved;
    pGrpIconDir->idType=header.idType;
    pGrpIconDir->idCount=header.idCount;
    //复制信息并设置每一个图标对应的ID。ID为位置索引号
    for(i=0; i<header.idCount; i++) {
        pGrpIconDir->idEntries[i].bWidth=pIconDirEntry[i].bWidth;
        pGrpIconDir->idEntries[i].bHeight=pIconDirEntry[i].bHeight;
        pGrpIconDir->idEntries[i].bColorCount=pIconDirEntry[i].bColorCount;
        pGrpIconDir->idEntries[i].bReserved=pIconDirEntry[i].bReserved;
        pGrpIconDir->idEntries[i].wPlanes=pIconDirEntry[i].wPlanes;
        pGrpIconDir->idEntries[i].wBitCount=pIconDirEntry[i].wBitCount;
        pGrpIconDir->idEntries[i].dwBytesInRes=pIconDirEntry[i].dwBytesInRes;
        pGrpIconDir->idEntries[i].nID=i+1; //id == 0 是 RT_GROUP_ICON 的id，我这里替换的时候出现问题，所以就 + 1 了。
    }
    //开始更新EXE中的图标资源，ID定为最小０，如果原来存在０ID的图标信息则被替换为新的。
    hUpdate = BeginUpdateResource(lpExeName, false);
    if (hUpdate!=NULL) {
        //首先更新RT_GROUP_ICON信息
        ret = UpdateResource(hUpdate, RT_GROUP_ICON, sResID, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (LPVOID)pGrpIconDir, nGSize);
        if (!ret) {
            delete[] pIconDirEntry;
            delete[] pGrpIconDir;
            CloseHandle(hIconFile);
            return	false;
        }

        //接着的是每一个Icon的信息存放
        for(i=0; i<header.idCount; i++) {
            //Icon的字节数
            nSize = pIconDirEntry[i].dwBytesInRes;
            //偏移文件的指针到当前图标的开始处
            dwRet=SetFilePointer(hIconFile, pIconDirEntry[i].dwImageOffset, NULL, FILE_BEGIN);
            if (dwRet==INVALID_SET_FILE_POINTER) {
                break;
            }
            //准备pIconBytes来存放文件里的Byte信息用于更新到EXE中。

            delete[] pIconBytes;

            pIconBytes = new BYTE[nSize];
            ZeroMemory(pIconBytes, nSize);
            ret = ReadFile(hIconFile, (LPVOID)pIconBytes, nSize, &dwReserved, NULL);
            if(!ret) {
                break;
            }
            //更新每一个ID对应的RT_ICON信息
            ret = UpdateResource(hUpdate, RT_ICON, MAKEINTRESOURCE(pGrpIconDir->idEntries[i].nID), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (LPVOID)pIconBytes, nSize);
            if(!ret) {
                break;
            }
        }
        //结束EXE资源的更新操作
        if (pIconBytes!=NULL) {
            delete[] pIconBytes;
        }

        if(!EndUpdateResource(hUpdate, false)) {
            return	false;
        }
    }

    //清理资源并关闭Icon文件，到此更新操作结束！
    delete	[]pGrpIconDir;
    delete	[]pIconDirEntry;
    CloseHandle(hIconFile);

    return	true;
}

bool Res_ReplaceString(const char* pszApp, int nResID, const char* pszText) {
    std::wstring	wText;
    string_ansi_to_utf16(pszText,	wText);

    int SourceId	= nResID;
    HINSTANCE hInst = ::LoadLibrary(pszApp);
    if(hInst == NULL) return false;

    std::vector<WCHAR> vStrTable;  // 资源数据

    int idStr = (SourceId-1)/16 + 1;  // 字符串表ID
    HRSRC hSrc = ::FindResource(hInst, MAKEINTRESOURCE(idStr), RT_STRING);
    if(hSrc != NULL) {
        LPVOID lpData = ::LockResource( ::LoadResource(hInst,hSrc) );
        DWORD dwSize = ::SizeofResource(hInst,hSrc);
        vStrTable.resize((dwSize+1)/sizeof(WCHAR));
        ::CopyMemory(&vStrTable[0],lpData,dwSize); // 取得数据
    }
    ::FreeLibrary(hInst);

    HANDLE hUpdateRes=BeginUpdateResource(pszApp,false);
    if(hUpdateRes == NULL) return false;  // 不能更新,浪费表情

    int nIndex = (SourceId-1)%16; // 字符串表中的位置

    UINT nPos = 1;
    for (int i = 0; i < nIndex; i++) {       // 移到我们要修改的位置
        if(vStrTable.size() <= nPos) vStrTable.resize(nPos+1);
        nPos += vStrTable[nPos];
        nPos++;
    }

    if(vStrTable.size()<=nPos) vStrTable.resize(nPos+1);
    // 删除原先数据
    if(vStrTable[nPos]>0) {
        std::vector<WCHAR>::iterator itrStart=vStrTable.begin();
        std::advance(itrStart,nPos+1);
        std::vector<WCHAR>::iterator itrEnd = itrStart;
        std::advance(itrEnd,vStrTable[nPos]);
        vStrTable.erase(itrStart,itrEnd);
    }

    int nLen = ::lstrlenW(wText.c_str());
    vStrTable[nPos] = (WCHAR)nLen;

    // 插入现在的数据
    if(nLen>0) {
        std::vector<WCHAR>::iterator itrStart=vStrTable.begin();
        std::advance(itrStart,nPos+1);
        vStrTable.insert(itrStart,wText.c_str(),wText.c_str()+nLen);
    }

    // 好了,可以替换了

    UpdateResource(hUpdateRes,
                   RT_STRING,
                   MAKEINTRESOURCE(idStr),
                   MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),  // 注意我这里用的语言不一样:)
                   &vStrTable[0],
                   vStrTable.size()*sizeof(WCHAR));

    return (FALSE != EndUpdateResource(hUpdateRes,FALSE));
}

//
//	获取资源内容
//
bool	Res_LoadResource(
    HMODULE		hModule,
    const char*	res_name,
    const char*	res_type,
    void*&		res_data,
    size_t&		res_size
) {
    HRSRC hRsrc		= FindResourceA(hModule, res_name, res_type);
    if(NULL == hRsrc)	return false;

    DWORD dwSize	= SizeofResource(hModule, hRsrc);
    if(0 == dwSize)		return false;

    HGLOBAL hGlobal	= LoadResource(hModule, hRsrc);
    if(NULL == hGlobal)	return false;

    LPVOID pBuffer	= LockResource(hGlobal);
    if(NULL == pBuffer)	return false;

    res_data	=	pBuffer;
    res_size	=	dwSize;

    return	true;
}

//
//	获取文件内容(必须确保空间足够大)
//
bool	Res_LoadFile(
    const char*	file_name,
    void*		res_data,
    size_t&		res_size
) {
    std::ifstream	ifs(file_name, std::ios::binary);
    if(!ifs) {
        return	false;
    }

    ifs.seekg(0, std::ios::end);
    size_t	file_size	= size_t(ifs.tellg());
    if(NULL == res_data) {
        res_size	= file_size;
        return	true;
    }

    if(res_size < file_size) {
        return	false;
    }

    res_size	= file_size;
    ifs.seekg(0, std::ios::beg);
    ifs.read((char*)res_data, res_size);

    return	true;
}
<commit_msg>unicode env errors.<commit_after>#include <string>
#include <vector>
#include <fstream>

#include <windows.h>

#include "simple/string.h"

typedef struct tagHEADER {
    WORD idReserved;
    WORD idType;
    WORD idCount;
} HEADER, *LPHEADER;

typedef struct tagICONDIRENTRY {
    BYTE bWidth;
    BYTE bHeight;
    BYTE bColorCount;
    BYTE bReserved;
    WORD wPlanes;
    WORD wBitCount;
    DWORD dwBytesInRes;
    DWORD dwImageOffset;
} ICONDIRENTRY, *LPICONDIRENTRY;

#pragma pack( push )
#pragma pack( 2 )
typedef struct tagGRPICONDIRENTRY {
    BYTE bWidth;
    BYTE bHeight;
    BYTE bColorCount;
    BYTE bReserved;
    WORD wPlanes;
    WORD wBitCount;
    DWORD dwBytesInRes;
    WORD nID;
} GRPICONDIRENTRY, *LPGRPICONDIRENTRY;;

typedef struct tagGRPICONDIR {
    WORD idReserved;
    WORD idType;
    WORD idCount;
    GRPICONDIRENTRY idEntries[1];
} GRPICONDIR, *LPGRPICONDIR;
#pragma pack( pop )

bool Res_ReplaceICO(const char* lpExeName, const char* sResID, const char* lpIconFile) {
    LPICONDIRENTRY pIconDirEntry(NULL);
    LPGRPICONDIR pGrpIconDir(NULL);
    HEADER header;
    LPBYTE pIconBytes(NULL);
    HANDLE hIconFile(NULL);
    DWORD dwRet(0), nSize(0), nGSize(0), dwReserved(0);
    HANDLE hUpdate(NULL);
    BOOL ret(FALSE);
    WORD i(0);

    //打开图标文件
    hIconFile = CreateFileA(lpIconFile, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hIconFile == INVALID_HANDLE_VALUE) {
        return	false;
    }
    //读取文件头部信息
    ret=ReadFile(hIconFile, &header, sizeof(HEADER), &dwReserved, NULL);
    if (!ret) {
        CloseHandle(hIconFile);
        return	false;
    }
    //建立每一个图标的目录信息存放区域
    pIconDirEntry = (LPICONDIRENTRY)new BYTE[header.idCount*sizeof(ICONDIRENTRY)];
    if (pIconDirEntry==NULL) {
        CloseHandle(hIconFile);
        return	false;
    }
    //从Icon文件中读取每一个图标的目录信息
    ret = ReadFile(hIconFile, pIconDirEntry, header.idCount*sizeof(ICONDIRENTRY), &dwReserved, NULL);
    if (!ret) {
        delete[] pIconDirEntry;
        CloseHandle(hIconFile);
        return	false;
    }
    //建立EXE文件中RT_GROUP_ICON所需的数据结构存放区域
    nGSize=sizeof(GRPICONDIR)+header.idCount*sizeof(ICONDIRENTRY);
    pGrpIconDir=(LPGRPICONDIR)new BYTE[nGSize];
    ZeroMemory(pGrpIconDir, nSize);
    //填充信息，这里相当于一个转换的过程
    pGrpIconDir->idReserved=header.idReserved;
    pGrpIconDir->idType=header.idType;
    pGrpIconDir->idCount=header.idCount;
    //复制信息并设置每一个图标对应的ID。ID为位置索引号
    for(i=0; i<header.idCount; i++) {
        pGrpIconDir->idEntries[i].bWidth=pIconDirEntry[i].bWidth;
        pGrpIconDir->idEntries[i].bHeight=pIconDirEntry[i].bHeight;
        pGrpIconDir->idEntries[i].bColorCount=pIconDirEntry[i].bColorCount;
        pGrpIconDir->idEntries[i].bReserved=pIconDirEntry[i].bReserved;
        pGrpIconDir->idEntries[i].wPlanes=pIconDirEntry[i].wPlanes;
        pGrpIconDir->idEntries[i].wBitCount=pIconDirEntry[i].wBitCount;
        pGrpIconDir->idEntries[i].dwBytesInRes=pIconDirEntry[i].dwBytesInRes;
        pGrpIconDir->idEntries[i].nID=i+1; //id == 0 是 RT_GROUP_ICON 的id，我这里替换的时候出现问题，所以就 + 1 了。
    }
    //开始更新EXE中的图标资源，ID定为最小０，如果原来存在０ID的图标信息则被替换为新的。
    hUpdate = BeginUpdateResourceA(lpExeName, false);
    if (hUpdate!=NULL) {
        //首先更新RT_GROUP_ICON信息
        ret = UpdateResourceA(hUpdate, (LPSTR)RT_GROUP_ICON, sResID, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (LPVOID)pGrpIconDir, nGSize);
        if (!ret) {
            delete[] pIconDirEntry;
            delete[] pGrpIconDir;
            CloseHandle(hIconFile);
            return	false;
        }

        //接着的是每一个Icon的信息存放
        for(i=0; i<header.idCount; i++) {
            //Icon的字节数
            nSize = pIconDirEntry[i].dwBytesInRes;
            //偏移文件的指针到当前图标的开始处
            dwRet=SetFilePointer(hIconFile, pIconDirEntry[i].dwImageOffset, NULL, FILE_BEGIN);
            if (dwRet==INVALID_SET_FILE_POINTER) {
                break;
            }
            //准备pIconBytes来存放文件里的Byte信息用于更新到EXE中。

            delete[] pIconBytes;

            pIconBytes = new BYTE[nSize];
            ZeroMemory(pIconBytes, nSize);
            ret = ReadFile(hIconFile, (LPVOID)pIconBytes, nSize, &dwReserved, NULL);
            if(!ret) {
                break;
            }
            //更新每一个ID对应的RT_ICON信息
            ret = UpdateResource(hUpdate, RT_ICON, MAKEINTRESOURCE(pGrpIconDir->idEntries[i].nID), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (LPVOID)pIconBytes, nSize);
            if(!ret) {
                break;
            }
        }
        //结束EXE资源的更新操作
        if (pIconBytes!=NULL) {
            delete[] pIconBytes;
        }

        if(!EndUpdateResource(hUpdate, false)) {
            return	false;
        }
    }

    //清理资源并关闭Icon文件，到此更新操作结束！
    delete	[]pGrpIconDir;
    delete	[]pIconDirEntry;
    CloseHandle(hIconFile);

    return	true;
}

bool Res_ReplaceString(const char* pszApp, int nResID, const char* pszText) {
    std::wstring	wText;
    string_ansi_to_utf16(pszText,	wText);

    int SourceId	= nResID;
    HINSTANCE hInst = ::LoadLibraryA(pszApp);
    if(hInst == NULL) return false;

    std::vector<WCHAR> vStrTable;  // 资源数据

    int idStr = (SourceId-1)/16 + 1;  // 字符串表ID
    HRSRC hSrc = ::FindResource(hInst, MAKEINTRESOURCE(idStr), RT_STRING);
    if(hSrc != NULL) {
        LPVOID lpData = ::LockResource( ::LoadResource(hInst,hSrc) );
        DWORD dwSize = ::SizeofResource(hInst,hSrc);
        vStrTable.resize((dwSize+1)/sizeof(WCHAR));
        ::CopyMemory(&vStrTable[0],lpData,dwSize); // 取得数据
    }
    ::FreeLibrary(hInst);

    HANDLE hUpdateRes=BeginUpdateResourceA(pszApp,false);
    if(hUpdateRes == NULL) return false;  // 不能更新,浪费表情

    int nIndex = (SourceId-1)%16; // 字符串表中的位置

    UINT nPos = 1;
    for (int i = 0; i < nIndex; i++) {       // 移到我们要修改的位置
        if(vStrTable.size() <= nPos) vStrTable.resize(nPos+1);
        nPos += vStrTable[nPos];
        nPos++;
    }

    if(vStrTable.size()<=nPos) vStrTable.resize(nPos+1);
    // 删除原先数据
    if(vStrTable[nPos]>0) {
        std::vector<WCHAR>::iterator itrStart=vStrTable.begin();
        std::advance(itrStart,nPos+1);
        std::vector<WCHAR>::iterator itrEnd = itrStart;
        std::advance(itrEnd,vStrTable[nPos]);
        vStrTable.erase(itrStart,itrEnd);
    }

    int nLen = ::lstrlenW(wText.c_str());
    vStrTable[nPos] = (WCHAR)nLen;

    // 插入现在的数据
    if(nLen>0) {
        std::vector<WCHAR>::iterator itrStart=vStrTable.begin();
        std::advance(itrStart,nPos+1);
        vStrTable.insert(itrStart,wText.c_str(),wText.c_str()+nLen);
    }

    // 好了,可以替换了

    UpdateResource(hUpdateRes,
                   RT_STRING,
                   MAKEINTRESOURCE(idStr),
                   MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),  // 注意我这里用的语言不一样:)
                   &vStrTable[0],
                   vStrTable.size()*sizeof(WCHAR));

    return (FALSE != EndUpdateResource(hUpdateRes,FALSE));
}

//
//	获取资源内容
//
bool	Res_LoadResource(
    HMODULE		hModule,
    const char*	res_name,
    const char*	res_type,
    void*&		res_data,
    size_t&		res_size
) {
    HRSRC hRsrc		= FindResourceA(hModule, res_name, res_type);
    if(NULL == hRsrc)	return false;

    DWORD dwSize	= SizeofResource(hModule, hRsrc);
    if(0 == dwSize)		return false;

    HGLOBAL hGlobal	= LoadResource(hModule, hRsrc);
    if(NULL == hGlobal)	return false;

    LPVOID pBuffer	= LockResource(hGlobal);
    if(NULL == pBuffer)	return false;

    res_data	=	pBuffer;
    res_size	=	dwSize;

    return	true;
}

//
//	获取文件内容(必须确保空间足够大)
//
bool	Res_LoadFile(
    const char*	file_name,
    void*		res_data,
    size_t&		res_size
) {
    std::ifstream	ifs(file_name, std::ios::binary);
    if(!ifs) {
        return	false;
    }

    ifs.seekg(0, std::ios::end);
    size_t	file_size	= size_t(ifs.tellg());
    if(NULL == res_data) {
        res_size	= file_size;
        return	true;
    }

    if(res_size < file_size) {
        return	false;
    }

    res_size	= file_size;
    ifs.seekg(0, std::ios::beg);
    ifs.read((char*)res_data, res_size);

    return	true;
}
<|endoftext|>


<commit_before>#pragma once

#include "systemMacro.h"
#include <OgreSharedPtr.h>
#include <OgreResourceManager.h>
#include <vector>
#include <algorithm>
#include <sndfile.h>
#include "AnnTypes.h"

namespace Annwvyn
{
	class AnnDllExport AnnAudioFile : public Ogre::Resource
	{
		///Where the data is actually stored, as bytes.
		std::vector<byte> data;

		///Read bytes from a data stream and stick them inside the "data" re-sizable array
		void readFromStream(Ogre::DataStreamPtr &stream);

		///Utility class that perform a static_cast<AnnAudioFile*> on the pointer you give it.
		inline static AnnAudioFile* cast(void* audioFileRawPtr);

	protected:
		///Actually load the data
		void loadImpl() override;

		///Clear the data vector
		void unloadImpl() override;

		///Return the size of the data vector
		size_t calculateSize() const override;

	public:
		///Create an audio file. This is intended to be called by a resource manager, not by the user.
		AnnAudioFile(Ogre::ResourceManager* creator,
			const Ogre::String& name,
			Ogre::ResourceHandle handle,
			const Ogre::String& group,
			bool isManual = false,
			Ogre::ManualResourceLoader* loader = nullptr);

		virtual ~AnnAudioFile();

		///Return a raw const pointer to the data, in bytes
		const byte* getData() const;

		///Return the size
		size_t getSize() const override;

		//Virtual IO interface

		///Structure that will contain function pointers to all the functions defined below
		static std::unique_ptr<SF_VIRTUAL_IO> sfVioStruct;

		///Get the length of the file. Give that function pointer to libsndfile.
		static sf_count_t sfVioGetFileLen(void* audioFileRawPtr);

		///Seek (move reading cursor) inside virtual file Give that function pointer to libsndfile.
		static sf_count_t sfVioSeek(sf_count_t offset, int whence, void* audioFileRawPtr);

		///REad "count" bytes from cursor to ptr. Will return number of bytes actually read. Will not read past the end of data but do not check writing to the pointer. Give that function pointer to libsndfile.
		static sf_count_t sfVioRead(void* ptr, sf_count_t count, void* audiFileRawPtr);

		///Do nothing. Dummy function just to fill up the interface. Give that function pointer to libsndfile.
		static sf_count_t sfVioWriteDummy(const void *, sf_count_t, void*);

		///return current cursor position. Give that function pointer to libsndfile.
		static sf_count_t sfVioTell(void* audioFileRawPtr);

		///Get the virtual I/O struct. Will initialize it at 1st call. Give that function pointer to libsndfile.
		static SF_VIRTUAL_IO* getSndFileVioStruct();

		///For cleanup. Will deallocate the VioStruct and set the pointer back to nullptr
		static void clearSndFileVioStruct();

		///Current cursor position. the only "state" used while reading the file from libsndfile (except for the data itself, that is non mutable)
		size_t sf_offset;
	};

	using AnnAudioFilePtr = Ogre::SharedPtr<AnnAudioFile>;

	class AnnAudioFileManager : public Ogre::ResourceManager, public Ogre::Singleton<AnnAudioFileManager>
	{
	protected:
		///Create the audio file resource itself
		Ogre::Resource* createImpl(const Ogre::String &name, Ogre::ResourceHandle handle,
			const Ogre::String &group, bool isManual, Ogre::ManualResourceLoader *loader,
			const Ogre::NameValuePairList *createParams) override;

	public:
		///Construct an AnnAudioFileManager. Will register itsel to the Ogre ResourceGroupManager.
		AnnAudioFileManager();

		///Will unregister itself to the Ogre ResourceGroupManager
		virtual ~AnnAudioFileManager();

		///Load a file via the AudioFileManager
		virtual AnnAudioFilePtr load(const Ogre::String& name, const Ogre::String& group);

		///Get singleton ref
		static AnnAudioFileManager& getSingleton();

		///Get singleton pointer
		static AnnAudioFileManager* getSingletonPtr();
	};
}<commit_msg>Add missing doxygen brief descriptions<commit_after>#pragma once

#include "systemMacro.h"
#include <OgreSharedPtr.h>
#include <OgreResourceManager.h>
#include <vector>
#include <algorithm>
#include <sndfile.h>
#include "AnnTypes.h"

namespace Annwvyn
{
	///Ogre resource that contain the data from a binary file for the audio engine importing
	class AnnDllExport AnnAudioFile : public Ogre::Resource
	{
		///Where the data is actually stored, as bytes.
		std::vector<byte> data;

		///Read bytes from a data stream and stick them inside the "data" re-sizable array
		void readFromStream(Ogre::DataStreamPtr &stream);

		///Utility class that perform a static_cast<AnnAudioFile*> on the pointer you give it.
		inline static AnnAudioFile* cast(void* audioFileRawPtr);

	protected:
		///Actually load the data
		void loadImpl() override;

		///Clear the data vector
		void unloadImpl() override;

		///Return the size of the data vector
		size_t calculateSize() const override;

	public:
		///Create an audio file. This is intended to be called by a resource manager, not by the user.
		AnnAudioFile(Ogre::ResourceManager* creator,
			const Ogre::String& name,
			Ogre::ResourceHandle handle,
			const Ogre::String& group,
			bool isManual = false,
			Ogre::ManualResourceLoader* loader = nullptr);

		virtual ~AnnAudioFile();

		///Return a raw const pointer to the data, in bytes
		const byte* getData() const;

		///Return the size
		size_t getSize() const override;

		//Virtual IO interface

		///Structure that will contain function pointers to all the functions defined below
		static std::unique_ptr<SF_VIRTUAL_IO> sfVioStruct;

		///Get the length of the file. Give that function pointer to libsndfile.
		static sf_count_t sfVioGetFileLen(void* audioFileRawPtr);

		///Seek (move reading cursor) inside virtual file Give that function pointer to libsndfile.
		static sf_count_t sfVioSeek(sf_count_t offset, int whence, void* audioFileRawPtr);

		///REad "count" bytes from cursor to ptr. Will return number of bytes actually read. Will not read past the end of data but do not check writing to the pointer. Give that function pointer to libsndfile.
		static sf_count_t sfVioRead(void* ptr, sf_count_t count, void* audiFileRawPtr);

		///Do nothing. Dummy function just to fill up the interface. Give that function pointer to libsndfile.
		static sf_count_t sfVioWriteDummy(const void *, sf_count_t, void*);

		///return current cursor position. Give that function pointer to libsndfile.
		static sf_count_t sfVioTell(void* audioFileRawPtr);

		///Get the virtual I/O struct. Will initialize it at 1st call. Give that function pointer to libsndfile.
		static SF_VIRTUAL_IO* getSndFileVioStruct();

		///For cleanup. Will deallocate the VioStruct and set the pointer back to nullptr
		static void clearSndFileVioStruct();

		///Current cursor position. the only "state" used while reading the file from libsndfile (except for the data itself, that is non mutable)
		size_t sf_offset;
	};

	using AnnAudioFilePtr = Ogre::SharedPtr<AnnAudioFile>;

	///Audio file ResourceManager
	class AnnAudioFileManager : public Ogre::ResourceManager, public Ogre::Singleton<AnnAudioFileManager>
	{
	protected:
		///Create the audio file resource itself
		Ogre::Resource* createImpl(const Ogre::String &name, Ogre::ResourceHandle handle,
			const Ogre::String &group, bool isManual, Ogre::ManualResourceLoader *loader,
			const Ogre::NameValuePairList *createParams) override;

	public:
		///Construct an AnnAudioFileManager. Will register itsel to the Ogre ResourceGroupManager.
		AnnAudioFileManager();

		///Will unregister itself to the Ogre ResourceGroupManager
		virtual ~AnnAudioFileManager();

		///Load a file via the AudioFileManager
		virtual AnnAudioFilePtr load(const Ogre::String& name, const Ogre::String& group);

		///Get singleton ref
		static AnnAudioFileManager& getSingleton();

		///Get singleton pointer
		static AnnAudioFileManager* getSingletonPtr();
	};
}<|endoftext|>