<commit_before>/*
 * grid_maintenance.c
 *
 *  Created on: Oct 12, 2011
 *      Author: bmetcalf
 */

#include <slsimlib.h>

/** \ingroup Constructor
 * \brief Constructor for initializing grid.
 *
 * Note: Deflection solver must be specified before creating a Grid.
 */
Grid::Grid(
		LensHndl lens      /// lens model for initializing grid
		,int N1d           /// Initial number of grid points in each dimension.
		,double center[2]  /// Center of grid.
		,double range      /// Full width of grid in whatever units will be used.
		 ){

	Point *i_points,*s_points;

	assert(N1d > 0);
	assert(range > 0);

	if(N1d <= 0){ERROR_MESSAGE(); std::cout << "cannot make Grid with no points" << std::endl; exit(1);}
	if(range <= 0){ERROR_MESSAGE(); std::cout << "cannot make Grid with no range" << std::endl; exit(1);}

	Ngrid_init = N1d;
	Ngrid_block = 3;  // never been tested with anything other than 3

	i_points = NewPointArray(Ngrid_init*Ngrid_init,true);
	xygridpoints(i_points,range,center,Ngrid_init,0);
	s_points=LinkToSourcePoints(i_points,Ngrid_init*Ngrid_init);
	lens->rayshooterInternal(Ngrid_init*Ngrid_init,i_points,false);
	// Build trees
	i_tree = BuildTree(i_points,Ngrid_init*Ngrid_init);
	s_tree = BuildTree(s_points,Ngrid_init*Ngrid_init);  // make tree on source plane a area splitting tree

	trashkist = new Kist;
}

/*
GridHndl NewGrid(LensHndl lens, int Ngrid,double center[2],double range){
	GridHndl grid = (Grid *)malloc(sizeof(Grid));
	Point *i_points,*s_points;

	grid->Ngrid = Ngrid;

	i_points = NewPointArray(Ngrid*Ngrid,true);
	xygridpoints(i_points,range,center,Ngrid,0);
	s_points=LinkToSourcePoints(i_points,Ngrid*Ngrid);
	lens->rayshooterInternal(Ngrid*Ngrid,i_points,false);
	// Build trees
	grid->i_tree = BuildTree(i_points,Ngrid*Ngrid);
	grid->s_tree = BuildTree(s_points,Ngrid*Ngrid);

	return grid;
}
*/

/** \ingroup Constructor
 * \brief Destructor for a Grid.  Frees all memory.
 */
Grid::~Grid(){
	freeTree(i_tree);
	freeTree(s_tree);

	delete trashkist;

	return;
}

/** \ingroup ImageFinding
 *  \brief Reinitializes the grid so that it is back to the original coarse grid, but if
 *  the lens has changed the source positions will be updated.
 */
void Grid::ReInitializeGrid(LensHndl lens){

	Point *i_points,*s_points;
	double range,center[2];
	unsigned long i;

	range = i_tree->top->boundary_p2[0] - i_tree->top->boundary_p1[0];
	center[0] = (i_tree->top->boundary_p2[0] + i_tree->top->boundary_p1[0])/2;
	center[1] = (i_tree->top->boundary_p2[1] + i_tree->top->boundary_p1[1])/2;

	//////////////////////////////
	  // redo grid with stars in it
	  // free old tree to speed up image finding
	emptyTree(i_tree);
	emptyTree(s_tree);

	// build new initial grid
	i_points = NewPointArray(Ngrid_init*Ngrid_init,true);
	xygridpoints(i_points,range,center,Ngrid_init,0);
	s_points=LinkToSourcePoints(i_points,Ngrid_init*Ngrid_init);
	lens->rayshooterInternal(Ngrid_init*Ngrid_init,i_points,false);

	// need to resize root of source tree.  It can change in size
	s_tree->top->boundary_p1[0]=s_points[0].x[0]; s_tree->top->boundary_p1[1]=s_points[0].x[1];
	s_tree->top->boundary_p2[0]=s_points[0].x[0]; s_tree->top->boundary_p2[1]=s_points[0].x[1];

	for(i=0;i<Ngrid_init*Ngrid_init;++i){

	    /* find X boundary */
		if(s_points[i].x[0] < s_tree->top->boundary_p1[0] ) s_tree->top->boundary_p1[0]=s_points[i].x[0];
	    if(s_points[i].x[0] > s_tree->top->boundary_p2[0] ) s_tree->top->boundary_p2[0]=s_points[i].x[0];

	    /* find Y boundary */
	    if(s_points[i].x[1] < s_tree->top->boundary_p1[1] ) s_tree->top->boundary_p1[1]=s_points[i].x[1];
	    if(s_points[i].x[1] > s_tree->top->boundary_p2[1] ) s_tree->top->boundary_p2[1]=s_points[i].x[1];
	  }

	  // a little extra room for future points
	  s_tree->top->boundary_p1[0] -=  range/Ngrid_init;
	  s_tree->top->boundary_p1[1] -=  range/Ngrid_init;
	  s_tree->top->boundary_p2[0] +=  range/Ngrid_init;
	  s_tree->top->boundary_p2[1] +=  range/Ngrid_init;

	  s_tree->top->center[0] = (s_tree->top->boundary_p1[0]+s_tree->top->boundary_p2[0])/2;
	  s_tree->top->center[1] = (s_tree->top->boundary_p1[1]+s_tree->top->boundary_p2[1])/2;

	// fill trees
	FillTree(i_tree,i_points,Ngrid_init*Ngrid_init);
	FillTree(s_tree,s_points,Ngrid_init*Ngrid_init);

	return;
}

/** \ingroup ImageFinding
 *
 * \brief DOES NOT WORK YET !!!!
 */

/** \ingroup ImageFinding
 * \brief Recalculate surface brightness at every point without changing the positions of the grid or any lens properties.
 *
 *  Recalculate the surface brightness at all points on the grid.
 * This is useful when changing the source model while preserving
 * changes in the grid.
 * Both i_tree and s_tree are both changed although only s_tree shows up here.
 *
 * returns the sum of the surface brightnesses
 */
double Grid::RefreshSurfaceBrightnesses(SourceHndl source){
	double y[2],total=0,tmp;

	MoveToTopList(s_tree->pointlist);
	for(unsigned long i=0;i<s_tree->pointlist->Npoints;++i,MoveDownList(s_tree->pointlist)){
		//y[0] = s_tree->pointlist->current->x[0]; - source->getX()[0];
		//y[1] = s_tree->pointlist->current->x[1]; - source->getX()[1];
		tmp = source->SurfaceBrightness(s_tree->pointlist->current->x);
		s_tree->pointlist->current->surface_brightness = s_tree->pointlist->current->image->surface_brightness
				= tmp;
		total += tmp;//*pow( s_tree->pointlist->current->gridsize,2);
		assert(s_tree->pointlist->current->surface_brightness >= 0.0);
		s_tree->pointlist->current->in_image = s_tree->pointlist->current->image->in_image
				= FALSE;
	}

	return total;
}

/** \ingroup ImageFinding
 * \brief Returns number of points on image plane.
 */
unsigned long Grid::getNumberOfPoints(){
	assert(i_tree->top->npoints == s_tree->top->npoints);
	assert(i_tree->top->npoints == i_tree->pointlist->Npoints);
	assert(s_tree->top->npoints == s_tree->pointlist->Npoints);

	return i_tree->top->npoints;
}

/**  \ingroup ImageFindingL2
 *
 * \brief Fundamental function used to divide a leaf in the tree into nine subcells.
 *
 * Source and image points are created, linked, shot and added to the trees.  The leaf
 * pointers of the points including the input are assigned.
 *
 * If some of the of the points are outside the original grid they will not be added in
 * which case THERE WILL BE LESS THEN Ngrid*Ngrid-1 points added.  The true number will
 * always be result->head.
 *
 * Returns a pointer to the list of image points that have been added.  This array can then be
 * used for calculating the surface brightness or marking them as in the image.
 */

Point * Grid::RefineLeaf(LensHndl lens,Point *point,bool kappa_off){
	//Point * RefineLeaf(LensHndl lens,TreeHndl i_tree,TreeHndl s_tree,Point *point,int Ngrid,bool kappa_off){

	Point *i_points = NewPointArray(Ngrid_block*Ngrid_block-1,true);
	Point *s_points;
	int Nout,kk;

	assert(point->leaf->child1 == NULL && point->leaf->child2 == NULL);
	assert(point->gridsize > pow(10.,-DBL_DIG) ); // If cells are too small they will cause problems.

	point->leaf->refined = true;
	xygridpoints(i_points,point->gridsize*(Ngrid_block-1)/Ngrid_block
	      ,point->x,Ngrid_block,1);
	point->gridsize /= Ngrid_block;
	point->image->gridsize /= Ngrid_block;

	// take out points that are outside of original grid
	Nout = 0;
	if( (point->x[0] == i_tree->top->boundary_p1[0]) || (point->x[0] == i_tree->top->boundary_p2[0])
			|| (point->x[1] == i_tree->top->boundary_p1[1]) || (point->x[1] == i_tree->top->boundary_p2[1]) ){

		  // remove the points that are outside initial image grid
		  for(kk=0,Nout=0;kk < (Ngrid_block*Ngrid_block-1);++kk){
			  if( !inbox(i_points[kk - Nout].x,i_tree->top->boundary_p1,i_tree->top->boundary_p2) ){
				  SwapPointsInArray(&i_points[kk - Nout],&i_points[Ngrid_block*Ngrid_block - 2 - Nout]);
				  ++Nout;
			  }
		  }
		  assert(Nout > 0);
	}

	//if(Nout > 0) i_points = AddPointToArray(i_points,Ngrid_block*Ngrid_block-1-Nout,Ngrid_block*Ngrid_block-1);

	int  Ntemp = Ngrid_block*Ngrid_block-1-Nout;

	s_points = LinkToSourcePoints(i_points,Ntemp);
	lens->rayshooterInternal(Ntemp,i_points,kappa_off);

	// remove the points that are outside initial source grid
	for(kk=0,Nout=0;kk < Ntemp;++kk){
		assert(s_points[kk - Nout].x[0] == s_points[kk - Nout].x[0]);
		if( !inbox(s_points[kk - Nout].x,s_tree->top->boundary_p1,s_tree->top->boundary_p2) ){
			SwapPointsInArray(&i_points[kk - Nout],&i_points[Ntemp - 1 - Nout]);
			SwapPointsInArray(&s_points[kk - Nout],&s_points[Ntemp - 1 - Nout]);
			++Nout;
		}
	}

	assert(i_points->head == Ngrid_block*Ngrid_block-1);
	assert(s_points->head == Ntemp);

	// free memory of points that where outside image and source regions
	Nout = Ngrid_block*Ngrid_block - 1 - Ntemp + Nout;
	if(Nout > 0){
		//i_points = AddPointToArray(i_points,Ngrid_block*Ngrid_block-1-Nout,Ngrid_block*Ngrid_block-1);
		//s_points = AddPointToArray(s_points,Ngrid_block*Ngrid_block-1-Nout,Ntemp);

		i_points = AddPointToArray(i_points,Ngrid_block*Ngrid_block-1-Nout,i_points->head);
		s_points = AddPointToArray(s_points,Ngrid_block*Ngrid_block-1-Nout,s_points->head);
	}
	assert(i_points->head == s_points->head);

	//*** these could be mode more efficient by starting at the current in tree
	AddPointsToTree(i_tree,i_points,i_points->head);
	AddPointsToTree(s_tree,s_points,s_points->head);

	//AddPointsToTree(i_tree,i_points,Ngrid_block*Ngrid_block-1-Nout);
	//AddPointsToTree(s_tree,s_points,Ngrid_block*Ngrid_block-1-Nout);

	// re-assign leaf of point that was to be refined
	assert(inbox(point->x,i_tree->top->boundary_p1,i_tree->top->boundary_p2));
	i_tree->current = point->leaf;
	_FindLeaf(i_tree,point->x,0);
	point->leaf = i_tree->current;

	assert(inbox(point->image->x,s_tree->top->boundary_p1,s_tree->top->boundary_p2));
	s_tree->current = point->image->leaf;
	_FindLeaf(s_tree,point->image->x,0);
	point->image->leaf = s_tree->current;

	assert(point->leaf->child1 == NULL && point->leaf->child2 == NULL);

	return i_points;
}

