<commit_before>/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France       *
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
* Web site: http://cgogn.unistra.fr/                                           *
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include <QApplication>
#include <QMatrix4x4>

#include <qoglviewer.h>
#include <vec.h>
#include <QMouseEvent>

#include <core/cmap/cmap2.h>

#include <io/map_import.h>

#include <geometry/algos/bounding_box.h>

#include <rendering/map_render.h>
#include <rendering/shaders/shader_flat.h>
#include <rendering/shaders/vbo.h>
#include <rendering/drawer.h>

#include <geometry/algos/picking.h>

#define DEFAULT_MESH_PATH CGOGN_STR(CGOGN_TEST_MESHES_PATH)

using Map2 = cgogn::CMap2<cgogn::DefaultMapTraits>;
//using Vec3 = Eigen::Vector3d;
using Vec3 = cgogn::geometry::Vec_T<std::array<double,3>>;

template<typename T>
using VertexAttributeHandler = Map2::VertexAttributeHandler<T>;

class Viewer : public QOGLViewer
{
public:
	Viewer();
	Viewer(const Viewer&) = delete;
	Viewer& operator=(const Viewer&) = delete;

	virtual void draw();
	virtual void init();
	virtual void mousePressEvent(QMouseEvent *e);
	virtual void keyPressEvent(QKeyEvent *);

	void import(const std::string& surfaceMesh);

	virtual ~Viewer();

private:
	void rayClick(QMouseEvent* event, QVector3D& P, QVector3D& Q);

	QRect viewport_;
	QMatrix4x4 proj_;
	QMatrix4x4 view_;

	Map2 map_;
	VertexAttributeHandler<Vec3> vertex_position_;

	cgogn::geometry::BoundingBox<Vec3> bb_;

	cgogn::rendering::MapRender* render_;

	cgogn::rendering::VBO* vbo_pos_;

	cgogn::rendering::ShaderFlat* shader2_;

	cgogn::rendering::Drawer* drawer_;

	int cell_picking;
};

//
// IMPLEMENTATION
//

void Viewer::import(const std::string& surfaceMesh)
{
	cgogn::io::import_surface<Vec3>(map_, surfaceMesh);

	vertex_position_ = map_.get_attribute<Vec3, Map2::Vertex::ORBIT>("position");

	cgogn::geometry::compute_bounding_box(vertex_position_, bb_);

	setSceneRadius(bb_.diag_size()/2.0);
	Vec3 center = bb_.center();
	setSceneCenter(qoglviewer::Vec(center[0], center[1], center[2]));
	showEntireScene();
}

Viewer::~Viewer()
{
	delete render_;
	delete vbo_pos_;
	delete shader2_;
}

Viewer::Viewer() :
	map_(),
	vertex_position_(),
	bb_(),
	render_(nullptr),
	vbo_pos_(nullptr),
	shader2_(nullptr),
	drawer_(nullptr),
	cell_picking(0)
{}

void Viewer::draw()
{
	camera()->getProjectionMatrix(proj_);
	camera()->getModelViewMatrix(view_);

	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(1.0f, 1.0f);

	shader2_->bind();
	shader2_->set_matrices(proj_,view_);
	shader2_->bind_vao(0);
	render_->draw(cgogn::rendering::TRIANGLES);
	shader2_->release_vao(0);
	shader2_->release();

	glDisable(GL_POLYGON_OFFSET_FILL);

	drawer_->call_list(proj_,view_);

}

void Viewer::init()
{
	glClearColor(0.1f,0.1f,0.3f,0.0f);

	vbo_pos_ = new cgogn::rendering::VBO(3);
	cgogn::rendering::update_vbo(vertex_position_, *vbo_pos_);
	render_ = new cgogn::rendering::MapRender();

	render_->init_primitives<Vec3>(map_, cgogn::rendering::TRIANGLES, vertex_position_);

	shader2_ = new cgogn::rendering::ShaderFlat;
	shader2_->add_vao();
	shader2_->set_vao(0, vbo_pos_);

	shader2_->bind();
	shader2_->set_front_color(QColor(0,200,0));
	shader2_->set_back_color(QColor(0,0,200));
	shader2_->set_ambiant_color(QColor(5,5,5));
	shader2_->release();

	drawer_ = new cgogn::rendering::Drawer(this);
}

void Viewer::rayClick(QMouseEvent* event, QVector3D& P, QVector3D& Q)
{
	int vp[4];
	glGetIntegerv(GL_VIEWPORT, vp);
	QRect viewport = QRect(vp[0],vp[1],vp[2],vp[3]);

	unsigned int x = event->x()*devicePixelRatio();
	unsigned int y = (this->height()-event->y())*devicePixelRatio();

	QVector3D wp(x,y,0.01);
	P = wp.unproject(view_,proj_,viewport);
	QVector3D wq(x,y,0.99);
	Q = wq.unproject(view_,proj_,viewport);

}

void Viewer::keyPressEvent(QKeyEvent *ev)
{
	switch (ev->key())
	{
		case Qt::Key_0:
			cell_picking = 0;
			break;
		case Qt::Key_1:
			cell_picking = 1;
			break;
		case Qt::Key_2:
			cell_picking = 2;
			break;
		case Qt::Key_3:
			cell_picking = 3;
			break;
	}
	QOGLViewer::keyPressEvent(ev);
}

void Viewer::mousePressEvent(QMouseEvent* event)
{
	if (event->modifiers() & Qt::ShiftModifier)
	{
		QVector3D P;
		QVector3D Q;
		rayClick(event,P,Q);

		Vec3 A(P[0],P[1],P[2]);
		Vec3 B(Q[0],Q[1],Q[2]);

		drawer_->new_list();
		switch(cell_picking)
		{
			case 0:
			{
				std::vector<Map2::Vertex> selected;
				cgogn::geometry::picking_vertex<Vec3>(map_,vertex_position_,A,B,selected);
				std::cout<< "Selected vertices: "<< selected.size()<<std::endl;
				if (!selected.empty())
				{
					drawer_->point_size_aa(4.0);
					drawer_->begin(GL_POINTS);
					// closest point in red
					drawer_->color3f(1.0,0.0,0.0);
					drawer_->vertex3fv(vertex_position_[selected[0]]);
					// others in yellow
					drawer_->color3f(1.0,1.0,0.0);
					for(unsigned int i=1u;i<selected.size();++i)
						drawer_->vertex3fv(vertex_position_[selected[i]]);
					drawer_->end();
				}
			}
			break;
			case 1:
			{
				std::vector<Map2::Edge> selected;
				cgogn::geometry::picking_edge<Vec3>(map_,vertex_position_,A,B,selected);
				std::cout<< "Selected edges: "<< selected.size()<<std::endl;
				if (!selected.empty())
				{
					drawer_->line_width(2.0);
					drawer_->begin(GL_LINES);
					// closest face in red
					drawer_->color3f(1.0,0.0,0.0);
					cgogn::rendering::add_edge_to_drawer<Vec3>(map_,selected[0],vertex_position_,drawer_);
					// others in yellow
					drawer_->color3f(1.0,1.0,0.0);
					for(unsigned int i=1u;i<selected.size();++i)
						cgogn::rendering::add_edge_to_drawer<Vec3>(map_,selected[i],vertex_position_,drawer_);
					drawer_->end();
				}
			}
			break;
			case 2:
			{
				std::vector<Map2::Face> selected;
				cgogn::geometry::picking_face<Vec3>(map_,vertex_position_,A,B,selected);
				std::cout<< "Selected faces: "<< selected.size()<<std::endl;
				if (!selected.empty())
				{
					drawer_->line_width(2.0);
					drawer_->begin(GL_LINES);
					// closest face in red
					drawer_->color3f(1.0,0.0,0.0);
					cgogn::rendering::add_face_to_drawer<Vec3>(map_,selected[0],vertex_position_,drawer_);
					// others in yellow
					drawer_->color3f(1.0,1.0,0.0);
					for(unsigned int i=1u;i<selected.size();++i)
						cgogn::rendering::add_face_to_drawer<Vec3>(map_,selected[i],vertex_position_,drawer_);
					drawer_->end();
				}
			}
			break;
			case 3:
			{
				std::vector<Map2::Volume> selected;
				cgogn::geometry::picking_volume<Vec3>(map_,vertex_position_,A,B,selected);
				std::cout<< "Selected volumes: "<< selected.size()<<std::endl;
				if (!selected.empty())
				{
					drawer_->line_width(2.0);
					drawer_->begin(GL_LINES);
					// closest face in red
					drawer_->color3f(1.0,0.0,0.0);
					cgogn::rendering::add_volume_to_drawer<Vec3>(map_,selected[0],vertex_position_,drawer_);
					// others in yellow
					drawer_->color3f(1.0,1.0,0.0);
					for(unsigned int i=1u;i<selected.size();++i)
						cgogn::rendering::add_volume_to_drawer<Vec3>(map_,selected[i],vertex_position_,drawer_);
					drawer_->end();
				}
			}
			break;
		}
		drawer_->end_list();
	}

	QOGLViewer::mousePressEvent(event);
}

int main(int argc, char** argv)
{
	std::string surfaceMesh;
	if (argc < 2)
	{
		std::cout << "USAGE: " << argv[0] << " [filename]" << std::endl;
		surfaceMesh = std::string(DEFAULT_MESH_PATH) + std::string("aneurysm3D_1.off");
		std::cout << "Using default mesh : " << surfaceMesh << std::endl;
	}
	else
		surfaceMesh = std::string(argv[1]);

	QApplication application(argc, argv);
	qoglviewer::init_ogl_context();

	// Instantiate the viewer.
	Viewer viewer;
	viewer.setWindowTitle("simpleViewer");
	viewer.import(surfaceMesh);
	viewer.show();
	viewer.resize(800,600);

	// Run main loop.
	return application.exec();
}
<commit_msg>remove feature supported only in Qt 5.5<commit_after>/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France       *
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
* Web site: http://cgogn.unistra.fr/                                           *
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include <QApplication>
#include <QMatrix4x4>

#include <qoglviewer.h>
#include <vec.h>
#include <QMouseEvent>
#include <QVector3D>

#include <core/cmap/cmap2.h>

#include <io/map_import.h>

#include <geometry/algos/bounding_box.h>

#include <rendering/map_render.h>
#include <rendering/shaders/shader_flat.h>
#include <rendering/shaders/vbo.h>
#include <rendering/drawer.h>

#include <geometry/algos/picking.h>

#define DEFAULT_MESH_PATH CGOGN_STR(CGOGN_TEST_MESHES_PATH)

using Map2 = cgogn::CMap2<cgogn::DefaultMapTraits>;
//using Vec3 = Eigen::Vector3d;
using Vec3 = cgogn::geometry::Vec_T<std::array<double,3>>;

template<typename T>
using VertexAttributeHandler = Map2::VertexAttributeHandler<T>;

class Viewer : public QOGLViewer
{
public:
	Viewer();
	Viewer(const Viewer&) = delete;
	Viewer& operator=(const Viewer&) = delete;

	virtual void draw();
	virtual void init();
	virtual void mousePressEvent(QMouseEvent *e);
	virtual void keyPressEvent(QKeyEvent *);

	void import(const std::string& surfaceMesh);

	virtual ~Viewer();

private:
	void rayClick(QMouseEvent* event, qoglviewer::Vec& P, qoglviewer::Vec& Q);

	QRect viewport_;
	QMatrix4x4 proj_;
	QMatrix4x4 view_;

	Map2 map_;
	VertexAttributeHandler<Vec3> vertex_position_;

	cgogn::geometry::BoundingBox<Vec3> bb_;

	cgogn::rendering::MapRender* render_;

	cgogn::rendering::VBO* vbo_pos_;

	cgogn::rendering::ShaderFlat* shader2_;

	cgogn::rendering::Drawer* drawer_;

	int cell_picking;
};

//
// IMPLEMENTATION
//

