<commit_before>/*!
 * This file is part of CameraPlus.
 *
 * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
 *
 * 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
 */

#include "filenaming.h"
#include <QDir>
#include <QDate>
#include <QFile>
#include <QDeclarativeInfo>

#define PATH QString("%1%2MyDocs%2cameraplus%2").arg(QDir::homePath()).arg(QDir::separator())
#define TEMP_PATH QString("%1%2MyDocs%2.cameraplus%2").arg(QDir::homePath()).arg(QDir::separator())

FileNaming::FileNaming(QObject *parent) :
  QObject(parent), m_index(-1) {

}

FileNaming::~FileNaming() {

}

QString FileNaming::imageSuffix() const {
  return m_image;
}

void FileNaming::setImageSuffix(const QString& suffix) {
  if (m_image != suffix) {
    m_image = suffix;
    emit imageSuffixChanged();
  }
}

QString FileNaming::videoSuffix() const {
  return m_video;
}

void FileNaming::setVideoSuffix(const QString& suffix) {
  if (m_video != suffix) {
    m_video = suffix;
    emit videoSuffixChanged();
  }
}

QString FileNaming::imageFileName() {
  return fileName(m_image);
}

QString FileNaming::videoFileName() {
  return fileName(m_video);
}

QString FileNaming::fileName(const QString& suffix) {
  QString path = FileNaming::path();
  QString date = QDate::currentDate().toString("yyyyMMdd");
  QDir dir(path);

  if (suffix.isEmpty()) {
    return QString();
  }

  if (path.isEmpty()) {
    return QString();
  }

  if (date != m_date) {
    m_index = -1;
    m_date = date;
  }

  if (m_index == -1) {
    QStringList filters(QString("*%1_*").arg(date));
    QStringList entries = dir.entryList(filters, QDir::Files, QDir::Name);
    if (entries.isEmpty()) {
      m_index = 0;
    }
    else {
      QString name = QFile(entries.last()).fileName();
      m_index = name.section('_', 1, 1).section('.', 0, 0).toInt();
    }
  }

  ++m_index;

  QString name = QString("%1%2_%3.%4").arg(path).arg(date).arg(QString().sprintf("%03i", m_index)).
    arg(suffix);

  if (QFile(name).exists()) {
    return QString();
  }

  return name;
}

QString FileNaming::path() {
  if (m_path.isEmpty()) {
    m_path = canonicalPath(PATH);
  }

  return m_path;
}

QString FileNaming::temporaryPath() {
  if (m_temp.isEmpty()) {
    m_temp = canonicalPath(TEMP_PATH);
  }

  return m_temp;
}

QString FileNaming::canonicalPath(const QString& path) {
  if (!QDir::root().mkpath(path)) {
    qmlInfo(this) << "Failed to create path" << path;
    return QString();
  }

  QString newPath = QFileInfo(path).canonicalFilePath();

  if (newPath.isEmpty()) {
    return newPath;
  }

  if (!newPath.endsWith(QDir::separator())) {
    newPath.append(QDir::separator());
  }

  return newPath;
}

QString FileNaming::temporaryVideoFileName() {
  QString path = temporaryPath();

  if (path.isEmpty()) {
    return path;
  }

  return QString("%1.cameraplus_video.tmp").arg(path);
}
<commit_msg>Store captures underneath MyDocs/DCIM<commit_after>/*!
 * This file is part of CameraPlus.
 *
 * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
 *
 * 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
 */

#include "filenaming.h"
#include <QDir>
#include <QDate>
#include <QFile>
#include <QDeclarativeInfo>

#define PATH QString("%1%2MyDocs%2DCIM%2").arg(QDir::homePath()).arg(QDir::separator())
#define TEMP_PATH QString("%1%2MyDocs%2.cameraplus%2").arg(QDir::homePath()).arg(QDir::separator())

FileNaming::FileNaming(QObject *parent) :
  QObject(parent), m_index(-1) {

}

FileNaming::~FileNaming() {

}

QString FileNaming::imageSuffix() const {
  return m_image;
}

void FileNaming::setImageSuffix(const QString& suffix) {
  if (m_image != suffix) {
    m_image = suffix;
    emit imageSuffixChanged();
  }
}

QString FileNaming::videoSuffix() const {
  return m_video;
}

void FileNaming::setVideoSuffix(const QString& suffix) {
  if (m_video != suffix) {
    m_video = suffix;
    emit videoSuffixChanged();
  }
}

QString FileNaming::imageFileName() {
  return fileName(m_image);
}

QString FileNaming::videoFileName() {
  return fileName(m_video);
}

QString FileNaming::fileName(const QString& suffix) {
  QString path = FileNaming::path();
  QString date = QDate::currentDate().toString("yyyyMMdd");
  QDir dir(path);

  if (suffix.isEmpty()) {
    return QString();
  }

  if (path.isEmpty()) {
    return QString();
  }

  if (date != m_date) {
    m_index = -1;
    m_date = date;
  }

  if (m_index == -1) {
    QStringList filters(QString("*%1_*").arg(date));
    QStringList entries = dir.entryList(filters, QDir::Files, QDir::Name);
    if (entries.isEmpty()) {
      m_index = 0;
    }
    else {
      QString name = QFile(entries.last()).fileName();
      m_index = name.section('_', 1, 1).section('.', 0, 0).toInt();
    }
  }

  ++m_index;

  QString name = QString("%1%2_%3.%4").arg(path).arg(date).arg(QString().sprintf("%03i", m_index)).
    arg(suffix);

  if (QFile(name).exists()) {
    return QString();
  }

  return name;
}

QString FileNaming::path() {
  if (m_path.isEmpty()) {
    m_path = canonicalPath(PATH);
  }

  return m_path;
}

QString FileNaming::temporaryPath() {
  if (m_temp.isEmpty()) {
    m_temp = canonicalPath(TEMP_PATH);
  }

  return m_temp;
}

QString FileNaming::canonicalPath(const QString& path) {
  if (!QDir::root().mkpath(path)) {
    qmlInfo(this) << "Failed to create path" << path;
    return QString();
  }

  QString newPath = QFileInfo(path).canonicalFilePath();

  if (newPath.isEmpty()) {
    return newPath;
  }

  if (!newPath.endsWith(QDir::separator())) {
    newPath.append(QDir::separator());
  }

  return newPath;
}

QString FileNaming::temporaryVideoFileName() {
  QString path = temporaryPath();

  if (path.isEmpty()) {
    return path;
  }

  return QString("%1.cameraplus_video.tmp").arg(path);
}
<|endoftext|>


<commit_before>#include <matrix.hpp>

	Matrix :: Matrix(){};

	Matrix :: Matrix(int a, int b)
	{
		columns = b;
		strings = a;
		matrix = new int*[a];

		for (int i = 0; i < a; i++)
		{
			matrix[i] = new int[b]{0};
		}
	};

	 void Matrix :: print(void) const
	{
		for (int i = 0; i < strings; i++)
		{
			for (int j = 0; j < columns; j++)
			{
				cout << get(i, j) << " ";
			}
			cout << endl;
		}
		cout << endl;
	};

	void Matrix ::  input(string filen)
	{
		ifstream file;
		file.open(filen);
		if (file_is_open())
			cout <<"error!"<endl;
		else
		{

		matrix[i] = new *int [strings];
		for (int i = 0; i < strings; i++)
		{
			matrix[i] = new *int [columns];
			for (int j = 0; j < columns; j++)
			{
				file >> matrix[i][j];
			}
		}
	};

	void Matrix :: set(int x, int y, int z)
	{
		matrix[x][y] = z;
	};

	int Matrix :: get(int x, int y) const
	{
		return matrix[x][y];
	};

	Matrix Matrix:: operator+ (Matrix a) const
	{
		Matrix c(strings, columns);

		for (int i = 0; i < strings; i++)
		{
			for (int j = 0; j < columns; j++)
			{
				c.set(i, j, a.get(i, j) + get(i, j));
			}
		}
		return c;
	};

	Matrix Matrix :: operator* (Matrix a) const
	{
		Matrix c(strings, a.columns);

		for (int i = 0; i < strings; i++)
		{
			for (int j = 0; j < a.columns; j++)
			{
				int temp = 0;
				for (int k = 0; k < strings; k++)
				{
					temp += get(i, k) * a.get(k, j);
				}
				c.set(i, j, temp);
			}
		}

		return c;
	};

	Matrix& Matrix :: operator= (Matrix &other)
	{
		if (this != &other)
		{
			for (int i = 0; i < strings; i++)
			{
				delete[] matrix[i];
			}

			delete[] matrix;

			columns = other.columns;
			strings = other.strings;

			matrix = new int*[strings];

			for (int i = 0; i < strings; i++)
			{
				matrix[i] = new int[columns]{0};
			}

			matrix = other.matrix;
		}
		return *this;
	};

	bool Matrix :: operator== (Matrix &a) const
	{
		bool k = false;

		for (int i = 0; i < strings; i++){

			for (int j = 0; j < columns; j++){

				if (matrix[i][j] == a.matrix[i][j])

					k = true;

			}

		}

		return k;
	}

	istream& operator>> (istream& infile, const Matrix& result)

	{

		for (int i = 0; i < result.strings; i++)

			for (int j = 0; j < result.columns; j++)

				infile >> result.matrix[i][j];

		return infile;

	}

	 ostream& operator<< (ostream& os, const Matrix& a)
	{
		for (int i = 0; i < a.strings; i++)
		{
			for (int j = 0; j < a.columns; j++)
			{
				os << a.matrix[i, j] << " ";
			}
			os << endl;
		}
		os << endl;
		return os;
	}

	Matrix :: ~Matrix()
	{
		/*for (int i = 0; i < strings; i++)
		{
			delete[] matrix[i];
		}

		delete[] matrix;*/
	};
};