<commit_msg>Test lines<commit_after>/*
 * grid_maintenance.c
 *
 *  Created on: Oct 12, 2011
 *      Author: bmetcalf
 */

#include <slsimlib.h>

/** \ingroup Constructor
 * \brief Constructor for initializing grid.
 *
 * Note: Deflection solver must be specified before creating a Grid.
 */
Grid::Grid(
		LensHndl lens      /// lens model for initializing grid
		,int N1d           /// Initial number of grid points in each dimension.
		,double center[2]  /// Center of grid.
		,double range      /// Full width of grid in whatever units will be used.
		 ){

	Point *i_points,*s_points;

	assert(N1d > 0);
	assert(range > 0);

	if(N1d <= 0){ERROR_MESSAGE(); std::cout << "cannot make Grid with no points" << std::endl; exit(1);}
	if(range <= 0){ERROR_MESSAGE(); std::cout << "cannot make Grid with no range" << std::endl; exit(1);}

	Ngrid_init = N1d;
	Ngrid_block = 3;  // never been tested with anything other than 3

	i_points = NewPointArray(Ngrid_init*Ngrid_init,true);
	xygridpoints(i_points,range,center,Ngrid_init,0);
	s_points=LinkToSourcePoints(i_points,Ngrid_init*Ngrid_init);
	lens->rayshooterInternal(Ngrid_init*Ngrid_init,i_points,false);
	// Build trees
	i_tree = BuildTree(i_points,Ngrid_init*Ngrid_init);
	s_tree = BuildTree(s_points,Ngrid_init*Ngrid_init);  // make tree on source plane a area splitting tree

	trashkist = new Kist;
}

/*
GridHndl NewGrid(LensHndl lens, int Ngrid,double center[2],double range){
	GridHndl grid = (Grid *)malloc(sizeof(Grid));
	Point *i_points,*s_points;

	grid->Ngrid = Ngrid;

	i_points = NewPointArray(Ngrid*Ngrid,true);
	xygridpoints(i_points,range,center,Ngrid,0);
	s_points=LinkToSourcePoints(i_points,Ngrid*Ngrid);
	lens->rayshooterInternal(Ngrid*Ngrid,i_points,false);
	// Build trees
	grid->i_tree = BuildTree(i_points,Ngrid*Ngrid);
	grid->s_tree = BuildTree(s_points,Ngrid*Ngrid);

	return grid;
}
*/

/** \ingroup Constructor
 * \brief Destructor for a Grid.  Frees all memory.
 */
Grid::~Grid(){
	freeTree(i_tree);
	freeTree(s_tree);

	delete trashkist;

	return;
}

/** \ingroup ImageFinding
 *  \brief Reinitializes the grid so that it is back to the original coarse grid, but if
 *  the lens has changed the source positions will be updated.
 */
void Grid::ReInitializeGrid(LensHndl lens){

	Point *i_points,*s_points;
	double range,center[2];
	unsigned long i;

	range = i_tree->top->boundary_p2[0] - i_tree->top->boundary_p1[0];
	center[0] = (i_tree->top->boundary_p2[0] + i_tree->top->boundary_p1[0])/2;
	center[1] = (i_tree->top->boundary_p2[1] + i_tree->top->boundary_p1[1])/2;

	//////////////////////////////
	  // redo grid with stars in it
	  // free old tree to speed up image finding
	emptyTree(i_tree);
	emptyTree(s_tree);

	// build new initial grid
	i_points = NewPointArray(Ngrid_init*Ngrid_init,true);
	xygridpoints(i_points,range,center,Ngrid_init,0);
	s_points=LinkToSourcePoints(i_points,Ngrid_init*Ngrid_init);
	lens->rayshooterInternal(Ngrid_init*Ngrid_init,i_points,false);

	// need to resize root of source tree.  It can change in size
	s_tree->top->boundary_p1[0]=s_points[0].x[0]; s_tree->top->boundary_p1[1]=s_points[0].x[1];
	s_tree->top->boundary_p2[0]=s_points[0].x[0]; s_tree->top->boundary_p2[1]=s_points[0].x[1];

	for(i=0;i<Ngrid_init*Ngrid_init;++i){

	    /* find X boundary */
		if(s_points[i].x[0] < s_tree->top->boundary_p1[0] ) s_tree->top->boundary_p1[0]=s_points[i].x[0];
	    if(s_points[i].x[0] > s_tree->top->boundary_p2[0] ) s_tree->top->boundary_p2[0]=s_points[i].x[0];

	    /* find Y boundary */
	    if(s_points[i].x[1] < s_tree->top->boundary_p1[1] ) s_tree->top->boundary_p1[1]=s_points[i].x[1];
	    if(s_points[i].x[1] > s_tree->top->boundary_p2[1] ) s_tree->top->boundary_p2[1]=s_points[i].x[1];
	  }

	  // a little extra room for future points
	  s_tree->top->boundary_p1[0] -=  range/Ngrid_init;
	  s_tree->top->boundary_p1[1] -=  range/Ngrid_init;
	  s_tree->top->boundary_p2[0] +=  range/Ngrid_init;
	  s_tree->top->boundary_p2[1] +=  range/Ngrid_init;

	  s_tree->top->center[0] = (s_tree->top->boundary_p1[0]+s_tree->top->boundary_p2[0])/2;
	  s_tree->top->center[1] = (s_tree->top->boundary_p1[1]+s_tree->top->boundary_p2[1])/2;

	// fill trees
	FillTree(i_tree,i_points,Ngrid_init*Ngrid_init);
	FillTree(s_tree,s_points,Ngrid_init*Ngrid_init);

	return;
}

/** \ingroup ImageFinding
 *
 * \brief DOES NOT WORK YET !!!!
 */

/** \ingroup ImageFinding
 * \brief Recalculate surface brightness at every point without changing the positions of the grid or any lens properties.
 *
 *  Recalculate the surface brightness at all points on the grid.
 * This is useful when changing the source model while preserving
 * changes in the grid.
 * Both i_tree and s_tree are both changed although only s_tree shows up here.
 *
 * returns the sum of the surface brightnesses
 */
double Grid::RefreshSurfaceBrightnesses(SourceHndl source){
	double y[2],total=0,tmp;

	MoveToTopList(s_tree->pointlist);
	for(unsigned long i=0;i<s_tree->pointlist->Npoints;++i,MoveDownList(s_tree->pointlist)){
		//y[0] = s_tree->pointlist->current->x[0]; - source->getX()[0];
		//y[1] = s_tree->pointlist->current->x[1]; - source->getX()[1];
		tmp = source->SurfaceBrightness(s_tree->pointlist->current->x);
		s_tree->pointlist->current->surface_brightness = s_tree->pointlist->current->image->surface_brightness
				= tmp;
		total += tmp;//*pow( s_tree->pointlist->current->gridsize,2);
		assert(s_tree->pointlist->current->surface_brightness >= 0.0);
		s_tree->pointlist->current->in_image = s_tree->pointlist->current->image->in_image
				= FALSE;
	}

	return total;
}

/** \ingroup ImageFinding
 * \brief Returns number of points on image plane.
 */
unsigned long Grid::getNumberOfPoints(){
	assert(i_tree->top->npoints == s_tree->top->npoints);
	assert(i_tree->top->npoints == i_tree->pointlist->Npoints);
	assert(s_tree->top->npoints == s_tree->pointlist->Npoints);

	return i_tree->top->npoints;
}

/**  \ingroup ImageFindingL2
 *
 * \brief Fundamental function used to divide a leaf in the tree into nine subcells.
 *
 * Source and image points are created, linked, shot and added to the trees.  The leaf
 * pointers of the points including the input are assigned.
 *
 * If some of the of the points are outside the original grid they will not be added in
 * which case THERE WILL BE LESS THEN Ngrid*Ngrid-1 points added.  The true number will
 * always be result->head.
 *
 * Returns a pointer to the list of image points that have been added.  This array can then be
 * used for calculating the surface brightness or marking them as in the image.
 */