void Viewer::import(const std::string& surfaceMesh)
{
	cgogn::io::import_surface<Vec3>(map_, surfaceMesh);

	vertex_position_ = map_.get_attribute<Vec3, Map2::Vertex::ORBIT>("position");

	cgogn::geometry::compute_bounding_box(vertex_position_, bb_);

	setSceneRadius(bb_.diag_size()/2.0);
	Vec3 center = bb_.center();
	setSceneCenter(qoglviewer::Vec(center[0], center[1], center[2]));
	showEntireScene();
}

Viewer::~Viewer()
{
	delete render_;
	delete vbo_pos_;
	delete shader2_;
}

Viewer::Viewer() :
	map_(),
	vertex_position_(),
	bb_(),
	render_(nullptr),
	vbo_pos_(nullptr),
	shader2_(nullptr),
	drawer_(nullptr),
	cell_picking(0)
{}

void Viewer::draw()
{
	camera()->getProjectionMatrix(proj_);
	camera()->getModelViewMatrix(view_);

	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(1.0f, 1.0f);

	shader2_->bind();
	shader2_->set_matrices(proj_,view_);
	shader2_->bind_vao(0);
	render_->draw(cgogn::rendering::TRIANGLES);
	shader2_->release_vao(0);
	shader2_->release();

	glDisable(GL_POLYGON_OFFSET_FILL);

	drawer_->call_list(proj_,view_);

}

void Viewer::init()
{
	glClearColor(0.1f,0.1f,0.3f,0.0f);

	vbo_pos_ = new cgogn::rendering::VBO(3);
	cgogn::rendering::update_vbo(vertex_position_, *vbo_pos_);
	render_ = new cgogn::rendering::MapRender();

	render_->init_primitives<Vec3>(map_, cgogn::rendering::TRIANGLES, vertex_position_);

	shader2_ = new cgogn::rendering::ShaderFlat;
	shader2_->add_vao();
	shader2_->set_vao(0, vbo_pos_);

	shader2_->bind();
	shader2_->set_front_color(QColor(0,200,0));
	shader2_->set_back_color(QColor(0,0,200));
	shader2_->set_ambiant_color(QColor(5,5,5));
	shader2_->release();

	drawer_ = new cgogn::rendering::Drawer(this);
}

void Viewer::rayClick(QMouseEvent* event, qoglviewer::Vec& P, qoglviewer::Vec& Q)
{
	P = camera()->unprojectedCoordinatesOf(qoglviewer::Vec(event->x(),event->y(),0.01));
	Q = camera()->unprojectedCoordinatesOf(qoglviewer::Vec(event->x(),event->y(),0.99));
}

void Viewer::keyPressEvent(QKeyEvent *ev)
{
	switch (ev->key())
	{
		case Qt::Key_0:
			cell_picking = 0;
			break;
		case Qt::Key_1:
			cell_picking = 1;
			break;
		case Qt::Key_2:
			cell_picking = 2;
			break;
		case Qt::Key_3:
			cell_picking = 3;
			break;
	}
	QOGLViewer::keyPressEvent(ev);
}

void Viewer::mousePressEvent(QMouseEvent* event)
{
	if (event->modifiers() & Qt::ShiftModifier)
	{
		qoglviewer::Vec P;
		qoglviewer::Vec Q;
		rayClick(event,P,Q);

		Vec3 A(P[0],P[1],P[2]);
		Vec3 B(Q[0],Q[1],Q[2]);

		drawer_->new_list();
		switch(cell_picking)
		{
			case 0:
			{
				std::vector<Map2::Vertex> selected;
				cgogn::geometry::picking_vertex<Vec3>(map_,vertex_position_,A,B,selected);
				std::cout<< "Selected vertices: "<< selected.size()<<std::endl;
				if (!selected.empty())
				{
					drawer_->point_size_aa(4.0);
					drawer_->begin(GL_POINTS);
					// closest point in red
					drawer_->color3f(1.0,0.0,0.0);
					drawer_->vertex3fv(vertex_position_[selected[0]]);
					// others in yellow
					drawer_->color3f(1.0,1.0,0.0);
					for(unsigned int i=1u;i<selected.size();++i)
						drawer_->vertex3fv(vertex_position_[selected[i]]);
					drawer_->end();
				}
			}
			break;
			case 1:
			{
				std::vector<Map2::Edge> selected;
				cgogn::geometry::picking_edge<Vec3>(map_,vertex_position_,A,B,selected);
				std::cout<< "Selected edges: "<< selected.size()<<std::endl;
				if (!selected.empty())
				{
					drawer_->line_width(2.0);
					drawer_->begin(GL_LINES);
					// closest face in red
					drawer_->color3f(1.0,0.0,0.0);
					cgogn::rendering::add_edge_to_drawer<Vec3>(map_,selected[0],vertex_position_,drawer_);
					// others in yellow
					drawer_->color3f(1.0,1.0,0.0);
					for(unsigned int i=1u;i<selected.size();++i)
						cgogn::rendering::add_edge_to_drawer<Vec3>(map_,selected[i],vertex_position_,drawer_);
					drawer_->end();
				}
			}
			break;
			case 2:
			{
				std::vector<Map2::Face> selected;
				cgogn::geometry::picking_face<Vec3>(map_,vertex_position_,A,B,selected);
				std::cout<< "Selected faces: "<< selected.size()<<std::endl;
				if (!selected.empty())
				{
					drawer_->line_width(2.0);
					drawer_->begin(GL_LINES);
					// closest face in red
					drawer_->color3f(1.0,0.0,0.0);
					cgogn::rendering::add_face_to_drawer<Vec3>(map_,selected[0],vertex_position_,drawer_);
					// others in yellow
					drawer_->color3f(1.0,1.0,0.0);
					for(unsigned int i=1u;i<selected.size();++i)
						cgogn::rendering::add_face_to_drawer<Vec3>(map_,selected[i],vertex_position_,drawer_);
					drawer_->end();
				}
			}
			break;
			case 3:
			{
				std::vector<Map2::Volume> selected;
				cgogn::geometry::picking_volume<Vec3>(map_,vertex_position_,A,B,selected);
				std::cout<< "Selected volumes: "<< selected.size()<<std::endl;
				if (!selected.empty())
				{
					drawer_->line_width(2.0);
					drawer_->begin(GL_LINES);
					// closest face in red
					drawer_->color3f(1.0,0.0,0.0);
					cgogn::rendering::add_volume_to_drawer<Vec3>(map_,selected[0],vertex_position_,drawer_);
					// others in yellow
					drawer_->color3f(1.0,1.0,0.0);
					for(unsigned int i=1u;i<selected.size();++i)
						cgogn::rendering::add_volume_to_drawer<Vec3>(map_,selected[i],vertex_position_,drawer_);
					drawer_->end();
				}
			}
			break;
		}
		drawer_->end_list();
	}

	QOGLViewer::mousePressEvent(event);
}

int main(int argc, char** argv)
{
	std::string surfaceMesh;
	if (argc < 2)
	{
		std::cout << "USAGE: " << argv[0] << " [filename]" << std::endl;
		surfaceMesh = std::string(DEFAULT_MESH_PATH) + std::string("aneurysm3D_1.off");
		std::cout << "Using default mesh : " << surfaceMesh << std::endl;
	}
	else
		surfaceMesh = std::string(argv[1]);

	QApplication application(argc, argv);
	qoglviewer::init_ogl_context();

	// Instantiate the viewer.
	Viewer viewer;
	viewer.setWindowTitle("simpleViewer");
	viewer.import(surfaceMesh);
	viewer.show();
	viewer.resize(800,600);

	// Run main loop.
	return application.exec();
}
<|endoftext|>


<commit_before>#include <memory_cache_serversettings.h>

#include <log.h>

#include <QTextStream>
#include <QFile>
#include <QDebug>
#include <QByteArray>
#include <QDateTime>
#include <QDir>

// IMemoryCache
QString MemoryCacheServerSettings::name(){
	return "serversettings";
}

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

MemoryCacheServerSettings::MemoryCacheServerSettings(IWebSocketServer *pWebSocketServer){
	m_pWebSocketServer = pWebSocketServer;
    TAG = "MemoryCacheServerSettings";

    QString sGroupProfile = "profile";
    addNewSetting(new ServerSettHelper(sGroupProfile, "profile_change_nick", true));

    QString sGroupMail = "mail";
    addNewSetting(new ServerSettHelper(sGroupMail, "mail_from", QString("freehackquest@gmail.com")));
    addNewSetting(new ServerSettHelper(sGroupMail, "mail_host", QString("ssl://smtp.gmail.com")));
    addNewSetting(new ServerSettHelper(sGroupMail, "mail_port", 465));
    addNewSetting(new ServerSettHelper(sGroupMail, "mail_username", QString("freehackquest@gmail.com")));
    addNewSetting(new ServerSettHelper(sGroupMail, "mail_password", QString("some"), true));
    addNewSetting(new ServerSettHelper(sGroupMail, "mail_auth", true));
    addNewSetting(new ServerSettHelper(sGroupMail, "mail_allow", true));
    addNewSetting(new ServerSettHelper(sGroupMail, "mail_system_message_admin_email", QString("")));

    // Google Map API
    QString sGroupGoogleMap = "google_map";
    addNewSetting(new ServerSettHelper(sGroupGoogleMap, "google_map_api_key", QString("some")));

    // server folders
    QString sGroupServerFolders = "server_folders";
    addNewSetting(new ServerSettHelper(sGroupServerFolders, "server_folder_games", QString("/var/www/html/fhq/files/games/")));
    addNewSetting(new ServerSettHelper(sGroupServerFolders, "server_folder_games_url", QString("https://freehackquest.com/files/games/")));

    QStringList listFoundInDatabase;

    QSqlDatabase db = *(pWebSocketServer->database());

    // load from database
    {
        QSqlQuery query(db);
        query.prepare("SELECT * FROM settings");
        query.exec();
        while (query.next()) {
            QSqlRecord record = query.record();
            QString sName = record.value("name").toString();
            QString sValue = record.value("value").toString();
            QString sType = record.value("type").toString();
            QString sGroup = record.value("group").toString();

            listFoundInDatabase << sName;

            if(m_mapSettings.contains(sName)){
                ServerSettHelper *pServerSettHelper = m_mapSettings[sName];
                if(sType != pServerSettHelper->type()){
                    Log::err(TAG, "Wrong type for setting '" + sName + "' (expected '" + pServerSettHelper->type() + "', but got: '" + sType + "'");
                    // TODO change type of setting or remove
                }else{
                    if(pServerSettHelper->isString()){
                        pServerSettHelper->setValue(sValue);
                    }else if(pServerSettHelper->isBoolean()){
                        pServerSettHelper->setValue(sValue == "yes");
                    }else if(pServerSettHelper->isInteger()){
                        // TODO check convertation string to int
                        pServerSettHelper->setValue(sValue.toInt());
                    }else if(pServerSettHelper->isPassword()){
                        pServerSettHelper->setValue(sValue);
                    }else{
                        Log::err(TAG, "No handle type for setting '" + sName + "'");
                    }
                }
            }else{
                Log::warn(TAG, "Undefined settings name in database: " + sName);
            }
        }
    }

    // check string settings in database
    foreach( QString sKey, m_mapSettings.keys()){
        if(!listFoundInDatabase.contains(sKey)){
            ServerSettHelper *pServerSettHelper = m_mapSettings.value(sKey);
            initSettingDatabase(pServerSettHelper);
        }
    }
}

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

void MemoryCacheServerSettings::addNewSetting(ServerSettHelper* pServerSettHelper){
    QString sName = pServerSettHelper->name();
    if(!m_mapSettings.contains(sName)){
        m_mapSettings[sName] = pServerSettHelper;
    }else{
        Log::warn(TAG, "Duplicate setting '" + sName + "'. Skip");
    }
}

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