<commit_msg>Update matrix.cpp<commit_after>#include <matrix.hpp>

	Matrix :: Matrix(){};

	Matrix :: Matrix(int a, int b)
	{
		columns = b;
		strings = a;
		matrix = new int*[a];

		for (int i = 0; i < a; i++)
		{
			matrix[i] = new int[b]{0};
		}
	};

	 void  print(void) const
	{
		for (int i = 0; i < strings; i++)
		{
			for (int j = 0; j < columns; j++)
			{
				cout << get(i, j) << " ";
			}
			cout << endl;
		}
		cout << endl;
	};

	void input(string filen)
	{
		ifstream file;
		file.open(filen);
		if (file_is_open())
			cout <<"error!"<endl;
		else
		{

		matrix[i] = new *int [strings];
		for (int i = 0; i < strings; i++)
		{
			matrix[i] = new *int [columns];
			for (int j = 0; j < columns; j++)
			{
				file >> matrix[i][j];
			}
		}
	};

	void set(int x, int y, int z)
	{
		matrix[x][y] = z;
	};

	int get(int x, int y) const
	{
		return matrix[x][y];
	};

	Matrix Matrix:: operator+ (Matrix a) const
	{
		Matrix c(strings, columns);

		for (int i = 0; i < strings; i++)
		{
			for (int j = 0; j < columns; j++)
			{
				c.set(i, j, a.get(i, j) + get(i, j));
			}
		}
		return c;
	};

	Matrix Matrix :: operator* (Matrix a) const
	{
		Matrix c(strings, a.columns);

		for (int i = 0; i < strings; i++)
		{
			for (int j = 0; j < a.columns; j++)
			{
				int temp = 0;
				for (int k = 0; k < strings; k++)
				{
					temp += get(i, k) * a.get(k, j);
				}
				c.set(i, j, temp);
			}
		}

		return c;
	};

	Matrix& Matrix :: operator= (Matrix &other)
	{
		if (this != &other)
		{
			for (int i = 0; i < strings; i++)
			{
				delete[] matrix[i];
			}

			delete[] matrix;

			columns = other.columns;
			strings = other.strings;

			matrix = new int*[strings];

			for (int i = 0; i < strings; i++)
			{
				matrix[i] = new int[columns]{0};
			}

			matrix = other.matrix;
		}
		return *this;
	};

	bool Matrix :: operator== (Matrix &a) const
	{
		bool k = false;

		for (int i = 0; i < strings; i++){

			for (int j = 0; j < columns; j++){

				if (matrix[i][j] == a.matrix[i][j])

					k = true;

			}

		}

		return k;
	}

	istream& operator>> (istream& infile, const Matrix& result)

	{

		for (int i = 0; i < result.strings; i++)

			for (int j = 0; j < result.columns; j++)

				infile >> result.matrix[i][j];

		return infile;

	}

	 ostream& operator<< (ostream& os, const Matrix& a)
	{
		for (int i = 0; i < a.strings; i++)
		{
			for (int j = 0; j < a.columns; j++)
			{
				os << a.matrix[i, j] << " ";
			}
			os << endl;
		}
		os << endl;
		return os;
	}

	Matrix :: ~Matrix()
	{
		/*for (int i = 0; i < strings; i++)
		{
			delete[] matrix[i];
		}

		delete[] matrix;*/
	};
};

<|endoftext|>


<commit_before>/**
 * @file EMD.cpp
 * @brief mex interface for EMD
 * @author Kota Yamaguchi
 * @date 2011
 */
#include "mexopencv.hpp"
using namespace std;
using namespace cv;

/**
 * Main entry called from Matlab
 * @param nlhs number of left-hand-side arguments
 * @param plhs pointers to mxArrays in the left-hand-side
 * @param nrhs number of right-hand-side arguments
 * @param prhs pointers to mxArrays in the right-hand-side
 */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
    // Check the number of arguments
    if (nrhs<2 || (nrhs%2)!=0 || nlhs>3)
        mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");

    // Argument vector
    vector<MxArray> rhs(prhs,prhs+nrhs);

    // Option processing
    int distType = cv::DIST_L2;
    Mat cost;
    float lowerBound = 0;
    for (int i=2; i<nrhs; i+=2) {
        string key = rhs[i].toString();
        if (key=="DistType")
            distType = (rhs[i+1].isChar()) ?
                DistType[rhs[i+1].toString()] : rhs[i+1].toInt();
        else if (key=="Cost")
            cost = rhs[i+1].toMat();
        else if (key=="LowerBound")
            lowerBound = rhs[i+1].toDouble();
        else
            mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
    }
    if (distType==cv::DIST_USER && cost.empty())
        mexErrMsgIdAndTxt("mexopencv:error","Cost matrix empty");

    // Process
    Mat signature1(rhs[0].toMat()), signature2(rhs[1].toMat()), flow;
    double d = EMD(signature1, signature2, distType, cost, &lowerBound, flow);
    plhs[0] = MxArray(d);
    if (nlhs>1)
        plhs[1] = MxArray(lowerBound);
    if (nlhs>2)
        plhs[2] = MxArray(flow);
}
<commit_msg>fix EMD in case user cost function is used<commit_after>/**
 * @file EMD.cpp
 * @brief mex interface for EMD
 * @author Kota Yamaguchi
 * @date 2011
 */
#include "mexopencv.hpp"
using namespace std;
using namespace cv;

/**
 * Main entry called from Matlab
 * @param nlhs number of left-hand-side arguments
 * @param plhs pointers to mxArrays in the left-hand-side
 * @param nrhs number of right-hand-side arguments
 * @param prhs pointers to mxArrays in the right-hand-side
 */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
    // Check the number of arguments
    if (nrhs<2 || (nrhs%2)!=0 || nlhs>3)
        mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");

    // Argument vector
    vector<MxArray> rhs(prhs,prhs+nrhs);

    // Option processing
    int distType = cv::DIST_L2;
    Mat cost;
    float lowerBound = 0;
    for (int i=2; i<nrhs; i+=2) {
        string key = rhs[i].toString();
        if (key=="DistType")
            distType = (rhs[i+1].isChar()) ?
                DistType[rhs[i+1].toString()] : rhs[i+1].toInt();
        else if (key=="Cost")
            cost = rhs[i+1].toMat();
        else if (key=="LowerBound")
            lowerBound = rhs[i+1].toDouble();
        else
            mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
    }
    if (distType==cv::DIST_USER && cost.empty())
        mexErrMsgIdAndTxt("mexopencv:error","Cost matrix empty");

    // Process
    Mat signature1(rhs[0].toMat()), signature2(rhs[1].toMat()), flow;
    double d;
    if (distType==cv::DIST_USER)
    {
        d = EMD(signature1, signature2, distType, cost);
    }
    else
    {
        d = EMD(signature1, signature2, distType, cost, &lowerBound, flow);
    }

    plhs[0] = MxArray(d);
    if (nlhs>1)
        plhs[1] = MxArray(lowerBound);
    if (nlhs>2)
        plhs[2] = MxArray(flow);
}
<|endoftext|>


<commit_before>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
//

#include "StarsPlugin.h"

#include <QtCore/QRectF>
#include <QtCore/QSize>
#include <QtCore/QDateTime>
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "MarbleDataFacade.h"
#include "GeoPainter.h"
#include "SunLocator.h"
#include "ViewportParams.h"
#include "MarbleWidget.h"

namespace Marble
{

StarsPlugin::StarsPlugin()
    : m_isInitialized( false ),
      m_starsLoaded( false ),
      m_marbleWidget( 0 )
{
}

QStringList StarsPlugin::backendTypes() const
{
    return QStringList( "stars" );
}

QString StarsPlugin::renderPolicy() const
{
    return QString( "SPECIFIED_ALWAYS" );
}

QStringList StarsPlugin::renderPosition() const
{
    QStringList layers = QStringList() << "STARS" << "ALWAYS_ON_TOP";
    return layers;
}

QString StarsPlugin::name() const
{
    return tr( "Stars Plugin" );
}

QString StarsPlugin::guiString() const
{
    return tr( "&Stars" );
}

QString StarsPlugin::nameId() const
{
    return QString( "stars" );
}

QString StarsPlugin::description() const
{
    return tr( "A plugin that shows the Starry Sky." );
}

QIcon StarsPlugin::icon () const
{
    return QIcon();
}

void StarsPlugin::initialize ()
{
    m_isInitialized = true;
}

bool StarsPlugin::isInitialized () const
{
    return m_isInitialized;
}

void StarsPlugin::loadStars() {
    mDebug() << Q_FUNC_INFO;
    // Load star data
    m_stars.clear();

    QFile starFile( MarbleDirs::path( "stars/stars.dat" ) );
    starFile.open( QIODevice::ReadOnly );
    QDataStream in( &starFile );

    // Read and check the header
    quint32 magic;
    in >> magic;
    if ( magic != 0x73746172 )
        return;

    // Read the version
    qint32 version;
    in >> version;
    if ( version > 001 ) {
        mDebug() << "stars.dat: file too new.";
        return;
    }
    double ra;
    double de;
    double mag;

    while ( !in.atEnd() ) {
        in >> ra;
        in >> de;
        in >> mag;
        StarPoint star( (qreal)(ra), (qreal)(de), (qreal)(mag) );
        m_stars << star;
//        mDebug() << "RA:" << ra << "DE:" << de << "MAG:" << mag;
    }
    m_starsLoaded = true;
}

bool StarsPlugin::render( GeoPainter *painter, ViewportParams *viewport,
                          const QString& renderPos, GeoSceneLayer * layer )
{
    Q_UNUSED( layer )

    if ( !(renderPos == "STARS" || renderPos == "ALWAYS_ON_TOP") ) {
        return true;
    }

    if( renderPos=="STARS" )
    {
        QString target = dataFacade()->target();

        // So far this starry sky plugin only supports displaying stars on earth.
        if ( target != "earth" ) {
            return true;
        }

        painter->save();

        painter->autoMapQuality();

        QPen starPen( Qt::NoPen );
        QBrush starBrush( Qt::white );

        painter->setPen( starPen );
        painter->setBrush( starBrush );

        QDateTime currentDateTime = dataFacade()->dateTime();

        qreal gmst = siderealTime( currentDateTime );
        qreal skyRotationAngle = gmst / 12.0 * M_PI;

        qreal centerLon, centerLat;
        viewport->centerCoordinates( centerLon, centerLat );

        Quaternion  skyAxis;
        skyAxis.createFromEuler( -centerLat , centerLon + skyRotationAngle, 0.0 );

        matrix       skyAxisMatrix;
        skyAxis.inverse().toMatrix( skyAxisMatrix );

        if ( !viewport->globeCoversViewport() && viewport->projection() == Spherical )
        {
            // Delayed initialization:
            // Load the star database only if the sky is actually being painted...
            if ( !m_starsLoaded ) {
                loadStars();
                m_starsLoaded = true;
            }

            int x, y;

            const qreal  skyRadius      = 0.6 * sqrt( (qreal)viewport->width() * viewport->width() + viewport->height() * viewport->height() );
            const qreal  earthRadius    = viewport->radius();

            QVector<StarPoint>::const_iterator i = m_stars.constBegin();
            QVector<StarPoint>::const_iterator itEnd = m_stars.constEnd();
            for (; i != itEnd; ++i)
            {
                Quaternion  qpos = (*i).quaternion();

                qpos.rotateAroundAxis( skyAxisMatrix );

                if ( qpos.v[Q_Z] > 0 ) {
                   continue;
                }

                qreal  earthCenteredX = qpos.v[Q_X] * skyRadius;
                qreal  earthCenteredY = qpos.v[Q_Y] * skyRadius;

                // Don't draw high placemarks (e.g. satellites) that aren't visible.
                if ( qpos.v[Q_Z] < 0
                    && ( ( earthCenteredX * earthCenteredX
                            + earthCenteredY * earthCenteredY )
                        < earthRadius * earthRadius ) ) {
                    continue;
                }

                // Let (x, y) be the position on the screen of the placemark..
                x = (int)(viewport->width()  / 2 + skyRadius * qpos.v[Q_X]);
                y = (int)(viewport->height() / 2 - skyRadius * qpos.v[Q_Y]);

                // Skip placemarks that are outside the screen area
                if ( x < 0 || x >= viewport->width()
    		 || y < 0 || y >= viewport->height() )
                    continue;

                qreal size;
                if ( (*i).magnitude() < -1 ) size = 6.5;
                else if ( (*i).magnitude() < 0 ) size = 5.5;
                else if ( (*i).magnitude() < 1 ) size = 4.5;
                else if ( (*i).magnitude() < 2 ) size = 4.0;
                else if ( (*i).magnitude() < 3 ) size = 3.0;
                else if ( (*i).magnitude() < 4 ) size = 2.0;
                else if ( (*i).magnitude() < 5 ) size = 1.0;
                else size = 0.5;
                painter->drawEllipse( QRectF( x, y, size, size ) );
            }
        }

        painter->restore();
    }

    if( renderPos == "ALWAYS_ON_TOP" )
    {
        m_marbleWidget = dynamic_cast<MarbleWidget*>( painter->device() );
        if( m_marbleWidget && m_marbleWidget->sunLocator()->getCentered() == true )
        {
            GeoDataCoordinates point( m_marbleWidget->sunLocator()->getLon(), m_marbleWidget->sunLocator()->getLat(), 0, GeoDataCoordinates::Degree );
            QImage image( MarbleDirs::path( "svg/sunshine.png" ) );
            painter->drawImage( point, image.scaled( QSize( 30, 30 ) ) );
        }
    }

    return true;
}

qreal StarsPlugin::siderealTime( const QDateTime& localDateTime )
{
    QDateTime utcDateTime = localDateTime.toTimeSpec ( Qt::UTC );
    qreal mjdUtc = (qreal)( utcDateTime.date().toJulianDay() );

    qreal offsetUtcSecs = -utcDateTime.time().secsTo( QTime( 00, 00 ) );
    qreal d_days = mjdUtc - 2451545.5;
    qreal d = d_days + ( offsetUtcSecs / ( 24.0 * 3600 ) );

    //  Appendix A of USNO Circular No. 163 (1981):
    //  Approximate value for Greenwich mean sidereal time in hours:
    //  (Loss of precision: 0.1 secs per century)
    qreal gmst = 18.697374558 + 24.06570982441908 * d;

    // Range (0..24) for gmst:
    return gmst - (int)( gmst / 24.0 ) * 24.0;
}

}