Point * Grid::RefineLeaf(LensHndl lens,Point *point,bool kappa_off){
	//Point * RefineLeaf(LensHndl lens,TreeHndl i_tree,TreeHndl s_tree,Point *point,int Ngrid,bool kappa_off){

	Point *i_points = NewPointArray(Ngrid_block*Ngrid_block-1,true);
	Point *s_points;
	int Nout,kk;

	assert(point->leaf->child1 == NULL && point->leaf->child2 == NULL);
	assert(point->gridsize > pow(10.,-DBL_DIG) ); // If cells are too small they will cause problems.

	point->leaf->refined = true;
	xygridpoints(i_points,point->gridsize*(Ngrid_block-1)/Ngrid_block
	      ,point->x,Ngrid_block,1);
	point->gridsize /= Ngrid_block;
	point->image->gridsize /= Ngrid_block;

	// take out points that are outside of original grid
	Nout = 0;
	if( (point->x[0] == i_tree->top->boundary_p1[0]) || (point->x[0] == i_tree->top->boundary_p2[0])
			|| (point->x[1] == i_tree->top->boundary_p1[1]) || (point->x[1] == i_tree->top->boundary_p2[1]) ){

		  // remove the points that are outside initial image grid
		  for(kk=0,Nout=0;kk < (Ngrid_block*Ngrid_block-1);++kk){
			  if( !inbox(i_points[kk - Nout].x,i_tree->top->boundary_p1,i_tree->top->boundary_p2) ){
				  SwapPointsInArray(&i_points[kk - Nout],&i_points[Ngrid_block*Ngrid_block - 2 - Nout]);
				  ++Nout;
			  }
		  }
		  assert(Nout > 0);
	}

	//if(Nout > 0) i_points = AddPointToArray(i_points,Ngrid_block*Ngrid_block-1-Nout,Ngrid_block*Ngrid_block-1);

	int  Ntemp = Ngrid_block*Ngrid_block-1-Nout;

	s_points = LinkToSourcePoints(i_points,Ntemp);
	lens->rayshooterInternal(Ntemp,i_points,kappa_off);

	// remove the points that are outside initial source grid
	for(kk=0,Nout=0;kk < Ntemp;++kk){
		assert(s_points[kk - Nout].x[0] == s_points[kk - Nout].x[0]);
		if( !inbox(s_points[kk - Nout].x,s_tree->top->boundary_p1,s_tree->top->boundary_p2) ){
			SwapPointsInArray(&i_points[kk - Nout],&i_points[Ntemp - 1 - Nout]);
			SwapPointsInArray(&s_points[kk - Nout],&s_points[Ntemp - 1 - Nout]);
			++Nout;
		}
	}

	assert(i_points->head == Ngrid_block*Ngrid_block-1);
	assert(s_points->head == Ntemp);

	// free memory of points that where outside image and source regions
	Nout = Ngrid_block*Ngrid_block - 1 - Ntemp + Nout;
	if(Nout > 0){
		//i_points = AddPointToArray(i_points,Ngrid_block*Ngrid_block-1-Nout,Ngrid_block*Ngrid_block-1);
		//s_points = AddPointToArray(s_points,Ngrid_block*Ngrid_block-1-Nout,Ntemp);

		i_points = AddPointToArray(i_points,Ngrid_block*Ngrid_block-1-Nout,i_points->head);
		s_points = AddPointToArray(s_points,Ngrid_block*Ngrid_block-1-Nout,s_points->head);
	}
	assert(i_points->head == s_points->head);

	//*** these could be mode more efficient by starting at the current in tree
	//TODO test line
	std::cout << "adding i_points to tree" << std::endl;
	AddPointsToTree(i_tree,i_points,i_points->head);
	std::cout << "adding s_points to tree" << std::endl;
	AddPointsToTree(s_tree,s_points,s_points->head);

	//AddPointsToTree(i_tree,i_points,Ngrid_block*Ngrid_block-1-Nout);
	//AddPointsToTree(s_tree,s_points,Ngrid_block*Ngrid_block-1-Nout);

	// re-assign leaf of point that was to be refined
	assert(inbox(point->x,i_tree->top->boundary_p1,i_tree->top->boundary_p2));
	i_tree->current = point->leaf;
	std::cout << "reassigning leaf for i_point" << std::endl;
	_FindLeaf(i_tree,point->x,0);
	point->leaf = i_tree->current;

	assert(inbox(point->image->x,s_tree->top->boundary_p1,s_tree->top->boundary_p2));
	s_tree->current = point->image->leaf;
	std::cout << "reassigning leaf for s_point" << std::endl;
	_FindLeaf(s_tree,point->image->x,0);
	point->image->leaf = s_tree->current;

	assert(point->leaf->child1 == NULL && point->leaf->child2 == NULL);

	std::cout << "" << std::endl;
	return i_points;
}

<|endoftext|>


<commit_before>/* This file is part of VoltDB.
 * Copyright (C) 2008-2015 VoltDB 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 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 "ConnectionPool.h"
#include <cassert>
#include <exception>
#include <iostream>
#include <boost/scoped_ptr.hpp>
#include <cstdio>
#include "InvocationResponse.hpp"
#include "ClientConfig.h"

namespace voltdb {

/*
 * Global connection pool instance that is intialized when the library is loaded and deleted on unload
 */
static ConnectionPool *gPool;

/*
 * A delegating listener that forwards to another listener that can be NULL. It is also possible to change
 * the listener being delegated to on the fly.
 */
class DelegatingStatusListener : public StatusListener {
public:
    StatusListener *m_listener;
    bool m_connectionLost;

    DelegatingStatusListener() : m_listener(NULL), m_connectionLost(false) {}

    bool uncaughtException(
            std::exception exception,
            boost::shared_ptr<voltdb::ProcedureCallback> callback,
            InvocationResponse response) {
        if (m_listener != NULL) {
            return m_listener->uncaughtException(exception, callback, response);
        }
        return false;
    }
    bool connectionLost(std::string hostname, int32_t connectionsLeft) {
        m_connectionLost = true;
        if (m_listener != NULL) {
            bool retval = m_listener->connectionLost(hostname, connectionsLeft);
            return retval;
        }
        return false;
    }
    bool connectionActive(std::string hostname, int32_t connectionsActive) {
        if (m_listener != NULL) {
            bool retval = m_listener->connectionActive(hostname, connectionsActive);
            return retval;
        } else {
            return false;
        }
    }

    bool backpressure(bool hasBackpressure) {
        if (m_listener != NULL) {
            return m_listener->backpressure(hasBackpressure);
        }
        return false;
    }
};

/*
 * A record for information associated with a client such as the delegating listener
 * and identifier. This can be used to return the client to the ClientMap after a script exits.
 */
class ClientStuff {
public:
    ClientStuff(
            voltdb::Client client,
            std::string identifier,
            DelegatingStatusListener *listener) :
    m_identifier(identifier), m_listener(listener), m_client(client)
    {}
    std::string m_identifier;
    DelegatingStatusListener *m_listener;
    voltdb::Client m_client;
};

/*
 * Short hand for an exception safe lock acquisition
 */
class LockGuard {
public:
    LockGuard(pthread_mutex_t &mutex) {
        m_mutex = &mutex;
        pthread_mutex_lock(m_mutex);
    }
    ~LockGuard() {
        pthread_mutex_unlock(m_mutex);
    }
private:
    pthread_mutex_t *m_mutex;
};

/*
 * Cleanup function used by thread local ptr to a list of clients
 * that were borrowed from the pool. It unsets the listener and returns the client
 * to the pool.
 */
void cleanupOnScriptEnd(void *ptr) {
    if (gPool != NULL) {
        LockGuard guard(gPool->m_lock);
        ClientSet *clients = reinterpret_cast<ClientSet*>(ptr);
        if (clients != NULL) {
            boost::scoped_ptr<ClientSet> guard(clients);
            for(ClientSet::iterator i = clients->begin(); i != clients->end(); i++) {
                (*i)->m_listener->m_listener = NULL;
                gPool->m_clients[(*i)->m_identifier].push_back(*i);
            }
            pthread_setspecific(gPool->m_borrowedClients, NULL);
        }
    }
}

ConnectionPool::ConnectionPool() {
    pthread_mutex_init(&m_lock, NULL);
    pthread_key_create(&m_borrowedClients, &cleanupOnScriptEnd);
}

/*
 * Destructor specifically deletes the thread local pointer because the cleanup method
 * needs acess to the members of ConnectionPool.
 */
ConnectionPool::~ConnectionPool() {
    pthread_mutex_destroy(&m_lock);
    pthread_key_delete(m_borrowedClients);
}

/*
 * Retrieve a client that is connected and authenticated
 * to the specified hostname and port. Will reuse an existing connection if one is available.
 */
voltdb::Client
ConnectionPool::acquireClient(
        std::string hostname,
        std::string username,
        std::string password,
        StatusListener *listener,
        unsigned short port,
        ClientAuthHashScheme sha)
throw (voltdb::Exception, voltdb::ConnectException, voltdb::LibEventException) {
    LockGuard guard(m_lock);
    ClientSet *clients = reinterpret_cast<ClientSet*>(pthread_getspecific(m_borrowedClients));
    if (clients == NULL) {
        clients = new ClientSet();
        pthread_setspecific( m_borrowedClients, static_cast<const void *>(clients));
    }
    char portBytes[16];
    unsigned int portInt = port;
    snprintf(portBytes, 16, "%d", portInt);
    std::string identifier = hostname + "," + std::string(portBytes) + "," + username + "," + password;

    // if a thread calls acquireClient() multiple times with the same identifier, reuse the same client
    for (ClientSet::iterator i = clients->begin(); i != clients->end(); i++) {
        if ((*i)->m_identifier == identifier) {
            return (*i)->m_client;
        }
    }

    std::vector<boost::shared_ptr<ClientStuff> > *clientStuffs = &m_clients[identifier];

    while (clientStuffs->size() > 0) {
        boost::shared_ptr<ClientStuff> clientStuff = clientStuffs->back();
        clientStuffs->pop_back();

        // run the event loop once to verify the connection is still available
        clientStuff->m_client.runOnce();

        if (clientStuff->m_listener->m_connectionLost) {
            // if this connection is lost, try the next
            continue;
        } else {
            // otherwise return this connection
            clientStuff->m_listener->m_listener = listener;
            clients->push_back(clientStuff);
            return clientStuff->m_client;
        }
    }

    // no connection available, make a new one
    DelegatingStatusListener *delegatingListener = new DelegatingStatusListener();
    Client client = voltdb::Client::create(ClientConfig( username, password, delegatingListener, sha));
    client.createConnection(hostname, port);
    boost::shared_ptr<ClientStuff> stuff(new ClientStuff(client, identifier, delegatingListener));
    stuff->m_listener->m_listener = listener;
    clients->push_back(stuff);
    return client;
}

voltdb::Client
ConnectionPool::acquireClient(
        std::string hostname,
        std::string username,
        std::string password,
        unsigned short port,
        ClientAuthHashScheme sha)