QString MemoryCacheServerSettings::getSettString(QString sName){
	QMutexLocker locker (&m_mtxServerSettings);
    QString sResult = "";
    if(m_mapSettings.contains(sName)){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);
        if(!pServerSettHelper->isString()){
            Log::err(TAG, "Wrong type setting string (get): " + sName);
        }else{
            sResult = pServerSettHelper->valueAsString();
        }
    }else{
        Log::err(TAG, "Not found server setting string (get): " + sName);
    }
    return sResult;
}

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

void MemoryCacheServerSettings::setSettString(QString sName, QString sValue){
	QMutexLocker locker (&m_mtxServerSettings);
    if(m_mapSettings.contains(sName)){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);
        if(!pServerSettHelper->isString()){
            Log::err(TAG, "Wrong type setting string (set): " + sName);
        }else{
            pServerSettHelper->setValue(sValue);
            updateSettingDatabase(pServerSettHelper);
        }
    }else{
        Log::err(TAG, "Not found server setting string (set): " + sName);
    }
}

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

QString MemoryCacheServerSettings::getSettPassword(QString sName){
    QMutexLocker locker (&m_mtxServerSettings);
    QString sResult = "";
    if(m_mapSettings.contains(sName)){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);
        if(!pServerSettHelper->isPassword()){
            Log::err(TAG, "Wrong type setting password (get): " + sName);
        }else{
            sResult = pServerSettHelper->valueAsString();
        }
    }else{
        Log::err(TAG, "Not found server setting password (get): " + sName);
    }
    return sResult;
}

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

void MemoryCacheServerSettings::setSettPassword(QString sName, QString sValue){
    QMutexLocker locker (&m_mtxServerSettings);
    if(m_mapSettings.contains(sName)){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);
        if(!pServerSettHelper->isPassword()){
            Log::err(TAG, "Wrong type setting string (set): " + sName);
        }else{
            pServerSettHelper->setValue(sValue);
            updateSettingDatabase(pServerSettHelper);
        }
    }else{
        Log::err(TAG, "Not found server setting string (set): " + sName);
    }
}

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

int MemoryCacheServerSettings::getSettInteger(QString sName){
	QMutexLocker locker (&m_mtxServerSettings);
    int nResult = 0;
    if(m_mapSettings.contains(sName)){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);
        if(!pServerSettHelper->isInteger()){
            Log::err(TAG, "Wrong type setting integer (get): " + sName);
        }else{
            nResult = pServerSettHelper->valueAsInteger();
        }
    }else{
        Log::err(TAG, "Not found server setting integer (get): " + sName);
    }
    return nResult;
}

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

void MemoryCacheServerSettings::setSettInteger(QString sName, int nValue){
	QMutexLocker locker (&m_mtxServerSettings);
    if(m_mapSettings.contains(sName)){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);
        if(!pServerSettHelper->isInteger()){
            Log::err(TAG, "Wrong type setting integer (set): " + sName);
        }else{
            pServerSettHelper->setValue(nValue);
            updateSettingDatabase(pServerSettHelper);
        }
    }else{
        Log::err(TAG, "Not found server setting integer (set): " + sName);
    }
}

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

bool MemoryCacheServerSettings::getSettBoolean(QString sName){
	QMutexLocker locker (&m_mtxServerSettings);
    bool bResult = false;
    if(m_mapSettings.contains(sName)){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);
        if(!pServerSettHelper->isBoolean()){
            Log::err(TAG, "Wrong type setting boolean (get): " + sName);
        }else{
            bResult = pServerSettHelper->valueAsBoolean();
        }
    }else{
        Log::err(TAG, "Not found server setting boolean (get): " + sName);
    }
    return bResult;
}

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

void MemoryCacheServerSettings::setSettBoolean(QString sName, bool bValue){
    QMutexLocker locker (&m_mtxServerSettings);
    if(m_mapSettings.contains(sName)){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);
        if(!pServerSettHelper->isBoolean()){
            Log::err(TAG, "Wrong type setting boolean (set): " + sName);
        }else{
            pServerSettHelper->setValue(bValue);
            updateSettingDatabase(pServerSettHelper);
        }
    }else{
        Log::err(TAG, "Not found server setting integer (set): " + sName);
    }
}

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

bool MemoryCacheServerSettings::hasSett(QString sName){
    return m_mapSettings.contains(sName);
}

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

QString MemoryCacheServerSettings::getSettType(QString sName){
    if(m_mapSettings.contains(sName)){
        return m_mapSettings[sName]->type();
    }
    return "";
}

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

QJsonArray MemoryCacheServerSettings::toJsonArray(){
    QJsonArray res;
    foreach( QString sName, m_mapSettings.keys()){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);

        QJsonObject sett;
        sett["name"] = pServerSettHelper->name();
        if(pServerSettHelper->isBoolean()){
			sett["value"] = pServerSettHelper->valueAsBoolean();
        }else if(pServerSettHelper->isString()){
            sett["value"] = pServerSettHelper->valueAsString();
        }else if(pServerSettHelper->isInteger()){
            sett["value"] = pServerSettHelper->valueAsInteger();
        }else if(pServerSettHelper->isPassword()){
            sett["value"] = "******";
        }else{
            sett["value"] = pServerSettHelper->valueAsString();
        }

        sett["group"] = pServerSettHelper->group();
        sett["type"] = pServerSettHelper->type();
        res.append(sett);
    }
	return res;
}

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

void MemoryCacheServerSettings::initSettingDatabase(ServerSettHelper *pServerSettHelper){
    Log::info(TAG, "Init settings to database: " + pServerSettHelper->name());
    QSqlDatabase db = *(m_pWebSocketServer->database());
    QSqlQuery query(db);
    query.prepare("INSERT INTO settings (`name`, `value`, `group`, `type`) VALUES (:name, :value, :group, :type)");
    query.bindValue(":name", pServerSettHelper->name());
    query.bindValue(":value", pServerSettHelper->valueAsString());
    query.bindValue(":group", pServerSettHelper->group());
    query.bindValue(":type", pServerSettHelper->type());
    if(!query.exec()){
        Log::err(TAG, query.lastError().text());
    }
}

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

void MemoryCacheServerSettings::updateSettingDatabase(ServerSettHelper *pServerSettHelper){
    QSqlDatabase db = *(m_pWebSocketServer->database());
    QSqlQuery query(db);
    query.prepare("UPDATE settings SET value = :value WHERE name = :name");
    query.bindValue(":value", pServerSettHelper->valueAsString());
    query.bindValue(":name", pServerSettHelper->name());
    if(!query.exec()){
        Log::err(TAG, query.lastError().text());
    }
}
<commit_msg>Updated server settings<commit_after>#include <memory_cache_serversettings.h>

#include <log.h>

#include <QTextStream>
#include <QFile>
#include <QDebug>
#include <QByteArray>
#include <QDateTime>
#include <QDir>

// IMemoryCache
QString MemoryCacheServerSettings::name(){
	return "serversettings";
}

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

MemoryCacheServerSettings::MemoryCacheServerSettings(IWebSocketServer *pWebSocketServer){
	m_pWebSocketServer = pWebSocketServer;
    TAG = "MemoryCacheServerSettings";

    QString sGroupProfile = "profile";
    addNewSetting(new ServerSettHelper(sGroupProfile, "profile_change_nick", true));

    QString sGroupMail = "mail";
    addNewSetting(new ServerSettHelper(sGroupMail, "mail_from", QString("freehackquest@gmail.com")));
    addNewSetting(new ServerSettHelper(sGroupMail, "mail_host", QString("ssl://smtp.gmail.com")));
    addNewSetting(new ServerSettHelper(sGroupMail, "mail_port", 465));
    addNewSetting(new ServerSettHelper(sGroupMail, "mail_username", QString("freehackquest@gmail.com")));
    addNewSetting(new ServerSettHelper(sGroupMail, "mail_password", QString("some"), true));
    addNewSetting(new ServerSettHelper(sGroupMail, "mail_auth", true));
    addNewSetting(new ServerSettHelper(sGroupMail, "mail_allow", true));
    addNewSetting(new ServerSettHelper(sGroupMail, "mail_system_message_admin_email", QString("")));

    // Google Map API
    QString sGroupGoogleMap = "google_map";
    addNewSetting(new ServerSettHelper(sGroupGoogleMap, "google_map_api_key", QString("some")));

    // server folders
    QString sGroupServerFolders = "server_folders";
    addNewSetting(new ServerSettHelper(sGroupServerFolders, "server_folder_games", QString("/var/www/html/fhq/files/games/")));
    addNewSetting(new ServerSettHelper(sGroupServerFolders, "server_folder_games_url", QString("https://freehackquest.com/files/games/")));
    addNewSetting(new ServerSettHelper(sGroupServerFolders, "server_folder_quests", QString("/var/www/html/fhq/files/quests/")));
    addNewSetting(new ServerSettHelper(sGroupServerFolders, "server_folder_quests_url", QString("https://freehackquest.com/files/quests/")));
    addNewSetting(new ServerSettHelper(sGroupServerFolders, "server_folder_users", QString("/var/www/html/fhq/files/quests/")));
    addNewSetting(new ServerSettHelper(sGroupServerFolders, "server_folder_users_url", QString("https://freehackquest.com/files/quests/")));

    QStringList listFoundInDatabase;

    QSqlDatabase db = *(pWebSocketServer->database());

    // load from database
    {
        QSqlQuery query(db);
        query.prepare("SELECT * FROM settings");
        query.exec();
        while (query.next()) {
            QSqlRecord record = query.record();
            QString sName = record.value("name").toString();
            QString sValue = record.value("value").toString();
            QString sType = record.value("type").toString();
            QString sGroup = record.value("group").toString();

            listFoundInDatabase << sName;

            if(m_mapSettings.contains(sName)){
                ServerSettHelper *pServerSettHelper = m_mapSettings[sName];
                if(sType != pServerSettHelper->type()){
                    Log::err(TAG, "Wrong type for setting '" + sName + "' (expected '" + pServerSettHelper->type() + "', but got: '" + sType + "'");
                    // TODO change type of setting or remove
                }else{
                    if(pServerSettHelper->isString()){
                        pServerSettHelper->setValue(sValue);
                    }else if(pServerSettHelper->isBoolean()){
                        pServerSettHelper->setValue(sValue == "yes");
                    }else if(pServerSettHelper->isInteger()){
                        // TODO check convertation string to int
                        pServerSettHelper->setValue(sValue.toInt());
                    }else if(pServerSettHelper->isPassword()){
                        pServerSettHelper->setValue(sValue);
                    }else{
                        Log::err(TAG, "No handle type for setting '" + sName + "'");
                    }
                }
            }else{
                Log::warn(TAG, "Undefined settings name in database: " + sName);
            }
        }
    }

    // check string settings in database
    foreach( QString sKey, m_mapSettings.keys()){
        if(!listFoundInDatabase.contains(sKey)){
            ServerSettHelper *pServerSettHelper = m_mapSettings.value(sKey);
            initSettingDatabase(pServerSettHelper);
        }
    }
}

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

void MemoryCacheServerSettings::addNewSetting(ServerSettHelper* pServerSettHelper){
    QString sName = pServerSettHelper->name();
    if(!m_mapSettings.contains(sName)){
        m_mapSettings[sName] = pServerSettHelper;
    }else{
        Log::warn(TAG, "Duplicate setting '" + sName + "'. Skip");
    }
}

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

QString MemoryCacheServerSettings::getSettString(QString sName){
	QMutexLocker locker (&m_mtxServerSettings);
    QString sResult = "";
    if(m_mapSettings.contains(sName)){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);
        if(!pServerSettHelper->isString()){
            Log::err(TAG, "Wrong type setting string (get): " + sName);
        }else{
            sResult = pServerSettHelper->valueAsString();
        }
    }else{
        Log::err(TAG, "Not found server setting string (get): " + sName);
    }
    return sResult;
}

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

