<commit_before>/*------------------------------------------------------------------------
* (The MIT License)
*
* Copyright (c) 2008-2011 Rhomobile, Inc.
*
* 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.
*
* http://rhomobile.com
*------------------------------------------------------------------------*/

#include "SplashScreen.h"
#include "RhoThread.h"
#include "IRhoClassFactory.h"
#include "RhoConf.h"
#include "Tokenizer.h"

namespace rho {
namespace common {
IMPLEMENT_LOGCLASS(CSplashScreen,"SplashScreen");

void CSplashScreen::start()
{
	if (m_nDelay>0 && m_startTime.toULong() == 0)
        m_startTime = CTimeInterval::getCurrentTime();
}

long CSplashScreen::howLongWaitMs()
{
   CTimeInterval endTime = CTimeInterval::getCurrentTime();
   long nTimeElapsed = endTime.minus(m_startTime).toULong();

   return m_nDelay * 1000 - nTimeElapsed;
}

void CSplashScreen::hide()
{
	if (m_nDelay<=0 || m_startTime.toULong() == 0)
		return;
	long nWaitMs = howLongWaitMs();
    m_startTime = CTimeInterval();
	if ( nWaitMs <= 0 )
		return;

    CAutoPtr<IRhoThreadImpl> ptrThread = rho_get_RhoClassFactory()->createThreadImpl();

    ptrThread->sleep(nWaitMs);
}

void CSplashScreen::init()
{
	String strSplash = RHOCONF().getString("splash_screen");

	CTokenizer stringtokenizer(strSplash, ";");
	while (stringtokenizer.hasMoreTokens()) {
		String tok = stringtokenizer.nextToken();
		tok = String_trim(tok);
		if (tok.length() == 0) {
			continue;
		}

		if (tok.find("delay") == 0)
		{
			int nEq = tok.find('=');
			if (nEq>=0)
			{
				String val = tok.substr(nEq+1);
				val = String_trim(val);
				if ( val.length() > 0 )
                    convertFromStringA( val.c_str(), m_nDelay );
			}
		}else if (tok.find("zoom") == 0)
		{
			m_nFlags |= VZOOM | HZOOM;
		}else if ( tok.find("vzoom") == 0)
		{
			m_nFlags |= VZOOM;
		}else if ( tok.find("hzoom") == 0)
		{
			m_nFlags |= HZOOM;
		}else if ( tok.find("center") == 0)
		{
			m_nFlags |= VCENTER | HCENTER;
		}else if ( tok.find("vcenter") == 0)
		{
			m_nFlags |= VCENTER;
		}else if ( tok.find("hcenter") == 0)
		{
			m_nFlags |= HCENTER;
		}

	}
}
}
}
<commit_msg>fix splash screen delay if delay not setted<commit_after>/*------------------------------------------------------------------------
* (The MIT License)
*
* Copyright (c) 2008-2011 Rhomobile, Inc.
*
* 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.
*
* http://rhomobile.com
*------------------------------------------------------------------------*/

#include "SplashScreen.h"
#include "RhoThread.h"
#include "IRhoClassFactory.h"
#include "RhoConf.h"
#include "Tokenizer.h"

namespace rho {
namespace common {
IMPLEMENT_LOGCLASS(CSplashScreen,"SplashScreen");

void CSplashScreen::start()
{
	if (m_nDelay>0 && m_startTime.toULong() == 0)
        m_startTime = CTimeInterval::getCurrentTime();
}

long CSplashScreen::howLongWaitMs()
{
   if (m_nDelay <= 0) {
       return 0;
   }
   CTimeInterval endTime = CTimeInterval::getCurrentTime();
   long nTimeElapsed = endTime.minus(m_startTime).toULong();

   return m_nDelay * 1000 - nTimeElapsed;
}

void CSplashScreen::hide()
{
	if (m_nDelay<=0 || m_startTime.toULong() == 0)
		return;
	long nWaitMs = howLongWaitMs();
    m_startTime = CTimeInterval();
	if ( nWaitMs <= 0 )
		return;

    CAutoPtr<IRhoThreadImpl> ptrThread = rho_get_RhoClassFactory()->createThreadImpl();

    ptrThread->sleep(nWaitMs);
}

void CSplashScreen::init()
{
	String strSplash = RHOCONF().getString("splash_screen");

	CTokenizer stringtokenizer(strSplash, ";");
	while (stringtokenizer.hasMoreTokens()) {
		String tok = stringtokenizer.nextToken();
		tok = String_trim(tok);
		if (tok.length() == 0) {
			continue;
		}

		if (tok.find("delay") == 0)
		{
			int nEq = tok.find('=');
			if (nEq>=0)
			{
				String val = tok.substr(nEq+1);
				val = String_trim(val);
				if ( val.length() > 0 )
                    convertFromStringA( val.c_str(), m_nDelay );
			}
		}else if (tok.find("zoom") == 0)
		{
			m_nFlags |= VZOOM | HZOOM;
		}else if ( tok.find("vzoom") == 0)
		{
			m_nFlags |= VZOOM;
		}else if ( tok.find("hzoom") == 0)
		{
			m_nFlags |= HZOOM;
		}else if ( tok.find("center") == 0)
		{
			m_nFlags |= VCENTER | HCENTER;
		}else if ( tok.find("vcenter") == 0)
		{
			m_nFlags |= VCENTER;
		}else if ( tok.find("hcenter") == 0)
		{
			m_nFlags |= HCENTER;
		}

	}
}
}
}
<|endoftext|>


<commit_before>/**
 *	@file		statistics.hpp
 *	@brief		An implemenation of statistics operations
 *	@author		seonho.oh@gmail.com
 *	@date		2013-07-01
 *	@version	1.0
 *
 *	@section	LICENSE
 *
 *		Copyright (c) 2007-2013, Seonho Oh
 *		All rights reserved.
 *
 *		Redistribution and use in source and binary forms, with or without
 *		modification, are permitted provided that the following conditions are
 *		met:
 *
 *		    * Redistributions of source code must retain the above copyright
 *		    notice, this list of conditions and the following disclaimer.
 *		    * Redistributions in binary form must reproduce the above copyright
 *		    notice, this list of conditions and the following disclaimer in the
 *		    documentation and/or other materials provided with the distribution.
 *		    * Neither the name of the <ORGANIZATION> nor the names of its
 *		    contributors may be used to endorse or promote products derived from
 *		    this software without specific prior written permission.
 *
 *		THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 *		IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 *		TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 *		PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 *		OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *		EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 *		PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 *		PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 *		LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *		NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *		SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include <armadillo>

namespace arma_ext
{
	using namespace arma;

	/**
	 *	@brief	2-D correlation coefficient
	 *	@param A
	 *	@param B
	 *	@return	the correlation coefficient between @c A and @c B, where @c A and @c B are matrices or vectors of the same size.
	 *			@c corr2 computes the correlation coefficient using
	 *			\f[
	 *				r = \frac{ \sum_{m}\sum_{n}(A_{mn}-\bar{A}) (B_{mn}-\bar{B}) }{\sqrt{ \left( \sum_{m}\sum_{n}(A_{mn}-\bar{A})^2 \right) \left( \sum_{m}\sum_{n}(B_{mn}-\bar{B})^2 \right)}}
	 *			\f]
	 *			where
	 *			\f$ \bar{A}\f$=mean2(A), and \f$\bar{B}\f$=mean2(B).
	 *	@see	http://www.mathworks.co.kr/kr/help/images/ref/corr2.html
	 */
	template <typename mat_type, typename prec_type>
	prec_type corr2(const mat_type& A, const mat_type& B)
	{
		typedef Mat<prec_type> tmat;
		tmat A1, B1;
		A1 = conv_to<tmat>::from(A);
		B1 = conv_to<tmat>::from(B);
		A1 -= mean2(A1);
		B1 -= mean2(B1);
		return accu(A1 % B1) / sqrt(accu(square(A1)) * accu(square(B1)));
	}
}<commit_msg>Add pairwise distance function<commit_after>/**
 *	@file		statistics.hpp
 *	@brief		An implemenation of statistics operations
 *	@author		seonho.oh@gmail.com
 *	@date		2013-07-01
 *	@version	1.0
 *
 *	@section	LICENSE
 *
 *		Copyright (c) 2007-2013, Seonho Oh
 *		All rights reserved.
 *
 *		Redistribution and use in source and binary forms, with or without
 *		modification, are permitted provided that the following conditions are
 *		met:
 *
 *		    * Redistributions of source code must retain the above copyright
 *		    notice, this list of conditions and the following disclaimer.
 *		    * Redistributions in binary form must reproduce the above copyright
 *		    notice, this list of conditions and the following disclaimer in the
 *		    documentation and/or other materials provided with the distribution.
 *		    * Neither the name of the <ORGANIZATION> nor the names of its
 *		    contributors may be used to endorse or promote products derived from
 *		    this software without specific prior written permission.
 *
 *		THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 *		IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 *		TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 *		PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 *		OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *		EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 *		PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 *		PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 *		LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *		NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *		SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include <armadillo>

namespace arma_ext
{
	using namespace arma;

	/**
	 *	@brief	2-D correlation coefficient
	 *	@param A
	 *	@param B
	 *	@return	the correlation coefficient between @c A and @c B, where @c A and @c B are matrices or vectors of the same size.
	 *			@c corr2 computes the correlation coefficient using
	 *			\f[
	 *				r = \frac{ \sum_{m}\sum_{n}(A_{mn}-\bar{A}) (B_{mn}-\bar{B}) }{\sqrt{ \left( \sum_{m}\sum_{n}(A_{mn}-\bar{A})^2 \right) \left( \sum_{m}\sum_{n}(B_{mn}-\bar{B})^2 \right)}}
	 *			\f]
	 *			where
	 *			\f$ \bar{A}\f$=mean2(A), and \f$\bar{B}\f$=mean2(B).
	 *	@see	http://www.mathworks.co.kr/kr/help/images/ref/corr2.html
	 */
	template <typename mat_type, typename prec_type>
	prec_type corr2(const mat_type& A, const mat_type& B)
	{
		typedef Mat<prec_type> tmat;
		tmat A1, B1;
		A1 = conv_to<tmat>::from(A);
		B1 = conv_to<tmat>::from(B);
		A1 -= mean2(A1);
		B1 -= mean2(B1);
		return accu(A1 % B1) / sqrt(accu(square(A1)) * accu(square(B1)));
	}

	/**
	 *	@brief	Distance metric
	 */
	enum distance_type : uword {
		euclidean,		///< Euclidean distance.
		seuclidean,		///< Standarized Eucliean distance.
		cityblock,		///< City block metric.
		minkowski,		///< Minkowski distance. The default exponent is 2.
		chebychev,		///< Chebychev distance (maximum coordinate difference).
		mahalanobis,	///< Mahalanobis distance, using the sample covariance of X.
		cosine,			///< One minus the cosine of the included angle between points(treated as vectors).
		correlation,	///< One minus the sample correlation between points (treatedas sequences of values).
		spearman,		///< One minus the sample Spearman's rank correlation betweenobservations (treated as sequences of values).
		hamming,		///< Hamming distance, which is the percentage of coordinatesthat differ.
		jaccard			///< One minus the Jaccard coefficient, which is the percentageof nonzero coordinates that differ.
	};

	/**
	 *	@brief	Pairwise distance between pairs of objects.<br>
	 *			Computes the distance between pairs of objects in \f$m\f$-by-\f$n\f$ data matrix \f$X\f$.
	 *			Rows of \f$X\f$ correspond to observations, and columns correspond to variables.
	 *			Output is the row vector of length \f$frac{m(m - 1)}{2}\f$, corresponding to pairs of observations in \f$X\f$.
	 *			The distances are arranged in the order \f$(2, 1), (3, 1), \cdots, (m, 1), (3, 2), \cdots, (m, 2), \cdots, (m, m - 1)\f$.
	 *			Output is commonly used as a dissimilarity matrix in clustering or multidimensional scailing.
	 *	@return	Pairwise distance.
	 */
	vec pdist(const mat& X, distance_type type = euclidean)
	{
		const uword m = X.n_rows;
		vec Y(m * (m - 1) / 2);
		double* ptr = Y.colptr(0);

		uword k = 0;
		for (uword i = 0 ; i < m ; i++)
			for (uword j = 1 ; j < m ; j++)
				ptr[k++] = sqrt(sum(square(X.row(j) - X.row(i))));

		return Y;
	}
}<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <cstdio>
#include <cassert>
#include <cstring>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include "funcionesDeBiblioteca.h"

using namespace std;

void ejecutarAlIniciarElPrograma();
void procesarCargaDeTextoEnCuadro(int numeroDeCuadroDeTexto, string texto);
void procesarClicEnBoton(int numeroDeBoton);
void procesarPulsacionDeTecla(char tecla);
void procesarClic(int X, int Y);

SDL_Surface* screen = NULL;
SDL_Surface* canvas = NULL;
SDL_Window* gWindow = NULL;
TTF_Font *font = NULL;

int mouseX = 0, mouseY = 0;
int mouseDownX = 0, mouseDownY = 0;