Q_EXPORT_PLUGIN2( StarsPlugin, Marble::StarsPlugin )

#include "StarsPlugin.moc"
<commit_msg>Remove "Plugin" from name. No other plugin has this as part of its name.<commit_after>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
//

#include "StarsPlugin.h"

#include <QtCore/QRectF>
#include <QtCore/QSize>
#include <QtCore/QDateTime>
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "MarbleDataFacade.h"
#include "GeoPainter.h"
#include "SunLocator.h"
#include "ViewportParams.h"
#include "MarbleWidget.h"

namespace Marble
{

StarsPlugin::StarsPlugin()
    : m_isInitialized( false ),
      m_starsLoaded( false ),
      m_marbleWidget( 0 )
{
}

QStringList StarsPlugin::backendTypes() const
{
    return QStringList( "stars" );
}

QString StarsPlugin::renderPolicy() const
{
    return QString( "SPECIFIED_ALWAYS" );
}

QStringList StarsPlugin::renderPosition() const
{
    QStringList layers = QStringList() << "STARS" << "ALWAYS_ON_TOP";
    return layers;
}

QString StarsPlugin::name() const
{
    return tr( "Stars" );
}

QString StarsPlugin::guiString() const
{
    return tr( "&Stars" );
}

QString StarsPlugin::nameId() const
{
    return QString( "stars" );
}

QString StarsPlugin::description() const
{
    return tr( "A plugin that shows the Starry Sky." );
}

QIcon StarsPlugin::icon () const
{
    return QIcon();
}

void StarsPlugin::initialize ()
{
    m_isInitialized = true;
}

bool StarsPlugin::isInitialized () const
{
    return m_isInitialized;
}

void StarsPlugin::loadStars() {
    mDebug() << Q_FUNC_INFO;
    // Load star data
    m_stars.clear();

    QFile starFile( MarbleDirs::path( "stars/stars.dat" ) );
    starFile.open( QIODevice::ReadOnly );
    QDataStream in( &starFile );

    // Read and check the header
    quint32 magic;
    in >> magic;
    if ( magic != 0x73746172 )
        return;

    // Read the version
    qint32 version;
    in >> version;
    if ( version > 001 ) {
        mDebug() << "stars.dat: file too new.";
        return;
    }
    double ra;
    double de;
    double mag;

    while ( !in.atEnd() ) {
        in >> ra;
        in >> de;
        in >> mag;
        StarPoint star( (qreal)(ra), (qreal)(de), (qreal)(mag) );
        m_stars << star;
//        mDebug() << "RA:" << ra << "DE:" << de << "MAG:" << mag;
    }
    m_starsLoaded = true;
}

bool StarsPlugin::render( GeoPainter *painter, ViewportParams *viewport,
                          const QString& renderPos, GeoSceneLayer * layer )
{
    Q_UNUSED( layer )

    if ( !(renderPos == "STARS" || renderPos == "ALWAYS_ON_TOP") ) {
        return true;
    }

    if( renderPos=="STARS" )
    {
        QString target = dataFacade()->target();

        // So far this starry sky plugin only supports displaying stars on earth.
        if ( target != "earth" ) {
            return true;
        }

        painter->save();

        painter->autoMapQuality();

        QPen starPen( Qt::NoPen );
        QBrush starBrush( Qt::white );

        painter->setPen( starPen );
        painter->setBrush( starBrush );

        QDateTime currentDateTime = dataFacade()->dateTime();

        qreal gmst = siderealTime( currentDateTime );
        qreal skyRotationAngle = gmst / 12.0 * M_PI;

        qreal centerLon, centerLat;
        viewport->centerCoordinates( centerLon, centerLat );

        Quaternion  skyAxis;
        skyAxis.createFromEuler( -centerLat , centerLon + skyRotationAngle, 0.0 );

        matrix       skyAxisMatrix;
        skyAxis.inverse().toMatrix( skyAxisMatrix );

        if ( !viewport->globeCoversViewport() && viewport->projection() == Spherical )
        {
            // Delayed initialization:
            // Load the star database only if the sky is actually being painted...
            if ( !m_starsLoaded ) {
                loadStars();
                m_starsLoaded = true;
            }

            int x, y;

            const qreal  skyRadius      = 0.6 * sqrt( (qreal)viewport->width() * viewport->width() + viewport->height() * viewport->height() );
            const qreal  earthRadius    = viewport->radius();

            QVector<StarPoint>::const_iterator i = m_stars.constBegin();
            QVector<StarPoint>::const_iterator itEnd = m_stars.constEnd();
            for (; i != itEnd; ++i)
            {
                Quaternion  qpos = (*i).quaternion();

                qpos.rotateAroundAxis( skyAxisMatrix );

                if ( qpos.v[Q_Z] > 0 ) {
                   continue;
                }

                qreal  earthCenteredX = qpos.v[Q_X] * skyRadius;
                qreal  earthCenteredY = qpos.v[Q_Y] * skyRadius;

                // Don't draw high placemarks (e.g. satellites) that aren't visible.
                if ( qpos.v[Q_Z] < 0
                    && ( ( earthCenteredX * earthCenteredX
                            + earthCenteredY * earthCenteredY )
                        < earthRadius * earthRadius ) ) {
                    continue;
                }

                // Let (x, y) be the position on the screen of the placemark..
                x = (int)(viewport->width()  / 2 + skyRadius * qpos.v[Q_X]);
                y = (int)(viewport->height() / 2 - skyRadius * qpos.v[Q_Y]);

                // Skip placemarks that are outside the screen area
                if ( x < 0 || x >= viewport->width()
    		 || y < 0 || y >= viewport->height() )
                    continue;

                qreal size;
                if ( (*i).magnitude() < -1 ) size = 6.5;
                else if ( (*i).magnitude() < 0 ) size = 5.5;
                else if ( (*i).magnitude() < 1 ) size = 4.5;
                else if ( (*i).magnitude() < 2 ) size = 4.0;
                else if ( (*i).magnitude() < 3 ) size = 3.0;
                else if ( (*i).magnitude() < 4 ) size = 2.0;
                else if ( (*i).magnitude() < 5 ) size = 1.0;
                else size = 0.5;
                painter->drawEllipse( QRectF( x, y, size, size ) );
            }
        }

        painter->restore();
    }

    if( renderPos == "ALWAYS_ON_TOP" )
    {
        m_marbleWidget = dynamic_cast<MarbleWidget*>( painter->device() );
        if( m_marbleWidget && m_marbleWidget->sunLocator()->getCentered() == true )
        {
            GeoDataCoordinates point( m_marbleWidget->sunLocator()->getLon(), m_marbleWidget->sunLocator()->getLat(), 0, GeoDataCoordinates::Degree );
            QImage image( MarbleDirs::path( "svg/sunshine.png" ) );
            painter->drawImage( point, image.scaled( QSize( 30, 30 ) ) );
        }
    }

    return true;
}

qreal StarsPlugin::siderealTime( const QDateTime& localDateTime )
{
    QDateTime utcDateTime = localDateTime.toTimeSpec ( Qt::UTC );
    qreal mjdUtc = (qreal)( utcDateTime.date().toJulianDay() );

    qreal offsetUtcSecs = -utcDateTime.time().secsTo( QTime( 00, 00 ) );
    qreal d_days = mjdUtc - 2451545.5;
    qreal d = d_days + ( offsetUtcSecs / ( 24.0 * 3600 ) );

    //  Appendix A of USNO Circular No. 163 (1981):
    //  Approximate value for Greenwich mean sidereal time in hours:
    //  (Loss of precision: 0.1 secs per century)
    qreal gmst = 18.697374558 + 24.06570982441908 * d;

    // Range (0..24) for gmst:
    return gmst - (int)( gmst / 24.0 ) * 24.0;
}

}

Q_EXPORT_PLUGIN2( StarsPlugin, Marble::StarsPlugin )

#include "StarsPlugin.moc"
<|endoftext|>


<commit_before>/*
 * This file is part of the µOS++ distribution.
 *   (https://github.com/micro-os-plus)
 * Copyright (c) 2015 Liviu Ionescu.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom
 * the Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#if defined(TRACE)

#include <cmsis-plus/os-app-config.h>
#include <cmsis-plus/diag/trace.h>

#include <cstdarg>
#include <cstdio>
#include <cstring>

#ifndef OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE
#define OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE (200)
#endif

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

namespace os
{
  namespace trace
  {
    // ----------------------------------------------------------------------

    void __attribute__((weak))
    initialize (void)
    {
      ;
    }

    /**
     * @brief Write the given number of bytes to the trace output channel.
     * @return  The number of characters actually written, or -1 if error.
     */
    ssize_t __attribute__((weak))
    write (const void* buf __attribute__((unused)), std::size_t nbyte)
    {
      return static_cast<ssize_t> (nbyte);
    }

    void __attribute__((weak))
    flush (void)
    {
      ;
    }

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

    int __attribute__((weak))
    printf (const char* format, ...)
    {
      std::va_list args;
      va_start(args, format);

      int ret = vprintf (format, args);

      va_end(args);
      return ret;
    }

    int __attribute__((weak))
    vprintf (const char* format, std::va_list args)
    {
      // Caution: allocated on the stack!
      char buf[OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE];

      // TODO: possibly rewrite it to no longer use newlib,
      // (although the nano version is no longer very heavy).

      // Print to the local buffer
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
      int ret = ::vsnprintf (buf, sizeof(buf), format, args);
#pragma GCC diagnostic pop
      if (ret > 0)
        {
          // Transfer the buffer to the device.
          ret = static_cast<int> (write (buf, static_cast<size_t> (ret)));
        }
      return ret;
    }

    int __attribute__((weak))
    puts (const char* s)
    {
      int ret = static_cast<int> (write (s, strlen (s)));
      if (ret > 0)
        {
          ret = static_cast<int> (write ("\n", 1)); // Add a line terminator
        }
      if (ret > 0)
        {
          return ret;
        }
      else
        {
          return EOF;
        }
    }

    int __attribute__((weak))
    putchar (int c)
    {
      int ret = static_cast<int> (write (reinterpret_cast<const char*> (&c), 1));
      if (ret > 0)
        {
          return c;
        }
      else
        {
          return EOF;
        }
    }

    void __attribute__((weak))
    dump_args (int argc, char* argv[])
    {
      printf ("main(argc=%d, argv=[", argc);
      for (int i = 0; i < argc; ++i)
        {
          if (i != 0)
            {
              printf (", ");
            }
          printf ("\"%s\"", argv[i]);
        }
      printf ("]);\n");
    }

  } /* namespace trace */
} /* namespace os */

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