void MemoryCacheServerSettings::setSettString(QString sName, QString sValue){
	QMutexLocker locker (&m_mtxServerSettings);
    if(m_mapSettings.contains(sName)){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);
        if(!pServerSettHelper->isString()){
            Log::err(TAG, "Wrong type setting string (set): " + sName);
        }else{
            pServerSettHelper->setValue(sValue);
            updateSettingDatabase(pServerSettHelper);
        }
    }else{
        Log::err(TAG, "Not found server setting string (set): " + sName);
    }
}

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

QString MemoryCacheServerSettings::getSettPassword(QString sName){
    QMutexLocker locker (&m_mtxServerSettings);
    QString sResult = "";
    if(m_mapSettings.contains(sName)){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);
        if(!pServerSettHelper->isPassword()){
            Log::err(TAG, "Wrong type setting password (get): " + sName);
        }else{
            sResult = pServerSettHelper->valueAsString();
        }
    }else{
        Log::err(TAG, "Not found server setting password (get): " + sName);
    }
    return sResult;
}

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

void MemoryCacheServerSettings::setSettPassword(QString sName, QString sValue){
    QMutexLocker locker (&m_mtxServerSettings);
    if(m_mapSettings.contains(sName)){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);
        if(!pServerSettHelper->isPassword()){
            Log::err(TAG, "Wrong type setting string (set): " + sName);
        }else{
            pServerSettHelper->setValue(sValue);
            updateSettingDatabase(pServerSettHelper);
        }
    }else{
        Log::err(TAG, "Not found server setting string (set): " + sName);
    }
}

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

int MemoryCacheServerSettings::getSettInteger(QString sName){
	QMutexLocker locker (&m_mtxServerSettings);
    int nResult = 0;
    if(m_mapSettings.contains(sName)){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);
        if(!pServerSettHelper->isInteger()){
            Log::err(TAG, "Wrong type setting integer (get): " + sName);
        }else{
            nResult = pServerSettHelper->valueAsInteger();
        }
    }else{
        Log::err(TAG, "Not found server setting integer (get): " + sName);
    }
    return nResult;
}

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

void MemoryCacheServerSettings::setSettInteger(QString sName, int nValue){
	QMutexLocker locker (&m_mtxServerSettings);
    if(m_mapSettings.contains(sName)){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);
        if(!pServerSettHelper->isInteger()){
            Log::err(TAG, "Wrong type setting integer (set): " + sName);
        }else{
            pServerSettHelper->setValue(nValue);
            updateSettingDatabase(pServerSettHelper);
        }
    }else{
        Log::err(TAG, "Not found server setting integer (set): " + sName);
    }
}

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

bool MemoryCacheServerSettings::getSettBoolean(QString sName){
	QMutexLocker locker (&m_mtxServerSettings);
    bool bResult = false;
    if(m_mapSettings.contains(sName)){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);
        if(!pServerSettHelper->isBoolean()){
            Log::err(TAG, "Wrong type setting boolean (get): " + sName);
        }else{
            bResult = pServerSettHelper->valueAsBoolean();
        }
    }else{
        Log::err(TAG, "Not found server setting boolean (get): " + sName);
    }
    return bResult;
}

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

void MemoryCacheServerSettings::setSettBoolean(QString sName, bool bValue){
    QMutexLocker locker (&m_mtxServerSettings);
    if(m_mapSettings.contains(sName)){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);
        if(!pServerSettHelper->isBoolean()){
            Log::err(TAG, "Wrong type setting boolean (set): " + sName);
        }else{
            pServerSettHelper->setValue(bValue);
            updateSettingDatabase(pServerSettHelper);
        }
    }else{
        Log::err(TAG, "Not found server setting integer (set): " + sName);
    }
}

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

bool MemoryCacheServerSettings::hasSett(QString sName){
    return m_mapSettings.contains(sName);
}

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

QString MemoryCacheServerSettings::getSettType(QString sName){
    if(m_mapSettings.contains(sName)){
        return m_mapSettings[sName]->type();
    }
    return "";
}

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

QJsonArray MemoryCacheServerSettings::toJsonArray(){
    QJsonArray res;
    foreach( QString sName, m_mapSettings.keys()){
        ServerSettHelper* pServerSettHelper = m_mapSettings.value(sName);

        QJsonObject sett;
        sett["name"] = pServerSettHelper->name();
        if(pServerSettHelper->isBoolean()){
			sett["value"] = pServerSettHelper->valueAsBoolean();
        }else if(pServerSettHelper->isString()){
            sett["value"] = pServerSettHelper->valueAsString();
        }else if(pServerSettHelper->isInteger()){
            sett["value"] = pServerSettHelper->valueAsInteger();
        }else if(pServerSettHelper->isPassword()){
            sett["value"] = "******";
        }else{
            sett["value"] = pServerSettHelper->valueAsString();
        }

        sett["group"] = pServerSettHelper->group();
        sett["type"] = pServerSettHelper->type();
        res.append(sett);
    }
	return res;
}

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

void MemoryCacheServerSettings::initSettingDatabase(ServerSettHelper *pServerSettHelper){
    Log::info(TAG, "Init settings to database: " + pServerSettHelper->name());
    QSqlDatabase db = *(m_pWebSocketServer->database());
    QSqlQuery query(db);
    query.prepare("INSERT INTO settings (`name`, `value`, `group`, `type`) VALUES (:name, :value, :group, :type)");
    query.bindValue(":name", pServerSettHelper->name());
    query.bindValue(":value", pServerSettHelper->valueAsString());
    query.bindValue(":group", pServerSettHelper->group());
    query.bindValue(":type", pServerSettHelper->type());
    if(!query.exec()){
        Log::err(TAG, query.lastError().text());
    }
}

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

void MemoryCacheServerSettings::updateSettingDatabase(ServerSettHelper *pServerSettHelper){
    QSqlDatabase db = *(m_pWebSocketServer->database());
    QSqlQuery query(db);
    query.prepare("UPDATE settings SET value = :value WHERE name = :name");
    query.bindValue(":value", pServerSettHelper->valueAsString());
    query.bindValue(":name", pServerSettHelper->name());
    if(!query.exec()){
        Log::err(TAG, query.lastError().text());
    }
}
<|endoftext|>


<commit_before>#ifndef utf8_hh_INCLUDED
#define utf8_hh_INCLUDED

#include "assert.hh"
#include "unicode.hh"
#include "units.hh"

#include <cstddef>

namespace Kakoune
{

namespace utf8
{

template<typename Iterator>
[[gnu::always_inline]]
inline char read(Iterator& it) noexcept { char c = *it; ++it; return c; }

// return true if it points to the first byte of a (either single or
// multibyte) character
[[gnu::always_inline]]
inline bool is_character_start(char c) noexcept
{
    return (c & 0xC0) != 0x80;
}

namespace InvalidPolicy
{

struct Assert
{
    Codepoint operator()(Codepoint cp) const { kak_assert(false); return cp; }
};

struct Pass
{
    Codepoint operator()(Codepoint cp) const noexcept { return cp; }
};

}

// returns the codepoint of the character whose first byte
// is pointed by it
template<typename InvalidPolicy = utf8::InvalidPolicy::Pass,
         typename Iterator>
Codepoint read_codepoint(Iterator& it, const Iterator& end)
    noexcept(noexcept(InvalidPolicy{}(0)))
{
    if (it == end)
        return InvalidPolicy{}(-1);
    // According to rfc3629, UTF-8 allows only up to 4 bytes.
    // (21 bits codepoint)
    unsigned char byte = read(it);
    if ((byte & 0x80) == 0) // 0xxxxxxx
        return byte;

    if (it == end)
        return InvalidPolicy{}(byte);

    if ((byte & 0xE0) == 0xC0) // 110xxxxx
        return ((byte & 0x1F) << 6) | (read(it) & 0x3F);

    if ((byte & 0xF0) == 0xE0) // 1110xxxx
    {
        Codepoint cp = ((byte & 0x0F) << 12) | ((read(it) & 0x3F) << 6);
        if (it == end)
            return InvalidPolicy{}(cp);
        return cp | (read(it) & 0x3F);
    }

    if ((byte & 0xF8) == 0xF0) // 11110xxx
    {
        Codepoint cp = ((byte & 0x0F) << 18) | ((read(it) & 0x3F) << 12);
        if (it == end)
            return InvalidPolicy{}(cp);
        cp |= (read(it) & 0x3F) << 6;
        if (it == end)
            return InvalidPolicy{}(cp);
        return cp | (read(it) & 0x3F);
    }
    return InvalidPolicy{}(byte);
}

template<typename InvalidPolicy = utf8::InvalidPolicy::Pass,
         typename Iterator>
Codepoint codepoint(Iterator it, const Iterator& end)
    noexcept(noexcept(read_codepoint<InvalidPolicy>(it, end)))
{
    return read_codepoint<InvalidPolicy>(it, end);
}

template<typename InvalidPolicy = utf8::InvalidPolicy::Pass>
ByteCount codepoint_size(char byte)
    noexcept(noexcept(InvalidPolicy{}(0)))
{
    if ((byte & 0x80) == 0) // 0xxxxxxx
        return 1;
    else if ((byte & 0xE0) == 0xC0) // 110xxxxx
        return 2;
    else if ((byte & 0xF0) == 0xE0) // 1110xxxx
        return 3;
    else if ((byte & 0xF8) == 0xF0) // 11110xxx
        return 4;
    else
    {
        InvalidPolicy{}(byte);
        return 1;
    }
}

struct invalid_codepoint{};

inline ByteCount codepoint_size(Codepoint cp)
{
    if (cp <= 0x7F)
        return 1;
    else if (cp <= 0x7FF)
        return 2;
    else if (cp <= 0xFFFF)
        return 3;
    else if (cp <= 0x10FFFF)
        return 4;
    else
        throw invalid_codepoint{};
}

template<typename Iterator>
void to_next(Iterator& it, const Iterator& end) noexcept
{
    if (it != end)
        ++it;
    while (it != end and not is_character_start(*it))
        ++it;
}

// returns an iterator to next character first byte
template<typename Iterator>
Iterator next(Iterator it, const Iterator& end) noexcept
{
    to_next(it, end);
    return it;
}

// returns it's parameter if it points to a character first byte,
// or else returns next character first byte
template<typename Iterator>
Iterator finish(Iterator it, const Iterator& end) noexcept
{
    while (it != end and (*(it) & 0xC0) == 0x80)
        ++it;
    return it;
}

template<typename Iterator>
void to_previous(Iterator& it, const Iterator& begin) noexcept
{
    if (it != begin)
        --it;
    while (not is_character_start(*it))
        --it;
}
// returns an iterator to the previous character first byte
template<typename Iterator>
Iterator previous(Iterator it, const Iterator& begin) noexcept
{
    to_previous(it, begin);
    return it;
}

// returns an iterator pointing to the first byte of the
// dth character after (or before if d < 0) the character
// pointed by it
template<typename Iterator>
Iterator advance(Iterator it, const Iterator& end, CharCount d) noexcept
{
    if (it == end)
        return it;

    if (d < 0)
    {
        while (it != end and d++ != 0)
            to_previous(it, end);
    }
    else if (d > 0)
    {
        while (it != end and d-- != 0)
            to_next(it, end);
    }
    return it;
}

// returns an iterator pointing to the first byte of the
// character at the dth column after (or before if d < 0)
// the character pointed by it
template<typename Iterator>
Iterator advance(Iterator it, const Iterator& end, ColumnCount d) noexcept
{
    if (it == end)
        return it;

    if (d < 0)
    {
        while (it != end and d < 0)
        {
            auto cur = it;
            to_previous(it, end);
            d += codepoint_width(codepoint(it, cur));
        }
    }
    else if (d > 0)
    {
        auto begin = it;
        while (it != end and d > 0)
        {
            d -= codepoint_width(read_codepoint(it, end));
            if (it != end and d < 0)
                to_previous(it, begin);
        }
    }
    return it;
}

// returns the character count between begin and end
template<typename Iterator>
CharCount distance(Iterator begin, const Iterator& end) noexcept
{
    CharCount dist = 0;

    while (begin != end)
    {
        if (is_character_start(read(begin)))
            ++dist;
    }
    return dist;
}

// returns the column count between begin and end
template<typename Iterator>
ColumnCount column_distance(Iterator begin, const Iterator& end) noexcept
{
    ColumnCount dist = 0;

    while (begin != end)
        dist += codepoint_width(read_codepoint(begin, end));
    return dist;
}

// returns an iterator to the first byte of the character it is into
template<typename Iterator>
Iterator character_start(Iterator it, const Iterator& begin) noexcept
{
    while (it != begin and not is_character_start(*it))
        --it;
    return it;
}

template<typename OutputIterator>
void dump(OutputIterator&& it, Codepoint cp)
{
    if (cp <= 0x7F)
        *it++ = cp;
    else if (cp <= 0x7FF)
    {
        *it++ = 0xC0 | (cp >> 6);
        *it++ = 0x80 | (cp & 0x3F);
    }
    else if (cp <= 0xFFFF)
    {
        *it++ = 0xE0 | (cp >> 12);
        *it++ = 0x80 | ((cp >> 6) & 0x3F);
        *it++ = 0x80 | (cp & 0x3F);
    }
    else if (cp <= 0x10FFFF)
    {
        *it++ = 0xF0 | (cp >> 18);
        *it++ = 0x80 | ((cp >> 12) & 0x3F);
        *it++ = 0x80 | ((cp >> 6)  & 0x3F);
        *it++ = 0x80 | (cp & 0x3F);
    }
    else
        throw invalid_codepoint{};
}

}

}