throw (voltdb::Exception, voltdb::ConnectException, voltdb::LibEventException) {
    return acquireClient(hostname, username, password, NULL, port, sha);
}

void ConnectionPool::returnClient(Client client) throw (voltdb::Exception) {
    LockGuard guard(m_lock);
    ClientSet *clients = reinterpret_cast<ClientSet*>(pthread_getspecific(m_borrowedClients));
    if (clients == NULL) {
        throw MisplacedClientException();
    }

    for (ClientSet::iterator i = clients->begin(); i != clients->end(); i++) {
        if ((*i)->m_client == client) {
            (*i)->m_listener->m_listener = NULL;
            m_clients[(*i)->m_identifier].push_back(*i);
            clients->erase(i);
            return;
        }
    }

    throw MisplacedClientException();
}

void ConnectionPool::closeClientConnection(Client client) throw (voltdb::Exception) {
    LockGuard guard(m_lock);
    ClientSet *clients = reinterpret_cast<ClientSet*>(pthread_getspecific(m_borrowedClients));
    if (clients == NULL) {
        throw MisplacedClientException();
    }

    for (ClientSet::iterator i = clients->begin(); i != clients->end(); i++) {
        if ((*i)->m_client == client) {
            client.close();
            (*i)->m_listener->m_listener = NULL;
            clients->erase(i);
            return;
        }
    }
}

/*
 * Return the number of clients held by this thread
 */
int ConnectionPool::numClientsBorrowed() {
    ClientSet *clients = reinterpret_cast<ClientSet*>(pthread_getspecific(m_borrowedClients));
    if (clients != NULL) {
        return clients->size();
    }
    return 0;
}

/*
 * Release any unreleased clients associated with this thread/script
 */
void ConnectionPool::onScriptEnd() {
    cleanupOnScriptEnd(pthread_getspecific(m_borrowedClients));
}

/*
 * Invoked by the external language/script environment when the library is loaded.
 * Creates the connection pool
 */
void onLoad() {
    assert(gPool == NULL);
    gPool = new ConnectionPool();
}

/*
 * Invoked by the external language/script environment when the library is unloaded.
 * Deletes the connection pool closing all connections. Does not drain connections.
 */
void onUnload() {
    assert(gPool != NULL);
    delete gPool;
    gPool = NULL;
}

/*
 * Invoked by the external language/script environment when a script ends. Causes
 * all connections acquired by this thread to be returned.
 */
void onScriptEnd() {
    assert(gPool != NULL);
    gPool->onScriptEnd();
}

voltdb::ConnectionPool* ConnectionPool::pool() {
    assert(gPool != NULL);
    return gPool;
}

}
<commit_msg>handle no object case.<commit_after>/* This file is part of VoltDB.
 * Copyright (C) 2008-2015 VoltDB 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 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 "ConnectionPool.h"
#include <cassert>
#include <exception>
#include <iostream>
#include <boost/scoped_ptr.hpp>
#include <cstdio>
#include "InvocationResponse.hpp"
#include "ClientConfig.h"

namespace voltdb {

/*
 * Global connection pool instance that is intialized when the library is loaded and deleted on unload
 */
static ConnectionPool *gPool;

/*
 * A delegating listener that forwards to another listener that can be NULL. It is also possible to change
 * the listener being delegated to on the fly.
 */
class DelegatingStatusListener : public StatusListener {
public:
    StatusListener *m_listener;
    bool m_connectionLost;

    DelegatingStatusListener() : m_listener(NULL), m_connectionLost(false) {}

    bool uncaughtException(
            std::exception exception,
            boost::shared_ptr<voltdb::ProcedureCallback> callback,
            InvocationResponse response) {
        if (m_listener != NULL) {
            return m_listener->uncaughtException(exception, callback, response);
        }
        return false;
    }
    bool connectionLost(std::string hostname, int32_t connectionsLeft) {
        m_connectionLost = true;
        if (m_listener != NULL) {
            bool retval = m_listener->connectionLost(hostname, connectionsLeft);
            return retval;
        }
        return false;
    }
    bool connectionActive(std::string hostname, int32_t connectionsActive) {
        if (m_listener != NULL) {
            bool retval = m_listener->connectionActive(hostname, connectionsActive);
            return retval;
        } else {
            return false;
        }
    }

    bool backpressure(bool hasBackpressure) {
        if (m_listener != NULL) {
            return m_listener->backpressure(hasBackpressure);
        }
        return false;
    }
};

/*
 * A record for information associated with a client such as the delegating listener
 * and identifier. This can be used to return the client to the ClientMap after a script exits.
 */
class ClientStuff {
public:
    ClientStuff(
            voltdb::Client client,
            std::string identifier,
            DelegatingStatusListener *listener) :
    m_identifier(identifier), m_listener(listener), m_client(client)
    {}
    std::string m_identifier;
    DelegatingStatusListener *m_listener;
    voltdb::Client m_client;
};

/*
 * Short hand for an exception safe lock acquisition
 */
class LockGuard {
public:
    LockGuard(pthread_mutex_t &mutex) {
        m_mutex = &mutex;
        pthread_mutex_lock(m_mutex);
    }
    ~LockGuard() {
        pthread_mutex_unlock(m_mutex);
    }
private:
    pthread_mutex_t *m_mutex;
};

/*
 * Cleanup function used by thread local ptr to a list of clients
 * that were borrowed from the pool. It unsets the listener and returns the client
 * to the pool.
 */
void cleanupOnScriptEnd(void *ptr) {
    if (gPool != NULL) {
        LockGuard guard(gPool->m_lock);
        ClientSet *clients = reinterpret_cast<ClientSet*>(ptr);
        if (clients != NULL) {
            boost::scoped_ptr<ClientSet> guard(clients);
            for(ClientSet::iterator i = clients->begin(); i != clients->end(); i++) {
                (*i)->m_listener->m_listener = NULL;
                gPool->m_clients[(*i)->m_identifier].push_back(*i);
            }
            pthread_setspecific(gPool->m_borrowedClients, NULL);
        }
    }
}

ConnectionPool::ConnectionPool() {
    pthread_mutex_init(&m_lock, NULL);
    pthread_key_create(&m_borrowedClients, &cleanupOnScriptEnd);
}

/*
 * Destructor specifically deletes the thread local pointer because the cleanup method
 * needs acess to the members of ConnectionPool.
 */
ConnectionPool::~ConnectionPool() {
    pthread_mutex_destroy(&m_lock);
    pthread_key_delete(m_borrowedClients);
}

/*
 * Retrieve a client that is connected and authenticated
 * to the specified hostname and port. Will reuse an existing connection if one is available.
 */
voltdb::Client
ConnectionPool::acquireClient(
        std::string hostname,
        std::string username,
        std::string password,
        StatusListener *listener,
        unsigned short port,
        ClientAuthHashScheme sha)
throw (voltdb::Exception, voltdb::ConnectException, voltdb::LibEventException) {
    LockGuard guard(m_lock);
    ClientSet *clients = reinterpret_cast<ClientSet*>(pthread_getspecific(m_borrowedClients));
    if (clients == NULL) {
        clients = new ClientSet();
        pthread_setspecific( m_borrowedClients, static_cast<const void *>(clients));
    }
    char portBytes[16];
    unsigned int portInt = port;
    snprintf(portBytes, 16, "%d", portInt);
    std::string identifier = hostname + "," + std::string(portBytes) + "," + username + "," + password;

    // if a thread calls acquireClient() multiple times with the same identifier, reuse the same client
    for (ClientSet::iterator i = clients->begin(); i != clients->end(); i++) {
        if ((*i)->m_identifier == identifier) {
            return (*i)->m_client;
        }
    }

    std::vector<boost::shared_ptr<ClientStuff> > *clientStuffs = &m_clients[identifier];

    while (clientStuffs->size() > 0) {
        boost::shared_ptr<ClientStuff> clientStuff = clientStuffs->back();
        clientStuffs->pop_back();

        // run the event loop once to verify the connection is still available
        clientStuff->m_client.runOnce();

        if (clientStuff->m_listener->m_connectionLost) {
            // if this connection is lost, try the next
            continue;
        } else {
            // otherwise return this connection
            clientStuff->m_listener->m_listener = listener;
            clients->push_back(clientStuff);
            return clientStuff->m_client;
        }
    }

    // no connection available, make a new one
    DelegatingStatusListener *delegatingListener = new DelegatingStatusListener();
    Client client = voltdb::Client::create(ClientConfig( username, password, delegatingListener, sha));
    client.createConnection(hostname, port);
    boost::shared_ptr<ClientStuff> stuff(new ClientStuff(client, identifier, delegatingListener));
    stuff->m_listener->m_listener = listener;
    clients->push_back(stuff);
    return client;
}

voltdb::Client
ConnectionPool::acquireClient(
        std::string hostname,
        std::string username,
        std::string password,
        unsigned short port,
        ClientAuthHashScheme sha)
throw (voltdb::Exception, voltdb::ConnectException, voltdb::LibEventException) {
    return acquireClient(hostname, username, password, NULL, port, sha);
}

void ConnectionPool::returnClient(Client client) throw (voltdb::Exception) {
    LockGuard guard(m_lock);
    ClientSet *clients = reinterpret_cast<ClientSet*>(pthread_getspecific(m_borrowedClients));
    if (clients == NULL) {
        throw MisplacedClientException();
    }

    for (ClientSet::iterator i = clients->begin(); i != clients->end(); i++) {
        if ((*i)->m_client == client) {
            (*i)->m_listener->m_listener = NULL;
            m_clients[(*i)->m_identifier].push_back(*i);
            clients->erase(i);
            return;
        }
    }

    throw MisplacedClientException();
}

void ConnectionPool::closeClientConnection(Client client) throw (voltdb::Exception) {
    LockGuard guard(m_lock);
    ClientSet *clients = reinterpret_cast<ClientSet*>(pthread_getspecific(m_borrowedClients));
    if (clients == NULL) {
        //No clients closing a stale object or not owned by this thread.
        return;
    }

    for (ClientSet::iterator i = clients->begin(); i != clients->end(); i++) {
        if ((*i)->m_client == client) {
            client.close();
            (*i)->m_listener->m_listener = NULL;
            clients->erase(i);
            return;
        }
    }
}

/*
 * Return the number of clients held by this thread
 */