void dibujarRectanguloEnSuperficie(int x1, int y1, int x2, int y2, Color color, SDL_Surface *superficie);
void escribirTextoEnSuperficie(int x,int y, string texto, Color color, SDL_Surface *superficie);

const int REBORDE_BOTON = 2;

struct Control
{
    int x1,y1,x2,y2;
    int numero;
    string texto;
    bool mouseEncima()
    {
        return x1 <= mouseX && mouseX < x2 &&
               y1 <= mouseY && mouseY < y2;
    }
    bool mousePulso()
    {
        return x1 <= mouseDownX && mouseDownX < x2 &&
               y1 <= mouseDownY && mouseDownY < y2;
    }
    bool presionado()
    {
        return mouseEncima() && mousePulso();
    }
};

struct Boton : public Control
{
    void dibujar()
    {
        if (presionado())
        {
            dibujarRectanguloEnSuperficie(x1,y1,x2,y2, GRIS_MUY_OSCURO, screen);
            dibujarRectanguloEnSuperficie(x1+REBORDE_BOTON,y1,x2,y2-REBORDE_BOTON, GRIS_OSCURO, screen);
            escribirTextoEnSuperficie(x1 + 2*REBORDE_BOTON, y1 + REBORDE_BOTON, texto, NEGRO, screen);
        }
        else
        {
            dibujarRectanguloEnSuperficie(x1,y1-REBORDE_BOTON,x2 + REBORDE_BOTON,y2, BLANCO, screen);
            dibujarRectanguloEnSuperficie(x1,y1,x2,y2, GRIS_CLARO, screen);
            escribirTextoEnSuperficie(x1 + REBORDE_BOTON, y1 + REBORDE_BOTON, texto, NEGRO, screen);
        }

    }
};

const int REBORDE_CUADRO = 2;
int cuadroEnElQueSeCargaTexto = -1;

struct CuadroDeTexto : public Control
{
    void dibujar()
    {
        if (cuadroEnElQueSeCargaTexto == numero)
        {
            dibujarRectanguloEnSuperficie(x1-REBORDE_CUADRO,y1-REBORDE_CUADRO,x2+REBORDE_CUADRO,y2+REBORDE_CUADRO, VERDE, screen);
            dibujarRectanguloEnSuperficie(x1,y1,x2,y2, GRIS_MUY_OSCURO, screen);
            escribirTextoEnSuperficie(x1 + REBORDE_CUADRO, y1 + REBORDE_CUADRO, texto, ROJO, screen);
        }
        else if (mouseEncima())
        {
            dibujarRectanguloEnSuperficie(x1-REBORDE_CUADRO,y1-REBORDE_CUADRO,x2+REBORDE_CUADRO,y2+REBORDE_CUADRO, BLANCO, screen);
            dibujarRectanguloEnSuperficie(x1,y1,x2,y2, NEGRO, screen);
            escribirTextoEnSuperficie(x1 + REBORDE_CUADRO, y1 + REBORDE_CUADRO, texto, AMARILLO, screen);
        }
        else
        {
            dibujarRectanguloEnSuperficie(x1-REBORDE_CUADRO,y1-REBORDE_CUADRO,x2+REBORDE_CUADRO,y2+REBORDE_CUADRO, ROJO, screen);
            dibujarRectanguloEnSuperficie(x1,y1,x2,y2, BLANCO, screen);
            escribirTextoEnSuperficie(x1 + REBORDE_CUADRO, y1 + REBORDE_CUADRO, texto, NEGRO, screen);
        }
    }
};

vector<Boton> botones;
vector<CuadroDeTexto> cuadrosDeTexto;

int proximoNumeroDeControl = 0;

extern const int RESOLUCION_HORIZONTAL;
extern const int RESOLUCION_VERTICAL;

template <typename T>
void eliminarControlPorNumero(vector<T> &v, int numeroDeControl, string mensajeDeError)
{
    for (int i = 0; i < (int)v.size(); i++)
    if (v[i].numero == numeroDeControl)
    {
        v.erase(v.begin() + i);
        return;
    }
    dibujarRectanguloEnSuperficie(0,0,RESOLUCION_HORIZONTAL, RESOLUCION_VERTICAL, AZUL, screen);
    escribirTextoEnSuperficie(100,100, mensajeDeError, BLANCO, screen);
    SDL_UpdateWindowSurface( gWindow );
    SDL_Delay(3000);
}

template <typename T>
int crearControl(int x1,int y1, int x2, int y2, string texto, vector<T> &v)
{
    T b;
    b.numero = proximoNumeroDeControl++;
    b.x1 = x1;
    b.y1 = y1;
    b.x2 = x2;
    b.y2 = y2;
    b.texto = texto;
    v.push_back(b);
    return b.numero;
}

int crearBoton(int x1,int y1, int x2, int y2, string texto)
{
    return crearControl(x1, y1, x2, y2, texto, botones);
}

void eliminarBoton(int numeroDeBoton)
{
    eliminarControlPorNumero(botones, numeroDeBoton, "El boton solicitado no existe! No puede ser eliminado.");
}

int crearCuadroDeTexto(int x1,int y1, int x2, int y2, string textoInicial)
{
    return crearControl(x1, y1, x2, y2, textoInicial, cuadrosDeTexto);
}

void eliminarCuadroDeTexto(int numeroDeCuadroDeTexto)
{
    eliminarControlPorNumero(cuadrosDeTexto, numeroDeCuadroDeTexto, "El cuadro de texto solicitado no existe! No puede ser eliminado.");
}

template <typename T>
void dibujarTodos(vector<T> &v)
{
    for (int i = 0; i < (int)v.size(); i++)
        v[i].dibujar();
}

void actualizarPantalla()
{
    SDL_BlitSurface(canvas, NULL, screen, NULL);
    dibujarTodos(botones);
    dibujarTodos(cuadrosDeTexto);
    SDL_UpdateWindowSurface( gWindow );
}

void finDeCargaDeTexto()
{
    if (cuadroEnElQueSeCargaTexto >= 0)
    {
        for (int i = 0; i < (int)cuadrosDeTexto.size(); i++)
        if (cuadrosDeTexto[i].numero == cuadroEnElQueSeCargaTexto)
        {
            procesarCargaDeTextoEnCuadro(cuadrosDeTexto[i].numero, cuadrosDeTexto[i].texto);
            break;
        }
        cuadroEnElQueSeCargaTexto = -1;
    }
}

void ejecutarElLoopPrincipal()
{
    SDL_Event evento;
    while (true)
    {
        actualizarPantalla();
        SDL_WaitEvent(&evento);
        switch(evento.type)
        {
            case SDL_QUIT:
                return;
                break;
            case SDL_KEYDOWN:
                if (evento.key.keysym.sym == SDLK_KP_ENTER ||
                    evento.key.keysym.sym == SDLK_RETURN)
                    finDeCargaDeTexto();
                if (evento.key.keysym.sym == SDLK_KP_BACKSPACE ||
                    evento.key.keysym.sym == SDLK_BACKSPACE)
                {
                    for (int i = 0; i < (int)cuadrosDeTexto.size(); i++)
                    if (cuadrosDeTexto[i].numero == cuadroEnElQueSeCargaTexto)
                    {
                        if (!cuadrosDeTexto[i].texto.empty())
                            cuadrosDeTexto[i].texto.erase(cuadrosDeTexto[i].texto.size() - 1);
                        break;
                    }
                }
                break;
            case SDL_TEXTINPUT: // Se puede usar SDL_KEYDOWN para dar acceso a las flechitas y no distinguir mayusculas, etc, pero esto es probablemente mas simple para el cliente.
                assert(strlen(evento.text.text) == 1);
                if (cuadroEnElQueSeCargaTexto >= 0)
                {
                    for (int i = 0; i < (int)cuadrosDeTexto.size(); i++)
                    if (cuadrosDeTexto[i].numero == cuadroEnElQueSeCargaTexto)
                    {
                        cuadrosDeTexto[i].texto += evento.text.text;
                        break;
                    }
                }
                else
                    procesarPulsacionDeTecla(evento.text.text[0]);
                break;
            case SDL_MOUSEMOTION:
                mouseX = evento.motion.x;
                mouseY = evento.motion.y;
                break;
            case SDL_MOUSEBUTTONDOWN:
                finDeCargaDeTexto();
                mouseX = mouseDownX = evento.button.x;
                mouseY = mouseDownY = evento.button.y;
                break;
            case SDL_MOUSEBUTTONUP:
                mouseX = evento.button.x;
                mouseY = evento.button.y;
                bool botonCliqueado = false;
                for (int i = 0; i < (int)botones.size(); i++)
                if (botones[i].presionado())
                {
                    procesarClicEnBoton(botones[i].numero);
                    botonCliqueado = true;
                    break;
                }
                if (!botonCliqueado && evento.button.clicks == 1)
                {
                    bool cuadroCliqueado = false;
                    for (int i = 0; i < (int)cuadrosDeTexto.size(); i++)
                    if (cuadrosDeTexto[i].presionado())
                    {
                        cuadroEnElQueSeCargaTexto = cuadrosDeTexto[i].numero;
                        cuadrosDeTexto[i].texto = "";
                        cuadroCliqueado = true;
                        break;
                    }
                    if (!cuadroCliqueado)
                        procesarClic(mouseX, mouseY);
                }
                mouseDownX = mouseDownY = -1000000;
                break;
        }
    }
}

extern const int TAMANIO_TEXTO;
extern const string TITULO_PROGRAMA;

int main()
{
    //Iniciar SDL
    SDL_Init( SDL_INIT_EVERYTHING );
    TTF_Init();

    //Preparar la ventana
    gWindow = SDL_CreateWindow( TITULO_PROGRAMA.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                                                         RESOLUCION_HORIZONTAL, RESOLUCION_VERTICAL, SDL_WINDOW_SHOWN );
    screen = SDL_GetWindowSurface( gWindow );
    canvas = SDL_CreateRGBSurface(0, RESOLUCION_HORIZONTAL, RESOLUCION_VERTICAL, 32, 0,0,0,0);

    // Cargar la fuente

    font = TTF_OpenFont("open-sans.ttf", TAMANIO_TEXTO);
    // Comienza nuestro driver!
    cout << "El driver ha comenzado." << endl;
    ejecutarAlIniciarElPrograma();
    ejecutarElLoopPrincipal();

    //Terminar SDL
    SDL_FreeSurface( canvas );
    SDL_DestroyWindow( gWindow );
    TTF_Quit();
    SDL_Quit();
    return 0;
}
<commit_msg>El driver ahora llama a tickDelReloj. Habria que "retrofittear" a los ejemplos anteriores.<commit_after>#include <iostream>
#include <vector>
#include <cstdio>
#include <cassert>
#include <cstring>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include "funcionesDeBiblioteca.h"

using namespace std;

void ejecutarAlIniciarElPrograma();
void procesarCargaDeTextoEnCuadro(int numeroDeCuadroDeTexto, string texto);
void procesarClicEnBoton(int numeroDeBoton);
void procesarPulsacionDeTecla(char tecla);
void procesarClic(int X, int Y);
void tickDelReloj();

SDL_Surface* screen = NULL;
SDL_Surface* canvas = NULL;
SDL_Window* gWindow = NULL;
TTF_Font *font = NULL;

int mouseX = 0, mouseY = 0;
int mouseDownX = 0, mouseDownY = 0;

void dibujarRectanguloEnSuperficie(int x1, int y1, int x2, int y2, Color color, SDL_Surface *superficie);
void escribirTextoEnSuperficie(int x,int y, string texto, Color color, SDL_Surface *superficie);

const int REBORDE_BOTON = 2;

struct Control
{
    int x1,y1,x2,y2;
    int numero;
    string texto;
    bool mouseEncima()
    {
        return x1 <= mouseX && mouseX < x2 &&
               y1 <= mouseY && mouseY < y2;
    }
    bool mousePulso()
    {
        return x1 <= mouseDownX && mouseDownX < x2 &&
               y1 <= mouseDownY && mouseDownY < y2;
    }
    bool presionado()
    {
        return mouseEncima() && mousePulso();
    }
};

struct Boton : public Control
{
    void dibujar()
    {
        if (presionado())
        {
            dibujarRectanguloEnSuperficie(x1,y1,x2,y2, GRIS_MUY_OSCURO, screen);
            dibujarRectanguloEnSuperficie(x1+REBORDE_BOTON,y1,x2,y2-REBORDE_BOTON, GRIS_OSCURO, screen);
            escribirTextoEnSuperficie(x1 + 2*REBORDE_BOTON, y1 + REBORDE_BOTON, texto, NEGRO, screen);
        }
        else
        {
            dibujarRectanguloEnSuperficie(x1,y1-REBORDE_BOTON,x2 + REBORDE_BOTON,y2, BLANCO, screen);
            dibujarRectanguloEnSuperficie(x1,y1,x2,y2, GRIS_CLARO, screen);
            escribirTextoEnSuperficie(x1 + REBORDE_BOTON, y1 + REBORDE_BOTON, texto, NEGRO, screen);
        }

    }
};

const int REBORDE_CUADRO = 2;
int cuadroEnElQueSeCargaTexto = -1;