using namespace os;

// These cannot be aliased, since they might be defined
// in a different translation units (and usually they are).

void __attribute__((weak))
trace_initialize (void)
{
  trace::initialize ();
}

ssize_t __attribute__((weak))
trace_write (const void* buf, std::size_t nbyte)
{
  return trace::write (buf, nbyte);
}

void __attribute__((weak))
trace_flush (void)
{
  return trace::flush ();
}

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

#if defined(__ARM_EABI__)

// For embedded platforms, optimise with aliases.
//
// Aliases can only refer symbols defined in the same translation unit
// and C++ de-mangling must be done manually.

int __attribute__((weak, alias ("_ZN2os5trace6printfEPKcz")))
trace_printf (const char* format, ...);

int __attribute__((weak, alias ("_ZN2os5trace7vprintfEPKcSt9__va_list")))
trace_vprintf (const char* format, ...);

int __attribute__((weak, alias("_ZN2os5trace4putsEPKc")))
trace_puts (const char *s);

int __attribute__((weak, alias("_ZN2os5trace7putcharEi")))
trace_putchar (int c);

void __attribute__((weak, alias("_ZN2os5trace9dump_argsEiPPc")))
trace_dump_args (int argc, char* argv[]);

#else

// For non-embedded platforms, to remain compatible with OS X which does
// not support aliases, redefine the C functions to call the C++ versions.

int
trace_printf (const char* format, ...)
{
  std::va_list args;
  va_start(args, format);

  int ret = trace::vprintf (format, args);

  va_end(args);
  return ret;
}

int
trace_vprintf (const char* format, va_list args)
{
  return trace::vprintf (format, args);
}

int
trace_puts (const char* s)
{
  return trace::puts (s);
}

int
trace_putchar (int c)
{
  return trace::putchar (c);
}

void
trace_dump_args (int argc, char* argv[])
{
  trace::dump_args (argc, argv);
}

#endif

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

#endif // defined(TRACE)
<commit_msg>diag/trace.cpp: puts accepts empty string<commit_after>/*
 * This file is part of the µOS++ distribution.
 *   (https://github.com/micro-os-plus)
 * Copyright (c) 2015 Liviu Ionescu.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom
 * the Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#if defined(TRACE)

#include <cmsis-plus/os-app-config.h>
#include <cmsis-plus/diag/trace.h>

#include <cstdarg>
#include <cstdio>
#include <cstring>

#ifndef OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE
#define OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE (200)
#endif

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

namespace os
{
  namespace trace
  {
    // ----------------------------------------------------------------------

    void __attribute__((weak))
    initialize (void)
    {
      ;
    }

    /**
     * @brief Write the given number of bytes to the trace output channel.
     * @return  The number of characters actually written, or -1 if error.
     */
    ssize_t __attribute__((weak))
    write (const void* buf __attribute__((unused)), std::size_t nbyte)
    {
      return static_cast<ssize_t> (nbyte);
    }

    void __attribute__((weak))
    flush (void)
    {
      ;
    }

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

    int __attribute__((weak))
    printf (const char* format, ...)
    {
      std::va_list args;
      va_start(args, format);

      int ret = vprintf (format, args);

      va_end(args);
      return ret;
    }

    int __attribute__((weak))
    vprintf (const char* format, std::va_list args)
    {
      // Caution: allocated on the stack!
      char buf[OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE];

      // TODO: possibly rewrite it to no longer use newlib,
      // (although the nano version is no longer very heavy).

      // Print to the local buffer
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
      int ret = ::vsnprintf (buf, sizeof(buf), format, args);
#pragma GCC diagnostic pop
      if (ret > 0)
        {
          // Transfer the buffer to the device.
          ret = static_cast<int> (write (buf, static_cast<size_t> (ret)));
        }
      return ret;
    }

    int __attribute__((weak))
    puts (const char* s)
    {
      int ret = static_cast<int> (write (s, strlen (s)));
      if (ret >= 0)
        {
          ret = static_cast<int> (write ("\n", 1)); // Add a line terminator
        }
      if (ret > 0)
        {
          return ret;
        }
      else
        {
          return EOF;
        }
    }

    int __attribute__((weak))
    putchar (int c)
    {
      int ret = static_cast<int> (write (reinterpret_cast<const char*> (&c), 1));
      if (ret > 0)
        {
          return c;
        }
      else
        {
          return EOF;
        }
    }

    void __attribute__((weak))
    dump_args (int argc, char* argv[])
    {
      printf ("main(argc=%d, argv=[", argc);
      for (int i = 0; i < argc; ++i)
        {
          if (i != 0)
            {
              printf (", ");
            }
          printf ("\"%s\"", argv[i]);
        }
      printf ("]);\n");
    }

  } /* namespace trace */
} /* namespace os */

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

using namespace os;

// These cannot be aliased, since they might be defined
// in a different translation units (and usually they are).

void __attribute__((weak))
trace_initialize (void)
{
  trace::initialize ();
}

ssize_t __attribute__((weak))
trace_write (const void* buf, std::size_t nbyte)
{
  return trace::write (buf, nbyte);
}

void __attribute__((weak))
trace_flush (void)
{
  return trace::flush ();
}

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

#if defined(__ARM_EABI__)

// For embedded platforms, optimise with aliases.
//
// Aliases can only refer symbols defined in the same translation unit
// and C++ de-mangling must be done manually.

int __attribute__((weak, alias ("_ZN2os5trace6printfEPKcz")))
trace_printf (const char* format, ...);

int __attribute__((weak, alias ("_ZN2os5trace7vprintfEPKcSt9__va_list")))
trace_vprintf (const char* format, ...);

int __attribute__((weak, alias("_ZN2os5trace4putsEPKc")))
trace_puts (const char *s);

int __attribute__((weak, alias("_ZN2os5trace7putcharEi")))
trace_putchar (int c);

void __attribute__((weak, alias("_ZN2os5trace9dump_argsEiPPc")))
trace_dump_args (int argc, char* argv[]);

#else

// For non-embedded platforms, to remain compatible with OS X which does
// not support aliases, redefine the C functions to call the C++ versions.

int
trace_printf (const char* format, ...)
{
  std::va_list args;
  va_start(args, format);

  int ret = trace::vprintf (format, args);

  va_end(args);
  return ret;
}

int
trace_vprintf (const char* format, va_list args)
{
  return trace::vprintf (format, args);
}

int
trace_puts (const char* s)
{
  return trace::puts (s);
}

int
trace_putchar (int c)
{
  return trace::putchar (c);
}

void
trace_dump_args (int argc, char* argv[])
{
  trace::dump_args (argc, argv);
}

#endif

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

#endif // defined(TRACE)
<|endoftext|>


<commit_before>#include "Channel.hpp"
#include "CMessage.hpp"
#include "Network.hpp"
#include "CDispatcher.hpp"
#include "CLog.hpp"

#include "fmt/format.h"

#undef SendMessage // Windows at its finest

Channel::Channel(ChannelId_t pawn_id, json &data) :
	m_PawnId(pawn_id)
{
	m_Id = data["id"].get<std::string>();
	m_Type = static_cast<Type>(data["type"].get<int>());
	if (m_Type == Type::GUILD_TEXT) // is a guild channel
	{
		m_GuildId = data["guild_id"].get<std::string>();
		m_Name = data["name"].get<std::string>();
		json &topic = data["topic"];
		if (!topic.is_null())
			m_Topic = topic.get<std::string>();
	}
}

void Channel::SendMessage(std::string &&msg)
{
	json data = {
		{ "content", std::move(msg) }
	};
	Network::Get()->Http().Post(fmt::format("/channels/{}/messages", GetId()), data.dump());
}

void ChannelManager::Initialize()
{
	assert(m_Initialized != m_InitValue);

	Network::Get()->WebSocket().RegisterEvent(WebSocket::Event::CHANNEL_CREATE, [](json &data)
	{
		ChannelManager::Get()->AddChannel(data);
	});

	Network::Get()->WebSocket().RegisterEvent(WebSocket::Event::READY, [this](json &data)
	{
		for (json &c : data["private_channels"])
			AddChannel(c);
		m_Initialized++;
	});

	// GUILD_CREATE event seems to be always sent after READY event with all guilds the bot is in
	Network::Get()->WebSocket().RegisterEvent(WebSocket::Event::GUILD_CREATE, [this](json &data)
	{
		for (json &c : data["channels"])
		{
			// manually add guild_id to channel data
			c["guild_id"] = data["id"];
			AddChannel(c);
		}
		m_Initialized++;
	});

	// PAWN callbacks
	Network::Get()->WebSocket().RegisterEvent(WebSocket::Event::MESSAGE_CREATE, [this](json &data)
	{
		CMessage msg(data);
		Channel_t const &channel = FindChannelById(msg.GetChannelId());
		if (channel)
		{
			CDispatcher::Get()->Dispatch([this, msg, &channel]()
			{
				// forward DCC_OnChannelMessage(DCC_Channel:channel, const author[], const message[]);
				PawnCallbackManager::Get()->Call("DCC_OnChannelMessage",
					channel->GetPawnId(), msg.GetAuthor(), msg.GetContent());
			});
		}
	});
}

void ChannelManager::WaitForInitialization()
{
	while (m_Initialized != m_InitValue)
		std::this_thread::sleep_for(std::chrono::milliseconds(20));
}

void ChannelManager::AddChannel(json &data)
{
	json &type = data["type"];
	if (!type.is_null() && type.get<std::string>() != "text")
		return; // we're only interested in text channels

	ChannelId_t id = 1;
	while (m_Channels.find(id) != m_Channels.end())
		++id;

	m_Channels.emplace(id, Channel_t(new Channel(id, data)));
}

Channel_t const &ChannelManager::FindChannel(ChannelId_t id)
{
	static Channel_t invalid_channel;
	auto it = m_Channels.find(id);
	if (it == m_Channels.end())
		return invalid_channel;
	return it->second;
}

Channel_t const &ChannelManager::FindChannelByName(std::string const &name)
{
	static Channel_t invalid_channel;
	for (auto const &c : m_Channels)
	{
		Channel_t const &channel = c.second;
		if (channel->GetName().compare(name) == 0)
			return channel;
	}
	return invalid_channel;
}

Channel_t const &ChannelManager::FindChannelById(Snowflake_t const &sfid)
{
	static Channel_t invalid_channel;
	for (auto const &c : m_Channels)
	{
		Channel_t const &channel = c.second;
		if (channel->GetId().compare(sfid) == 0)
			return channel;
	}
	return invalid_channel;
}
<commit_msg>fix channel type check<commit_after>#include "Channel.hpp"
#include "CMessage.hpp"
#include "Network.hpp"
#include "CDispatcher.hpp"
#include "CLog.hpp"