int ConnectionPool::numClientsBorrowed() {
    ClientSet *clients = reinterpret_cast<ClientSet*>(pthread_getspecific(m_borrowedClients));
    if (clients != NULL) {
        return clients->size();
    }
    return 0;
}

/*
 * Release any unreleased clients associated with this thread/script
 */
void ConnectionPool::onScriptEnd() {
    cleanupOnScriptEnd(pthread_getspecific(m_borrowedClients));
}

/*
 * Invoked by the external language/script environment when the library is loaded.
 * Creates the connection pool
 */
void onLoad() {
    assert(gPool == NULL);
    gPool = new ConnectionPool();
}

/*
 * Invoked by the external language/script environment when the library is unloaded.
 * Deletes the connection pool closing all connections. Does not drain connections.
 */
void onUnload() {
    assert(gPool != NULL);
    delete gPool;
    gPool = NULL;
}

/*
 * Invoked by the external language/script environment when a script ends. Causes
 * all connections acquired by this thread to be returned.
 */
void onScriptEnd() {
    assert(gPool != NULL);
    gPool->onScriptEnd();
}

voltdb::ConnectionPool* ConnectionPool::pool() {
    assert(gPool != NULL);
    return gPool;
}

}
<|endoftext|>


<commit_before>/* -*- c++ -*- */
/*
 * Copyright (c) 2013 The Native Client Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "native_client/src/shared/serialization/serialization.h"

#include <stdio.h>
#include <string.h>

#include "native_client/src/shared/platform/nacl_check.h"

namespace nacl {

int const kInitialBufferSize = 256;

SerializationBuffer::SerializationBuffer()
    : nbytes_(0)
    , in_use_(0)
    , read_ix_(0) {}

SerializationBuffer::SerializationBuffer(uint8_t const *data_buffer,
                                         size_t nbytes)
    : nbytes_(0)  // EnsureTotalSize will update
    , in_use_(nbytes)
    , read_ix_(0) {
  EnsureTotalSize(nbytes);
  memcpy(&buffer_[0], data_buffer, nbytes);
}

bool SerializationBuffer::Serialize(char const *cstr, size_t char_count) {
  if (char_count > ~(uint32_t) 0) {
    return false;
  }
  AddTag<char *>();
  AddVal(static_cast<uint32_t>(char_count));
  for (size_t ix = 0; ix < char_count; ++ix) {
    AddVal<uint8_t>(cstr[ix]);
  }
  return true;
}

bool SerializationBuffer::Serialize(char const *cstr) {
  size_t len = strlen(cstr) + 1;  // The ASCII character NUL is included
  return Serialize(cstr, len);
}

bool SerializationBuffer::Serialize(std::string str) {
  size_t bytes = str.size();
  if (bytes > ~(uint32_t) 0) {
    return false;
  }
  AddTag<std::string>();
  AddVal(static_cast<uint32_t>(bytes));
  for (size_t ix = 0; ix < bytes; ++ix) {
    AddVal<uint8_t>(str[ix]);
  }
  return true;
}

bool SerializationBuffer::Deserialize(char *cstr, size_t *buffer_size) {
  size_t orig = cur_read_pos();
  if (bytes_unread() < kTagBytes + SerializationTraits<uint32_t>::kBytes) {
    return false;
  }
  if (ReadTag() != SerializationTraits<char *>::kTag) {
    reset_read_pos(orig);
    return false;
  }
  uint32_t char_count;
  if (!GetUint32(&char_count)) {
    reset_read_pos(orig);
    return false;
  }
  if (char_count > *buffer_size) {
    *buffer_size = char_count;
    reset_read_pos(orig);
    return true;  // true means check buffer_size!
  }
  for (size_t ix = 0; ix < char_count; ++ix) {
    uint8_t byte;
    if (!GetVal(&byte)) {
      reset_read_pos(orig);
      return false;  // encoded data is garbled!
    }
    cstr[ix] = byte;
  }
  *buffer_size = char_count;
  return true;
}

bool SerializationBuffer::Deserialize(char **cstr_out) {
  size_t nbytes = 256;
  char *buffer = new char[nbytes];

  size_t used = nbytes;
  if (!Deserialize(buffer, &used)) {
    return false;
  }
  if (used > nbytes) {
    delete[] buffer;
    buffer = new char[used];
    CHECK(Deserialize(buffer, &used));
  }
  *cstr_out = buffer;
  return true;
}

bool SerializationBuffer::Deserialize(std::string *str) {
  size_t orig = cur_read_pos();
  if (bytes_unread() < kTagBytes + SerializationTraits<uint32_t>::kBytes) {
    return false;
  }
  if (ReadTag() != SerializationTraits<std::string>::kTag) {
    reset_read_pos(orig);
    return false;
  }
  uint32_t bytes;
  if (!GetUint32(&bytes)) {
    reset_read_pos(orig);
    return false;
  }
  for (size_t ix = 0; ix < bytes; ++ix) {
    uint8_t b;
    if (!GetUint8(&b)) {
      reset_read_pos(orig);
      return false;
    }
    str->push_back(b);
  }
  return true;
}

void SerializationBuffer::AddUint8(uint8_t value) {
  EnsureAvailableSpace(sizeof value);
  buffer_[in_use_] = value;
  in_use_ += sizeof value;
}

void SerializationBuffer::AddUint16(uint16_t value) {
  EnsureAvailableSpace(sizeof value);
  buffer_[in_use_ + 0] = static_cast<uint8_t>(value >> 0);
  buffer_[in_use_ + 1] = static_cast<uint8_t>(value >> 8);
  in_use_ += sizeof value;
}

void SerializationBuffer::AddUint32(uint32_t value) {
  EnsureAvailableSpace(sizeof value);
  buffer_[in_use_ + 0] = static_cast<uint8_t>(value >> 0);
  buffer_[in_use_ + 1] = static_cast<uint8_t>(value >> 8);
  buffer_[in_use_ + 2] = static_cast<uint8_t>(value >> 16);
  buffer_[in_use_ + 3] = static_cast<uint8_t>(value >> 24);
  in_use_ += sizeof value;
}

void SerializationBuffer::AddUint64(uint64_t value) {
  EnsureAvailableSpace(sizeof value);
  buffer_[in_use_ + 0] = static_cast<uint8_t>(value >> 0);
  buffer_[in_use_ + 1] = static_cast<uint8_t>(value >> 8);
  buffer_[in_use_ + 2] = static_cast<uint8_t>(value >> 16);
  buffer_[in_use_ + 3] = static_cast<uint8_t>(value >> 24);
  buffer_[in_use_ + 4] = static_cast<uint8_t>(value >> 32);
  buffer_[in_use_ + 5] = static_cast<uint8_t>(value >> 40);
  buffer_[in_use_ + 6] = static_cast<uint8_t>(value >> 48);
  buffer_[in_use_ + 7] = static_cast<uint8_t>(value >> 56);
  in_use_ += sizeof value;
}

#if defined(NACL_HAS_IEEE_754)
void SerializationBuffer::AddFloat(float value) {
  union ieee754_float v;
  v.f = value;
  AddUint32((static_cast<uint32_t>(v.ieee.negative) << 31) |
            (static_cast<uint32_t>(v.ieee.exponent) << 23) |
            (static_cast<uint32_t>(v.ieee.mantissa) << 0));
}

void SerializationBuffer::AddDouble(double value) {
  union ieee754_double v;
  v.d = value;
  AddUint64((static_cast<uint64_t>(v.ieee.negative) << 63) |
            (static_cast<uint64_t>(v.ieee.exponent) << 52) |
            (static_cast<uint64_t>(v.ieee.mantissa0) << 32) |
            (static_cast<uint64_t>(v.ieee.mantissa1) << 0));
}

void SerializationBuffer::AddLongDouble(long double value) {
  union ieee854_long_double v;
  v.d = value;
  AddUint16((static_cast<uint16_t>(v.ieee.negative) << 15) |
            (static_cast<uint16_t>(v.ieee.exponent) << 0));
  AddUint64((static_cast<uint64_t>(v.ieee.mantissa0) << 32) |
            (static_cast<uint64_t>(v.ieee.mantissa1) << 0));
}
#endif

bool SerializationBuffer::GetUint8(uint8_t *value) {
  if (bytes_unread() < sizeof *value) {
    return false;
  }
  *value = static_cast<uint8_t>(buffer_[read_ix_]);
  read_ix_ += sizeof *value;
  return true;
}

bool SerializationBuffer::GetUint16(uint16_t *value) {
  if (bytes_unread() < sizeof *value) {
    return false;
  }
  *value = ((static_cast<uint16_t>(buffer_[read_ix_ + 0]) << 0) |
            (static_cast<uint16_t>(buffer_[read_ix_ + 1]) << 8));
  read_ix_ += sizeof *value;
  return true;
}

bool SerializationBuffer::GetUint32(uint32_t *value) {
  if (bytes_unread() < sizeof *value) {
    return false;
  }
  *value = ((static_cast<uint32_t>(buffer_[read_ix_ + 0]) << 0) |
            (static_cast<uint32_t>(buffer_[read_ix_ + 1]) << 8) |
            (static_cast<uint32_t>(buffer_[read_ix_ + 2]) << 16) |
            (static_cast<uint32_t>(buffer_[read_ix_ + 3]) << 24));
  read_ix_ += sizeof *value;
  return true;
}

bool SerializationBuffer::GetUint64(uint64_t *value) {
  if (bytes_unread() < sizeof *value) {
    return false;
  }
  *value = ((static_cast<uint64_t>(buffer_[read_ix_ + 0]) << 0) |
            (static_cast<uint64_t>(buffer_[read_ix_ + 1]) << 8) |
            (static_cast<uint64_t>(buffer_[read_ix_ + 2]) << 16) |
            (static_cast<uint64_t>(buffer_[read_ix_ + 3]) << 24) |
            (static_cast<uint64_t>(buffer_[read_ix_ + 4]) << 32) |
            (static_cast<uint64_t>(buffer_[read_ix_ + 5]) << 40) |
            (static_cast<uint64_t>(buffer_[read_ix_ + 6]) << 48) |
            (static_cast<uint64_t>(buffer_[read_ix_ + 7]) << 56));
  read_ix_ += sizeof *value;
  return true;
}

#if defined(NACL_HAS_IEEE_754)
bool SerializationBuffer::GetFloat(float *value) {
  union ieee754_float v;
  uint32_t encoded = 0;
  if (!GetUint32(&encoded)) {
    return false;
  }
  v.ieee.negative = encoded >> 31;
  v.ieee.exponent = encoded >> 23;
  v.ieee.mantissa = encoded;
  *value = v.f;
  return true;
}

bool SerializationBuffer::GetDouble(double *value) {
  union ieee754_double v;
  uint64_t encoded;
  if (!GetUint64(&encoded)) {
    return false;
  }
  v.ieee.negative = encoded >> 63;
  v.ieee.exponent = encoded >> 52;
  v.ieee.mantissa0 = encoded >> 32;
  v.ieee.mantissa1 = encoded;
  *value = v.d;
  return true;
}

bool SerializationBuffer::GetLongDouble(long double *value) {
  union ieee854_long_double v;
  uint16_t encoded1;
  uint64_t encoded2;
  if (in_use_ < read_ix_ + 10) {
    return false;
  }
  if (!GetUint16(&encoded1) || !GetUint64(&encoded2)) {
    return false;
  }
  v.ieee.negative = (encoded1 >> 15) & 1;
  v.ieee.exponent = encoded1;
  v.ieee.mantissa0 = encoded2 >> 32;
  v.ieee.mantissa1 = encoded2;
  *value = v.d;
  return true;
}
#endif

void SerializationBuffer::EnsureTotalSize(size_t req_size) {
  if (nbytes_ >= req_size) {
    return;
  }
  size_t new_size = (0 == nbytes_) ? kInitialBufferSize : 2 * nbytes_;
  CHECK(new_size > nbytes_);  // no arithmetic overflow
  if (new_size < req_size) {
    new_size = req_size;
  }
  buffer_.resize(new_size);
  nbytes_ = new_size;
}

void SerializationBuffer::EnsureAvailableSpace(size_t req_space) {
  CHECK(nbytes_ >= in_use_);
  CHECK((~(size_t) 0) - in_use_ >= req_space);
  size_t new_size = in_use_ + req_space;
  EnsureTotalSize(new_size);
}

}  // namespace nacl
<commit_msg>Fixed minor memory leak in SerializationBuffer::Deserialize().<commit_after>/* -*- c++ -*- */
/*
 * Copyright (c) 2013 The Native Client Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "native_client/src/shared/serialization/serialization.h"

#include <stdio.h>
#include <string.h>

#include "native_client/src/shared/platform/nacl_check.h"

namespace nacl {

int const kInitialBufferSize = 256;

SerializationBuffer::SerializationBuffer()
    : nbytes_(0)
    , in_use_(0)
    , read_ix_(0) {}

SerializationBuffer::SerializationBuffer(uint8_t const *data_buffer,
                                         size_t nbytes)
    : nbytes_(0)  // EnsureTotalSize will update
    , in_use_(nbytes)
    , read_ix_(0) {
  EnsureTotalSize(nbytes);
  memcpy(&buffer_[0], data_buffer, nbytes);
}

bool SerializationBuffer::Serialize(char const *cstr, size_t char_count) {
  if (char_count > ~(uint32_t) 0) {
    return false;
  }
  AddTag<char *>();
  AddVal(static_cast<uint32_t>(char_count));
  for (size_t ix = 0; ix < char_count; ++ix) {
    AddVal<uint8_t>(cstr[ix]);
  }
  return true;
}

bool SerializationBuffer::Serialize(char const *cstr) {
  size_t len = strlen(cstr) + 1;  // The ASCII character NUL is included
  return Serialize(cstr, len);
}

bool SerializationBuffer::Serialize(std::string str) {
  size_t bytes = str.size();
  if (bytes > ~(uint32_t) 0) {
    return false;
  }
  AddTag<std::string>();
  AddVal(static_cast<uint32_t>(bytes));
  for (size_t ix = 0; ix < bytes; ++ix) {
    AddVal<uint8_t>(str[ix]);
  }
  return true;
}

bool SerializationBuffer::Deserialize(char *cstr, size_t *buffer_size) {
  size_t orig = cur_read_pos();
  if (bytes_unread() < kTagBytes + SerializationTraits<uint32_t>::kBytes) {
    return false;
  }
  if (ReadTag() != SerializationTraits<char *>::kTag) {
    reset_read_pos(orig);
    return false;
  }
  uint32_t char_count;
  if (!GetUint32(&char_count)) {
    reset_read_pos(orig);
    return false;
  }
  if (char_count > *buffer_size) {
    *buffer_size = char_count;
    reset_read_pos(orig);
    return true;  // true means check buffer_size!
  }
  for (size_t ix = 0; ix < char_count; ++ix) {
    uint8_t byte;
    if (!GetVal(&byte)) {
      reset_read_pos(orig);
      return false;  // encoded data is garbled!
    }
    cstr[ix] = byte;
  }
  *buffer_size = char_count;
  return true;
}

bool SerializationBuffer::Deserialize(char **cstr_out) {
  size_t nbytes = 256;
  char *buffer = new char[nbytes];

  size_t used = nbytes;
  if (!Deserialize(buffer, &used)) {
    delete[] buffer;
    return false;
  }
  if (used > nbytes) {
    delete[] buffer;
    buffer = new char[used];
    CHECK(Deserialize(buffer, &used));
  }
  *cstr_out = buffer;
  return true;
}

bool SerializationBuffer::Deserialize(std::string *str) {
  size_t orig = cur_read_pos();
  if (bytes_unread() < kTagBytes + SerializationTraits<uint32_t>::kBytes) {
    return false;
  }
  if (ReadTag() != SerializationTraits<std::string>::kTag) {
    reset_read_pos(orig);
    return false;
  }
  uint32_t bytes;
  if (!GetUint32(&bytes)) {
    reset_read_pos(orig);
    return false;
  }
  for (size_t ix = 0; ix < bytes; ++ix) {
    uint8_t b;
    if (!GetUint8(&b)) {
      reset_read_pos(orig);
      return false;
    }
    str->push_back(b);
  }
  return true;
}

void SerializationBuffer::AddUint8(uint8_t value) {
  EnsureAvailableSpace(sizeof value);
  buffer_[in_use_] = value;
  in_use_ += sizeof value;
}

void SerializationBuffer::AddUint16(uint16_t value) {
  EnsureAvailableSpace(sizeof value);
  buffer_[in_use_ + 0] = static_cast<uint8_t>(value >> 0);
  buffer_[in_use_ + 1] = static_cast<uint8_t>(value >> 8);
  in_use_ += sizeof value;
}

void SerializationBuffer::AddUint32(uint32_t value) {
  EnsureAvailableSpace(sizeof value);
  buffer_[in_use_ + 0] = static_cast<uint8_t>(value >> 0);
  buffer_[in_use_ + 1] = static_cast<uint8_t>(value >> 8);
  buffer_[in_use_ + 2] = static_cast<uint8_t>(value >> 16);
  buffer_[in_use_ + 3] = static_cast<uint8_t>(value >> 24);
  in_use_ += sizeof value;
}

void SerializationBuffer::AddUint64(uint64_t value) {
  EnsureAvailableSpace(sizeof value);
  buffer_[in_use_ + 0] = static_cast<uint8_t>(value >> 0);
  buffer_[in_use_ + 1] = static_cast<uint8_t>(value >> 8);
  buffer_[in_use_ + 2] = static_cast<uint8_t>(value >> 16);
  buffer_[in_use_ + 3] = static_cast<uint8_t>(value >> 24);
  buffer_[in_use_ + 4] = static_cast<uint8_t>(value >> 32);
  buffer_[in_use_ + 5] = static_cast<uint8_t>(value >> 40);
  buffer_[in_use_ + 6] = static_cast<uint8_t>(value >> 48);
  buffer_[in_use_ + 7] = static_cast<uint8_t>(value >> 56);
  in_use_ += sizeof value;
}

#if defined(NACL_HAS_IEEE_754)
void SerializationBuffer::AddFloat(float value) {
  union ieee754_float v;
  v.f = value;
  AddUint32((static_cast<uint32_t>(v.ieee.negative) << 31) |
            (static_cast<uint32_t>(v.ieee.exponent) << 23) |
            (static_cast<uint32_t>(v.ieee.mantissa) << 0));
}

void SerializationBuffer::AddDouble(double value) {
  union ieee754_double v;
  v.d = value;
  AddUint64((static_cast<uint64_t>(v.ieee.negative) << 63) |
            (static_cast<uint64_t>(v.ieee.exponent) << 52) |
            (static_cast<uint64_t>(v.ieee.mantissa0) << 32) |
            (static_cast<uint64_t>(v.ieee.mantissa1) << 0));
}

void SerializationBuffer::AddLongDouble(long double value) {
  union ieee854_long_double v;
  v.d = value;
  AddUint16((static_cast<uint16_t>(v.ieee.negative) << 15) |
            (static_cast<uint16_t>(v.ieee.exponent) << 0));
  AddUint64((static_cast<uint64_t>(v.ieee.mantissa0) << 32) |
            (static_cast<uint64_t>(v.ieee.mantissa1) << 0));
}
#endif

bool SerializationBuffer::GetUint8(uint8_t *value) {
  if (bytes_unread() < sizeof *value) {
    return false;
  }
  *value = static_cast<uint8_t>(buffer_[read_ix_]);
  read_ix_ += sizeof *value;
  return true;
}

bool SerializationBuffer::GetUint16(uint16_t *value) {
  if (bytes_unread() < sizeof *value) {
    return false;
  }
  *value = ((static_cast<uint16_t>(buffer_[read_ix_ + 0]) << 0) |
            (static_cast<uint16_t>(buffer_[read_ix_ + 1]) << 8));
  read_ix_ += sizeof *value;
  return true;
}

bool SerializationBuffer::GetUint32(uint32_t *value) {
  if (bytes_unread() < sizeof *value) {
    return false;
  }
  *value = ((static_cast<uint32_t>(buffer_[read_ix_ + 0]) << 0) |
            (static_cast<uint32_t>(buffer_[read_ix_ + 1]) << 8) |
            (static_cast<uint32_t>(buffer_[read_ix_ + 2]) << 16) |
            (static_cast<uint32_t>(buffer_[read_ix_ + 3]) << 24));
  read_ix_ += sizeof *value;
  return true;
}

bool SerializationBuffer::GetUint64(uint64_t *value) {
  if (bytes_unread() < sizeof *value) {
    return false;
  }
  *value = ((static_cast<uint64_t>(buffer_[read_ix_ + 0]) << 0) |
            (static_cast<uint64_t>(buffer_[read_ix_ + 1]) << 8) |
            (static_cast<uint64_t>(buffer_[read_ix_ + 2]) << 16) |
            (static_cast<uint64_t>(buffer_[read_ix_ + 3]) << 24) |
            (static_cast<uint64_t>(buffer_[read_ix_ + 4]) << 32) |
            (static_cast<uint64_t>(buffer_[read_ix_ + 5]) << 40) |
            (static_cast<uint64_t>(buffer_[read_ix_ + 6]) << 48) |
            (static_cast<uint64_t>(buffer_[read_ix_ + 7]) << 56));
  read_ix_ += sizeof *value;
  return true;
}

#if defined(NACL_HAS_IEEE_754)
bool SerializationBuffer::GetFloat(float *value) {
  union ieee754_float v;
  uint32_t encoded = 0;
  if (!GetUint32(&encoded)) {
    return false;
  }
  v.ieee.negative = encoded >> 31;
  v.ieee.exponent = encoded >> 23;
  v.ieee.mantissa = encoded;
  *value = v.f;
  return true;
}

bool SerializationBuffer::GetDouble(double *value) {
  union ieee754_double v;
  uint64_t encoded;
  if (!GetUint64(&encoded)) {
    return false;
  }
  v.ieee.negative = encoded >> 63;
  v.ieee.exponent = encoded >> 52;
  v.ieee.mantissa0 = encoded >> 32;
  v.ieee.mantissa1 = encoded;
  *value = v.d;
  return true;
}

bool SerializationBuffer::GetLongDouble(long double *value) {
  union ieee854_long_double v;
  uint16_t encoded1;
  uint64_t encoded2;
  if (in_use_ < read_ix_ + 10) {
    return false;
  }
  if (!GetUint16(&encoded1) || !GetUint64(&encoded2)) {
    return false;
  }
  v.ieee.negative = (encoded1 >> 15) & 1;
  v.ieee.exponent = encoded1;
  v.ieee.mantissa0 = encoded2 >> 32;
  v.ieee.mantissa1 = encoded2;
  *value = v.d;
  return true;
}
#endif

void SerializationBuffer::EnsureTotalSize(size_t req_size) {
  if (nbytes_ >= req_size) {
    return;
  }
  size_t new_size = (0 == nbytes_) ? kInitialBufferSize : 2 * nbytes_;
  CHECK(new_size > nbytes_);  // no arithmetic overflow
  if (new_size < req_size) {
    new_size = req_size;
  }
  buffer_.resize(new_size);
  nbytes_ = new_size;
}

void SerializationBuffer::EnsureAvailableSpace(size_t req_space) {
  CHECK(nbytes_ >= in_use_);
  CHECK((~(size_t) 0) - in_use_ >= req_space);
  size_t new_size = in_use_ + req_space;
  EnsureTotalSize(new_size);
}

}  // namespace nacl
<|endoftext|>


<commit_before>//
//  NotificationOverlay.cpp
//  Kepler
//
//  Created by Tom Carden on 6/2/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#include "NotificationOverlay.h"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <sstream>
#include "cinder/Font.h"
#include "cinder/Text.h"
#include "Globals.h"

using std::stringstream;

NotificationOverlay::NotificationOverlay() {
    mActive			= false;
    mFadeDelay		= 2.0f;
    mFadeDuration	= 1.0f;
}

NotificationOverlay::~NotificationOverlay() {
    hide();
}

void NotificationOverlay::setup( AppCocoaTouch *app, const Orientation &orientation, const Font &font )
{
    mApp = app;
    setInterfaceOrientation(orientation);
	mFont = font;
}

void NotificationOverlay::update()
{
    if (!mActive) return;

    // if enough time has passed, hide the overlay (cleanup happens in hide())
    float elapsedSince = mApp->getElapsedSeconds() - mLastShowTime;
    if (elapsedSince > mFadeDelay + mFadeDuration) {
        hide();
    }
}

void NotificationOverlay::draw()
{
    if (!mActive) return;

    float elapsedSince = mApp->getElapsedSeconds() - mLastShowTime;

    float alpha = 1.0f;

    if (elapsedSince > mFadeDelay) {
        alpha = 1.0f - (elapsedSince - mFadeDelay) / mFadeDuration;
    }

	Vec2f center = Vec2f( mInterfaceSize.x * 0.5f, mInterfaceSize.y - 250.0f );

    Vec2f iconTopLeft(			center.x - mCurrentSrcArea.getWidth()/2.0f, center.y - mCurrentSrcArea.getHeight()/2.0f );
    Vec2f iconBottomRight(		center.x + mCurrentSrcArea.getWidth()/2.0f, center.y + mCurrentSrcArea.getHeight()/2.0f );
    Rectf iconRect( iconTopLeft, iconBottomRight );

	float halfWidth = mMessageTexture.getWidth() * 0.5f;
	Vec2f messageTopLeft(		center.x - halfWidth, iconBottomRight.y - 10.0f );
	Vec2f messageBottomRight(	center.x + halfWidth, iconBottomRight.y + mMessageTexture.getHeight() - 10.0f );
	Rectf messageRect( messageTopLeft, messageBottomRight );

	float border = 20.0f;
	Vec2f blackBgTopLeft(		messageTopLeft.x - border, iconTopLeft.y - 5.0f );
	Vec2f blackBgBottomRight(	messageBottomRight.x + border, messageBottomRight.y + border );
	Rectf blackBgRect( blackBgTopLeft, blackBgBottomRight );

	glPushMatrix();
    glMultMatrixf( mOrientationMatrix );
	gl::color( ColorA( 1.0f, 1.0f, 1.0f, alpha ) );
	gl::draw( mMessageTexture, messageRect );
    gl::draw( mCurrentTexture, mCurrentSrcArea, iconRect );
	glPopMatrix();
}

void NotificationOverlay::setInterfaceOrientation( const Orientation &orientation )
{
    mInterfaceOrientation = orientation;
    mOrientationMatrix = getOrientationMatrix44(mInterfaceOrientation, getWindowSize());

    mInterfaceSize = getWindowSize();

    if ( isLandscapeOrientation( mInterfaceOrientation ) ) {
        mInterfaceSize = mInterfaceSize.yx(); // swizzle it!
    }
}

void NotificationOverlay::show(const gl::Texture &texture, const Area &srcArea, const string &message)
{
    mCurrentTexture = texture;
    mCurrentSrcArea = srcArea;
    mCurrentMessage = message;

	TextLayout layout;
	layout.setFont( mFont );
	layout.setColor( ColorA( BRIGHT_BLUE, 0.5f ) );
    vector<string> results;
    boost::split(results, message, boost::is_any_of("\n"));
    for (int i = 0; i < results.size(); i++) {
        layout.addCenteredLine( results[i] );
    }
	mMessageTexture = gl::Texture( layout.render( true, true ) );

    mActive = true;
    mLastShowTime = mApp->getElapsedSeconds();
}

void NotificationOverlay::hide()
{
    mActive = false;
    mCurrentTexture.reset();
}
<commit_msg>fix newline layout in NotificationOverlay<commit_after>//
//  NotificationOverlay.cpp
//  Kepler
//
//  Created by Tom Carden on 6/2/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#include "NotificationOverlay.h"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <sstream>
#include "cinder/Font.h"
#include "cinder/Text.h"
#include "Globals.h"

using std::stringstream;

NotificationOverlay::NotificationOverlay() {
    mActive			= false;
    mFadeDelay		= 2.0f;
    mFadeDuration	= 1.0f;
}

NotificationOverlay::~NotificationOverlay() {
    hide();
}

void NotificationOverlay::setup( AppCocoaTouch *app, const Orientation &orientation, const Font &font )
{
    mApp = app;
    setInterfaceOrientation(orientation);
	mFont = font;
}

void NotificationOverlay::update()
{
    if (!mActive) return;

    // if enough time has passed, hide the overlay (cleanup happens in hide())
    float elapsedSince = mApp->getElapsedSeconds() - mLastShowTime;
    if (elapsedSince > mFadeDelay + mFadeDuration) {
        hide();
    }
}

void NotificationOverlay::draw()
{
    if (!mActive) return;

    float elapsedSince = mApp->getElapsedSeconds() - mLastShowTime;

    float alpha = 1.0f;

    if (elapsedSince > mFadeDelay) {
        alpha = 1.0f - (elapsedSince - mFadeDelay) / mFadeDuration;
    }

	Vec2f pos = Vec2f( mInterfaceSize.x * 0.5f, mInterfaceSize.y - 250.0f - mMessageTexture.getHeight() );
	Vec2f iconSize = mCurrentSrcArea.getSize();

    Rectf iconRect( pos - iconSize/2.0f, pos + iconSize/2.0f );

	float halfWidth = mMessageTexture.getWidth() * 0.5f;
	Vec2f messageTopLeft(	  pos.x - halfWidth, iconRect.y2 - 10.0f );
	Vec2f messageBottomRight( pos.x + halfWidth, iconRect.y2 + mMessageTexture.getHeight() - 10.0f );
	Rectf messageRect( messageTopLeft, messageBottomRight );

	glPushMatrix();
    glMultMatrixf( mOrientationMatrix );
	gl::color( ColorA( 1.0f, 1.0f, 1.0f, alpha ) );
	gl::draw( mMessageTexture, messageRect );
    gl::draw( mCurrentTexture, mCurrentSrcArea, iconRect );
	glPopMatrix();
}

void NotificationOverlay::setInterfaceOrientation( const Orientation &orientation )
{
    mInterfaceOrientation = orientation;
    mOrientationMatrix = getOrientationMatrix44(mInterfaceOrientation, getWindowSize());

    mInterfaceSize = getWindowSize();

    if ( isLandscapeOrientation( mInterfaceOrientation ) ) {
        mInterfaceSize = mInterfaceSize.yx(); // swizzle it!
    }
}

void NotificationOverlay::show(const gl::Texture &texture, const Area &srcArea, const string &message)
{
    mCurrentTexture = texture;
    mCurrentSrcArea = srcArea;
    mCurrentMessage = message;

	TextLayout layout;
	layout.setFont( mFont );
	layout.setColor( ColorA( BRIGHT_BLUE, 0.5f ) );
    vector<string> results;
    boost::split(results, message, boost::is_any_of("\n"));
    for (int i = 0; i < results.size(); i++) {
        layout.addCenteredLine( results[i] );
    }
	mMessageTexture = gl::Texture( layout.render( true, true ) );

    mActive = true;
    mLastShowTime = mApp->getElapsedSeconds();
}

void NotificationOverlay::hide()
{
    mActive = false;
    mCurrentTexture.reset();
}
<|endoftext|>


<commit_before>// Begin CVS Header
//   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/optimization/COptTask.cpp,v $
//   $Revision: 1.43 $
//   $Name:  $
//   $Author: shoops $
//   $Date: 2012/06/20 21:17:11 $
// End CVS Header

// Copyright (C) 2012 - 2010 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

// Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

/**
 * COptTask class.
 *
 * This class implements a optimization task which is comprised of a
 * of a problem and a method.
 *
 */