#endif // utf8_hh_INCLUDED
<commit_msg>Fix utf8::to_previous that could go before the begin iterator<commit_after>#ifndef utf8_hh_INCLUDED
#define utf8_hh_INCLUDED

#include "assert.hh"
#include "unicode.hh"
#include "units.hh"

#include <cstddef>

namespace Kakoune
{

namespace utf8
{

template<typename Iterator>
[[gnu::always_inline]]
inline char read(Iterator& it) noexcept { char c = *it; ++it; return c; }

// return true if it points to the first byte of a (either single or
// multibyte) character
[[gnu::always_inline]]
inline bool is_character_start(char c) noexcept
{
    return (c & 0xC0) != 0x80;
}

namespace InvalidPolicy
{

struct Assert
{
    Codepoint operator()(Codepoint cp) const { kak_assert(false); return cp; }
};

struct Pass
{
    Codepoint operator()(Codepoint cp) const noexcept { return cp; }
};

}

// returns the codepoint of the character whose first byte
// is pointed by it
template<typename InvalidPolicy = utf8::InvalidPolicy::Pass,
         typename Iterator>
Codepoint read_codepoint(Iterator& it, const Iterator& end)
    noexcept(noexcept(InvalidPolicy{}(0)))
{
    if (it == end)
        return InvalidPolicy{}(-1);
    // According to rfc3629, UTF-8 allows only up to 4 bytes.
    // (21 bits codepoint)
    unsigned char byte = read(it);
    if ((byte & 0x80) == 0) // 0xxxxxxx
        return byte;

    if (it == end)
        return InvalidPolicy{}(byte);

    if ((byte & 0xE0) == 0xC0) // 110xxxxx
        return ((byte & 0x1F) << 6) | (read(it) & 0x3F);

    if ((byte & 0xF0) == 0xE0) // 1110xxxx
    {
        Codepoint cp = ((byte & 0x0F) << 12) | ((read(it) & 0x3F) << 6);
        if (it == end)
            return InvalidPolicy{}(cp);
        return cp | (read(it) & 0x3F);
    }

    if ((byte & 0xF8) == 0xF0) // 11110xxx
    {
        Codepoint cp = ((byte & 0x0F) << 18) | ((read(it) & 0x3F) << 12);
        if (it == end)
            return InvalidPolicy{}(cp);
        cp |= (read(it) & 0x3F) << 6;
        if (it == end)
            return InvalidPolicy{}(cp);
        return cp | (read(it) & 0x3F);
    }
    return InvalidPolicy{}(byte);
}

template<typename InvalidPolicy = utf8::InvalidPolicy::Pass,
         typename Iterator>
Codepoint codepoint(Iterator it, const Iterator& end)
    noexcept(noexcept(read_codepoint<InvalidPolicy>(it, end)))
{
    return read_codepoint<InvalidPolicy>(it, end);
}

template<typename InvalidPolicy = utf8::InvalidPolicy::Pass>
ByteCount codepoint_size(char byte)
    noexcept(noexcept(InvalidPolicy{}(0)))
{
    if ((byte & 0x80) == 0) // 0xxxxxxx
        return 1;
    else if ((byte & 0xE0) == 0xC0) // 110xxxxx
        return 2;
    else if ((byte & 0xF0) == 0xE0) // 1110xxxx
        return 3;
    else if ((byte & 0xF8) == 0xF0) // 11110xxx
        return 4;
    else
    {
        InvalidPolicy{}(byte);
        return 1;
    }
}

struct invalid_codepoint{};

inline ByteCount codepoint_size(Codepoint cp)
{
    if (cp <= 0x7F)
        return 1;
    else if (cp <= 0x7FF)
        return 2;
    else if (cp <= 0xFFFF)
        return 3;
    else if (cp <= 0x10FFFF)
        return 4;
    else
        throw invalid_codepoint{};
}

template<typename Iterator>
void to_next(Iterator& it, const Iterator& end) noexcept
{
    if (it != end)
        ++it;
    while (it != end and not is_character_start(*it))
        ++it;
}

// returns an iterator to next character first byte
template<typename Iterator>
Iterator next(Iterator it, const Iterator& end) noexcept
{
    to_next(it, end);
    return it;
}

// returns it's parameter if it points to a character first byte,
// or else returns next character first byte
template<typename Iterator>
Iterator finish(Iterator it, const Iterator& end) noexcept
{
    while (it != end and (*(it) & 0xC0) == 0x80)
        ++it;
    return it;
}

template<typename Iterator>
void to_previous(Iterator& it, const Iterator& begin) noexcept
{
    if (it != begin)
        --it;
    while (it != begin and not is_character_start(*it))
        --it;
}
// returns an iterator to the previous character first byte
template<typename Iterator>
Iterator previous(Iterator it, const Iterator& begin) noexcept
{
    to_previous(it, begin);
    return it;
}

// returns an iterator pointing to the first byte of the
// dth character after (or before if d < 0) the character
// pointed by it
template<typename Iterator>
Iterator advance(Iterator it, const Iterator& end, CharCount d) noexcept
{
    if (it == end)
        return it;

    if (d < 0)
    {
        while (it != end and d++ != 0)
            to_previous(it, end);
    }
    else if (d > 0)
    {
        while (it != end and d-- != 0)
            to_next(it, end);
    }
    return it;
}

// returns an iterator pointing to the first byte of the
// character at the dth column after (or before if d < 0)
// the character pointed by it
template<typename Iterator>
Iterator advance(Iterator it, const Iterator& end, ColumnCount d) noexcept
{
    if (it == end)
        return it;

    if (d < 0)
    {
        while (it != end and d < 0)
        {
            auto cur = it;
            to_previous(it, end);
            d += codepoint_width(codepoint(it, cur));
        }
    }
    else if (d > 0)
    {
        auto begin = it;
        while (it != end and d > 0)
        {
            d -= codepoint_width(read_codepoint(it, end));
            if (it != end and d < 0)
                to_previous(it, begin);
        }
    }
    return it;
}

// returns the character count between begin and end
template<typename Iterator>
CharCount distance(Iterator begin, const Iterator& end) noexcept
{
    CharCount dist = 0;

    while (begin != end)
    {
        if (is_character_start(read(begin)))
            ++dist;
    }
    return dist;
}

// returns the column count between begin and end
template<typename Iterator>
ColumnCount column_distance(Iterator begin, const Iterator& end) noexcept
{
    ColumnCount dist = 0;

    while (begin != end)
        dist += codepoint_width(read_codepoint(begin, end));
    return dist;
}

// returns an iterator to the first byte of the character it is into
template<typename Iterator>
Iterator character_start(Iterator it, const Iterator& begin) noexcept
{
    while (it != begin and not is_character_start(*it))
        --it;
    return it;
}

template<typename OutputIterator>
void dump(OutputIterator&& it, Codepoint cp)
{
    if (cp <= 0x7F)
        *it++ = cp;
    else if (cp <= 0x7FF)
    {
        *it++ = 0xC0 | (cp >> 6);
        *it++ = 0x80 | (cp & 0x3F);
    }
    else if (cp <= 0xFFFF)
    {
        *it++ = 0xE0 | (cp >> 12);
        *it++ = 0x80 | ((cp >> 6) & 0x3F);
        *it++ = 0x80 | (cp & 0x3F);
    }
    else if (cp <= 0x10FFFF)
    {
        *it++ = 0xF0 | (cp >> 18);
        *it++ = 0x80 | ((cp >> 12) & 0x3F);
        *it++ = 0x80 | ((cp >> 6)  & 0x3F);
        *it++ = 0x80 | (cp & 0x3F);
    }
    else
        throw invalid_codepoint{};
}

}

}

#endif // utf8_hh_INCLUDED
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: MasterPagesPanel.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-13 14:44:27 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "MasterPagesPanel.hxx"
#include "../ScrollPanel.hxx"
#include "CurrentMasterPagesSelector.hxx"
#include "RecentMasterPagesSelector.hxx"
#include "AllMasterPagesSelector.hxx"

#include "DrawViewShell.hxx"
#include "ViewShellBase.hxx"

#include "strings.hrc"
#include "sdresid.hxx"

namespace sd { namespace toolpanel { namespace controls {

MasterPagesPanel::MasterPagesPanel (TreeNode* pParent, ViewShellBase& rBase)
    : SubToolPanel (pParent)
{
    SdDrawDocument* pDocument = rBase.GetDocument();

    ScrollPanel* pScrollPanel = new ScrollPanel (this);

    // Create a panel with the master pages that are in use by the currently
    // edited document.
    DrawViewShell* pDrawViewShell = static_cast<DrawViewShell*>(
        rBase.GetMainViewShell());
    controls::MasterPagesSelector* pSelector
        = new controls::CurrentMasterPagesSelector (
            this,
            *pDocument,
            rBase,
            *pDrawViewShell);
    pSelector->LateInit();
    pScrollPanel->AddControl (
        ::std::auto_ptr<TreeNode>(pSelector),
        SdResId(STR_TASKPANEL_CURRENT_MASTER_PAGES_TITLE));

    // Create a panel with the most recently used master pages.
    pSelector = new controls::RecentMasterPagesSelector (
        this,
        *pDocument,
        rBase);
    pSelector->LateInit();
    pScrollPanel->AddControl (
        ::std::auto_ptr<TreeNode>(pSelector),
        SdResId(STR_TASKPANEL_RECENT_MASTER_PAGES_TITLE));

    // Create a panel with all available master pages.
    pSelector = new controls::AllMasterPagesSelector (
        this,
        *pDocument,
        rBase,
        *pDrawViewShell);
    pSelector->LateInit();
    pScrollPanel->AddControl (
        ::std::auto_ptr<TreeNode>(pSelector),
        SdResId(STR_TASKPANEL_ALL_MASTER_PAGES_TITLE));

    AddControl (::std::auto_ptr<TreeNode>(pScrollPanel));
}

MasterPagesPanel::~MasterPagesPanel (void)
{
}

} } } // end of namespace ::sd::toolpanel::controls
<commit_msg>INTEGRATION: CWS presentationengine01 (1.2.12); FILE MERGED 2004/09/30 15:40:22 af 1.2.12.1: #i34242# Added support for help ids.<commit_after>/*************************************************************************
 *
 *  $RCSfile: MasterPagesPanel.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2004-11-26 20:26:20 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "MasterPagesPanel.hxx"