struct CuadroDeTexto : public Control
{
    void dibujar()
    {
        if (cuadroEnElQueSeCargaTexto == numero)
        {
            dibujarRectanguloEnSuperficie(x1-REBORDE_CUADRO,y1-REBORDE_CUADRO,x2+REBORDE_CUADRO,y2+REBORDE_CUADRO, VERDE, screen);
            dibujarRectanguloEnSuperficie(x1,y1,x2,y2, GRIS_MUY_OSCURO, screen);
            escribirTextoEnSuperficie(x1 + REBORDE_CUADRO, y1 + REBORDE_CUADRO, texto, ROJO, screen);
        }
        else if (mouseEncima())
        {
            dibujarRectanguloEnSuperficie(x1-REBORDE_CUADRO,y1-REBORDE_CUADRO,x2+REBORDE_CUADRO,y2+REBORDE_CUADRO, BLANCO, screen);
            dibujarRectanguloEnSuperficie(x1,y1,x2,y2, NEGRO, screen);
            escribirTextoEnSuperficie(x1 + REBORDE_CUADRO, y1 + REBORDE_CUADRO, texto, AMARILLO, screen);
        }
        else
        {
            dibujarRectanguloEnSuperficie(x1-REBORDE_CUADRO,y1-REBORDE_CUADRO,x2+REBORDE_CUADRO,y2+REBORDE_CUADRO, ROJO, screen);
            dibujarRectanguloEnSuperficie(x1,y1,x2,y2, BLANCO, screen);
            escribirTextoEnSuperficie(x1 + REBORDE_CUADRO, y1 + REBORDE_CUADRO, texto, NEGRO, screen);
        }
    }
};

vector<Boton> botones;
vector<CuadroDeTexto> cuadrosDeTexto;

int proximoNumeroDeControl = 0;

extern const int RESOLUCION_HORIZONTAL;
extern const int RESOLUCION_VERTICAL;

template <typename T>
void eliminarControlPorNumero(vector<T> &v, int numeroDeControl, string mensajeDeError)
{
    for (int i = 0; i < (int)v.size(); i++)
    if (v[i].numero == numeroDeControl)
    {
        v.erase(v.begin() + i);
        return;
    }
    dibujarRectanguloEnSuperficie(0,0,RESOLUCION_HORIZONTAL, RESOLUCION_VERTICAL, AZUL, screen);
    escribirTextoEnSuperficie(100,100, mensajeDeError, BLANCO, screen);
    SDL_UpdateWindowSurface( gWindow );
    SDL_Delay(3000);
}

template <typename T>
int crearControl(int x1,int y1, int x2, int y2, string texto, vector<T> &v)
{
    T b;
    b.numero = proximoNumeroDeControl++;
    b.x1 = x1;
    b.y1 = y1;
    b.x2 = x2;
    b.y2 = y2;
    b.texto = texto;
    v.push_back(b);
    return b.numero;
}

int crearBoton(int x1,int y1, int x2, int y2, string texto)
{
    return crearControl(x1, y1, x2, y2, texto, botones);
}

void eliminarBoton(int numeroDeBoton)
{
    eliminarControlPorNumero(botones, numeroDeBoton, "El boton solicitado no existe! No puede ser eliminado.");
}

int crearCuadroDeTexto(int x1,int y1, int x2, int y2, string textoInicial)
{
    return crearControl(x1, y1, x2, y2, textoInicial, cuadrosDeTexto);
}

void eliminarCuadroDeTexto(int numeroDeCuadroDeTexto)
{
    eliminarControlPorNumero(cuadrosDeTexto, numeroDeCuadroDeTexto, "El cuadro de texto solicitado no existe! No puede ser eliminado.");
}

template <typename T>
void dibujarTodos(vector<T> &v)
{
    for (int i = 0; i < (int)v.size(); i++)
        v[i].dibujar();
}

void actualizarPantalla()
{
    SDL_BlitSurface(canvas, NULL, screen, NULL);
    dibujarTodos(botones);
    dibujarTodos(cuadrosDeTexto);
    SDL_UpdateWindowSurface( gWindow );
}

void finDeCargaDeTexto()
{
    if (cuadroEnElQueSeCargaTexto >= 0)
    {
        for (int i = 0; i < (int)cuadrosDeTexto.size(); i++)
        if (cuadrosDeTexto[i].numero == cuadroEnElQueSeCargaTexto)
        {
            procesarCargaDeTextoEnCuadro(cuadrosDeTexto[i].numero, cuadrosDeTexto[i].texto);
            break;
        }
        cuadroEnElQueSeCargaTexto = -1;
    }
}

Uint32 timerCallback(Uint32 interval, void*)
{
    // Create a user event to call the game loop.
    SDL_Event event;

    event.type = SDL_USEREVENT;
    event.user.type = SDL_USEREVENT;
    event.user.code = 1;
    event.user.data1 = 0;
    event.user.data2 = 0;

    SDL_PushEvent(&event);

    return interval;
}

extern const int MILISEGUNDOS_RELOJ;

void ejecutarElLoopPrincipal()
{
    SDL_AddTimer(MILISEGUNDOS_RELOJ, timerCallback , NULL);
    SDL_Event evento;
    while (true)
    {
        actualizarPantalla();
        SDL_WaitEvent(&evento);
        switch(evento.type)
        {
            case SDL_USEREVENT:
                tickDelReloj();
                break;
            case SDL_QUIT:
                return;
                break;
            case SDL_KEYDOWN:
                if (evento.key.keysym.sym == SDLK_KP_ENTER ||
                    evento.key.keysym.sym == SDLK_RETURN)
                    finDeCargaDeTexto();
                if (evento.key.keysym.sym == SDLK_KP_BACKSPACE ||
                    evento.key.keysym.sym == SDLK_BACKSPACE)
                {
                    for (int i = 0; i < (int)cuadrosDeTexto.size(); i++)
                    if (cuadrosDeTexto[i].numero == cuadroEnElQueSeCargaTexto)
                    {
                        if (!cuadrosDeTexto[i].texto.empty())
                            cuadrosDeTexto[i].texto.erase(cuadrosDeTexto[i].texto.size() - 1);
                        break;
                    }
                }
                break;
            case SDL_TEXTINPUT: // Se puede usar SDL_KEYDOWN para dar acceso a las flechitas y no distinguir mayusculas, etc, pero esto es probablemente mas simple para el cliente.
                assert(strlen(evento.text.text) == 1);
                if (cuadroEnElQueSeCargaTexto >= 0)
                {
                    for (int i = 0; i < (int)cuadrosDeTexto.size(); i++)
                    if (cuadrosDeTexto[i].numero == cuadroEnElQueSeCargaTexto)
                    {
                        cuadrosDeTexto[i].texto += evento.text.text;
                        break;
                    }
                }
                else
                    procesarPulsacionDeTecla(evento.text.text[0]);
                break;
            case SDL_MOUSEMOTION:
                mouseX = evento.motion.x;
                mouseY = evento.motion.y;
                break;
            case SDL_MOUSEBUTTONDOWN:
                finDeCargaDeTexto();
                mouseX = mouseDownX = evento.button.x;
                mouseY = mouseDownY = evento.button.y;
                break;
            case SDL_MOUSEBUTTONUP:
                mouseX = evento.button.x;
                mouseY = evento.button.y;
                bool botonCliqueado = false;
                for (int i = 0; i < (int)botones.size(); i++)
                if (botones[i].presionado())
                {
                    procesarClicEnBoton(botones[i].numero);
                    botonCliqueado = true;
                    break;
                }
                if (!botonCliqueado && evento.button.clicks == 1)
                {
                    bool cuadroCliqueado = false;
                    for (int i = 0; i < (int)cuadrosDeTexto.size(); i++)
                    if (cuadrosDeTexto[i].presionado())
                    {
                        cuadroEnElQueSeCargaTexto = cuadrosDeTexto[i].numero;
                        cuadrosDeTexto[i].texto = "";
                        cuadroCliqueado = true;
                        break;
                    }
                    if (!cuadroCliqueado)
                        procesarClic(mouseX, mouseY);
                }
                mouseDownX = mouseDownY = -1000000;
                break;
        }
    }
}

extern const int TAMANIO_TEXTO;
extern const string TITULO_PROGRAMA;

int main()
{
    //Iniciar SDL
    SDL_Init( SDL_INIT_EVERYTHING );
    TTF_Init();

    //Preparar la ventana
    gWindow = SDL_CreateWindow( TITULO_PROGRAMA.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                                                         RESOLUCION_HORIZONTAL, RESOLUCION_VERTICAL, SDL_WINDOW_SHOWN );
    screen = SDL_GetWindowSurface( gWindow );
    canvas = SDL_CreateRGBSurface(0, RESOLUCION_HORIZONTAL, RESOLUCION_VERTICAL, 32, 0,0,0,0);

    // Cargar la fuente

    font = TTF_OpenFont("open-sans.ttf", TAMANIO_TEXTO);
    // Comienza nuestro driver!
    cout << "El driver ha comenzado." << endl;
    ejecutarAlIniciarElPrograma();
    ejecutarElLoopPrincipal();

    //Terminar SDL
    SDL_FreeSurface( canvas );
    SDL_DestroyWindow( gWindow );
    TTF_Quit();
    SDL_Quit();
    return 0;
}
<|endoftext|>


<commit_before>/* Copyright (C) 2006 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */

#include <sql_priv.h>
#include <stdlib.h>
#include <ctype.h>
#include <mysql_version.h>
#include <mysql/plugin.h>
#include <my_global.h>
#include <my_dir.h>
#include "my_pthread.h"                         // pthread_handler_t
#include "my_sys.h"                             // my_write, my_malloc
#include "m_string.h"                           // strlen
#include "sql_plugin.h"                         // st_plugin_int

/*
  Disable __attribute__() on non-gcc compilers.
*/
#if !defined(__attribute__) && !defined(__GNUC__)
#define __attribute__(A)
#endif

#define HEART_STRING_BUFFER 100

struct mysql_heartbeat_context
{
  pthread_t heartbeat_thread;
  File heartbeat_file;
};

pthread_handler_t mysql_heartbeat(void *p)
{
  DBUG_ENTER("mysql_heartbeat");
  struct mysql_heartbeat_context *con= (struct mysql_heartbeat_context *)p;
  char buffer[HEART_STRING_BUFFER];
  unsigned int x= 0;
  time_t result;
  struct tm tm_tmp;

  while(1)
  {
    sleep(5);

    result= time(NULL);
    localtime_r(&result, &tm_tmp);
    my_snprintf(buffer, sizeof(buffer),
                "Heartbeat at %02d%02d%02d %2d:%02d:%02d\n",
                tm_tmp.tm_year % 100,
                tm_tmp.tm_mon+1,
                tm_tmp.tm_mday,
                tm_tmp.tm_hour,
                tm_tmp.tm_min,
                tm_tmp.tm_sec);
    my_write(con->heartbeat_file, (uchar*) buffer, strlen(buffer), MYF(0));
    x++;
  }

  DBUG_RETURN(0);
}

/*
  Initialize the daemon example at server start or plugin installation.

  SYNOPSIS
    daemon_example_plugin_init()

  DESCRIPTION
    Starts up heartbeatbeat thread

  RETURN VALUE
    0                    success
    1                    failure (cannot happen)
*/

static int daemon_example_plugin_init(void *p)
{

  DBUG_ENTER("daemon_example_plugin_init");
  struct mysql_heartbeat_context *con;
  pthread_attr_t attr;          /* Thread attributes */
  char heartbeat_filename[FN_REFLEN];
  char buffer[HEART_STRING_BUFFER];
  time_t result= time(NULL);
  struct tm tm_tmp;

  struct st_plugin_int *plugin= (struct st_plugin_int *)p;

  con= (struct mysql_heartbeat_context *)
    my_malloc(sizeof(struct mysql_heartbeat_context), MYF(0));

  fn_format(heartbeat_filename, "mysql-heartbeat", "", ".log",
            MY_REPLACE_EXT | MY_UNPACK_FILENAME);
  unlink(heartbeat_filename);
  con->heartbeat_file= my_open(heartbeat_filename, O_CREAT|O_RDWR, MYF(0));

  /*
    No threads exist at this point in time, so this is thread safe.
  */
  localtime_r(&result, &tm_tmp);
  my_snprintf(buffer, sizeof(buffer),
              "Starting up at %02d%02d%02d %2d:%02d:%02d\n",
              tm_tmp.tm_year % 100,
              tm_tmp.tm_mon+1,
              tm_tmp.tm_mday,
              tm_tmp.tm_hour,
              tm_tmp.tm_min,
              tm_tmp.tm_sec);
  my_write(con->heartbeat_file, (uchar*) buffer, strlen(buffer), MYF(0));

  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr,
                              PTHREAD_CREATE_JOINABLE);

  /* now create the thread */
  if (pthread_create(&con->heartbeat_thread, &attr, mysql_heartbeat,
                     (void *)con) != 0)
  {
    fprintf(stderr,"Could not create heartbeat thread!\n");
    exit(0);
  }
  plugin->data= (void *)con;

  DBUG_RETURN(0);
}