#include "fmt/format.h"

#undef SendMessage // Windows at its finest

Channel::Channel(ChannelId_t pawn_id, json &data) :
	m_PawnId(pawn_id)
{
	m_Id = data["id"].get<std::string>();
	m_Type = static_cast<Type>(data["type"].get<int>());
	if (m_Type == Type::GUILD_TEXT) // is a guild channel
	{
		m_GuildId = data["guild_id"].get<std::string>();
		m_Name = data["name"].get<std::string>();
		json &topic = data["topic"];
		if (!topic.is_null())
			m_Topic = topic.get<std::string>();
	}
}

void Channel::SendMessage(std::string &&msg)
{
	json data = {
		{ "content", std::move(msg) }
	};
	Network::Get()->Http().Post(fmt::format("/channels/{}/messages", GetId()), data.dump());
}

void ChannelManager::Initialize()
{
	assert(m_Initialized != m_InitValue);

	Network::Get()->WebSocket().RegisterEvent(WebSocket::Event::CHANNEL_CREATE, [](json &data)
	{
		ChannelManager::Get()->AddChannel(data);
	});

	Network::Get()->WebSocket().RegisterEvent(WebSocket::Event::READY, [this](json &data)
	{
		for (json &c : data["private_channels"])
			AddChannel(c);
		m_Initialized++;
	});

	// GUILD_CREATE event seems to be always sent after READY event with all guilds the bot is in
	Network::Get()->WebSocket().RegisterEvent(WebSocket::Event::GUILD_CREATE, [this](json &data)
	{
		for (json &c : data["channels"])
		{
			// manually add guild_id to channel data
			c["guild_id"] = data["id"];
			AddChannel(c);
		}
		m_Initialized++;
	});

	// PAWN callbacks
	Network::Get()->WebSocket().RegisterEvent(WebSocket::Event::MESSAGE_CREATE, [this](json &data)
	{
		CMessage msg(data);
		Channel_t const &channel = FindChannelById(msg.GetChannelId());
		if (channel)
		{
			CDispatcher::Get()->Dispatch([this, msg, &channel]()
			{
				// forward DCC_OnChannelMessage(DCC_Channel:channel, const author[], const message[]);
				PawnCallbackManager::Get()->Call("DCC_OnChannelMessage",
					channel->GetPawnId(), msg.GetAuthor(), msg.GetContent());
			});
		}
	});
}

void ChannelManager::WaitForInitialization()
{
	while (m_Initialized != m_InitValue)
		std::this_thread::sleep_for(std::chrono::milliseconds(20));
}

void ChannelManager::AddChannel(json &data)
{
	json &type = data["type"];
	if (!type.is_null())
	{
		Channel::Type ch_type = static_cast<Channel::Type>(type.get<int>());
		if (ch_type != Channel::Type::GUILD_TEXT
			&& ch_type != Channel::Type::DM
			&& ch_type != Channel::Type::GROUP_DM)
		{
			return; // we're only interested in text channels
		}
	}

	ChannelId_t id = 1;
	while (m_Channels.find(id) != m_Channels.end())
		++id;

	m_Channels.emplace(id, Channel_t(new Channel(id, data)));
}

Channel_t const &ChannelManager::FindChannel(ChannelId_t id)
{
	static Channel_t invalid_channel;
	auto it = m_Channels.find(id);
	if (it == m_Channels.end())
		return invalid_channel;
	return it->second;
}

Channel_t const &ChannelManager::FindChannelByName(std::string const &name)
{
	static Channel_t invalid_channel;
	for (auto const &c : m_Channels)
	{
		Channel_t const &channel = c.second;
		if (channel->GetName().compare(name) == 0)
			return channel;
	}
	return invalid_channel;
}

Channel_t const &ChannelManager::FindChannelById(Snowflake_t const &sfid)
{
	static Channel_t invalid_channel;
	for (auto const &c : m_Channels)
	{
		Channel_t const &channel = c.second;
		if (channel->GetId().compare(sfid) == 0)
			return channel;
	}
	return invalid_channel;
}
<|endoftext|>


<commit_before><commit_msg>Setting env vars in aqua's InitSalMain should long be unnecessary<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: salinst.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: pluby $ $Date: 2000-11-19 02:37:03 $
 *
 *  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 <stdio.h>

#define _SV_SALINST_CXX

#ifndef _SV_SALDATA_HXX
#include <saldata.hxx>
#endif
#ifndef _SV_SALINST_HXX
#include <salinst.hxx>
#endif
#ifndef _SV_SALFRAME_HXX
#include <salframe.hxx>
#endif
#ifndef _SV_SALOBJ_HXX
#include <salobj.hxx>
#endif
#ifndef _SV_SALSYS_H
#include <salsys.hxx>
#endif
#ifndef _SV_VCLAPPLICATION_H
#include <VCLApplication.h>
#endif

// =======================================================================

void SalAbort( const XubString& rErrorText )
{
    if( !rErrorText.Len() )
        fprintf( stderr, "Application Error" );
    else
        fprintf( stderr,
            ByteString( rErrorText, gsl_getSystemTextEncoding() ).GetBuffer() );
    abort();
}

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

void InitSalData()
{
    SalData *pSalData = new SalData;
    SetSalData( pSalData );
}

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

void DeInitSalData()
{
    SalData *pSalData = GetSalData();
    delete pSalData;
    SetSalData( NULL );
}

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

void SetFilterCallback( void* pCallback, void* pInst )
{
    SalData *pSalData = GetSalData();
    pSalData->mpFirstInstance->maInstData.mpFilterCallback = pCallback;
    pSalData->mpFirstInstance->maInstData.mpFilterInst = pInst;
}

// =======================================================================

SalInstance* CreateSalInstance()
{
    SalData* pSalData = GetSalData();
    SalInstance* pInst = new SalInstance;

    // init instance (only one instance in this version !!!)
    pSalData->mpFirstInstance = pInst;

    return pInst;
}

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

void DestroySalInstance( SalInstance* pInst )
{
    delete pInst;
}

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

SalInstance::SalInstance()
{
}

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

SalInstance::~SalInstance()
{
}

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

vos::IMutex* SalInstance::GetYieldMutex()
{
    return NULL;
}

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

ULONG SalInstance::ReleaseYieldMutex()
{
    return 0;
}

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

void SalInstance::AcquireYieldMutex( ULONG nCount )
{
}

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

void SalInstance::Yield( BOOL bWait )
{
    // Start the event queue. Note that VCLApplication_run() will not return
    // until the application shuts down. On other platforms, this function
    // returns after each event is pulled off the event queue and dispatched.
    // Instead, we have enter this method only once and let VCLApplication_run
    // do all of the pulling and dispatching of events.
    VCLApplication_run();
}

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

BOOL SalInstance::AnyInput( USHORT nType )
{
    return FALSE;
}

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

SalFrame* SalInstance::CreateChildFrame( SystemParentData* pSystemParentData, ULONG nSalFrameStyle )
{
    return NULL;
}

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

SalFrame* SalInstance::CreateFrame( SalFrame* pParent, ULONG nSalFrameStyle )
{
    SalFrame *pFrame = new SalFrame;

    pFrame->maFrameData.mpParent = pParent;

    // Create the native window
    pFrame->maFrameData.mhWnd = VCLWindow_new( nSalFrameStyle, NULL,
        pFrame, &(pFrame->maFrameData) );

    return pFrame;
}

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

void SalInstance::DestroyFrame( SalFrame* pFrame )
{
    delete ( pFrame );
}

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

SalObject* SalInstance::CreateObject( SalFrame* pParent )
{
    SalObject *pObject = new SalObject;

    pObject->maObjectData.mhWnd = pParent->maFrameData.mhWnd;

    return pObject;
}

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

void SalInstance::DestroyObject( SalObject* pObject )
{
    delete ( pObject );
}

void SalInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList )
{
}

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

void SalInstance::GetPrinterQueueState( SalPrinterQueueInfo* pInfo )
{
}

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

void SalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo )
{
}

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

XubString SalInstance::GetDefaultPrinter()
{
    return XubString();
}

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

SalInfoPrinter* SalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo,
                                                ImplJobSetup* pSetupData )
{
    return NULL;
}

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

void SalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter )
{
}

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

SalSystem* SalInstance::CreateSystem()
{
    return new SalSystem();
}

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

void SalInstance::DestroySystem( SalSystem* pSystem )
{
    delete pSystem;
}
<commit_msg>Implemented modal event loop to support modal dialog windows<commit_after>/*************************************************************************
 *
 *  $RCSfile: salinst.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: pluby $ $Date: 2000-11-20 05:44:22 $
 *
 *  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 <stdio.h>

#define _SV_SALINST_CXX

#ifndef _SV_SALDATA_HXX
#include <saldata.hxx>
#endif
#ifndef _SV_SALINST_HXX
#include <salinst.hxx>
#endif
#ifndef _SV_SALFRAME_HXX
#include <salframe.hxx>
#endif
#ifndef _SV_SALOBJ_HXX
#include <salobj.hxx>
#endif
#ifndef _SV_SALSYS_HXX
#include <salsys.hxx>
#endif
#ifndef _SV_DIALOG_HXX
#include <dialog.hxx>
#endif
#ifndef _SV_VCLAPPLICATION_H
#include <VCLApplication.h>
#endif

// =======================================================================

void SalAbort( const XubString& rErrorText )
{
    if( !rErrorText.Len() )
        fprintf( stderr, "Application Error" );
    else
        fprintf( stderr,
            ByteString( rErrorText, gsl_getSystemTextEncoding() ).GetBuffer() );
    abort();
}

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

void InitSalData()
{
    SalData *pSalData = new SalData;
    SetSalData( pSalData );
}

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

void DeInitSalData()
{
    SalData *pSalData = GetSalData();
    delete pSalData;
    SetSalData( NULL );
}

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

void SetFilterCallback( void* pCallback, void* pInst )
{
    SalData *pSalData = GetSalData();
    pSalData->mpFirstInstance->maInstData.mpFilterCallback = pCallback;
    pSalData->mpFirstInstance->maInstData.mpFilterInst = pInst;
}

// =======================================================================

SalInstance* CreateSalInstance()
{
    SalData* pSalData = GetSalData();
    SalInstance* pInst = new SalInstance;

    // init instance (only one instance in this version !!!)
    pSalData->mpFirstInstance = pInst;

    return pInst;
}

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

void DestroySalInstance( SalInstance* pInst )
{
    delete pInst;
}

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

SalInstance::SalInstance()
{
}

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

SalInstance::~SalInstance()
{
}

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

vos::IMutex* SalInstance::GetYieldMutex()
{
    return NULL;
}

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

ULONG SalInstance::ReleaseYieldMutex()
{
    return 0;
}

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

void SalInstance::AcquireYieldMutex( ULONG nCount )
{
}

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

void SalInstance::Yield( BOOL bWait )
{
    ImplSVData* pSVData = ImplGetSVData();

    // Check if this is a request from a modal window
    if ( pSVData->maAppData.mnModalMode )
    {
        // If this is a request from a modal window, run a modal session.
        // Note that VCLApplication_runModalForWindow will not return until
        // the modal session has ended.
        Dialog *pDialog = pSVData->maWinData.mpLastExecuteDlg;
        if ( pDialog ) {
            SalFrame *pFrame = pDialog->ImplGetFrame();
            if ( pFrame && pFrame->maFrameData.mhWnd )
                VCLApplication_runModalForWindow( pFrame->maFrameData.mhWnd );
        }
    }
    else
    {
        // If this is not a request from a modal window, start the event queue.
        // Note that VCLApplication_run() will not return until the
        // application shuts down. On other platforms, this function returns
        // after each event is pulled off the event queue and dispatched.
        // Instead, we have enter this method only once and let
        // VCLApplication_run do all of the pulling and dispatching of events.
        VCLApplication_run();
    }
}

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

BOOL SalInstance::AnyInput( USHORT nType )
{
    return FALSE;
}

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

SalFrame* SalInstance::CreateChildFrame( SystemParentData* pSystemParentData, ULONG nSalFrameStyle )
{
    return NULL;
}

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

SalFrame* SalInstance::CreateFrame( SalFrame* pParent, ULONG nSalFrameStyle )
{
    SalFrame *pFrame = new SalFrame;

    pFrame->maFrameData.mpParent = pParent;

    // Create the native window
    pFrame->maFrameData.mhWnd = VCLWindow_new( nSalFrameStyle, NULL,
        pFrame, &(pFrame->maFrameData) );

    return pFrame;
}

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

void SalInstance::DestroyFrame( SalFrame* pFrame )
{
    delete ( pFrame );
}

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

SalObject* SalInstance::CreateObject( SalFrame* pParent )
{
    SalObject *pObject = new SalObject;

    pObject->maObjectData.mhWnd = pParent->maFrameData.mhWnd;

    return pObject;
}

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

void SalInstance::DestroyObject( SalObject* pObject )
{
    delete ( pObject );
}

void SalInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList )
{
}

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

void SalInstance::GetPrinterQueueState( SalPrinterQueueInfo* pInfo )
{
}

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

void SalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo )
{
}

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

XubString SalInstance::GetDefaultPrinter()
{
    return XubString();
}

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

SalInfoPrinter* SalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo,
                                                ImplJobSetup* pSetupData )
{
    return NULL;
}

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

void SalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter )
{
}

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

SalSystem* SalInstance::CreateSystem()
{
    return new SalSystem();
}

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

void SalInstance::DestroySystem( SalSystem* pSystem )
{
    delete pSystem;
}
<|endoftext|>


<commit_before>/*
 * Use and distribution licensed under the Apache license version 2.
 *
 * See the COPYING file in the root project directory for full text.
 */