#include "../ScrollPanel.hxx"
#include "CurrentMasterPagesSelector.hxx"
#include "RecentMasterPagesSelector.hxx"
#include "AllMasterPagesSelector.hxx"

#include "DrawViewShell.hxx"
#include "ViewShellBase.hxx"

#include "strings.hrc"
#include "sdresid.hxx"
#include "helpids.h"

namespace sd { namespace toolpanel { namespace controls {

MasterPagesPanel::MasterPagesPanel (TreeNode* pParent, ViewShellBase& rBase)
    : SubToolPanel (pParent)
{
    SdDrawDocument* pDocument = rBase.GetDocument();

    ScrollPanel* pScrollPanel = new ScrollPanel (this);

    // Create a panel with the master pages that are in use by the currently
    // edited document.
    DrawViewShell* pDrawViewShell = static_cast<DrawViewShell*>(
        rBase.GetMainViewShell());
    controls::MasterPagesSelector* pSelector
        = new controls::CurrentMasterPagesSelector (
            this,
            *pDocument,
            rBase,
            *pDrawViewShell);
    pSelector->LateInit();
    pScrollPanel->AddControl (
        ::std::auto_ptr<TreeNode>(pSelector),
        SdResId(STR_TASKPANEL_CURRENT_MASTER_PAGES_TITLE),
        HID_SD_CURRENT_MASTERS);

    // Create a panel with the most recently used master pages.
    pSelector = new controls::RecentMasterPagesSelector (
        this,
        *pDocument,
        rBase);
    pSelector->LateInit();
    pScrollPanel->AddControl (
        ::std::auto_ptr<TreeNode>(pSelector),
        SdResId(STR_TASKPANEL_RECENT_MASTER_PAGES_TITLE),
        HID_SD_RECENT_MASTERS);

    // Create a panel with all available master pages.
    pSelector = new controls::AllMasterPagesSelector (
        this,
        *pDocument,
        rBase,
        *pDrawViewShell);
    pSelector->LateInit();
    pScrollPanel->AddControl (
        ::std::auto_ptr<TreeNode>(pSelector),
        SdResId(STR_TASKPANEL_ALL_MASTER_PAGES_TITLE),
        HID_SD_ALL_MASTERS);

    AddControl (::std::auto_ptr<TreeNode>(pScrollPanel));
}

MasterPagesPanel::~MasterPagesPanel (void)
{
}

} } } // end of namespace ::sd::toolpanel::controls
<|endoftext|>


<commit_before>//
// Copyright (C) 2006-2007 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2006-2007 SIPez LLC.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
//////////////////////////////////////////////////////////////////////////////

#include <mp/MpCodecFactory.h>
#include <os/OsTime.h>
#include <os/OsDateTime.h>

#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
#include <sipxunit/TestUtilities.h>

/// Sample rate in samples per second.
#define SAMPLE_RATE             8000
/// Size of audio frame in samples.
#define FRAME_SIZE              80
/// Maximum length of audio data we expect from decoder in samples.
#define DECODED_FRAME_MAX_SIZE  (FRAME_SIZE*6)
/// Maximum size of encoded frame in bytes.
#define ENCODED_FRAME_MAX_SIZE  (FRAME_SIZE*sizeof(MpAudioSample))
/// Number of RTP packets to encode/decode.
#define NUM_PACKETS_TO_TEST      3

///  Unit test for testing performance of supported codecs.
class MpCodecsPerformanceTest : public CppUnit::TestCase
{
   CPPUNIT_TEST_SUITE(MpCodecsPerformanceTest);
   CPPUNIT_TEST(testCodecsPreformance);
   CPPUNIT_TEST_SUITE_END();

public:

   void setUp()
   {
      // Create pool for data buffers
      mpPool = new MpBufPool(ENCODED_FRAME_MAX_SIZE + MpArrayBuf::getHeaderSize(), 1);
      CPPUNIT_ASSERT(mpPool != NULL);

      // Create pool for buffer headers
      mpHeadersPool = new MpBufPool(sizeof(MpRtpBuf), 1);
      CPPUNIT_ASSERT(mpHeadersPool != NULL);

      // Set mpHeadersPool as default pool for audio and data pools.
      MpRtpBuf::smpDefaultPool = mpHeadersPool;
   }

   void tearDown()
   {
      if (mpPool != NULL)
      {
         delete mpPool;
      }
      if (mpHeadersPool != NULL)
      {
         delete mpHeadersPool;
      }
   }

   void testCodecsPreformance()
   {
      MpCodecFactory  *pCodecFactory;
      const UtlString *pCodecMimeTypes;
      unsigned         codecMimeTypesNum;

      // Get/create codec factory
      pCodecFactory = MpCodecFactory::getMpCodecFactory();
      CPPUNIT_ASSERT(pCodecFactory != NULL);

      // Load all available codecs
      CPPUNIT_ASSERT_EQUAL(OS_SUCCESS,
                           pCodecFactory->loadAllDynCodecs(".", CODEC_PLUGINS_FILTER));

      pCodecFactory->getMimeTypes(codecMimeTypesNum, (const UtlString*&)pCodecMimeTypes);
      CPPUNIT_ASSERT(codecMimeTypesNum>0);

      for (unsigned i=0; i<codecMimeTypesNum; i++)
      {
         const char **pCodecFmtps;
         unsigned     codecFmtpsNum;
         pCodecFactory->getCodecFmtps(pCodecMimeTypes[i], codecFmtpsNum, pCodecFmtps);
         if (codecFmtpsNum == 0)
         {
            testOneCodecPreformance(pCodecFactory, pCodecMimeTypes[i], "");
         }
         else
         {
            for (int fmtpNum=0; fmtpNum<codecFmtpsNum; fmtpNum++)
            {
               testOneCodecPreformance(pCodecFactory,
                                       pCodecMimeTypes[i],
                                       pCodecFmtps[fmtpNum]);
            }
         }
      }
   }

protected:
   MpBufPool *mpPool;         ///< Pool for data buffers
   MpBufPool *mpHeadersPool;  ///< Pool for buffers headers

   void testOneCodecPreformance(MpCodecFactory *pCodecFactory,
                                const UtlString &codecMime,
                                const UtlString &codecFmtp,
                                int sampleRate,
                                int numChannels)
   {
      MpDecoderBase *pDecoder;
      MpEncoderBase *pEncoder;
      MpAudioSample  pOriginal[FRAME_SIZE];
      MpAudioSample  pDecoded[DECODED_FRAME_MAX_SIZE];
      int            encodeFrameNum = 0;

      // Create and initialize decoder and encoder
      CPPUNIT_ASSERT_EQUAL(OS_SUCCESS,
                           pCodecFactory->createDecoder(codecMime, codecFmtp,
                                                        sampleRate, numChannels,
                                                        0, pDecoder));
      CPPUNIT_ASSERT_EQUAL(OS_SUCCESS,
                           pDecoder->initDecode());
      // Could not test speed of signaling codec
      if (pDecoder->getInfo()->isSignalingCodec())
      {
         pDecoder->freeDecode();
         delete pDecoder;
         return;
      }
      CPPUNIT_ASSERT_EQUAL(OS_SUCCESS,
                           pCodecFactory->createEncoder(codecMime, codecFmtp, 0, pEncoder));
      CPPUNIT_ASSERT_EQUAL(OS_SUCCESS,
                           pEncoder->initEncode());

      for (int i=0; i<NUM_PACKETS_TO_TEST; i++)
      {
         int            maxBytesPerPacket = (pEncoder->getInfo()->getMaxPacketBits() + 7) / 8;
         int            tmpSamplesConsumed;
         int            tmpEncodedSize;
         UtlBoolean     tmpSendNow;
         MpAudioBuf::SpeechType tmpSpeechType;
         MpRtpBufPtr    pRtpPacket = mpPool->getBuffer();
         unsigned char *pRtpPayloadPtr = (unsigned char *)pRtpPacket->getDataWritePtr();
         int            payloadSize = 0;
         int            samplesInPacket = 0;
         OsTime         start;
         OsTime         stop;
         OsTime         diff;

         // Encode frames until we get tmpSendNow set or reach packet size limit.
         do
         {
            // Encode one frame and measure time it took.
            OsStatus result;
            OsDateTime::getCurTime(start);
            result = pEncoder->encode(pOriginal, FRAME_SIZE, tmpSamplesConsumed,
                                      pRtpPayloadPtr,
                                      ENCODED_FRAME_MAX_SIZE-payloadSize,
                                      tmpEncodedSize, tmpSendNow,
                                      tmpSpeechType);
            OsDateTime::getCurTime(stop);
            CPPUNIT_ASSERT_EQUAL(OS_SUCCESS, result);

            // Print timing in TSV format
            diff = stop - start;
            printf("encode %s %s;%d;%ld.%06ld;%ld.%06ld\n",
                   codecMime.data(), codecFmtp.data(),
                   encodeFrameNum,
                   start.seconds(), start.usecs(),
                   diff.seconds(), diff.usecs());

            // Adjust encoding state
            payloadSize += tmpEncodedSize;
            pRtpPayloadPtr += tmpEncodedSize;
            samplesInPacket += tmpSamplesConsumed;
            CPPUNIT_ASSERT(payloadSize <= ENCODED_FRAME_MAX_SIZE);
            encodeFrameNum++;
         } while(! ((tmpSendNow == TRUE) || (maxBytesPerPacket == payloadSize)));
         pRtpPacket->setPayloadSize(payloadSize);

         // Decode frame, measure time and verify, that we decoded same number of samples.
         OsDateTime::getCurTime(start);
         tmpSamplesConsumed = pDecoder->decode(pRtpPacket, DECODED_FRAME_MAX_SIZE,
                                             pDecoded);
         OsDateTime::getCurTime(stop);
         CPPUNIT_ASSERT_EQUAL(samplesInPacket, tmpSamplesConsumed);

         // Print timing in TSV format
         diff = stop - start;
         printf("decode %s %s;%d;%ld.%06ld;%ld.%06ld\n",
                codecMime.data(), codecFmtp.data(),
                i,
                start.seconds(), start.usecs(),
                diff.seconds(), diff.usecs());
      }

      // Free encoder and decoder
      CPPUNIT_ASSERT_EQUAL(OS_SUCCESS,
                           pDecoder->freeDecode());
      delete pDecoder;
      CPPUNIT_ASSERT_EQUAL(OS_SUCCESS,
                           pEncoder->freeEncode());
      delete pEncoder;
   }

};

CPPUNIT_TEST_SUITE_REGISTRATION(MpCodecsPerformanceTest);
<commit_msg>Update MpCodecsPerformanceTest to work with latest changes in codecs.<commit_after>//
// Copyright (C) 2006-2007 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2006-2007 SIPez LLC.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
//////////////////////////////////////////////////////////////////////////////

#include <mp/MpCodecFactory.h>
#include <os/OsTime.h>
#include <os/OsDateTime.h>

#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
#include <sipxunit/TestUtilities.h>

/// Sample rate in samples per second.
#define SAMPLE_RATE             8000
/// Size of audio frame in samples.
#define FRAME_SIZE              80
/// Maximum length of audio data we expect from decoder in samples.
#define DECODED_FRAME_MAX_SIZE  (FRAME_SIZE*6)
/// Maximum size of encoded frame in bytes.
#define ENCODED_FRAME_MAX_SIZE  (FRAME_SIZE*sizeof(MpAudioSample))
/// Number of RTP packets to encode/decode.
#define NUM_PACKETS_TO_TEST      3
/// Maximum number of milliseconds in packet.
#define MAX_PACKET_TIME          20
/// Maximum number of samples in packet.
#define MAX_PACKET_SAMPLES       (MAX_PACKET_TIME*SAMPLE_RATE)/1000

// Setup codec paths..
static UtlString sCodecPaths[] = {
#ifdef WIN32
                                  "bin",
                                  "..\\bin",
#elif __pingtel_on_posix__
                                  "../../../../bin",
                                  "../../../bin",
#else
#                                 error "Unknown platform"
#endif
                                  "."
                                 };