/*
  Terminate the daemon example at server shutdown or plugin deinstallation.

  SYNOPSIS
    daemon_example_plugin_deinit()
    Does nothing.

  RETURN VALUE
    0                    success
    1                    failure (cannot happen)

*/

static int daemon_example_plugin_deinit(void *p)
{
  DBUG_ENTER("daemon_example_plugin_deinit");
  char buffer[HEART_STRING_BUFFER];
  struct st_plugin_int *plugin= (struct st_plugin_int *)p;
  struct mysql_heartbeat_context *con=
    (struct mysql_heartbeat_context *)plugin->data;
  time_t result= time(NULL);
  struct tm tm_tmp;

  pthread_cancel(con->heartbeat_thread);

  localtime_r(&result, &tm_tmp);
  my_snprintf(buffer, sizeof(buffer),
              "Shutting down at %02d%02d%02d %2d:%02d:%02d\n",
              tm_tmp.tm_year % 100,
              tm_tmp.tm_mon+1,
              tm_tmp.tm_mday,
              tm_tmp.tm_hour,
              tm_tmp.tm_min,
              tm_tmp.tm_sec);
  my_write(con->heartbeat_file, (uchar*) buffer, strlen(buffer), MYF(0));
  my_close(con->heartbeat_file, MYF(0));

  my_free((char *)con, MYF(0));

  DBUG_RETURN(0);
}

struct st_mysql_daemon daemon_example_plugin=
{ MYSQL_DAEMON_INTERFACE_VERSION  };

/*
  Plugin library descriptor
*/

mysql_declare_plugin(daemon_example)
{
  MYSQL_DAEMON_PLUGIN,
  &daemon_example_plugin,
  "daemon_example",
  "Brian Aker",
  "Daemon example, creates a heartbeat beat file in mysql-heartbeat.log",
  PLUGIN_LICENSE_GPL,
  daemon_example_plugin_init, /* Plugin Init */
  daemon_example_plugin_deinit, /* Plugin Deinit */
  0x0100 /* 1.0 */,
  NULL,                       /* status variables                */
  NULL,                       /* system variables                */
  NULL                        /* config options                  */
}
mysql_declare_plugin_end;
<commit_msg>Pull in time.h for localtime_r.<commit_after>/* Copyright (C) 2006 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */

#include <sql_priv.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>				// localtime_r
#include <mysql_version.h>
#include <mysql/plugin.h>
#include <my_global.h>
#include <my_dir.h>
#include "my_pthread.h"                         // pthread_handler_t
#include "my_sys.h"                             // my_write, my_malloc
#include "m_string.h"                           // strlen
#include "sql_plugin.h"                         // st_plugin_int

/*
  Disable __attribute__() on non-gcc compilers.
*/
#if !defined(__attribute__) && !defined(__GNUC__)
#define __attribute__(A)
#endif

#define HEART_STRING_BUFFER 100

struct mysql_heartbeat_context
{
  pthread_t heartbeat_thread;
  File heartbeat_file;
};

pthread_handler_t mysql_heartbeat(void *p)
{
  DBUG_ENTER("mysql_heartbeat");
  struct mysql_heartbeat_context *con= (struct mysql_heartbeat_context *)p;
  char buffer[HEART_STRING_BUFFER];
  unsigned int x= 0;
  time_t result;
  struct tm tm_tmp;

  while(1)
  {
    sleep(5);

    result= time(NULL);
    localtime_r(&result, &tm_tmp);
    my_snprintf(buffer, sizeof(buffer),
                "Heartbeat at %02d%02d%02d %2d:%02d:%02d\n",
                tm_tmp.tm_year % 100,
                tm_tmp.tm_mon+1,
                tm_tmp.tm_mday,
                tm_tmp.tm_hour,
                tm_tmp.tm_min,
                tm_tmp.tm_sec);
    my_write(con->heartbeat_file, (uchar*) buffer, strlen(buffer), MYF(0));
    x++;
  }

  DBUG_RETURN(0);
}

/*
  Initialize the daemon example at server start or plugin installation.

  SYNOPSIS
    daemon_example_plugin_init()

  DESCRIPTION
    Starts up heartbeatbeat thread

  RETURN VALUE
    0                    success
    1                    failure (cannot happen)
*/

static int daemon_example_plugin_init(void *p)
{

  DBUG_ENTER("daemon_example_plugin_init");
  struct mysql_heartbeat_context *con;
  pthread_attr_t attr;          /* Thread attributes */
  char heartbeat_filename[FN_REFLEN];
  char buffer[HEART_STRING_BUFFER];
  time_t result= time(NULL);
  struct tm tm_tmp;

  struct st_plugin_int *plugin= (struct st_plugin_int *)p;

  con= (struct mysql_heartbeat_context *)
    my_malloc(sizeof(struct mysql_heartbeat_context), MYF(0));

  fn_format(heartbeat_filename, "mysql-heartbeat", "", ".log",
            MY_REPLACE_EXT | MY_UNPACK_FILENAME);
  unlink(heartbeat_filename);
  con->heartbeat_file= my_open(heartbeat_filename, O_CREAT|O_RDWR, MYF(0));

  /*
    No threads exist at this point in time, so this is thread safe.
  */
  localtime_r(&result, &tm_tmp);
  my_snprintf(buffer, sizeof(buffer),
              "Starting up at %02d%02d%02d %2d:%02d:%02d\n",
              tm_tmp.tm_year % 100,
              tm_tmp.tm_mon+1,
              tm_tmp.tm_mday,
              tm_tmp.tm_hour,
              tm_tmp.tm_min,
              tm_tmp.tm_sec);
  my_write(con->heartbeat_file, (uchar*) buffer, strlen(buffer), MYF(0));

  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr,
                              PTHREAD_CREATE_JOINABLE);

  /* now create the thread */
  if (pthread_create(&con->heartbeat_thread, &attr, mysql_heartbeat,
                     (void *)con) != 0)
  {
    fprintf(stderr,"Could not create heartbeat thread!\n");
    exit(0);
  }
  plugin->data= (void *)con;

  DBUG_RETURN(0);
}

/*
  Terminate the daemon example at server shutdown or plugin deinstallation.

  SYNOPSIS
    daemon_example_plugin_deinit()
    Does nothing.

  RETURN VALUE
    0                    success
    1                    failure (cannot happen)

*/

static int daemon_example_plugin_deinit(void *p)
{
  DBUG_ENTER("daemon_example_plugin_deinit");
  char buffer[HEART_STRING_BUFFER];
  struct st_plugin_int *plugin= (struct st_plugin_int *)p;
  struct mysql_heartbeat_context *con=
    (struct mysql_heartbeat_context *)plugin->data;
  time_t result= time(NULL);
  struct tm tm_tmp;

  pthread_cancel(con->heartbeat_thread);

  localtime_r(&result, &tm_tmp);
  my_snprintf(buffer, sizeof(buffer),
              "Shutting down at %02d%02d%02d %2d:%02d:%02d\n",
              tm_tmp.tm_year % 100,
              tm_tmp.tm_mon+1,
              tm_tmp.tm_mday,
              tm_tmp.tm_hour,
              tm_tmp.tm_min,
              tm_tmp.tm_sec);
  my_write(con->heartbeat_file, (uchar*) buffer, strlen(buffer), MYF(0));
  my_close(con->heartbeat_file, MYF(0));

  my_free((char *)con, MYF(0));

  DBUG_RETURN(0);
}

struct st_mysql_daemon daemon_example_plugin=
{ MYSQL_DAEMON_INTERFACE_VERSION  };

/*
  Plugin library descriptor
*/

mysql_declare_plugin(daemon_example)
{
  MYSQL_DAEMON_PLUGIN,
  &daemon_example_plugin,
  "daemon_example",
  "Brian Aker",
  "Daemon example, creates a heartbeat beat file in mysql-heartbeat.log",
  PLUGIN_LICENSE_GPL,
  daemon_example_plugin_init, /* Plugin Init */
  daemon_example_plugin_deinit, /* Plugin Deinit */
  0x0100 /* 1.0 */,
  NULL,                       /* status variables                */
  NULL,                       /* system variables                */
  NULL                        /* config options                  */
}
mysql_declare_plugin_end;
<|endoftext|>


<commit_before>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * Razor - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2012 Razor team
 * Authors:
 *   Johannes Zellner <webmaster@nebulon.de>
 *
 * This program or 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
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include "razorvolume.h"

#include "volumebutton.h"
#include "volumepopup.h"
#include "razorvolumeconfiguration.h"
#include "audiodevice.h"
#ifdef USE_PULSEAUDIO
#include "pulseaudioengine.h"
#endif
#ifdef USE_ALSA
#include "alsaengine.h"
#endif

#include <QtGui/QMessageBox>
#include <QtDebug>
#include <qtxdg/xdgicon.h>
#include <razorqxt/qxtglobalshortcut.h>
#include <razorqt/razornotification.h>

EXPORT_RAZOR_PANEL_PLUGIN_CPP(RazorVolume)

RazorVolume::RazorVolume(const RazorPanelPluginStartInfo* startInfo, QWidget* parent):
        RazorPanelPlugin(startInfo, parent),
        m_defaultSinkIndex(0),
        m_defaultSink(0)
{
    setObjectName("Volume");

    m_volumeButton = new VolumeButton(panel(), this);
    addWidget(m_volumeButton);

    m_configWindow = new RazorVolumeConfiguration(settings(), this);

    // global key shortcuts
    m_keyVolumeUp = new QxtGlobalShortcut(this);
    m_keyVolumeDown = new QxtGlobalShortcut(this);
    m_keyMuteToggle = new QxtGlobalShortcut(this);

    QKeySequence keySequenceVolumeUp(Qt::Key_VolumeUp);
    if (!m_keyVolumeUp->setShortcut(keySequenceVolumeUp)) {
        RazorNotification::notify(tr("Show Desktop: Global shortcut '%1' cannot be registered").arg(keySequenceVolumeUp.toString()));
    }

    QKeySequence keySequenceVolumeDown(Qt::Key_VolumeDown);
    if (!m_keyVolumeDown->setShortcut(keySequenceVolumeDown)) {
        RazorNotification::notify(tr("Show Desktop: Global shortcut '%1' cannot be registered").arg(keySequenceVolumeDown.toString()));
    }

    QKeySequence keySequenceMuteToggle(Qt::Key_VolumeMute);
    if (!m_keyMuteToggle->setShortcut(keySequenceMuteToggle)) {
        RazorNotification::notify(tr("Show Desktop: Global shortcut '%1' cannot be registered").arg(keySequenceMuteToggle.toString()));
    }

    connect(m_keyVolumeUp, SIGNAL(activated()), this, SLOT(handleShortcutVolumeUp()));
    connect(m_keyVolumeDown, SIGNAL(activated()), this, SLOT(handleShortcutVolumeDown()));
    connect(m_keyMuteToggle, SIGNAL(activated()), this, SLOT(handleShortcutVolumeMute()));

#ifdef USE_PULSEAUDIO
    m_engine = new PulseAudioEngine(this);
#else
    m_engine = new AlsaEngine(this);
#endif

    connect(m_engine, SIGNAL(sinkListChanged()), this, SLOT(updateConfigurationSinkList()));
    updateConfigurationSinkList();
}

void RazorVolume::showConfigureDialog()
{
    m_configWindow->show();
    m_configWindow->raise();
    m_configWindow->activateWindow();
}

void RazorVolume::settingsChanged()
{
    m_defaultSinkIndex = settings().value(SETTINGS_DEVICE, SETTINGS_DEFAULT_DEVICE).toInt();
    if (m_engine->sinks().at(m_defaultSinkIndex)) {
        m_defaultSink = m_engine->sinks().at(m_defaultSinkIndex);
        m_volumeButton->volumePopup()->setDevice(m_defaultSink);
    }

    m_volumeButton->setShowOnClicked(settings().value(SETTINGS_SHOW_ON_LEFTCLICK, SETTINGS_DEFAULT_SHOW_ON_LEFTCLICK).toBool());
    m_volumeButton->setMuteOnMiddleClick(settings().value(SETTINGS_MUTE_ON_MIDDLECLICK, SETTINGS_DEFAULT_MUTE_ON_MIDDLECLICK).toBool());
    m_volumeButton->setMixerCommand(settings().value(SETTINGS_MIXER_COMMAND, SETTINGS_DEFAULT_MIXER_COMMAND).toString());
}

void RazorVolume::updateConfigurationSinkList()
{
    m_configWindow->setSinkList(m_engine->sinks());
    settingsChanged();
}

void RazorVolume::handleShortcutVolumeUp()
{
    if (m_defaultSink)
        m_defaultSink->setVolume(m_defaultSink->volume() + settings().value(SETTINGS_STEP, SETTINGS_DEFAULT_STEP).toInt());
}

void RazorVolume::handleShortcutVolumeDown()
{
    if (m_defaultSink)
        m_defaultSink->setVolume(m_defaultSink->volume() - settings().value(SETTINGS_STEP, SETTINGS_DEFAULT_STEP).toInt());
}