#include "copasi.h"

#include "COptTask.h"
#include "COptProblem.h"
#include "COptMethod.h"
#include "report/CKeyFactory.h"
#include "report/CReport.h"

#include "model/CModel.h"
#include "model/CState.h"

//#include "trajectory/CTrajectoryTask.h"
//#include "trajectory/CTrajectoryProblem.h"
//#include "steadystate/CSteadyStateTask.h"
//#include "steadystate/CSteadyStateProblem.h"
//#include "utilities/COutputHandler.h"

const unsigned int COptTask::ValidMethods[] =
{
  CCopasiMethod::Statistics,
  CCopasiMethod::GeneticAlgorithm,
  CCopasiMethod::GeneticAlgorithmSR,
  CCopasiMethod::HookeJeeves,
  CCopasiMethod::LevenbergMarquardt,
  CCopasiMethod::EvolutionaryProgram,
  CCopasiMethod::RandomSearch,
  CCopasiMethod::NelderMead,
  CCopasiMethod::ParticleSwarm,
  CCopasiMethod::Praxis,
  CCopasiMethod::TruncatedNewton,
  CCopasiMethod::SimulatedAnnealing,
#ifdef COPASI_DEBUG
  CCopasiMethod::CoranaWalk,
  CCopasiMethod::DifferentialEvolution,
#endif // COPASI_DEBUG
  CCopasiMethod::SRES,
  CCopasiMethod::SteepestDescent,
  CCopasiMethod::unset
};