static size_t sNumCodecPaths = sizeof(sCodecPaths)/sizeof(sCodecPaths[0]);

///  Unit test for testing performance of supported codecs.
class MpCodecsPerformanceTest : public CppUnit::TestCase
{
   CPPUNIT_TEST_SUITE(MpCodecsPerformanceTest);
   CPPUNIT_TEST(testCodecsPreformance);
   CPPUNIT_TEST_SUITE_END();

public:

   void setUp()
   {
      // Create pool for data buffers
      mpPool = new MpBufPool(ENCODED_FRAME_MAX_SIZE + MpArrayBuf::getHeaderSize(), 1);
      CPPUNIT_ASSERT(mpPool != NULL);

      // Create pool for buffer headers
      mpHeadersPool = new MpBufPool(sizeof(MpRtpBuf), 1);
      CPPUNIT_ASSERT(mpHeadersPool != NULL);

      // Set mpHeadersPool as default pool for audio and data pools.
      MpRtpBuf::smpDefaultPool = mpHeadersPool;
   }

   void tearDown()
   {
      if (mpPool != NULL)
      {
         delete mpPool;
      }
      if (mpHeadersPool != NULL)
      {
         delete mpHeadersPool;
      }
   }

   void testCodecsPreformance()
   {
      MpCodecFactory  *pCodecFactory;
      const MppCodecInfoV1_1 **pCodecInfo;
      unsigned         codecInfoNum;

      // Get/create codec factory
      pCodecFactory = MpCodecFactory::getMpCodecFactory();
      CPPUNIT_ASSERT(pCodecFactory != NULL);

      // Load all available codecs
      size_t i;
      for(i = 0; i < sNumCodecPaths; i++)
      {
         pCodecFactory->loadAllDynCodecs(sCodecPaths[i],
                                         CODEC_PLUGINS_FILTER);
      }

      // Get list of loaded codecs
      pCodecFactory->getCodecInfoArray(codecInfoNum, pCodecInfo);
      CPPUNIT_ASSERT(codecInfoNum>0);

      for (unsigned i=0; i<codecInfoNum; i++)
      {
         const char **pCodecFmtps;
         unsigned     codecFmtpsNum;
         codecFmtpsNum = pCodecInfo[i]->fmtpsNum;
         pCodecFmtps = pCodecInfo[i]->fmtps;
         if (codecFmtpsNum == 0)
         {
            testOneCodecPreformance(pCodecFactory,
                                    pCodecInfo[i]->mimeSubtype,
                                    "",
                                    pCodecInfo[i]->sampleRate,
                                    pCodecInfo[i]->numChannels);
         }
         else
         {
            for (unsigned fmtpNum=0; fmtpNum<codecFmtpsNum; fmtpNum++)
            {
               testOneCodecPreformance(pCodecFactory,
                                       pCodecInfo[i]->mimeSubtype,
                                       pCodecFmtps[fmtpNum],
                                       pCodecInfo[i]->sampleRate,
                                       pCodecInfo[i]->numChannels);
            }
         }
      }

      // Free codec factory
      MpCodecFactory::freeSingletonHandle();
   }

protected:
   MpBufPool *mpPool;         ///< Pool for data buffers
   MpBufPool *mpHeadersPool;  ///< Pool for buffers headers

   void testOneCodecPreformance(MpCodecFactory *pCodecFactory,
                                const UtlString &codecMime,
                                const UtlString &codecFmtp,
                                int sampleRate,
                                int numChannels)
   {
      MpDecoderBase *pDecoder;
      MpEncoderBase *pEncoder;
      MpAudioSample  pOriginal[FRAME_SIZE];
      MpAudioSample  pDecoded[DECODED_FRAME_MAX_SIZE];
      int            encodeFrameNum = 0;
      int            codecFrameSamples;

      // Create and initialize decoder and encoder
      CPPUNIT_ASSERT_EQUAL(OS_SUCCESS,
                           pCodecFactory->createDecoder(codecMime, codecFmtp,
                                                        sampleRate, numChannels,
                                                        0, pDecoder));
      CPPUNIT_ASSERT_EQUAL(OS_SUCCESS,
                           pDecoder->initDecode());
      // Could not test speed of signaling codec
      if (pDecoder->getInfo()->isSignalingCodec())
      {
         pDecoder->freeDecode();
         delete pDecoder;
         return;
      }
      CPPUNIT_ASSERT_EQUAL(OS_SUCCESS,
                           pCodecFactory->createEncoder(codecMime, codecFmtp,
                                                        sampleRate, numChannels,
                                                        0, pEncoder));
      CPPUNIT_ASSERT_EQUAL(OS_SUCCESS,
                           pEncoder->initEncode());

      // Get number of samples we'll pack to get one packet
      if (pEncoder->getInfo()->getCodecType() == CODEC_TYPE_FRAME_BASED)
      {
         codecFrameSamples = pEncoder->getInfo()->getNumSamplesPerFrame();
      }
      else if (pEncoder->getInfo()->getCodecType() == CODEC_TYPE_SAMPLE_BASED)
      {
         codecFrameSamples = FRAME_SIZE;
      }
      else
      {
         assert(!"Unknown codec type!");
      }

      for (int i=0; i<NUM_PACKETS_TO_TEST; i++)
      {
         int            tmpSamplesConsumed;
         int            tmpEncodedSize;
         UtlBoolean     tmpSendNow;
         MpAudioBuf::SpeechType tmpSpeechType;
         MpRtpBufPtr    pRtpPacket = mpPool->getBuffer();
         unsigned char *pRtpPayloadPtr = (unsigned char *)pRtpPacket->getDataWritePtr();
         int            payloadSize = 0;
         int            samplesInPacket = 0;
         OsTime         start;
         OsTime         stop;
         OsTime         diff;

         // Encode frames until we get tmpSendNow set or reach packet size limit.
         do
         {
            // Encode one frame and measure time it took.
            OsStatus result;
            OsDateTime::getCurTime(start);
            result = pEncoder->encode(pOriginal, FRAME_SIZE, tmpSamplesConsumed,
                                      pRtpPayloadPtr,
                                      ENCODED_FRAME_MAX_SIZE-payloadSize,
                                      tmpEncodedSize, tmpSendNow,
                                      tmpSpeechType);
            OsDateTime::getCurTime(stop);
            CPPUNIT_ASSERT_EQUAL(OS_SUCCESS, result);

            // Print timing in TSV format
            diff = stop - start;
            printf("encode %s %s;%d;%ld.%06ld;%ld.%06ld\n",
                   codecMime.data(), codecFmtp.data(),
                   encodeFrameNum,
                   start.seconds(), start.usecs(),
                   diff.seconds(), diff.usecs());

            // Adjust encoding state
            payloadSize += tmpEncodedSize;
            pRtpPayloadPtr += tmpEncodedSize;
            samplesInPacket += tmpSamplesConsumed;
            CPPUNIT_ASSERT(payloadSize <= ENCODED_FRAME_MAX_SIZE);
            encodeFrameNum++;
         } while( (tmpSendNow != TRUE) &&
                  (samplesInPacket+codecFrameSamples <= MAX_PACKET_SAMPLES));
         pRtpPacket->setPayloadSize(payloadSize);

         // Decode frame, measure time and verify, that we decoded same number of samples.
         OsDateTime::getCurTime(start);
         tmpSamplesConsumed = pDecoder->decode(pRtpPacket, DECODED_FRAME_MAX_SIZE,
                                             pDecoded);
         OsDateTime::getCurTime(stop);
         CPPUNIT_ASSERT_EQUAL(samplesInPacket, tmpSamplesConsumed);

         // Print timing in TSV format
         diff = stop - start;
         printf("decode %s %s;%d;%ld.%06ld;%ld.%06ld\n",
                codecMime.data(), codecFmtp.data(),
                i,
                start.seconds(), start.usecs(),
                diff.seconds(), diff.usecs());
      }

      // Free encoder and decoder
      CPPUNIT_ASSERT_EQUAL(OS_SUCCESS,
                           pDecoder->freeDecode());
      delete pDecoder;
      CPPUNIT_ASSERT_EQUAL(OS_SUCCESS,
                           pEncoder->freeEncode());
      delete pEncoder;
   }

};

CPPUNIT_TEST_SUITE_REGISTRATION(MpCodecsPerformanceTest);
<|endoftext|>


<commit_before>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * 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 "compiler/rewriter/rules/ruleset.h"
#include "compiler/expression/expr.h"
#include "compiler/rewriter/tools/expr_tools.h"
#include "indexing/value_index.h"

namespace zorba {

static store::Item_t get_uri(expr *e)
{
  // The following two checks are required if we run after
  // normalization. It does not hurt, otherwise -- so leave it
  // here.
  if (e->get_expr_kind() == promote_expr_kind) {
    e = static_cast<promote_expr *>(e)->get_input();
  }
  if (is_data(e)) {
    e = get_fo_arg(e, 0);
  }
  if (e->get_expr_kind() == const_expr_kind) {
    return static_cast<const_expr *>(e)->get_val();
  }
  return NULL;
}

RULE_REWRITE_PRE(ExpandBuildIndex)
{
  if (node->get_expr_kind() == fo_expr_kind) {
    fo_expr *fo = static_cast<fo_expr *>(&*node);
    if (fo->get_func() == LOOKUP_RESOLVED_FN(ZORBA_OPEXTENSIONS_NS, "build-index", 1)) {
      store::Item_t uri_item(get_uri((*fo)[0].getp()));
      if (uri_item == NULL) {
        ZORBA_ASSERT(false);
      }
      xqpStringStore_t uristore;
      uri_item->getStringValue(uristore);
      xqp_string uri(uristore);
      ValueIndex *vi = rCtx.getStaticContext()->lookup_index(uri);
      if (vi == NULL) {
        ZORBA_ASSERT(false);
      }
      std::vector<expr_t> se_args;
      expr_t open_index_arg(new const_expr(fo->get_loc(), uri_item));
      expr_t open_index(new fo_expr(fo->get_loc(), LOOKUP_OP1("index-session-opener"), open_index_arg));
      se_args.push_back(open_index);

      expr::substitution_t subst;

      flwor_expr::clause_list_t clauses;
      expr_t de = vi->getDomainExpression()->clone(subst);
      var_expr_t dot = vi->getDomainVariable();
      var_expr_t pos = vi->getDomainPositionVariable();
      var_expr_t newdot = new var_expr(dot->get_loc(), dot->get_kind(), dot->get_varname());
      var_expr_t newpos = new var_expr(pos->get_loc(), pos->get_kind(), pos->get_varname());
      subst[dot] = newdot;
      subst[pos] = newpos;
      flwor_expr::forletref_t fc = new forlet_clause(forlet_clause::for_clause, newdot, newpos, NULL, de);
      newdot->set_forlet_clause(fc);
      newpos->set_forlet_clause(fc);

      clauses.push_back(fc);

      std::vector<expr_t> index_insert_args;
      expr_t insert_index_uri(new const_expr(fo->get_loc(), uri_item));
      index_insert_args.push_back(insert_index_uri);

      expr_t insert_index_var(new wrapper_expr(fo->get_loc(), newdot));
      index_insert_args.push_back(insert_index_var);

      const std::vector<expr_t>& idx_fields(vi->getIndexFieldExpressions());
      int n = idx_fields.size();
      for(int i = 0; i < n; ++i) {
        index_insert_args.push_back(idx_fields[i]->clone(subst));
      }
      expr_t re(new fo_expr(fo->get_loc(), LOOKUP_OPN("index-builder"), index_insert_args));

      rchandle<flwor_expr> flwor = new flwor_expr(fo->get_loc(), clauses, re);

      se_args.push_back(flwor.getp());

      expr_t close_index_arg(new const_expr(fo->get_loc(), uri_item));
      expr_t close_index(new fo_expr(fo->get_loc(), LOOKUP_OP1("index-session-closer"), close_index_arg));
      se_args.push_back(close_index);
      expr_t se = new sequential_expr(fo->get_loc(), se_args);
      return se;
    }
  }
  return NULL;
}

RULE_REWRITE_POST(ExpandBuildIndex)
{
  return NULL;
}

}
/* vim:set ts=2 sw=2: */
<commit_msg>fix the windows build<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * 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 "compiler/rewriter/rules/ruleset.h"
#include "compiler/expression/expr.h"
#include "compiler/rewriter/tools/expr_tools.h"
#include "indexing/value_index.h"