void RazorVolume::handleShortcutVolumeMute()
{
    if (m_defaultSink)
        m_defaultSink->toggleMute();
}
<commit_msg>razor-panel/plugin-volume: Use center alignment<commit_after>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * Razor - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2012 Razor team
 * Authors:
 *   Johannes Zellner <webmaster@nebulon.de>
 *
 * This program or 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
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include "razorvolume.h"

#include "volumebutton.h"
#include "volumepopup.h"
#include "razorvolumeconfiguration.h"
#include "audiodevice.h"
#ifdef USE_PULSEAUDIO
#include "pulseaudioengine.h"
#endif
#ifdef USE_ALSA
#include "alsaengine.h"
#endif

#include <QtGui/QMessageBox>
#include <QtDebug>
#include <qtxdg/xdgicon.h>
#include <razorqxt/qxtglobalshortcut.h>
#include <razorqt/razornotification.h>

EXPORT_RAZOR_PANEL_PLUGIN_CPP(RazorVolume)

RazorVolume::RazorVolume(const RazorPanelPluginStartInfo* startInfo, QWidget* parent):
        RazorPanelPlugin(startInfo, parent),
        m_defaultSinkIndex(0),
        m_defaultSink(0)
{
    setObjectName("Volume");

    layout()->setAlignment(Qt::AlignCenter);
    m_volumeButton = new VolumeButton(panel(), this);
    addWidget(m_volumeButton);

    m_configWindow = new RazorVolumeConfiguration(settings(), this);

    // global key shortcuts
    m_keyVolumeUp = new QxtGlobalShortcut(this);
    m_keyVolumeDown = new QxtGlobalShortcut(this);
    m_keyMuteToggle = new QxtGlobalShortcut(this);

    QKeySequence keySequenceVolumeUp(Qt::Key_VolumeUp);
    if (!m_keyVolumeUp->setShortcut(keySequenceVolumeUp)) {
        RazorNotification::notify(tr("Show Desktop: Global shortcut '%1' cannot be registered").arg(keySequenceVolumeUp.toString()));
    }

    QKeySequence keySequenceVolumeDown(Qt::Key_VolumeDown);
    if (!m_keyVolumeDown->setShortcut(keySequenceVolumeDown)) {
        RazorNotification::notify(tr("Show Desktop: Global shortcut '%1' cannot be registered").arg(keySequenceVolumeDown.toString()));
    }

    QKeySequence keySequenceMuteToggle(Qt::Key_VolumeMute);
    if (!m_keyMuteToggle->setShortcut(keySequenceMuteToggle)) {
        RazorNotification::notify(tr("Show Desktop: Global shortcut '%1' cannot be registered").arg(keySequenceMuteToggle.toString()));
    }

    connect(m_keyVolumeUp, SIGNAL(activated()), this, SLOT(handleShortcutVolumeUp()));
    connect(m_keyVolumeDown, SIGNAL(activated()), this, SLOT(handleShortcutVolumeDown()));
    connect(m_keyMuteToggle, SIGNAL(activated()), this, SLOT(handleShortcutVolumeMute()));

#ifdef USE_PULSEAUDIO
    m_engine = new PulseAudioEngine(this);
#else
    m_engine = new AlsaEngine(this);
#endif

    connect(m_engine, SIGNAL(sinkListChanged()), this, SLOT(updateConfigurationSinkList()));
    updateConfigurationSinkList();
}

void RazorVolume::showConfigureDialog()
{
    m_configWindow->show();
    m_configWindow->raise();
    m_configWindow->activateWindow();
}

void RazorVolume::settingsChanged()
{
    m_defaultSinkIndex = settings().value(SETTINGS_DEVICE, SETTINGS_DEFAULT_DEVICE).toInt();
    if (m_engine->sinks().at(m_defaultSinkIndex)) {
        m_defaultSink = m_engine->sinks().at(m_defaultSinkIndex);
        m_volumeButton->volumePopup()->setDevice(m_defaultSink);
    }

    m_volumeButton->setShowOnClicked(settings().value(SETTINGS_SHOW_ON_LEFTCLICK, SETTINGS_DEFAULT_SHOW_ON_LEFTCLICK).toBool());
    m_volumeButton->setMuteOnMiddleClick(settings().value(SETTINGS_MUTE_ON_MIDDLECLICK, SETTINGS_DEFAULT_MUTE_ON_MIDDLECLICK).toBool());
    m_volumeButton->setMixerCommand(settings().value(SETTINGS_MIXER_COMMAND, SETTINGS_DEFAULT_MIXER_COMMAND).toString());
}

void RazorVolume::updateConfigurationSinkList()
{
    m_configWindow->setSinkList(m_engine->sinks());
    settingsChanged();
}

void RazorVolume::handleShortcutVolumeUp()
{
    if (m_defaultSink)
        m_defaultSink->setVolume(m_defaultSink->volume() + settings().value(SETTINGS_STEP, SETTINGS_DEFAULT_STEP).toInt());
}

void RazorVolume::handleShortcutVolumeDown()
{
    if (m_defaultSink)
        m_defaultSink->setVolume(m_defaultSink->volume() - settings().value(SETTINGS_STEP, SETTINGS_DEFAULT_STEP).toInt());
}

void RazorVolume::handleShortcutVolumeMute()
{
    if (m_defaultSink)
        m_defaultSink->toggleMute();
}
<|endoftext|>


<commit_before>/* The MIT License

Copyright (c) 2011 Sahab Yazdani

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.
*/

#include <cstdlib>
#include <cmath>

#include "bitmap.h"

Bitmap::Bitmap( std::string filename ) {
	using std::ceil;

	file = PNG::load( filename );

	intensityMap = new unsigned char[file->w * file->h];
	unsigned char *imPtr = intensityMap, *cPtr = file->data;

	for (unsigned int y = 0; y < file->h; y++) {
		for (unsigned int x = 0; x < file->w; x++, imPtr++, cPtr+=4) {
			*imPtr = 255 - (unsigned char)ceil(((float)(*(cPtr)) * 0.2126 + (float)(*(cPtr+1)) * 0.7152 + (float)(*(cPtr+2)) * 0.0722));
		}
	}
}

Bitmap::~Bitmap() {
	PNG::freePng( file );
	delete[] intensityMap;
}

float Bitmap::getIntensity( float x, float y ) {
	using std::floor;

	// from wikipedia
	unsigned char *iMPtr = intensityMap + (unsigned int)floor(y) * file->w + (unsigned int)floor(x);
	float fX = x - floor(x), fY = y - floor(y);

	return
		(float)(*(iMPtr)) * (1 - fX) * (1 - fY) +
		(float)(*(iMPtr + 1)) * fX * (1 - fY) +
		(float)(*(iMPtr + file->w)) * (1 - fX) * fY +
		(float)(*(iMPtr + file->w + 1)) * fX * fY;
}

void Bitmap::getColour( float x, float y, unsigned char &r, unsigned char &g, unsigned char &b ) {
	using std::floor;

	float fX = x - floor(x), fY = y - floor(y);
	float f00 = (1 - fX) * (1 - fY),
		f10 = fX * (1 - fY),
		f01 = (1 - fX) * fY,
		f11 = fX * fY;

	unsigned char *dataPtr = file->data + (((unsigned int)floor(y) * file->w + (unsigned int)floor(x)) * 4);
	r = floor((float)(*(dataPtr)) * f00 +
		(float)(*(dataPtr + 4)) * f10 +
		(float)(*(dataPtr + file->w * 4)) * f01 +
		(float)(*(dataPtr + file->w * 4 + 4)) * f11);

	dataPtr++;
	g = floor((float)(*(dataPtr)) * f00 +
		(float)(*(dataPtr + 4)) * f10 +
		(float)(*(dataPtr + file->w * 4)) * f01 +
		(float)(*(dataPtr + file->w * 4 + 4)) * f11);

	dataPtr++;
	b = floor((float)(*(dataPtr)) * f00 +
		(float)(*(dataPtr + 4)) * f10 +
		(float)(*(dataPtr + file->w * 4)) * f01 +
		(float)(*(dataPtr + file->w * 4 + 4)) * f11);
}

unsigned int Bitmap::getWidth() {
	return file->w;
}

unsigned int Bitmap::getHeight() {
	return file->h;
}

<commit_msg>Fix a Visual Studio build warning.<commit_after>/* The MIT License

Copyright (c) 2011 Sahab Yazdani

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.
*/

#include <cstdlib>
#include <cmath>

#include "bitmap.h"

Bitmap::Bitmap( std::string filename ) {
	using std::ceil;

	file = PNG::load( filename );

	intensityMap = new unsigned char[file->w * file->h];
	unsigned char *imPtr = intensityMap, *cPtr = file->data;

	for (unsigned int y = 0; y < file->h; y++) {
		for (unsigned int x = 0; x < file->w; x++, imPtr++, cPtr+=4) {
			*imPtr = 255 - (unsigned char)ceil(((float)(*(cPtr)) * 0.2126 + (float)(*(cPtr+1)) * 0.7152 + (float)(*(cPtr+2)) * 0.0722));
		}
	}
}

Bitmap::~Bitmap() {
	PNG::freePng( file );
	delete[] intensityMap;
}

float Bitmap::getIntensity( float x, float y ) {
	using std::floor;

	// from wikipedia
	unsigned char *iMPtr = intensityMap + (unsigned int)floor(y) * file->w + (unsigned int)floor(x);
	float fX = x - floor(x), fY = y - floor(y);

	return
		(float)(*(iMPtr)) * (1 - fX) * (1 - fY) +
		(float)(*(iMPtr + 1)) * fX * (1 - fY) +
		(float)(*(iMPtr + file->w)) * (1 - fX) * fY +
		(float)(*(iMPtr + file->w + 1)) * fX * fY;
}

void Bitmap::getColour( float x, float y, unsigned char &r, unsigned char &g, unsigned char &b ) {
	using std::floor;

	float fX = x - floor(x), fY = y - floor(y);
	float f00 = (1 - fX) * (1 - fY),
		f10 = fX * (1 - fY),
		f01 = (1 - fX) * fY,
		f11 = fX * fY;

	unsigned char *dataPtr = file->data + (((unsigned int)floor(y) * file->w + (unsigned int)floor(x)) * 4);
	r = (unsigned char)floor((float)(*(dataPtr)) * f00 +
		(float)(*(dataPtr + 4)) * f10 +
		(float)(*(dataPtr + file->w * 4)) * f01 +
		(float)(*(dataPtr + file->w * 4 + 4)) * f11);

	dataPtr++;
	g = (unsigned char)floor((float)(*(dataPtr)) * f00 +
		(float)(*(dataPtr + 4)) * f10 +
		(float)(*(dataPtr + file->w * 4)) * f01 +
		(float)(*(dataPtr + file->w * 4 + 4)) * f11);

	dataPtr++;
	b = (unsigned char)floor((float)(*(dataPtr)) * f00 +
		(float)(*(dataPtr + 4)) * f10 +
		(float)(*(dataPtr + file->w * 4)) * f01 +
		(float)(*(dataPtr + file->w * 4 + 4)) * f11);
}

unsigned int Bitmap::getWidth() {
	return file->w;
}

unsigned int Bitmap::getHeight() {
	return file->h;
}

<|endoftext|>


<commit_before>/*
 * ===============================================================
 *    Description:  Get BTC block implementation.
 *
 *         Author:  Ayush Dubey, dubey@cs.cornell.edu
 *
 * Copyright (C) 2014, Cornell University, see the LICENSE file
 *                     for licensing agreement
 * ===============================================================
 */

#define weaver_debug_
#include "common/stl_serialization.h"
#include "node_prog/node_prog_type.h"
#include "node_prog/get_btc_block.h"

using node_prog::search_type;
using node_prog::get_btc_block_params;
using node_prog::get_btc_block_state;
using node_prog::cache_response;
using node_prog::Cache_Value_Base;

// params
get_btc_block_params :: get_btc_block_params()
    : returning(false)
{ }

uint64_t
get_btc_block_params :: size() const
{
    return message::size(block)
         + message::size(node)
         + message::size(txs)
         + message::size(returning)
         + message::size(tx_to_get)
         + message::size(block_node);
}

void
get_btc_block_params :: pack(e::packer &packer) const
{
    message::pack_buffer(packer, block);
    message::pack_buffer(packer, node);
    message::pack_buffer(packer, txs);
    message::pack_buffer(packer, returning);
    message::pack_buffer(packer, tx_to_get);
    message::pack_buffer(packer, block_node);
}

void
get_btc_block_params :: unpack(e::unpacker &unpacker)
{
    message::unpack_buffer(unpacker, block);
    message::unpack_buffer(unpacker, node);
    message::unpack_buffer(unpacker, txs);
    message::unpack_buffer(unpacker, returning);
    message::unpack_buffer(unpacker, tx_to_get);
    message::unpack_buffer(unpacker, block_node);
}

get_btc_block_state :: get_btc_block_state()
    : outstanding_count(0)
{ }

uint64_t
get_btc_block_state :: size() const
{
    return message::size(outstanding_count)
         + message::size(txs);
}

void
get_btc_block_state :: pack(e::packer &packer) const
{
    message::pack_buffer(packer, outstanding_count);
    message::pack_buffer(packer, txs);
}