#include <string.h>

#include <iostream>

#include <sqltoast/sqltoast.h>

#include "measure.h"
#include "printer.h"

using namespace std;

struct parser {
    sqltoast::parse_options_t opts;
    sqltoast::parse_input_t subject;
    sqltoast::parse_result_t res;
    parser(sqltoast::parse_options_t& opts, const std::string &input) :
        opts(opts),
        subject(input.cbegin(), input.cend())
    {}
    void operator()() {
        res = sqltoast::parse(subject, opts);
    }
};

void usage(const char* prg_name) {
    cout << "Usage: " << prg_name << " [--disable-timer] [--yaml] <SQL>" << endl;
    cout << " using libsqltoast version " <<
        SQLTOAST_VERSION_MAJOR << '.' <<
        SQLTOAST_VERSION_MINOR << endl;
}

int main (int argc, char *argv[])
{
    std::string input;
    bool disable_timer = false;
    bool use_yaml = false;

    for (int x = 1; x < argc; x++) {
        if (strcmp(argv[x], "--disable-timer") == 0) {
            disable_timer = true;
            continue;
        }
        if (strcmp(argv[x], "--yaml") == 0) {
            use_yaml = true;
            continue;
        }
        input.assign(argv[x]);
        break;
    }
    if (input.empty()) {
        usage(argv[0]);
        return 1;
    }

    sqltoast::parse_options_t opts = {sqltoast::SQL_DIALECT_ANSI_1992, false};
    parser p(opts, input);

    auto dur = measure<std::chrono::nanoseconds>::execution(p);
    sqltoaster::printer ptr(p.res, cout);
    if (use_yaml)
        ptr.set_yaml(cout);
    if (p.res.code == sqltoast::PARSE_OK) {
        cout << "OK";
        cout << ptr << std::endl;
    } else if (p.res.code == sqltoast::PARSE_INPUT_ERROR) {
        cout << "Input error: " << p.res.error << endl;
    } else {
        cout << "Syntax error." << endl;
        cout << p.res.error << endl;
    }
    if (! disable_timer)
        cout << "(took " << dur << " nanoseconds)" << endl;
    return 0;
}
<commit_msg>Make std:: namespace explicit in sqltoaster/main.cc<commit_after>/*
 * Use and distribution licensed under the Apache license version 2.
 *
 * See the COPYING file in the root project directory for full text.
 */

#include <string.h>

#include <iostream>

#include <sqltoast/sqltoast.h>

#include "measure.h"
#include "printer.h"

struct parser {
    sqltoast::parse_options_t opts;
    sqltoast::parse_input_t subject;
    sqltoast::parse_result_t res;
    parser(sqltoast::parse_options_t& opts, const std::string &input) :
        opts(opts),
        subject(input.cbegin(), input.cend())
    {}
    void operator()() {
        res = sqltoast::parse(subject, opts);
    }
};

void usage(const char* prg_name) {
    std::cout << "Usage: " << prg_name <<
        " [--disable-timer] [--yaml] <SQL>" << std::endl;
    std::cout << " using libsqltoast version " <<
        SQLTOAST_VERSION_MAJOR << '.' <<
        SQLTOAST_VERSION_MINOR << std::endl;
}

int main (int argc, char *argv[])
{
    std::string input;
    bool disable_timer = false;
    bool use_yaml = false;

    for (int x = 1; x < argc; x++) {
        if (strcmp(argv[x], "--disable-timer") == 0) {
            disable_timer = true;
            continue;
        }
        if (strcmp(argv[x], "--yaml") == 0) {
            use_yaml = true;
            continue;
        }
        input.assign(argv[x]);
        break;
    }
    if (input.empty()) {
        usage(argv[0]);
        return 1;
    }

    sqltoast::parse_options_t opts = {sqltoast::SQL_DIALECT_ANSI_1992, false};
    parser p(opts, input);

    auto dur = measure<std::chrono::nanoseconds>::execution(p);
    sqltoaster::printer ptr(p.res, std::cout);
    if (use_yaml)
        ptr.set_yaml(std::cout);
    if (p.res.code == sqltoast::PARSE_OK) {
        std::cout << "OK";
        std::cout << ptr << std::endl;
    } else if (p.res.code == sqltoast::PARSE_INPUT_ERROR) {
        std::cout << "Input error: " << p.res.error << std::endl;
    } else {
        std::cout << "Syntax error." << std::endl;
        std::cout << p.res.error << std::endl;
    }
    if (! disable_timer)
        std::cout << "(took " << dur << " nanoseconds)" << std::endl;
    return 0;
}
<|endoftext|>


<commit_before>#include "Contours.h"
#include "OpenCV.h"
#include <nan.h>

#include <iostream>

Nan::Persistent<FunctionTemplate> Contour::constructor;

void Contour::Init(Local<Object> target) {
  Nan::HandleScope scope;

  // Class/contructor
  Local<FunctionTemplate> ctor = Nan::New<FunctionTemplate>(Contour::New);
  constructor.Reset(ctor);
  ctor->InstanceTemplate()->SetInternalFieldCount(1);
  ctor->SetClassName(Nan::New("Contours").ToLocalChecked());

  // Prototype
  // Local<ObjectTemplate> proto = constructor->PrototypeTemplate();
  Nan::SetPrototypeMethod(ctor, "point", Point);
  Nan::SetPrototypeMethod(ctor, "points", Points);
  Nan::SetPrototypeMethod(ctor, "size", Size);
  Nan::SetPrototypeMethod(ctor, "cornerCount", CornerCount);
  Nan::SetPrototypeMethod(ctor, "area", Area);
  Nan::SetPrototypeMethod(ctor, "arcLength", ArcLength);
  Nan::SetPrototypeMethod(ctor, "approxPolyDP", ApproxPolyDP);
  Nan::SetPrototypeMethod(ctor, "convexHull", ConvexHull);
  Nan::SetPrototypeMethod(ctor, "boundingRect", BoundingRect);
  Nan::SetPrototypeMethod(ctor, "minAreaRect", MinAreaRect);
  Nan::SetPrototypeMethod(ctor, "fitEllipse", FitEllipse);
  Nan::SetPrototypeMethod(ctor, "isConvex", IsConvex);
  Nan::SetPrototypeMethod(ctor, "moments", Moments);
  Nan::SetPrototypeMethod(ctor, "hierarchy", Hierarchy);
  Nan::SetPrototypeMethod(ctor, "serialize", Serialize);
  Nan::SetPrototypeMethod(ctor, "deserialize", Deserialize);
  target->Set(Nan::New("Contours").ToLocalChecked(), ctor->GetFunction());
};

NAN_METHOD(Contour::New) {
  Nan::HandleScope scope;

  if (info.This()->InternalFieldCount() == 0) {
    Nan::ThrowTypeError("Cannot instantiate without new");
  }

  Contour *contours;
  contours = new Contour;

  contours->Wrap(info.Holder());
  info.GetReturnValue().Set(info.Holder());
}

Contour::Contour() :
    Nan::ObjectWrap() {
}

NAN_METHOD(Contour::Point) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();
  int index = info[1]->NumberValue();

  cv::Point point = self->contours[pos][index];

  Local<Object> data = Nan::New<Object>();
  data->Set(Nan::New("x").ToLocalChecked(), Nan::New<Number>(point.x));
  data->Set(Nan::New("y").ToLocalChecked(), Nan::New<Number>(point.y));

  info.GetReturnValue().Set(data);
}

NAN_METHOD(Contour::Points) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();

  std::vector<cv::Point> points = self->contours[pos];
  Local<Array> data = Nan::New<Array>(points.size());

  for (std::vector<int>::size_type i = 0; i != points.size(); i++) {
    Local<Object> point_data = Nan::New<Object>();
    point_data->Set(Nan::New<String>("x").ToLocalChecked(), Nan::New<Number>(points[i].x));
    point_data->Set(Nan::New<String>("y").ToLocalChecked(), Nan::New<Number>(points[i].y));

    data->Set(i, point_data);
  }

  info.GetReturnValue().Set(data);
}

// FIXME: this should better be called "Length" as ``Contours`` is an Array like
// structure also, this would allow to use ``Size`` for the function returning
// the number of corners in the contour for better consistency with OpenCV.
NAN_METHOD(Contour::Size) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());

  info.GetReturnValue().Set(Nan::New<Number>(self->contours.size()));
}

NAN_METHOD(Contour::CornerCount) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();

  info.GetReturnValue().Set(Nan::New<Number>(self->contours[pos].size()));
}

NAN_METHOD(Contour::Area) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();

  // info.GetReturnValue().Set(Nan::New<Number>(contourArea(self->contours)));
  info.GetReturnValue().Set(Nan::New<Number>(contourArea(cv::Mat(self->contours[pos]))));
}