COptTask::COptTask(const CCopasiTask::Type & type,
                   const CCopasiContainer * pParent):
    CCopasiTask(type, pParent)
{
  mpProblem = new COptProblem(type, this);
  mpMethod = COptMethod::createMethod();
  this->add(mpMethod, true);
  //  mpMethod->setObjectParent(this);
  ((COptMethod *) mpMethod)->setProblem((COptProblem *) mpProblem);
}

COptTask::COptTask(const COptTask & src,
                   const CCopasiContainer * pParent):
    CCopasiTask(src, pParent)
{
  mpProblem = new COptProblem(*(COptProblem *) src.mpProblem, this);
  mpMethod = COptMethod::createMethod(src.mpMethod->getSubType());
  this->add(mpMethod, true);
  //  mpMethod->setObjectParent(this);
  ((COptMethod *) mpMethod)->setProblem((COptProblem *) mpProblem);
}

COptTask::~COptTask()
{cleanup();}

void COptTask::cleanup() {}

bool COptTask::setCallBack(CProcessReport * pCallBack)
{
  bool success = CCopasiTask::setCallBack(pCallBack);

  if (!mpProblem->setCallBack(pCallBack)) success = false;

  if (!mpMethod->setCallBack(pCallBack)) success = false;

  return success;
}