void
get_btc_block_state :: unpack(e::unpacker &unpacker)
{
    message::unpack_buffer(unpacker, outstanding_count);
    message::unpack_buffer(unpacker, txs);
}

std::pair<search_type, std::vector<std::pair<db::remote_node, get_btc_block_params>>>
node_prog :: get_btc_block_node_program(node_prog::node &n,
   db::remote_node &rn,
   get_btc_block_params &params,
   std::function<get_btc_block_state&()> state_getter,
   std::function<void(std::shared_ptr<Cache_Value_Base>, std::shared_ptr<std::vector<db::remote_node>>, cache_key_t)>&,
   cache_response<Cache_Value_Base>*)
{
    get_btc_block_state &state = state_getter();
    std::vector<std::pair<db::remote_node, get_btc_block_params>> next;

    if (!params.returning) {
        // request spreading out

        if (n.get_handle() == params.block || n.is_alias(params.block)) {
            // this is btc block vertex
            std::string block_tx_str = "BLOCK_TX_";
            params.block_node = rn;
            state.outstanding_count = 0;
            std::vector<std::pair<db::remote_node, std::string>> txs_to_get;
            for (edge &e: n.get_edges()) {
                if (e.get_handle().compare(0, block_tx_str.size(), block_tx_str) == 0) {
                    std::string tx_to_get = e.get_handle().substr(block_tx_str.size());
                    WDEBUG << tx_to_get << std::endl;
                    txs_to_get.emplace_back(std::make_pair(e.get_neighbor(), tx_to_get));
                }
            }

            if (txs_to_get.empty()) {
                n.get_client_node(params.node, true, true, true);
                next.emplace_back(std::make_pair(db::coordinator, std::move(params)));
            } else {
                for (const auto &p: txs_to_get) {
                    params.tx_to_get.clear();
                    params.tx_to_get.emplace_back(p.second);
                    next.emplace_back(std::make_pair(p.first, params));
                    state.outstanding_count++;
                }
            }
        } else {
            // this is neighbor of btc block, i.e. a btc tx vertex
            assert(!params.tx_to_get.empty());

            std::unordered_map<std::string, btc_tx_t> seen_txs;
            for (const std::string &tx_id: params.tx_to_get) {
                uint64_t tx_index = 0;
                while (true) {
                    std::string tx_handle = "TXOUT_" + tx_id + "_" + std::to_string(tx_index++);
                    if (n.edge_exists(tx_handle)) {
                        WDEBUG << tx_handle << std::endl;
                        edge &e = n.get_edge(tx_handle);
                        cl::edge cl_edge;
                        e.get_client_edge(n.get_handle(), cl_edge);

                        bool exists = seen_txs.find(tx_id) != seen_txs.end();
                        btc_tx_t &btc_tx = seen_txs[tx_id];
                        btc_tx.second.emplace_back(cl_edge);

                        if (!exists) {
                            std::vector<std::string> input_txes;
                            for (auto pvec: e.get_properties()) {
                                for (auto &p: pvec) {
                                    if (p->key == "input_txes") {
                                        input_txes.emplace_back("CXIN_" + p->value);
                                    }
                                }
                            }

                            for (const std::string &itx: input_txes) {
                                if (n.edge_exists(itx)) {
                                    edge &in_e = n.get_edge(itx);
                                    in_e.get_client_edge(n.get_handle(), cl_edge);
                                    btc_tx.first.emplace_back(cl_edge);
                                }
                            }
                        }
                    } else {
                        break;
                    }
                }
            }

            for (const auto &p: seen_txs) {
                params.txs.emplace_back(p.second);
            }
            params.returning = true;
            next.emplace_back(std::make_pair(params.block_node, std::move(params)));
        }

    } else {
        // request returning to start node
        assert(n.get_handle() == params.block || n.is_alias(params.block));

        for (const auto &tx: params.txs) {
            state.txs.emplace_back(tx);
        }

        if (--state.outstanding_count == 0) {
            n.get_client_node(params.node, true, true, true);
            params.txs = state.txs;
            next.emplace_back(std::make_pair(db::coordinator, std::move(params)));
        }

    }

    return std::make_pair(search_type::BREADTH_FIRST, std::move(next));
}
<commit_msg>update get btc block<commit_after>/*
 * ===============================================================
 *    Description:  Get BTC block implementation.
 *
 *         Author:  Ayush Dubey, dubey@cs.cornell.edu
 *
 * Copyright (C) 2014, Cornell University, see the LICENSE file
 *                     for licensing agreement
 * ===============================================================
 */

#define weaver_debug_
#include "common/stl_serialization.h"
#include "node_prog/node_prog_type.h"
#include "node_prog/get_btc_block.h"

using node_prog::search_type;
using node_prog::get_btc_block_params;
using node_prog::get_btc_block_state;
using node_prog::cache_response;
using node_prog::Cache_Value_Base;

// params
get_btc_block_params :: get_btc_block_params()
    : returning(false)
{ }

uint64_t
get_btc_block_params :: size() const
{
    return message::size(block)
         + message::size(node)
         + message::size(txs)
         + message::size(returning)
         + message::size(tx_to_get)
         + message::size(block_node);
}

void
get_btc_block_params :: pack(e::packer &packer) const
{
    message::pack_buffer(packer, block);
    message::pack_buffer(packer, node);
    message::pack_buffer(packer, txs);
    message::pack_buffer(packer, returning);
    message::pack_buffer(packer, tx_to_get);
    message::pack_buffer(packer, block_node);
}

void
get_btc_block_params :: unpack(e::unpacker &unpacker)
{
    message::unpack_buffer(unpacker, block);
    message::unpack_buffer(unpacker, node);
    message::unpack_buffer(unpacker, txs);
    message::unpack_buffer(unpacker, returning);
    message::unpack_buffer(unpacker, tx_to_get);
    message::unpack_buffer(unpacker, block_node);
}

get_btc_block_state :: get_btc_block_state()
    : outstanding_count(0)
{ }

uint64_t
get_btc_block_state :: size() const
{
    return message::size(outstanding_count)
         + message::size(txs);
}

void
get_btc_block_state :: pack(e::packer &packer) const
{
    message::pack_buffer(packer, outstanding_count);
    message::pack_buffer(packer, txs);
}

void
get_btc_block_state :: unpack(e::unpacker &unpacker)
{
    message::unpack_buffer(unpacker, outstanding_count);
    message::unpack_buffer(unpacker, txs);
}

std::pair<search_type, std::vector<std::pair<db::remote_node, get_btc_block_params>>>
node_prog :: get_btc_block_node_program(node_prog::node &n,
   db::remote_node &rn,
   get_btc_block_params &params,
   std::function<get_btc_block_state&()> state_getter,
   std::function<void(std::shared_ptr<Cache_Value_Base>, std::shared_ptr<std::vector<db::remote_node>>, cache_key_t)>&,
   cache_response<Cache_Value_Base>*)
{
    get_btc_block_state &state = state_getter();
    std::vector<std::pair<db::remote_node, get_btc_block_params>> next;

    if (!params.returning) {
        // request spreading out

        if (n.get_handle() == params.block || n.is_alias(params.block)) {
            // this is btc block vertex
            std::string block_tx_str = "BLOCK_TX_";
            params.block_node = rn;
            state.outstanding_count = 0;
            std::vector<std::pair<db::remote_node, std::string>> txs_to_get;
            for (edge &e: n.get_edges()) {
                if (e.get_handle().compare(0, block_tx_str.size(), block_tx_str) == 0) {
                    std::string tx_to_get = e.get_handle().substr(block_tx_str.size());
                    WDEBUG << tx_to_get << std::endl;
                    txs_to_get.emplace_back(std::make_pair(e.get_neighbor(), tx_to_get));
                }
            }

            if (txs_to_get.empty()) {
                n.get_client_node(params.node, true, true, true);
                next.emplace_back(std::make_pair(db::coordinator, std::move(params)));
            } else {
                for (const auto &p: txs_to_get) {
                    params.tx_to_get.clear();
                    params.tx_to_get.emplace_back(p.second);
                    next.emplace_back(std::make_pair(p.first, params));
                    state.outstanding_count++;
                }
            }
        } else {
            // this is neighbor of btc block, i.e. a btc tx vertex
            assert(!params.tx_to_get.empty());

            std::unordered_map<std::string, btc_tx_t> seen_txs;
            for (const std::string &tx_id: params.tx_to_get) {
                uint64_t tx_index = 0;
                while (true) {
                    std::string tx_handle = "TXOUT_" + tx_id + "_" + std::to_string(tx_index);
                    if (n.edge_exists(tx_handle)) {
                        WDEBUG << tx_handle << std::endl;
                        edge &e = n.get_edge(tx_handle);
                        cl::edge cl_edge;
                        e.get_client_edge(n.get_handle(), cl_edge);
                        std::string consumed_tx_handle = "CTX_" + tx_id + "_" + std::to_string(tx_index);
                        if (n.edge_exists(consumed_tx_handle)) {
                            edge &ctx_edge = n.get_edge(consumed_tx_handle);
                            std::shared_ptr<cl::property> consumed_prop(new cl::property());
                            consumed_prop->key = "consumed";
                            consumed_prop->value = ctx_edge.get_neighbor().handle;
                            cl_edge.properties.emplace_back(consumed_prop);
                        }

                        bool exists = seen_txs.find(tx_id) != seen_txs.end();
                        btc_tx_t &btc_tx = seen_txs[tx_id];
                        btc_tx.second.emplace_back(cl_edge);

                        if (!exists) {
                            std::vector<std::string> input_txes;
                            for (auto pvec: e.get_properties()) {
                                for (auto &p: pvec) {
                                    if (p->key == "input_txes") {
                                        input_txes.emplace_back("CXIN_" + p->value);
                                    }
                                }
                            }

                            for (const std::string &itx: input_txes) {
                                if (n.edge_exists(itx)) {
                                    edge &in_e = n.get_edge(itx);
                                    in_e.get_client_edge(n.get_handle(), cl_edge);
                                    btc_tx.first.emplace_back(cl_edge);
                                }
                            }
                        }
                    } else {
                        break;
                    }

                    tx_index++;
                }
            }

            for (const auto &p: seen_txs) {
                params.txs.emplace_back(p.second);
            }
            params.returning = true;
            next.emplace_back(std::make_pair(params.block_node, std::move(params)));
        }

    } else {
        // request returning to start node
        assert(n.get_handle() == params.block || n.is_alias(params.block));

        for (const auto &tx: params.txs) {
            state.txs.emplace_back(tx);
        }

        if (--state.outstanding_count == 0) {
            n.get_client_node(params.node, true, true, true);
            params.txs = state.txs;
            next.emplace_back(std::make_pair(db::coordinator, std::move(params)));
        }

    }

    return std::make_pair(search_type::BREADTH_FIRST, std::move(next));
}
<|endoftext|>


<commit_before>#include <cmath>
#include <cstddef>
#include <limits>
#include <memory>
#include <type_traits>
#include <utility>
#include <gtest/gtest.h>
#include <entt/core/memory.hpp>
#include "../common/basic_test_allocator.hpp"
#include "../common/throwing_allocator.hpp"

TEST(Memory, ToAddress) {
    std::shared_ptr<int> shared = std::make_shared<int>();
    auto *plain = std::addressof(*shared);

    ASSERT_EQ(entt::to_address(shared), plain);
    ASSERT_EQ(entt::to_address(plain), plain);
}

TEST(Memory, PoccaPocmaAndPocs) {
    test::basic_test_allocator<int> lhs, rhs;
    // honestly, I don't even know how one is supposed to test such a thing :)
    entt::propagate_on_container_copy_assignment(lhs, rhs);
    entt::propagate_on_container_move_assignment(lhs, rhs);
    entt::propagate_on_container_swap(lhs, rhs);
}

TEST(Memory, IsPowerOfTwo) {
    // constexpr-ness guaranteed
    constexpr auto zero_is_power_of_two = entt::is_power_of_two(0u);

    ASSERT_FALSE(zero_is_power_of_two);
    ASSERT_TRUE(entt::is_power_of_two(1u));
    ASSERT_TRUE(entt::is_power_of_two(2u));
    ASSERT_TRUE(entt::is_power_of_two(4u));
    ASSERT_FALSE(entt::is_power_of_two(7u));
    ASSERT_TRUE(entt::is_power_of_two(128u));
    ASSERT_FALSE(entt::is_power_of_two(200u));
}

TEST(Memory, NextPowerOfTwo) {
    // constexpr-ness guaranteed
    constexpr auto next_power_of_two_of_zero = entt::next_power_of_two(0u);

    ASSERT_EQ(next_power_of_two_of_zero, 1u);
    ASSERT_EQ(entt::next_power_of_two(1u), 1u);
    ASSERT_EQ(entt::next_power_of_two(2u), 2u);
    ASSERT_EQ(entt::next_power_of_two(3u), 4u);
    ASSERT_EQ(entt::next_power_of_two(17u), 32u);
    ASSERT_EQ(entt::next_power_of_two(32u), 32u);
    ASSERT_EQ(entt::next_power_of_two(33u), 64u);
    ASSERT_EQ(entt::next_power_of_two(std::pow(2, 16)), std::pow(2, 16));
    ASSERT_EQ(entt::next_power_of_two(std::pow(2, 16) + 1u), std::pow(2, 17));
}