namespace zorba {

static store::Item_t get_uri(expr *e)
{
  // The following two checks are required if we run after
  // normalization. It does not hurt, otherwise -- so leave it
  // here.
  if (e->get_expr_kind() == promote_expr_kind) {
    e = static_cast<promote_expr *>(e)->get_input();
  }
  if (is_data(e)) {
    e = get_fo_arg(e, 0);
  }
  if (e->get_expr_kind() == const_expr_kind) {
    return static_cast<const_expr *>(e)->get_val();
  }
  return NULL;
}

RULE_REWRITE_PRE(ExpandBuildIndex)
{
  if (node->get_expr_kind() == fo_expr_kind) {
    fo_expr *fo = static_cast<fo_expr *>(&*node);
    if (fo->get_func() == LOOKUP_RESOLVED_FN(ZORBA_OPEXTENSIONS_NS, "build-index", 1)) {
      store::Item_t uri_item(get_uri((*fo)[0].getp()));
      if (uri_item == NULL) {
        ZORBA_ASSERT(false);
      }
      xqpStringStore_t uristore;
      uri_item->getStringValue(uristore);
      xqp_string uri(uristore);
      ValueIndex *vi = rCtx.getStaticContext()->lookup_index(uri);
      if (vi == NULL) {
        ZORBA_ASSERT(false);
      }
      std::vector<expr_t> se_args;
      expr_t open_index_arg(new const_expr(fo->get_loc(), uri_item));
      expr_t open_index(new fo_expr(fo->get_loc(), LOOKUP_OP1("index-session-opener"), open_index_arg));
      se_args.push_back(open_index);

      expr::substitution_t subst;

      flwor_expr::clause_list_t clauses;
      expr_t de = vi->getDomainExpression()->clone(subst);
      var_expr_t dot = vi->getDomainVariable();
      var_expr_t pos = vi->getDomainPositionVariable();
      var_expr_t newdot = new var_expr(dot->get_loc(), dot->get_kind(), dot->get_varname());
      var_expr_t newpos = new var_expr(pos->get_loc(), pos->get_kind(), pos->get_varname());
      subst[dot] = newdot;
      subst[pos] = newpos;
      flwor_expr::forletref_t fc = new forlet_clause(forlet_clause::for_clause, newdot, newpos, NULL, de);
      newdot->set_forlet_clause(fc);
      newpos->set_forlet_clause(fc);

      clauses.push_back(fc);

      std::vector<expr_t> index_insert_args;
      expr_t insert_index_uri(new const_expr(fo->get_loc(), uri_item));
      index_insert_args.push_back(insert_index_uri);

      expr_t insert_index_var(new wrapper_expr(fo->get_loc(), newdot.getp()));
      index_insert_args.push_back(insert_index_var);

      const std::vector<expr_t>& idx_fields(vi->getIndexFieldExpressions());
      int n = idx_fields.size();
      for(int i = 0; i < n; ++i) {
        index_insert_args.push_back(idx_fields[i]->clone(subst));
      }
      expr_t re(new fo_expr(fo->get_loc(), LOOKUP_OPN("index-builder"), index_insert_args));

      rchandle<flwor_expr> flwor = new flwor_expr(fo->get_loc(), clauses, re);

      se_args.push_back(flwor.getp());

      expr_t close_index_arg(new const_expr(fo->get_loc(), uri_item));
      expr_t close_index(new fo_expr(fo->get_loc(), LOOKUP_OP1("index-session-closer"), close_index_arg));
      se_args.push_back(close_index);
      expr_t se = new sequential_expr(fo->get_loc(), se_args);
      return se;
    }
  }
  return NULL;
}

RULE_REWRITE_POST(ExpandBuildIndex)
{
  return NULL;
}

}
/* vim:set ts=2 sw=2: */
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016 DeepCortex GmbH <legal@eventql.io>
 * Authors:
 *   - Paul Asmuth <paul@eventql.io>
 *   - Laura Schlimmer <laura@eventql.io>
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License ("the license") as
 * published by the Free Software Foundation, either version 3 of the License,
 * or any later version.
 *
 * In accordance with Section 7(e) of the license, the licensing of the Program
 * under the license does not imply a trademark license. Therefore any rights,
 * title and interest in our trademarks remain entirely with us.
 *
 * This program 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 license for more details.
 *
 * You can be released from the requirements of the license by purchasing a
 * commercial license. Buying such a license is mandatory as soon as you develop
 * commercial activities involving this program without disclosing the source
 * code of your own applications
 */
#include <eventql/cli/commands/cluster_remove_server.h>
#include <eventql/util/cli/flagparser.h>
#include "eventql/config/config_directory.h"
#include "eventql/util/random.h"

namespace eventql {
namespace cli {

const String ClusterRemoveServer::kName_ = "cluster-remove-server";
const String ClusterRemoveServer::kDescription_ =
    "Remove an existing server from an existing cluster.";

ClusterRemoveServer::ClusterRemoveServer(
    RefPtr<ProcessConfig> process_cfg) :
    process_cfg_(process_cfg) {}

Status ClusterRemoveServer::execute(
    const std::vector<std::string>& argv,
    FileInputStream* stdin_is,
    OutputStream* stdout_os,
    OutputStream* stderr_os) {
  ::cli::FlagParser flags;

  flags.defineFlag(
      "server_name",
      ::cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "node name",
      "<string>");

  flags.defineFlag(
      "soft",
      ::cli::FlagParser::T_SWITCH,
      false,
      NULL,
      NULL,
      "switch",
      "<switch>");

  flags.defineFlag(
      "hard",
      ::cli::FlagParser::T_SWITCH,
      false,
      NULL,
      NULL,
      "switch",
      "<string>");

  try {
    flags.parseArgv(argv);

    bool remove_hard = flags.isSet("hard");
    bool remove_soft = flags.isSet("soft");
    if (!(remove_hard ^ remove_soft)) {
      stderr_os->write("ERROR: either --hard or --soft must be set\n");
      return Status(eFlagError);
    }

    ScopedPtr<ConfigDirectory> cdir;
    {
      auto rc = ConfigDirectoryFactory::getConfigDirectoryForClient(
          process_cfg_.get(),
          &cdir);

      if (rc.isSuccess()) {
        rc = cdir->start();
      }

      if (!rc.isSuccess()) {
        stderr_os->write(StringUtil::format("ERROR: $0\n", rc.message()));
        return rc;
      }
    }

    auto cfg = cdir->getServerConfig(flags.getString("server_name"));
    if (remove_soft) {
      cfg.set_is_leaving(true);
    }
    if (remove_hard) {
      cfg.set_is_dead(true);
    }

    cdir->updateServerConfig(cfg);
    cdir->stop();

  } catch (const Exception& e) {
    stderr_os->write(StringUtil::format(
        "$0: $1\n",
        e.getTypeName(),
        e.getMessage()));
    return Status(e);
  }

  return Status::success();
}

const String& ClusterRemoveServer::getName() const {
  return kName_;
}

const String& ClusterRemoveServer::getDescription() const {
  return kDescription_;
}

void ClusterRemoveServer::printHelp(OutputStream* stdout_os) const {
  stdout_os->write(StringUtil::format(
      "\nevqlctl-$0 - $1\n\n", kName_, kDescription_));

  stdout_os->write(
      "Usage: evqlctl cluster-remove-server [OPTIONS]\n"
      "  --server_name            The name of the server to add.\n"
      "  --soft                   Enable the soft-leave operation.\n"
      "  --hard                   Enable the hard-leave operation.\n");
}

} // namespace cli
} // namespace eventql

<commit_msg>evqlctl cluster-remove-server help message typo<commit_after>/**
 * Copyright (c) 2016 DeepCortex GmbH <legal@eventql.io>
 * Authors:
 *   - Paul Asmuth <paul@eventql.io>
 *   - Laura Schlimmer <laura@eventql.io>
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License ("the license") as
 * published by the Free Software Foundation, either version 3 of the License,
 * or any later version.
 *
 * In accordance with Section 7(e) of the license, the licensing of the Program
 * under the license does not imply a trademark license. Therefore any rights,
 * title and interest in our trademarks remain entirely with us.
 *
 * This program 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 license for more details.
 *
 * You can be released from the requirements of the license by purchasing a
 * commercial license. Buying such a license is mandatory as soon as you develop
 * commercial activities involving this program without disclosing the source
 * code of your own applications
 */
#include <eventql/cli/commands/cluster_remove_server.h>
#include <eventql/util/cli/flagparser.h>
#include "eventql/config/config_directory.h"
#include "eventql/util/random.h"

namespace eventql {
namespace cli {

const String ClusterRemoveServer::kName_ = "cluster-remove-server";
const String ClusterRemoveServer::kDescription_ =
    "Remove an existing server from an existing cluster.";

ClusterRemoveServer::ClusterRemoveServer(
    RefPtr<ProcessConfig> process_cfg) :
    process_cfg_(process_cfg) {}

Status ClusterRemoveServer::execute(
    const std::vector<std::string>& argv,
    FileInputStream* stdin_is,
    OutputStream* stdout_os,
    OutputStream* stderr_os) {
  ::cli::FlagParser flags;

  flags.defineFlag(
      "server_name",
      ::cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "node name",
      "<string>");

  flags.defineFlag(
      "soft",
      ::cli::FlagParser::T_SWITCH,
      false,
      NULL,
      NULL,
      "switch",
      "<switch>");

  flags.defineFlag(
      "hard",
      ::cli::FlagParser::T_SWITCH,
      false,
      NULL,
      NULL,
      "switch",
      "<string>");

  try {
    flags.parseArgv(argv);

    bool remove_hard = flags.isSet("hard");
    bool remove_soft = flags.isSet("soft");
    if (!(remove_hard ^ remove_soft)) {
      stderr_os->write("ERROR: either --hard or --soft must be set\n");
      return Status(eFlagError);
    }

    ScopedPtr<ConfigDirectory> cdir;
    {
      auto rc = ConfigDirectoryFactory::getConfigDirectoryForClient(
          process_cfg_.get(),
          &cdir);

      if (rc.isSuccess()) {
        rc = cdir->start();
      }

      if (!rc.isSuccess()) {
        stderr_os->write(StringUtil::format("ERROR: $0\n", rc.message()));
        return rc;
      }
    }

    auto cfg = cdir->getServerConfig(flags.getString("server_name"));
    if (remove_soft) {
      cfg.set_is_leaving(true);
    }
    if (remove_hard) {
      cfg.set_is_dead(true);
    }

    cdir->updateServerConfig(cfg);
    cdir->stop();

  } catch (const Exception& e) {
    stderr_os->write(StringUtil::format(
        "$0: $1\n",
        e.getTypeName(),
        e.getMessage()));
    return Status(e);
  }

  return Status::success();
}

const String& ClusterRemoveServer::getName() const {
  return kName_;
}

const String& ClusterRemoveServer::getDescription() const {
  return kDescription_;
}

void ClusterRemoveServer::printHelp(OutputStream* stdout_os) const {
  stdout_os->write(StringUtil::format(
      "\nevqlctl-$0 - $1\n\n", kName_, kDescription_));

  stdout_os->write(
      "Usage: evqlctl cluster-remove-server [OPTIONS]\n"
      "  --server_name            The name of the server to remove.\n"
      "  --soft                   Enable the soft-leave operation.\n"
      "  --hard                   Enable the hard-leave operation.\n");
}

} // namespace cli
} // namespace eventql

<|endoftext|>