bool COptTask::initialize(const OutputFlag & of,
                          COutputHandler * pOutputHandler,
                          std::ostream * pOstream)
{
  COptProblem * pProblem = dynamic_cast<COptProblem *>(mpProblem);
  COptMethod * pMethod = dynamic_cast<COptMethod *>(mpMethod);

  if (!pProblem || !pMethod) return false;

  //initialize reporting
  bool success = true;

  //do the part of the initialization of the subtask that needs to be
  //performed before the output is initialized. This is kind of a hack,
  //we need to find a more general solution for this
  if (!pProblem->initializeSubtaskBeforeOutput()) success = false;

  if (!CCopasiTask::initialize(of, pOutputHandler, pOstream)) success = false;

  //if (!mReport.open(pOstream)) success = false;
  //if (!mReport.compile()) success = false;

  if (!pProblem->initialize()) success = false;

  pMethod->setProblem(pProblem);
  //  if (!pMethod->initialize()) return false;

  return success;
}

bool COptTask::process(const bool & /* useInitialValues */)
{
  COptProblem * pProblem = dynamic_cast<COptProblem *>(mpProblem);
  COptMethod * pMethod = dynamic_cast<COptMethod *>(mpMethod);

  if (!pProblem || !pMethod) return false;

  mpMethod->isValidProblem(mpProblem);

  pProblem->randomizeStartValues();

  output(COutputInterface::BEFORE);

  bool success = pMethod->optimise();

  pProblem->calculateStatistics();

  output(COutputInterface::AFTER);

  return success;
}

bool COptTask::setMethodType(const int & type)
{
  CCopasiMethod::SubType Type = (CCopasiMethod::SubType) type;

  if (mpMethod->getSubType() == Type) return true;

  pdelete(mpMethod);

  mpMethod = createMethod(Type);
  this->add(mpMethod, true);

  return true;
}

// virtual
CCopasiMethod * COptTask::createMethod(const int & type) const
{
  CCopasiMethod::SubType Type = (CCopasiMethod::SubType) type;

  return COptMethod::createMethod(Type);
}
<commit_msg>Enabled differential evolution in release.<commit_after>// Copyright (C) 2010 - 2012 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

// Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2005 - 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

/**
 * COptTask class.
 *
 * This class implements a optimization task which is comprised of a
 * of a problem and a method.
 *
 */
#include "copasi.h"

#include "COptTask.h"
#include "COptProblem.h"
#include "COptMethod.h"
#include "report/CKeyFactory.h"
#include "report/CReport.h"

#include "model/CModel.h"
#include "model/CState.h"

//#include "trajectory/CTrajectoryTask.h"
//#include "trajectory/CTrajectoryProblem.h"
//#include "steadystate/CSteadyStateTask.h"
//#include "steadystate/CSteadyStateProblem.h"
//#include "utilities/COutputHandler.h"

const unsigned int COptTask::ValidMethods[] =
{
  CCopasiMethod::Statistics,
  CCopasiMethod::GeneticAlgorithm,
  CCopasiMethod::GeneticAlgorithmSR,
  CCopasiMethod::HookeJeeves,
  CCopasiMethod::LevenbergMarquardt,
  CCopasiMethod::EvolutionaryProgram,
  CCopasiMethod::RandomSearch,
  CCopasiMethod::NelderMead,
  CCopasiMethod::ParticleSwarm,
  CCopasiMethod::Praxis,
  CCopasiMethod::TruncatedNewton,
  CCopasiMethod::SimulatedAnnealing,
#ifdef COPASI_DEBUG
  CCopasiMethod::CoranaWalk,
#endif // COPASI_DEBUG
  CCopasiMethod::DifferentialEvolution,
  CCopasiMethod::SRES,
  CCopasiMethod::SteepestDescent,
  CCopasiMethod::unset
};

COptTask::COptTask(const CCopasiTask::Type & type,
                   const CCopasiContainer * pParent):
  CCopasiTask(type, pParent)
{
  mpProblem = new COptProblem(type, this);
  mpMethod = COptMethod::createMethod();
  this->add(mpMethod, true);
  //  mpMethod->setObjectParent(this);
  ((COptMethod *) mpMethod)->setProblem((COptProblem *) mpProblem);
}

COptTask::COptTask(const COptTask & src,
                   const CCopasiContainer * pParent):
  CCopasiTask(src, pParent)
{
  mpProblem = new COptProblem(*(COptProblem *) src.mpProblem, this);
  mpMethod = COptMethod::createMethod(src.mpMethod->getSubType());
  this->add(mpMethod, true);
  //  mpMethod->setObjectParent(this);
  ((COptMethod *) mpMethod)->setProblem((COptProblem *) mpProblem);
}

COptTask::~COptTask()
{cleanup();}

void COptTask::cleanup() {}

bool COptTask::setCallBack(CProcessReport * pCallBack)
{
  bool success = CCopasiTask::setCallBack(pCallBack);

  if (!mpProblem->setCallBack(pCallBack)) success = false;

  if (!mpMethod->setCallBack(pCallBack)) success = false;

  return success;
}

bool COptTask::initialize(const OutputFlag & of,
                          COutputHandler * pOutputHandler,
                          std::ostream * pOstream)
{
  COptProblem * pProblem = dynamic_cast<COptProblem *>(mpProblem);
  COptMethod * pMethod = dynamic_cast<COptMethod *>(mpMethod);

  if (!pProblem || !pMethod) return false;

  //initialize reporting
  bool success = true;

  //do the part of the initialization of the subtask that needs to be
  //performed before the output is initialized. This is kind of a hack,
  //we need to find a more general solution for this
  if (!pProblem->initializeSubtaskBeforeOutput()) success = false;

  if (!CCopasiTask::initialize(of, pOutputHandler, pOstream)) success = false;

  //if (!mReport.open(pOstream)) success = false;
  //if (!mReport.compile()) success = false;

  if (!pProblem->initialize()) success = false;

  pMethod->setProblem(pProblem);
  //  if (!pMethod->initialize()) return false;

  return success;
}

bool COptTask::process(const bool & /* useInitialValues */)
{
  COptProblem * pProblem = dynamic_cast<COptProblem *>(mpProblem);
  COptMethod * pMethod = dynamic_cast<COptMethod *>(mpMethod);

  if (!pProblem || !pMethod) return false;

  mpMethod->isValidProblem(mpProblem);

  pProblem->randomizeStartValues();

  output(COutputInterface::BEFORE);

  bool success = pMethod->optimise();

  pProblem->calculateStatistics();

  output(COutputInterface::AFTER);

  return success;
}

bool COptTask::setMethodType(const int & type)
{
  CCopasiMethod::SubType Type = (CCopasiMethod::SubType) type;

  if (mpMethod->getSubType() == Type) return true;

  pdelete(mpMethod);

  mpMethod = createMethod(Type);
  this->add(mpMethod, true);

  return true;
}

// virtual
CCopasiMethod * COptTask::createMethod(const int & type) const
{
  CCopasiMethod::SubType Type = (CCopasiMethod::SubType) type;

  return COptMethod::createMethod(Type);
}
<|endoftext|>