TEST(MemoryDeathTest, NextPowerOfTwo) {
    ASSERT_DEATH(static_cast<void>(entt::next_power_of_two((std::size_t{1u} << (std::numeric_limits<std::size_t>::digits - 1)) + 1)), "");
}

TEST(Memory, FastMod) {
    // constexpr-ness guaranteed
    constexpr auto fast_mod_of_zero = entt::fast_mod(0u, 8u);

    ASSERT_EQ(fast_mod_of_zero, 0u);
    ASSERT_EQ(entt::fast_mod(7u, 8u), 7u);
    ASSERT_EQ(entt::fast_mod(8u, 8u), 0u);
}

TEST(Memory, AllocateUnique) {
    test::throwing_allocator<double> allocator{};
    test::throwing_allocator<int>::trigger_on_allocate = true;

    ASSERT_THROW((entt::allocate_unique<int>(allocator, 0)), test::throwing_allocator<int>::exception_type);

    std::unique_ptr<int, entt::allocation_deleter<test::throwing_allocator<int>>> ptr = entt::allocate_unique<int>(allocator, 42);

    ASSERT_TRUE(ptr);
    ASSERT_EQ(*ptr, 42);

    ptr.reset();

    ASSERT_FALSE(ptr);
}
<commit_msg>test: uses-allocator construction guaranteed for allocate_unique<commit_after>#include <cmath>
#include <cstddef>
#include <limits>
#include <memory>
#include <type_traits>
#include <utility>
#include <gtest/gtest.h>
#include <entt/core/memory.hpp>
#include "../common/basic_test_allocator.hpp"
#include "../common/throwing_allocator.hpp"
#include "../common/tracked_memory_resource.hpp"

TEST(Memory, ToAddress) {
    std::shared_ptr<int> shared = std::make_shared<int>();
    auto *plain = std::addressof(*shared);

    ASSERT_EQ(entt::to_address(shared), plain);
    ASSERT_EQ(entt::to_address(plain), plain);
}

TEST(Memory, PoccaPocmaAndPocs) {
    test::basic_test_allocator<int> lhs, rhs;
    // honestly, I don't even know how one is supposed to test such a thing :)
    entt::propagate_on_container_copy_assignment(lhs, rhs);
    entt::propagate_on_container_move_assignment(lhs, rhs);
    entt::propagate_on_container_swap(lhs, rhs);
}

TEST(Memory, IsPowerOfTwo) {
    // constexpr-ness guaranteed
    constexpr auto zero_is_power_of_two = entt::is_power_of_two(0u);

    ASSERT_FALSE(zero_is_power_of_two);
    ASSERT_TRUE(entt::is_power_of_two(1u));
    ASSERT_TRUE(entt::is_power_of_two(2u));
    ASSERT_TRUE(entt::is_power_of_two(4u));
    ASSERT_FALSE(entt::is_power_of_two(7u));
    ASSERT_TRUE(entt::is_power_of_two(128u));
    ASSERT_FALSE(entt::is_power_of_two(200u));
}

TEST(Memory, NextPowerOfTwo) {
    // constexpr-ness guaranteed
    constexpr auto next_power_of_two_of_zero = entt::next_power_of_two(0u);

    ASSERT_EQ(next_power_of_two_of_zero, 1u);
    ASSERT_EQ(entt::next_power_of_two(1u), 1u);
    ASSERT_EQ(entt::next_power_of_two(2u), 2u);
    ASSERT_EQ(entt::next_power_of_two(3u), 4u);
    ASSERT_EQ(entt::next_power_of_two(17u), 32u);
    ASSERT_EQ(entt::next_power_of_two(32u), 32u);
    ASSERT_EQ(entt::next_power_of_two(33u), 64u);
    ASSERT_EQ(entt::next_power_of_two(std::pow(2, 16)), std::pow(2, 16));
    ASSERT_EQ(entt::next_power_of_two(std::pow(2, 16) + 1u), std::pow(2, 17));
}

TEST(MemoryDeathTest, NextPowerOfTwo) {
    ASSERT_DEATH(static_cast<void>(entt::next_power_of_two((std::size_t{1u} << (std::numeric_limits<std::size_t>::digits - 1)) + 1)), "");
}

TEST(Memory, FastMod) {
    // constexpr-ness guaranteed
    constexpr auto fast_mod_of_zero = entt::fast_mod(0u, 8u);

    ASSERT_EQ(fast_mod_of_zero, 0u);
    ASSERT_EQ(entt::fast_mod(7u, 8u), 7u);
    ASSERT_EQ(entt::fast_mod(8u, 8u), 0u);
}

TEST(Memory, AllocateUnique) {
    test::throwing_allocator<double> allocator{};
    test::throwing_allocator<int>::trigger_on_allocate = true;

    ASSERT_THROW((entt::allocate_unique<int>(allocator, 0)), test::throwing_allocator<int>::exception_type);

    std::unique_ptr<int, entt::allocation_deleter<test::throwing_allocator<int>>> ptr = entt::allocate_unique<int>(allocator, 42);

    ASSERT_TRUE(ptr);
    ASSERT_EQ(*ptr, 42);

    ptr.reset();

    ASSERT_FALSE(ptr);
}

#if defined(ENTT_HAS_TRACKED_MEMORY_RESOURCE)

TEST(Memory, UsesAllocatorConstruction) {
    using string_type = typename test::tracked_memory_resource::string_type;

    test::tracked_memory_resource memory_resource{};
    std::pmr::polymorphic_allocator<string_type> allocator{&memory_resource};
    const char *str = "a string long enough to force an allocation (hopefully)";

    std::unique_ptr<string_type, entt::allocation_deleter<std::pmr::polymorphic_allocator<string_type>>> ptr = entt::allocate_unique<string_type>(allocator, str);

    ASSERT_GT(memory_resource.do_allocate_counter(), 1u);
    ASSERT_EQ(memory_resource.do_deallocate_counter(), 0u);
}

#endif
<|endoftext|>


<commit_before>#include "process.hpp"
#include <iostream>
#include <vector>
#include <atomic>

using namespace std;

int main() {
  atomic<bool> stdout_error(false);
  atomic<bool> exit_status_error(false);
  vector<thread> threads;
  for(size_t ct=0;ct<4;ct++) {
    threads.emplace_back([&stdout_error, &exit_status_error, ct]() {
      for(size_t c=0;c<1000;c++) {
        Process process("echo Hello World "+std::to_string(c)+" "+std::to_string(ct), "", [&stdout_error, ct, c](const char *bytes, size_t n) {
          if(std::string(bytes, n)!="Hello World "+std::to_string(c)+" "+std::to_string(ct)+"\n")
            stdout_error=true;
        }, [](const char *bytes, size_t n) {
        }, true);
        auto exit_status=process.get_exit_status();
        if(exit_status!=0)
          exit_status_error=true;
        if(exit_status_error)
          return;
        if(stdout_error)
          return;
      }
    });
  }

  for(auto &thread: threads)
    thread.join();

  if(stdout_error) {
    cerr << "Wrong output to stdout." << endl;
    return 1;
  }
  if(exit_status_error) {
    cerr << "Process returned failure." << endl;
    return 1;
  }

  return 0;
}<commit_msg>Now runs equal number of processes in both tests for runtime comparison<commit_after>#include "process.hpp"
#include <iostream>
#include <vector>
#include <atomic>

using namespace std;

int main() {
  atomic<bool> stdout_error(false);
  atomic<bool> exit_status_error(false);
  vector<thread> threads;
  for(size_t ct=0;ct<4;ct++) {
    threads.emplace_back([&stdout_error, &exit_status_error, ct]() {
      for(size_t c=0;c<2500;c++) {
        Process process("echo Hello World "+std::to_string(c)+" "+std::to_string(ct), "", [&stdout_error, ct, c](const char *bytes, size_t n) {
          if(std::string(bytes, n)!="Hello World "+std::to_string(c)+" "+std::to_string(ct)+"\n")
            stdout_error=true;
        }, [](const char *bytes, size_t n) {
        }, true);
        auto exit_status=process.get_exit_status();
        if(exit_status!=0)
          exit_status_error=true;
        if(exit_status_error)
          return;
        if(stdout_error)
          return;
      }
    });
  }

  for(auto &thread: threads)
    thread.join();

  if(stdout_error) {
    cerr << "Wrong output to stdout." << endl;
    return 1;
  }
  if(exit_status_error) {
    cerr << "Process returned failure." << endl;
    return 1;
  }

  return 0;
}<|endoftext|>


<commit_before>// Copyright (c) 2012 Steinwurf ApS
// All Rights Reserved
//
// Distributed under the "BSD License". See the accompanying LICENSE.rst file.

#include <sak/storage.hpp>

#include <cstdint>
#include <vector>
#include <iterator>

#include <gtest/gtest.h>

template<class PodType>
void test_vector_helper(uint32_t vector_size)
{
    std::vector<PodType> v(vector_size);

    sak::const_storage cs = sak::storage(v);
    EXPECT_EQ(cs.m_size, vector_size * sizeof(PodType));
    EXPECT_EQ(sak::cast_storage<PodType>(cs), &v[0]);
    EXPECT_EQ(std::distance(cs.begin(), cs.end()), 1);

    sak::mutable_storage ms = sak::storage(v);
    EXPECT_EQ(ms.m_size, vector_size * sizeof(PodType));
    EXPECT_EQ(sak::cast_storage<PodType>(ms), &v[0]);
    EXPECT_EQ(std::distance(ms.begin(), ms.end()), 1);
}

TEST(TestStorage, test_storage_function_vector)
{
    uint32_t size = rand() % 100000;
    test_vector_helper<char>(size);
    test_vector_helper<short>(size);
    test_vector_helper<int>(size);
    test_vector_helper<uint8_t>(size);
    test_vector_helper<uint16_t>(size);
    test_vector_helper<uint32_t>(size);
    test_vector_helper<uint64_t>(size);
}

template<class PodType>
void test_buffer_helper(uint32_t vector_size)
{
    std::vector<PodType> v(vector_size);

    PodType* v_data = &v[0];
    uint32_t v_size = vector_size * sizeof(PodType);

    sak::const_storage cs = sak::storage(v_data, v_size);
    EXPECT_EQ(cs.m_size, v_size);
    EXPECT_EQ(sak::cast_storage<PodType>(cs), &v_data[0]);
    EXPECT_EQ(std::distance(cs.begin(), cs.end()), 1);

    sak::mutable_storage ms = sak::storage(v_data, v_size);
    EXPECT_EQ(ms.m_size, v_size);
    EXPECT_EQ(sak::cast_storage<PodType>(ms), &v_data[0]);
    EXPECT_EQ(std::distance(ms.begin(), ms.end()), 1);

    // Check const
    const PodType* v_data_const = v_data;

    sak::const_storage const_cs = sak::storage(v_data_const, v_size);
    EXPECT_EQ(const_cs.m_size, v_size);
    EXPECT_EQ(sak::cast_storage<PodType>(const_cs), &v_data_const[0]);
    EXPECT_EQ(std::distance(const_cs.begin(), const_cs.end()), 1);
}

TEST(TestStorage, test_storage_function_buffer)
{
    uint32_t size = rand() % 100000;
    test_buffer_helper<char>(size);
    test_buffer_helper<short>(size);
    test_buffer_helper<int>(size);
    test_buffer_helper<uint8_t>(size);
    test_buffer_helper<uint16_t>(size);
    test_buffer_helper<uint32_t>(size);
    test_buffer_helper<uint64_t>(size);
}

TEST(TestStorage, test_mutable_to_const_conversion)
{
    uint32_t size = 500;
    std::vector<uint8_t> v(size);

    sak::mutable_storage ms = sak::storage(v);
    sak::const_storage cs = ms;
    cs = ms;
}

TEST(TestStorage, test_split_storage)
{
    uint32_t size = 500;
    uint32_t split = 100;
    std::vector<uint8_t> v(size);

    auto storage = sak::storage(v);
    auto storage_sequence = sak::split_storage(storage, split);

    EXPECT_EQ(storage_sequence.size(), 5U);
    for (uint32_t i = 0; i < storage_sequence.size(); ++i)
    {
        EXPECT_EQ(storage_sequence[i].m_size, split);
    }
}

TEST(TestStorage, test_offset_storage)
{
    {
        uint32_t size = 500;
        uint32_t split = 100;
        std::vector<uint8_t> v(size);

        sak::mutable_storage old_storage = sak::storage(v);

        auto new_storage = old_storage + split;
        EXPECT_EQ(new_storage.m_size, 400U);
        EXPECT_EQ(new_storage.m_data, &v[100]);

        new_storage += 100;
        EXPECT_EQ(new_storage.m_size, 300U);
        EXPECT_EQ(new_storage.m_data, &v[200]);
    }

    {
        uint32_t size = 500;
        uint32_t split = 100;
        std::vector<uint8_t> v(size);

        sak::const_storage old_storage = sak::storage(v);

        auto new_storage = old_storage + split;
        EXPECT_EQ(new_storage.m_size, 400U);
        EXPECT_EQ(new_storage.m_data, &v[100]);

        new_storage += 100;
        EXPECT_EQ(new_storage.m_size, 300U);
        EXPECT_EQ(new_storage.m_data, &v[200]);
    }
}