NAN_METHOD(Contour::ArcLength) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();
  bool isClosed = info[1]->BooleanValue();

  info.GetReturnValue().Set(Nan::New<Number>(arcLength(cv::Mat(self->contours[pos]), isClosed)));
}

NAN_METHOD(Contour::ApproxPolyDP) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();
  double epsilon = info[1]->NumberValue();
  bool isClosed = info[2]->BooleanValue();

  cv::Mat approxed;
  approxPolyDP(cv::Mat(self->contours[pos]), approxed, epsilon, isClosed);
  approxed.copyTo(self->contours[pos]);

  info.GetReturnValue().Set(Nan::Null());
}

NAN_METHOD(Contour::ConvexHull) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());

  int pos = info[0]->NumberValue();
  bool clockwise = info[1]->BooleanValue();

  cv::Mat hull;
  cv::convexHull(cv::Mat(self->contours[pos]), hull, clockwise);
  hull.copyTo(self->contours[pos]);

  info.GetReturnValue().Set(Nan::Null());
}

NAN_METHOD(Contour::BoundingRect) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();

  cv::Rect bounding = cv::boundingRect(cv::Mat(self->contours[pos]));
  Local<Object> rect = Nan::New<Object>();

  rect->Set(Nan::New("x").ToLocalChecked(), Nan::New<Number>(bounding.x));
  rect->Set(Nan::New("y").ToLocalChecked(), Nan::New<Number>(bounding.y));
  rect->Set(Nan::New("width").ToLocalChecked(), Nan::New<Number>(bounding.width));
  rect->Set(Nan::New("height").ToLocalChecked(), Nan::New<Number>(bounding.height));

  info.GetReturnValue().Set(rect);
}

NAN_METHOD(Contour::MinAreaRect) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();

  cv::RotatedRect minimum = cv::minAreaRect(cv::Mat(self->contours[pos]));

  Local<Object> rect = Nan::New<Object>();
  rect->Set(Nan::New("angle").ToLocalChecked(), Nan::New<Number>(minimum.angle));

  Local<Object> size = Nan::New<Object>();
  size->Set(Nan::New("height").ToLocalChecked(), Nan::New<Number>(minimum.size.height));
  size->Set(Nan::New("width").ToLocalChecked(), Nan::New<Number>(minimum.size.width));
  rect->Set(Nan::New("size").ToLocalChecked(), size);

  Local<Object> center = Nan::New<Object>();
  center->Set(Nan::New("x").ToLocalChecked(), Nan::New<Number>(minimum.center.x));
  center->Set(Nan::New("y").ToLocalChecked(), Nan::New<Number>(minimum.center.y));

  v8::Local<v8::Array> points = Nan::New<Array>(4);

  cv::Point2f rect_points[4];
  minimum.points(rect_points);

  for (unsigned int i=0; i<4; i++) {
    Local<Object> point = Nan::New<Object>();
    point->Set(Nan::New("x").ToLocalChecked(), Nan::New<Number>(rect_points[i].x));
    point->Set(Nan::New("y").ToLocalChecked(), Nan::New<Number>(rect_points[i].y));
    points->Set(i, point);
  }

  rect->Set(Nan::New("points").ToLocalChecked(), points);

  info.GetReturnValue().Set(rect);
}

NAN_METHOD(Contour::FitEllipse) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();

  if (self->contours[pos].size() >= 5) {  // Minimum number for an ellipse
    cv::RotatedRect ellipse = cv::fitEllipse(cv::Mat(self->contours[pos]));

    Local<Object> jsEllipse = Nan::New<Object>();
    jsEllipse->Set(Nan::New("angle").ToLocalChecked(), Nan::New<Number>(ellipse.angle));

    Local<Object> size = Nan::New<Object>();
    size->Set(Nan::New("height").ToLocalChecked(), Nan::New<Number>(ellipse.size.height));
    size->Set(Nan::New("width").ToLocalChecked(), Nan::New<Number>(ellipse.size.width));
    jsEllipse->Set(Nan::New("size").ToLocalChecked(), size);

    Local<Object> center = Nan::New<Object>();
    center->Set(Nan::New("x").ToLocalChecked(), Nan::New<Number>(ellipse.center.x));
    center->Set(Nan::New("y").ToLocalChecked(), Nan::New<Number>(ellipse.center.y));
    jsEllipse->Set(Nan::New("center").ToLocalChecked(), center);

    info.GetReturnValue().Set(jsEllipse);
  }

  info.GetReturnValue().Set(Nan::Null());
}

NAN_METHOD(Contour::IsConvex) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();

  info.GetReturnValue().Set(Nan::New<Boolean>(isContourConvex(cv::Mat(self->contours[pos]))));
}

NAN_METHOD(Contour::Moments) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();

  // Get the moments
  cv::Moments mu = moments( self->contours[pos], false );

  Local<Object> res = Nan::New<Object>();

  res->Set(Nan::New("m00").ToLocalChecked(), Nan::New<Number>(mu.m00));
  res->Set(Nan::New("m10").ToLocalChecked(), Nan::New<Number>(mu.m10));
  res->Set(Nan::New("m01").ToLocalChecked(), Nan::New<Number>(mu.m01));
  res->Set(Nan::New("m11").ToLocalChecked(), Nan::New<Number>(mu.m11));

  info.GetReturnValue().Set(res);
}

NAN_METHOD(Contour::Hierarchy) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->IntegerValue();

  cv::Vec4i hierarchy = self->hierarchy[pos];

  Local<Array> res = Nan::New<Array>(4);

  res->Set(0, Nan::New<Number>(hierarchy[0]));
  res->Set(1, Nan::New<Number>(hierarchy[1]));
  res->Set(2, Nan::New<Number>(hierarchy[2]));
  res->Set(3, Nan::New<Number>(hierarchy[3]));

  info.GetReturnValue().Set(res);
}

NAN_METHOD(Contour::Serialize) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());

  Local<Array> contours_data = Nan::New<Array>(self->contours.size());

  for (std::vector<int>::size_type i = 0; i != self->contours.size(); i++) {
    std::vector<cv::Point> points = self->contours[i];
    Local<Array> contour_data = Nan::New<Array>(points.size());

    for (std::vector<int>::size_type j = 0; j != points.size(); j++) {
      Local<Array> point_data = Nan::New<Array>(2);
      point_data->Set(0, Nan::New<Number>(points[j].x));
      point_data->Set(1, Nan::New<Number>(points[j].y));

      contour_data->Set(j, point_data);
    }
    contours_data->Set(i, contour_data);
  }

  Local<Array> hierarchy_data = Nan::New<Array>(self->hierarchy.size());
  for (std::vector<int>::size_type i = 0; i != self->hierarchy.size(); i++) {
    Local<Array> contour_data = Nan::New<Array>(4);
    contour_data->Set(0, Nan::New<Number>(self->hierarchy[i][0]));
    contour_data->Set(1, Nan::New<Number>(self->hierarchy[i][1]));
    contour_data->Set(2, Nan::New<Number>(self->hierarchy[i][2]));
    contour_data->Set(3, Nan::New<Number>(self->hierarchy[i][3]));

    hierarchy_data->Set(i, contour_data);
  }

  Local<Object> data = Nan::New<Object>();
  data->Set(Nan::New<String>("contours").ToLocalChecked(), contours_data);
  data->Set(Nan::New<String>("hierarchy").ToLocalChecked(), hierarchy_data);

  info.GetReturnValue().Set(data);
}

NAN_METHOD(Contour::Deserialize) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());

  Local<Object> data = Local<Object>::Cast(info[0]);

  Local<Array> contours_data = Local<Array>::Cast(data->Get(Nan::New<String>("contours").ToLocalChecked()));
  Local<Array> hierarchy_data = Local<Array>::Cast(data->Get(Nan::New<String>("hierarchy").ToLocalChecked()));

  std::vector<std::vector<cv::Point> > contours_res;
  int contours_length = contours_data->Length();

  for (int i = 0; i < contours_length; i++) {
    Local<Array> contour_data = Local<Array>::Cast(contours_data->Get(i));
    std::vector<cv::Point> points;

    int contour_length = contour_data->Length();
    for (int j = 0; j < contour_length; j++) {
      Local<Array> point_data = Local<Array>::Cast(contour_data->Get(j));
      int x = point_data->Get(0)->IntegerValue();
      int y = point_data->Get(1)->IntegerValue();
      points.push_back(cv::Point(x, y));
    }

    contours_res.push_back(points);
  }

  std::vector<cv::Vec4i> hierarchy_res;
  int hierarchy_length = hierarchy_data->Length();

  for (int i = 0; i < hierarchy_length; i++) {
    Local<Array> contour_data = Local<Array>::Cast(hierarchy_data->Get(i));
    int a = contour_data->Get(0)->IntegerValue();
    int b = contour_data->Get(1)->IntegerValue();
    int c = contour_data->Get(2)->IntegerValue();
    int d = contour_data->Get(3)->IntegerValue();
    hierarchy_res.push_back(cv::Vec4i(a, b, c, d));
  }

  self->contours = contours_res;
  self->hierarchy = hierarchy_res;

  info.GetReturnValue().Set(Nan::Null());
}
<commit_msg>Add support for the 'Oriented' area flag in contourArea<commit_after>#include "Contours.h"
#include "OpenCV.h"
#include <nan.h>

#include <iostream>

Nan::Persistent<FunctionTemplate> Contour::constructor;

void Contour::Init(Local<Object> target) {
  Nan::HandleScope scope;

  // Class/contructor
  Local<FunctionTemplate> ctor = Nan::New<FunctionTemplate>(Contour::New);
  constructor.Reset(ctor);
  ctor->InstanceTemplate()->SetInternalFieldCount(1);
  ctor->SetClassName(Nan::New("Contours").ToLocalChecked());

  // Prototype
  // Local<ObjectTemplate> proto = constructor->PrototypeTemplate();
  Nan::SetPrototypeMethod(ctor, "point", Point);
  Nan::SetPrototypeMethod(ctor, "points", Points);
  Nan::SetPrototypeMethod(ctor, "size", Size);
  Nan::SetPrototypeMethod(ctor, "cornerCount", CornerCount);
  Nan::SetPrototypeMethod(ctor, "area", Area);
  Nan::SetPrototypeMethod(ctor, "arcLength", ArcLength);
  Nan::SetPrototypeMethod(ctor, "approxPolyDP", ApproxPolyDP);
  Nan::SetPrototypeMethod(ctor, "convexHull", ConvexHull);
  Nan::SetPrototypeMethod(ctor, "boundingRect", BoundingRect);
  Nan::SetPrototypeMethod(ctor, "minAreaRect", MinAreaRect);
  Nan::SetPrototypeMethod(ctor, "fitEllipse", FitEllipse);
  Nan::SetPrototypeMethod(ctor, "isConvex", IsConvex);
  Nan::SetPrototypeMethod(ctor, "moments", Moments);
  Nan::SetPrototypeMethod(ctor, "hierarchy", Hierarchy);
  Nan::SetPrototypeMethod(ctor, "serialize", Serialize);
  Nan::SetPrototypeMethod(ctor, "deserialize", Deserialize);
  target->Set(Nan::New("Contours").ToLocalChecked(), ctor->GetFunction());
};

NAN_METHOD(Contour::New) {
  Nan::HandleScope scope;

  if (info.This()->InternalFieldCount() == 0) {
    Nan::ThrowTypeError("Cannot instantiate without new");
  }

  Contour *contours;
  contours = new Contour;

  contours->Wrap(info.Holder());
  info.GetReturnValue().Set(info.Holder());
}