TEST(TestStorage, is_equal)
{
    {
        std::vector<uint8_t> d1(10);
        std::vector<uint8_t> d2(11);

        EXPECT_FALSE(sak::is_equal(sak::storage(d1), sak::storage(d2)));
        EXPECT_TRUE(sak::is_equal(sak::storage(d1), sak::storage(d1)));
        EXPECT_TRUE(sak::is_equal(sak::storage(d2), sak::storage(d2)));
    }

    {
        std::vector<uint8_t> d1(10, 'a');
        std::vector<uint8_t> d2(10, 'b');

        EXPECT_FALSE(sak::is_equal(sak::storage(d1), sak::storage(d2)));
        EXPECT_TRUE(sak::is_equal(sak::storage(d1), sak::storage(d1)));
        EXPECT_TRUE(sak::is_equal(sak::storage(d2), sak::storage(d2)));
    }

    {
        std::vector<uint8_t> d1(10, 'a');
        std::vector<uint8_t> d2(10, 'a');

        EXPECT_TRUE(sak::is_equal(sak::storage(d1), sak::storage(d2)));
        EXPECT_TRUE(sak::is_equal(sak::storage(d1), sak::storage(d1)));
        EXPECT_TRUE(sak::is_equal(sak::storage(d2), sak::storage(d2)));
    }

    {
        std::vector<uint8_t> d1(10, 'a');
        std::vector<uint8_t> d2(9, 'a');

        EXPECT_FALSE(sak::is_equal(sak::storage(d1), sak::storage(d2)));
    }

    {
        std::vector<uint8_t> d1(10, 'a');
        auto d2 = sak::storage(d1);
        EXPECT_TRUE(sak::is_equal(sak::storage(d1), d2));
        d2 += 2;

        EXPECT_FALSE(sak::is_equal(sak::storage(d1), d2));
    }
}

TEST(TestStorage, is_same)
{
    {
        std::vector<uint8_t> d1(10);
        std::vector<uint8_t> d2(11);

        EXPECT_FALSE(sak::is_same(sak::storage(d1), sak::storage(d2)));
        EXPECT_TRUE(sak::is_same(sak::storage(d1), sak::storage(d1)));
        EXPECT_TRUE(sak::is_same(sak::storage(d2), sak::storage(d2)));
    }

    {
        std::vector<uint8_t> d1(10, 'a');
        std::vector<uint8_t> d2(10, 'b');

        EXPECT_FALSE(sak::is_same(sak::storage(d1), sak::storage(d2)));
        EXPECT_TRUE(sak::is_same(sak::storage(d1), sak::storage(d1)));
        EXPECT_TRUE(sak::is_same(sak::storage(d2), sak::storage(d2)));
    }

    {
        std::vector<uint8_t> d1(10, 'a');
        std::vector<uint8_t> d2(10, 'a');

        EXPECT_FALSE(sak::is_same(sak::storage(d1), sak::storage(d2)));
        EXPECT_TRUE(sak::is_same(sak::storage(d1), sak::storage(d1)));
        EXPECT_TRUE(sak::is_same(sak::storage(d2), sak::storage(d2)));
    }

    {
        std::vector<uint8_t> d1(10, 'a');
        std::vector<uint8_t> d2(9, 'a');

        EXPECT_FALSE(sak::is_same(sak::storage(d1), sak::storage(d2)));
    }

    {
        std::vector<uint8_t> d1(10, 'a');
        auto d2 = sak::storage(d1);
        EXPECT_TRUE(sak::is_same(sak::storage(d1), d2));
        d2 += 2;

        EXPECT_FALSE(sak::is_same(sak::storage(d1), d2));
    }
}

TEST(TestStorage, string_helper)
{
    {
        std::string str = "test";
        auto storage = sak::storage(str);
        EXPECT_EQ(storage.m_size, str.size());
        EXPECT_EQ(storage.m_data, (uint8_t*)str.c_str());
    }
}
<commit_msg>test const storage to mutable storage convertion<commit_after>// Copyright (c) 2012 Steinwurf ApS
// All Rights Reserved
//
// Distributed under the "BSD License". See the accompanying LICENSE.rst file.

#include <sak/storage.hpp>

#include <cstdint>
#include <vector>
#include <iterator>

#include <gtest/gtest.h>

template<class PodType>
void test_vector_helper(uint32_t vector_size)
{
    std::vector<PodType> v(vector_size);

    sak::const_storage cs = sak::storage(v);
    EXPECT_EQ(cs.m_size, vector_size * sizeof(PodType));
    EXPECT_EQ(sak::cast_storage<PodType>(cs), &v[0]);
    EXPECT_EQ(std::distance(cs.begin(), cs.end()), 1);

    sak::mutable_storage ms = sak::storage(v);
    EXPECT_EQ(ms.m_size, vector_size * sizeof(PodType));
    EXPECT_EQ(sak::cast_storage<PodType>(ms), &v[0]);
    EXPECT_EQ(std::distance(ms.begin(), ms.end()), 1);
}

TEST(TestStorage, test_storage_function_vector)
{
    uint32_t size = rand() % 100000;
    test_vector_helper<char>(size);
    test_vector_helper<short>(size);
    test_vector_helper<int>(size);
    test_vector_helper<uint8_t>(size);
    test_vector_helper<uint16_t>(size);
    test_vector_helper<uint32_t>(size);
    test_vector_helper<uint64_t>(size);
}

template<class PodType>
void test_buffer_helper(uint32_t vector_size)
{
    std::vector<PodType> v(vector_size);

    PodType* v_data = &v[0];
    uint32_t v_size = vector_size * sizeof(PodType);

    sak::const_storage cs = sak::storage(v_data, v_size);
    EXPECT_EQ(cs.m_size, v_size);
    EXPECT_EQ(sak::cast_storage<PodType>(cs), &v_data[0]);
    EXPECT_EQ(std::distance(cs.begin(), cs.end()), 1);

    sak::mutable_storage ms = sak::storage(v_data, v_size);
    EXPECT_EQ(ms.m_size, v_size);
    EXPECT_EQ(sak::cast_storage<PodType>(ms), &v_data[0]);
    EXPECT_EQ(std::distance(ms.begin(), ms.end()), 1);

    // Check const
    const PodType* v_data_const = v_data;

    sak::const_storage const_cs = sak::storage(v_data_const, v_size);
    EXPECT_EQ(const_cs.m_size, v_size);
    EXPECT_EQ(sak::cast_storage<PodType>(const_cs), &v_data_const[0]);
    EXPECT_EQ(std::distance(const_cs.begin(), const_cs.end()), 1);
}

TEST(TestStorage, test_storage_function_buffer)
{
    uint32_t size = rand() % 100000;
    test_buffer_helper<char>(size);
    test_buffer_helper<short>(size);
    test_buffer_helper<int>(size);
    test_buffer_helper<uint8_t>(size);
    test_buffer_helper<uint16_t>(size);
    test_buffer_helper<uint32_t>(size);
    test_buffer_helper<uint64_t>(size);
}

TEST(TestStorage, test_mutable_to_const_conversion)
{
    uint32_t size = 500;
    std::vector<uint8_t> v(size);

    sak::mutable_storage ms = sak::storage(v);
    sak::const_storage cs = ms;
    cs = ms;
}

TEST(TestStorage, test_split_storage)
{
    uint32_t size = 500;
    uint32_t split = 100;
    std::vector<uint8_t> v(size);

    auto storage = sak::storage(v);
    auto storage_sequence = sak::split_storage(storage, split);

    EXPECT_EQ(storage_sequence.size(), 5U);
    for (uint32_t i = 0; i < storage_sequence.size(); ++i)
    {
        EXPECT_EQ(storage_sequence[i].m_size, split);
    }
}

TEST(TestStorage, test_offset_storage)
{
    {
        uint32_t size = 500;
        uint32_t split = 100;
        std::vector<uint8_t> v(size);

        sak::mutable_storage old_storage = sak::storage(v);

        auto new_storage = old_storage + split;
        EXPECT_EQ(new_storage.m_size, 400U);
        EXPECT_EQ(new_storage.m_data, &v[100]);

        new_storage += 100;
        EXPECT_EQ(new_storage.m_size, 300U);
        EXPECT_EQ(new_storage.m_data, &v[200]);
    }

    {
        uint32_t size = 500;
        uint32_t split = 100;
        std::vector<uint8_t> v(size);

        sak::const_storage old_storage = sak::storage(v);

        auto new_storage = old_storage + split;
        EXPECT_EQ(new_storage.m_size, 400U);
        EXPECT_EQ(new_storage.m_data, &v[100]);

        new_storage += 100;
        EXPECT_EQ(new_storage.m_size, 300U);
        EXPECT_EQ(new_storage.m_data, &v[200]);
    }
}

TEST(TestStorage, is_equal)
{
    {
        std::vector<uint8_t> d1(10);
        std::vector<uint8_t> d2(11);

        EXPECT_FALSE(sak::is_equal(sak::storage(d1), sak::storage(d2)));
        EXPECT_TRUE(sak::is_equal(sak::storage(d1), sak::storage(d1)));
        EXPECT_TRUE(sak::is_equal(sak::storage(d2), sak::storage(d2)));
    }

    {
        std::vector<uint8_t> d1(10, 'a');
        std::vector<uint8_t> d2(10, 'b');

        EXPECT_FALSE(sak::is_equal(sak::storage(d1), sak::storage(d2)));
        EXPECT_TRUE(sak::is_equal(sak::storage(d1), sak::storage(d1)));
        EXPECT_TRUE(sak::is_equal(sak::storage(d2), sak::storage(d2)));
    }

    {
        std::vector<uint8_t> d1(10, 'a');
        std::vector<uint8_t> d2(10, 'a');

        EXPECT_TRUE(sak::is_equal(sak::storage(d1), sak::storage(d2)));
        EXPECT_TRUE(sak::is_equal(sak::storage(d1), sak::storage(d1)));
        EXPECT_TRUE(sak::is_equal(sak::storage(d2), sak::storage(d2)));
    }

    {
        std::vector<uint8_t> d1(10, 'a');
        std::vector<uint8_t> d2(9, 'a');

        EXPECT_FALSE(sak::is_equal(sak::storage(d1), sak::storage(d2)));
    }

    {
        std::vector<uint8_t> d1(10, 'a');
        auto d2 = sak::storage(d1);
        EXPECT_TRUE(sak::is_equal(sak::storage(d1), d2));
        d2 += 2;

        EXPECT_FALSE(sak::is_equal(sak::storage(d1), d2));
    }
}

TEST(TestStorage, is_same)
{
    {
        std::vector<uint8_t> d1(10);
        std::vector<uint8_t> d2(11);

        EXPECT_FALSE(sak::is_same(sak::storage(d1), sak::storage(d2)));
        EXPECT_TRUE(sak::is_same(sak::storage(d1), sak::storage(d1)));
        EXPECT_TRUE(sak::is_same(sak::storage(d2), sak::storage(d2)));
    }

    {
        std::vector<uint8_t> d1(10, 'a');
        std::vector<uint8_t> d2(10, 'b');

        EXPECT_FALSE(sak::is_same(sak::storage(d1), sak::storage(d2)));
        EXPECT_TRUE(sak::is_same(sak::storage(d1), sak::storage(d1)));
        EXPECT_TRUE(sak::is_same(sak::storage(d2), sak::storage(d2)));
    }

    {
        std::vector<uint8_t> d1(10, 'a');
        std::vector<uint8_t> d2(10, 'a');

        EXPECT_FALSE(sak::is_same(sak::storage(d1), sak::storage(d2)));
        EXPECT_TRUE(sak::is_same(sak::storage(d1), sak::storage(d1)));
        EXPECT_TRUE(sak::is_same(sak::storage(d2), sak::storage(d2)));
    }

    {
        std::vector<uint8_t> d1(10, 'a');
        std::vector<uint8_t> d2(9, 'a');

        EXPECT_FALSE(sak::is_same(sak::storage(d1), sak::storage(d2)));
    }

    {
        std::vector<uint8_t> d1(10, 'a');
        auto d2 = sak::storage(d1);
        EXPECT_TRUE(sak::is_same(sak::storage(d1), d2));
        d2 += 2;

        EXPECT_FALSE(sak::is_same(sak::storage(d1), d2));
    }
}

TEST(TestStorage, string_helper)
{
    {
        std::string str = "test";
        auto storage = sak::storage(str);
        EXPECT_EQ(str.size(), storage.m_size);
        EXPECT_EQ((uint8_t*)str.c_str(), storage.m_data);
    }
    {
        // Test that we are able to take a mutable storage as a const storage.
        auto size_of_const_storage = [](sak::const_storage storage)
        {
            return storage.m_size;
        };
        std::string str = "test";
        sak::const_storage storage = sak::storage(str);
        EXPECT_EQ(str.size(), size_of_const_storage(storage));
    }
}
<|endoftext|>