Contour::Contour() :
    Nan::ObjectWrap() {
}

NAN_METHOD(Contour::Point) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();
  int index = info[1]->NumberValue();

  cv::Point point = self->contours[pos][index];

  Local<Object> data = Nan::New<Object>();
  data->Set(Nan::New("x").ToLocalChecked(), Nan::New<Number>(point.x));
  data->Set(Nan::New("y").ToLocalChecked(), Nan::New<Number>(point.y));

  info.GetReturnValue().Set(data);
}

NAN_METHOD(Contour::Points) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();

  std::vector<cv::Point> points = self->contours[pos];
  Local<Array> data = Nan::New<Array>(points.size());

  for (std::vector<int>::size_type i = 0; i != points.size(); i++) {
    Local<Object> point_data = Nan::New<Object>();
    point_data->Set(Nan::New<String>("x").ToLocalChecked(), Nan::New<Number>(points[i].x));
    point_data->Set(Nan::New<String>("y").ToLocalChecked(), Nan::New<Number>(points[i].y));

    data->Set(i, point_data);
  }

  info.GetReturnValue().Set(data);
}

// FIXME: this should better be called "Length" as ``Contours`` is an Array like
// structure also, this would allow to use ``Size`` for the function returning
// the number of corners in the contour for better consistency with OpenCV.
NAN_METHOD(Contour::Size) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());

  info.GetReturnValue().Set(Nan::New<Number>(self->contours.size()));
}

NAN_METHOD(Contour::CornerCount) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();

  info.GetReturnValue().Set(Nan::New<Number>(self->contours[pos].size()));
}

NAN_METHOD(Contour::Area) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();
  bool orientation = (info.Length() > 1 && info[1]->BooleanValue());

  // info.GetReturnValue().Set(Nan::New<Number>(contourArea(self->contours)));
  info.GetReturnValue().Set(Nan::New<Number>(contourArea(cv::Mat(self->contours[pos]), orientation)));
}

NAN_METHOD(Contour::ArcLength) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();
  bool isClosed = info[1]->BooleanValue();

  info.GetReturnValue().Set(Nan::New<Number>(arcLength(cv::Mat(self->contours[pos]), isClosed)));
}

NAN_METHOD(Contour::ApproxPolyDP) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();
  double epsilon = info[1]->NumberValue();
  bool isClosed = info[2]->BooleanValue();

  cv::Mat approxed;
  approxPolyDP(cv::Mat(self->contours[pos]), approxed, epsilon, isClosed);
  approxed.copyTo(self->contours[pos]);

  info.GetReturnValue().Set(Nan::Null());
}

NAN_METHOD(Contour::ConvexHull) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());

  int pos = info[0]->NumberValue();
  bool clockwise = info[1]->BooleanValue();

  cv::Mat hull;
  cv::convexHull(cv::Mat(self->contours[pos]), hull, clockwise);
  hull.copyTo(self->contours[pos]);

  info.GetReturnValue().Set(Nan::Null());
}

NAN_METHOD(Contour::BoundingRect) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();

  cv::Rect bounding = cv::boundingRect(cv::Mat(self->contours[pos]));
  Local<Object> rect = Nan::New<Object>();

  rect->Set(Nan::New("x").ToLocalChecked(), Nan::New<Number>(bounding.x));
  rect->Set(Nan::New("y").ToLocalChecked(), Nan::New<Number>(bounding.y));
  rect->Set(Nan::New("width").ToLocalChecked(), Nan::New<Number>(bounding.width));
  rect->Set(Nan::New("height").ToLocalChecked(), Nan::New<Number>(bounding.height));

  info.GetReturnValue().Set(rect);
}

NAN_METHOD(Contour::MinAreaRect) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();

  cv::RotatedRect minimum = cv::minAreaRect(cv::Mat(self->contours[pos]));

  Local<Object> rect = Nan::New<Object>();
  rect->Set(Nan::New("angle").ToLocalChecked(), Nan::New<Number>(minimum.angle));

  Local<Object> size = Nan::New<Object>();
  size->Set(Nan::New("height").ToLocalChecked(), Nan::New<Number>(minimum.size.height));
  size->Set(Nan::New("width").ToLocalChecked(), Nan::New<Number>(minimum.size.width));
  rect->Set(Nan::New("size").ToLocalChecked(), size);

  Local<Object> center = Nan::New<Object>();
  center->Set(Nan::New("x").ToLocalChecked(), Nan::New<Number>(minimum.center.x));
  center->Set(Nan::New("y").ToLocalChecked(), Nan::New<Number>(minimum.center.y));

  v8::Local<v8::Array> points = Nan::New<Array>(4);

  cv::Point2f rect_points[4];
  minimum.points(rect_points);

  for (unsigned int i=0; i<4; i++) {
    Local<Object> point = Nan::New<Object>();
    point->Set(Nan::New("x").ToLocalChecked(), Nan::New<Number>(rect_points[i].x));
    point->Set(Nan::New("y").ToLocalChecked(), Nan::New<Number>(rect_points[i].y));
    points->Set(i, point);
  }

  rect->Set(Nan::New("points").ToLocalChecked(), points);

  info.GetReturnValue().Set(rect);
}

NAN_METHOD(Contour::FitEllipse) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();

  if (self->contours[pos].size() >= 5) {  // Minimum number for an ellipse
    cv::RotatedRect ellipse = cv::fitEllipse(cv::Mat(self->contours[pos]));

    Local<Object> jsEllipse = Nan::New<Object>();
    jsEllipse->Set(Nan::New("angle").ToLocalChecked(), Nan::New<Number>(ellipse.angle));

    Local<Object> size = Nan::New<Object>();
    size->Set(Nan::New("height").ToLocalChecked(), Nan::New<Number>(ellipse.size.height));
    size->Set(Nan::New("width").ToLocalChecked(), Nan::New<Number>(ellipse.size.width));
    jsEllipse->Set(Nan::New("size").ToLocalChecked(), size);

    Local<Object> center = Nan::New<Object>();
    center->Set(Nan::New("x").ToLocalChecked(), Nan::New<Number>(ellipse.center.x));
    center->Set(Nan::New("y").ToLocalChecked(), Nan::New<Number>(ellipse.center.y));
    jsEllipse->Set(Nan::New("center").ToLocalChecked(), center);

    info.GetReturnValue().Set(jsEllipse);
  }

  info.GetReturnValue().Set(Nan::Null());
}

NAN_METHOD(Contour::IsConvex) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();

  info.GetReturnValue().Set(Nan::New<Boolean>(isContourConvex(cv::Mat(self->contours[pos]))));
}

NAN_METHOD(Contour::Moments) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->NumberValue();

  // Get the moments
  cv::Moments mu = moments( self->contours[pos], false );

  Local<Object> res = Nan::New<Object>();

  res->Set(Nan::New("m00").ToLocalChecked(), Nan::New<Number>(mu.m00));
  res->Set(Nan::New("m10").ToLocalChecked(), Nan::New<Number>(mu.m10));
  res->Set(Nan::New("m01").ToLocalChecked(), Nan::New<Number>(mu.m01));
  res->Set(Nan::New("m11").ToLocalChecked(), Nan::New<Number>(mu.m11));

  info.GetReturnValue().Set(res);
}

NAN_METHOD(Contour::Hierarchy) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());
  int pos = info[0]->IntegerValue();

  cv::Vec4i hierarchy = self->hierarchy[pos];

  Local<Array> res = Nan::New<Array>(4);

  res->Set(0, Nan::New<Number>(hierarchy[0]));
  res->Set(1, Nan::New<Number>(hierarchy[1]));
  res->Set(2, Nan::New<Number>(hierarchy[2]));
  res->Set(3, Nan::New<Number>(hierarchy[3]));

  info.GetReturnValue().Set(res);
}

NAN_METHOD(Contour::Serialize) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());

  Local<Array> contours_data = Nan::New<Array>(self->contours.size());

  for (std::vector<int>::size_type i = 0; i != self->contours.size(); i++) {
    std::vector<cv::Point> points = self->contours[i];
    Local<Array> contour_data = Nan::New<Array>(points.size());

    for (std::vector<int>::size_type j = 0; j != points.size(); j++) {
      Local<Array> point_data = Nan::New<Array>(2);
      point_data->Set(0, Nan::New<Number>(points[j].x));
      point_data->Set(1, Nan::New<Number>(points[j].y));

      contour_data->Set(j, point_data);
    }
    contours_data->Set(i, contour_data);
  }

  Local<Array> hierarchy_data = Nan::New<Array>(self->hierarchy.size());
  for (std::vector<int>::size_type i = 0; i != self->hierarchy.size(); i++) {
    Local<Array> contour_data = Nan::New<Array>(4);
    contour_data->Set(0, Nan::New<Number>(self->hierarchy[i][0]));
    contour_data->Set(1, Nan::New<Number>(self->hierarchy[i][1]));
    contour_data->Set(2, Nan::New<Number>(self->hierarchy[i][2]));
    contour_data->Set(3, Nan::New<Number>(self->hierarchy[i][3]));

    hierarchy_data->Set(i, contour_data);
  }

  Local<Object> data = Nan::New<Object>();
  data->Set(Nan::New<String>("contours").ToLocalChecked(), contours_data);
  data->Set(Nan::New<String>("hierarchy").ToLocalChecked(), hierarchy_data);

  info.GetReturnValue().Set(data);
}

NAN_METHOD(Contour::Deserialize) {
  Nan::HandleScope scope;

  Contour *self = Nan::ObjectWrap::Unwrap<Contour>(info.This());

  Local<Object> data = Local<Object>::Cast(info[0]);

  Local<Array> contours_data = Local<Array>::Cast(data->Get(Nan::New<String>("contours").ToLocalChecked()));
  Local<Array> hierarchy_data = Local<Array>::Cast(data->Get(Nan::New<String>("hierarchy").ToLocalChecked()));

  std::vector<std::vector<cv::Point> > contours_res;
  int contours_length = contours_data->Length();

  for (int i = 0; i < contours_length; i++) {
    Local<Array> contour_data = Local<Array>::Cast(contours_data->Get(i));
    std::vector<cv::Point> points;

    int contour_length = contour_data->Length();
    for (int j = 0; j < contour_length; j++) {
      Local<Array> point_data = Local<Array>::Cast(contour_data->Get(j));
      int x = point_data->Get(0)->IntegerValue();
      int y = point_data->Get(1)->IntegerValue();
      points.push_back(cv::Point(x, y));
    }

    contours_res.push_back(points);
  }

  std::vector<cv::Vec4i> hierarchy_res;
  int hierarchy_length = hierarchy_data->Length();

  for (int i = 0; i < hierarchy_length; i++) {
    Local<Array> contour_data = Local<Array>::Cast(hierarchy_data->Get(i));
    int a = contour_data->Get(0)->IntegerValue();
    int b = contour_data->Get(1)->IntegerValue();
    int c = contour_data->Get(2)->IntegerValue();
    int d = contour_data->Get(3)->IntegerValue();
    hierarchy_res.push_back(cv::Vec4i(a, b, c, d));
  }

  self->contours = contours_res;
  self->hierarchy = hierarchy_res;

  info.GetReturnValue().Set(Nan::Null());
}
<|endoftext|>