<commit_before># include "vtkPointData.h"
# include "vtkPoints.h"
# include "vtkPolyDataMapper.h"
# include "vtkRenderWindow.h"
# include "vtkJPEGReader.h"
# include "vtkOBJReader.h"
# include "vtkProperty.h"
# include "vtkOpenGLHardwareSupport.h"
# include "vtkOpenGLRenderWindow.h"

#include "vtkTexturingHelper.h"

vtkTexturingHelper::vtkTexturingHelper()
{
	this->thePolyData_ = NULL;
	this->theActor_ = vtkActor::New();
	this->geoExtensionsMap_[".obj"] = &vtkTexturingHelper::readOBJFile;
	this->imgExtensionsMap_[".jpg"] = &vtkTexturingHelper::readjPEGTexture;
	this->TCoordsCount_ = 0;
}

vtkTexturingHelper::~vtkTexturingHelper()
{
}

void	vtkTexturingHelper::readjPEGTexture(int index)
{
	vtkJPEGReader*	jPEGReader = vtkJPEGReader::New();
	vtkTexture*		newTexture = vtkTexture::New();

	jPEGReader->SetFileName(this->texturesFiles_[index].c_str());
	jPEGReader->Update();
	newTexture->SetInputConnection(jPEGReader->GetOutputPort());
	this->textures_.push_back(newTexture);
}

void	vtkTexturingHelper::configureTexture(int texIndex)
{
	if (texIndex == 0) {
		std::cout << "replace tex" << std::endl;
		this->textures_[texIndex]->SetBlendingMode(vtkTexture::VTK_TEXTURE_BLENDING_MODE_REPLACE);
	} else {
		std::cout << "add tex" << std::endl;
		this->textures_[texIndex]->SetBlendingMode(vtkTexture::VTK_TEXTURE_BLENDING_MODE_ADD);
	}
	/*this->textures_[texIndex]->RepeatOff();
	this->textures_[texIndex]->EdgeClampOn();
	this->textures_[texIndex]->InterpolateOn(); */
}

void	vtkTexturingHelper::convertImagesToTextures()
{
	int	texIndex;

	for (texIndex = 0; texIndex != this->texturesFiles_.size(); texIndex++)
	{
		std::string	ext = this->texturesFiles_[texIndex].substr(this->texturesFiles_[texIndex].find_last_of("."));

		std::cout << "Extension of " << this->texturesFiles_[texIndex] << ": " << ext << std::endl;
		if (this->imgExtensionsMap_.find(ext) != this->imgExtensionsMap_.end()) {
			(this->*imgExtensionsMap_[ext])(texIndex);
			this->configureTexture(texIndex);
		} else {
			std::cerr << "Unknown extension: " << ext << std::endl;
		}
	}
}

void	vtkTexturingHelper::applyTextures()
{
	vtkPolyDataMapper * mapper = vtkPolyDataMapper::New();

	this->convertImagesToTextures();
	std::cout << "yello" << std::endl;
	mapper->SetInput(this->thePolyData_);

	bool	supported;
	int	tu = 0;
	int	textureUnit = vtkProperty::VTK_TEXTURE_UNIT_0;
	vtkRenderWindow	*tmp = vtkRenderWindow::New();
	vtkOpenGLHardwareSupport * hardware =
    vtkOpenGLRenderWindow::SafeDownCast(tmp)->GetHardwareSupport();

  supported = hardware->GetSupportsMultiTexturing();
  if (supported)
    {
		tu = hardware->GetNumberOfFixedTextureUnits();
		std::cout << "Multi-texturing is hardware supported: supports " << tu << " multi textures" << std::endl;
    }
  if (supported && tu >= 2)
    {
		 std::cout << "Mapping multi-textures" << std::endl;

		for (unsigned int texNumber = 0; texNumber <= tu && texNumber < this->TCoordsArrays_.size(); texNumber++) {
			 std::cout << "Mapping multi-texture " << this->TCoordsArrays_[texNumber]->GetName() << std::endl;
			mapper->MapDataArrayToMultiTextureAttribute(
				textureUnit, this->TCoordsArrays_[texNumber]->GetName(),
			vtkDataObject::FIELD_ASSOCIATION_POINTS);
			this->thePolyData_->GetPointData()->AddArray(this->TCoordsArrays_[texNumber]);
			textureUnit++;
		}
		textureUnit = vtkProperty::VTK_TEXTURE_UNIT_0;
		for (unsigned int texNumber = 0; texNumber < this->TCoordsArrays_.size(); texNumber++) {
			std::cout << "Setting Textures" << std::endl;
			this->theActor_->GetProperty()->SetTexture(textureUnit, this->textures_[texNumber]);
			textureUnit++;
		}
    }
  else
  {
    // no multitexturing just show one texture.
	this->theActor_->SetTexture(this->textures_[0]);
  }
  this->theActor_->SetMapper(mapper);
  std::cout << "Done Mapping multi-textures" << std::endl;
  std::cout << "PolyData arrays = " << this->thePolyData_->GetPointData()->GetNumberOfArrays() << std::endl;
  tmp->Delete();
}

void	vtkTexturingHelper::insertNewTCoordsArray()
{
	vtkFloatArray	*newTCoords = vtkFloatArray::New();
	std::stringstream	ss;
	std::string	arrayName;

	ss << this->TCoordsCount_;
	arrayName = "TCoords" + ss.str();
	newTCoords->SetName(arrayName.c_str());
	newTCoords->SetNumberOfComponents(2);
	this->TCoordsCount_++;
	for (unsigned int pointNbr = 0; pointNbr < this->thePolyData_->GetPointData()->GetNumberOfTuples(); pointNbr++) {
			newTCoords->InsertNextTuple2(-1.0, -1.0);
	}
	this->TCoordsArrays_.push_back(newTCoords);
}

// Method called after we retrieved the polyData from .obj file with vtkOBJReader.
// VTK doesn't make the differences between the texture coordinates of each image: it just stores everything in one big array.
// So we have to re-read the file by ourselves, to know how many TCoords points are allocated to each image, and then
// create as many smaller arrays than necessary, filling them with the right values at the right place, putting "-1"'s on all the
// points indexes that aren't supposed to be covered by a texture.
// This process also assumes the files are in the right order (i.e. the order in which this->texturesFiles_ has been filled matches
// the order in which the images' texture coordinates are given in the .obj file).
// This may change in the future if this class implements the .mtl file parsing (which would even avoid us to have to specify the
// image files' names manually).
void		vtkTexturingHelper::retrieveOBJFileTCoords()
{
	std::string		prevWord = "";
	std::ifstream	objFile;
	std::string		line;
	unsigned int	texPointsCount = 0;

	objFile.open(this->geoFile_);
	std::cout << "get lucky opening" << std::endl;
	if (!objFile.is_open())
	{
		std::cerr << "Unable to open OBJ file " << this->geoFile_ << std::endl;
	}
	while ( objFile.good() )
	{
		std::stringstream	ss;
		std::string			word;
		float				x, y;

		getline(objFile, line);
		ss << line;
		ss >> word >> x >> y; // assumes the line is well made (in case of a "vt line" it should be like "vt 42.84 42.84")
		if (word == "vt") {
			if (prevWord != "vt") {
				std::cout << "on " << word << " " << x << " " << y << " with before " << prevWord << std::endl;
				insertNewTCoordsArray(); // if we find a vertex texture line and it's the first of a row: create a new TCoords array
			}
			int arrayNbr;
			// In a Obj file, texture coordinates are listed by texture, so we want to put it in the TCoords array of the right texture
			// but not in the array of other textures. But every TCoords array musts also have the same number of points than the mesh!
			// So to do this we append the coordinates to the concerned TCoords array (the last one created)
			// and put (-1.0, -1.0) in the others instead.
			for (arrayNbr = 0; arrayNbr != this->TCoordsArrays_.size() - 1; arrayNbr++) {
				this->TCoordsArrays_[arrayNbr]->SetTuple2(texPointsCount, -1.0, -1.0);
			}
			this->TCoordsArrays_[arrayNbr]->SetTuple2(texPointsCount, x, y);
			texPointsCount++;
		}
		prevWord = word;

	}
	objFile.close();
	std::cout << "Object number of points: " << this->thePolyData_->GetPointData()->GetNumberOfTuples() << std::endl;
	int arrayNbr;
	// In a Obj file, texture coordinates are listed by texture, so we want to put it in the TCoords array of the right texture
	// but not in the array of other textures. But every TCoords array musts also have the same number of points than the mesh!
	// So to do this we append the coordinates to the concerned TCoords array (the last one created)
	// and put (-1.0, -1.0) in the others instead.
	for (arrayNbr = 0; arrayNbr != this->TCoordsArrays_.size(); arrayNbr++) {
		std::cout << this->TCoordsArrays_[arrayNbr]->GetName() << " number of tuples: " << this->TCoordsArrays_[arrayNbr]->GetNumberOfTuples() << std::endl;
	}
}

// Method to obtain a PolyData out of a Wavefront OBJ file
void		vtkTexturingHelper::readOBJFile()
{
	vtkOBJReader* reader = vtkOBJReader::New();

	cout << "Reading obj" << endl;
	reader->SetFileName(this->geoFile_.c_str());
	reader->Update();
	this->thePolyData_ = reader->GetOutput();
	std::cout << "Object number of points: " << this->thePolyData_->GetPointData()->GetNumberOfTuples() << std::endl;
	//reader->Delete();
	std::cout << "Object number of points: " << this->thePolyData_->GetPointData()->GetNumberOfTuples() << std::endl;
	cout << "Done reading" << endl;
	this->retrieveOBJFileTCoords();
}

void		vtkTexturingHelper::addTextureFile(std::string imageFile)
{
	this->texturesFiles_.push_back(imageFile);
}

//This method avoids the user to call the addTextureFile function a lot of times, when you have a lot of texture files that follow the
// same naming convention,
//	since it permits to simply tell to " get *number* images which name begins by *rootName* ", which will be actually followed by
//	an underscore and the number of the image (starting from 0), and ended by the file extension.
//	e.g. passing it ("sasha", ".jpg", 3) as parameters will make it add "sasha_0.jpg", "sasha_1.jpg", and "sasha_2.jpg" to the
//	list of the texture files to use.
// This is a filename convention since you usually have a geometry file (like "sasha.obj"), and its texture files with the same name,
// an underscore and a number appended to it.
void		vtkTexturingHelper::associateTextureFiles(std::string rootName, std::string extension, int numberOfFiles)
{
	std::string textureFile;

	for (int i = 0; i < numberOfFiles; i++)
	{
		std::stringstream	ss;

		ss << i;
		textureFile = rootName + "_" + ss.str() + extension;
		std::cout << "Adding " << textureFile << std::endl;
		this->addTextureFile(textureFile);
	}
}

void		vtkTexturingHelper::readGeometryFile()
{
	std::cout << this->geoFile_ << "?" << std::endl;
	int idx = this->geoFile_.rfind('.');
	std::cout << "?" << std::endl;
	if (idx != std::string::npos) {
		std::cerr << "Extension of " << geoFile_ << " is wat"  << std::endl;
	}
	else {
		std::cout << "euh" << std::endl;
	}
	std::string	ext = this->geoFile_.substr(geoFile_.find_last_of("."));
	if (this->geoExtensionsMap_.find(ext) != this->geoExtensionsMap_.end()) {
		(this->*geoExtensionsMap_[ext])();
	}
}

void	vtkTexturingHelper::clearTexturesList()
{
	this->texturesFiles_.clear();
}

vtkPolyData*	vtkTexturingHelper::getPolyData() const
{
	return this->thePolyData_;
}

vtkActor*	vtkTexturingHelper::getActor() const
{
	return this->theActor_;
}

void	vtkTexturingHelper::setPolyData(vtkPolyData *polyData)
{
	this->thePolyData_ = polyData;
}

void	vtkTexturingHelper::setGeometryFile(std::string file)
{
	this->geoFile_ = file;
}<commit_msg>I forgot to remove some debug output...<commit_after># include "vtkPointData.h"
# include "vtkPoints.h"
# include "vtkPolyDataMapper.h"
# include "vtkRenderWindow.h"
# include "vtkJPEGReader.h"
# include "vtkOBJReader.h"
# include "vtkProperty.h"
# include "vtkOpenGLHardwareSupport.h"
# include "vtkOpenGLRenderWindow.h"

#include "vtkTexturingHelper.h"

vtkTexturingHelper::vtkTexturingHelper()
{
	this->thePolyData_ = NULL;
	this->theActor_ = vtkActor::New();
	this->geoExtensionsMap_[".obj"] = &vtkTexturingHelper::readOBJFile;
	this->imgExtensionsMap_[".jpg"] = &vtkTexturingHelper::readjPEGTexture;
	this->TCoordsCount_ = 0;
}

vtkTexturingHelper::~vtkTexturingHelper()
{
}

void	vtkTexturingHelper::readjPEGTexture(int index)
{
	vtkJPEGReader*	jPEGReader = vtkJPEGReader::New();
	vtkTexture*		newTexture = vtkTexture::New();

	jPEGReader->SetFileName(this->texturesFiles_[index].c_str());
	jPEGReader->Update();
	newTexture->SetInputConnection(jPEGReader->GetOutputPort());
	this->textures_.push_back(newTexture);
}

void	vtkTexturingHelper::configureTexture(int texIndex)
{
	if (texIndex == 0) {
		this->textures_[texIndex]->SetBlendingMode(vtkTexture::VTK_TEXTURE_BLENDING_MODE_REPLACE);
	} else {
		this->textures_[texIndex]->SetBlendingMode(vtkTexture::VTK_TEXTURE_BLENDING_MODE_ADD);
	}
}

void	vtkTexturingHelper::convertImagesToTextures()
{
	int	texIndex;

	for (texIndex = 0; texIndex != this->texturesFiles_.size(); texIndex++)
	{
		std::string	ext = this->texturesFiles_[texIndex].substr(this->texturesFiles_[texIndex].find_last_of("."));

		if (this->imgExtensionsMap_.find(ext) != this->imgExtensionsMap_.end()) {
			(this->*imgExtensionsMap_[ext])(texIndex);
			this->configureTexture(texIndex);
		} else {
			std::cerr << "Unknown extension: " << ext << std::endl;
		}
	}
}

void	vtkTexturingHelper::applyTextures()
{
	vtkPolyDataMapper * mapper = vtkPolyDataMapper::New();

	this->convertImagesToTextures();
	mapper->SetInput(this->thePolyData_);

	bool	supported;
	int	tu = 0;
	int	textureUnit = vtkProperty::VTK_TEXTURE_UNIT_0;
	vtkRenderWindow	*tmp = vtkRenderWindow::New();
	vtkOpenGLHardwareSupport * hardware =
    vtkOpenGLRenderWindow::SafeDownCast(tmp)->GetHardwareSupport();

  supported = hardware->GetSupportsMultiTexturing();
  if (supported)
    {
		tu = hardware->GetNumberOfFixedTextureUnits();
    }
  if (supported && tu >= 2)
    {

		for (unsigned int texNumber = 0; texNumber <= tu && texNumber < this->TCoordsArrays_.size(); texNumber++) {
			mapper->MapDataArrayToMultiTextureAttribute(
				textureUnit, this->TCoordsArrays_[texNumber]->GetName(),
			vtkDataObject::FIELD_ASSOCIATION_POINTS);
			this->thePolyData_->GetPointData()->AddArray(this->TCoordsArrays_[texNumber]);
			textureUnit++;
		}
		textureUnit = vtkProperty::VTK_TEXTURE_UNIT_0;
		for (unsigned int texNumber = 0; texNumber < this->TCoordsArrays_.size(); texNumber++) {
			this->theActor_->GetProperty()->SetTexture(textureUnit, this->textures_[texNumber]);
			textureUnit++;
		}
    }
  else
  {
    // no multitexturing just show one texture.
	this->theActor_->SetTexture(this->textures_[0]);
  }
  this->theActor_->SetMapper(mapper);
  tmp->Delete();
}

void	vtkTexturingHelper::insertNewTCoordsArray()
{
	vtkFloatArray	*newTCoords = vtkFloatArray::New();
	std::stringstream	ss;
	std::string	arrayName;

	ss << this->TCoordsCount_;
	arrayName = "TCoords" + ss.str();
	newTCoords->SetName(arrayName.c_str());
	newTCoords->SetNumberOfComponents(2);
	this->TCoordsCount_++;
	for (unsigned int pointNbr = 0; pointNbr < this->thePolyData_->GetPointData()->GetNumberOfTuples(); pointNbr++) {
			newTCoords->InsertNextTuple2(-1.0, -1.0);
	}
	this->TCoordsArrays_.push_back(newTCoords);
}

// Method called after we retrieved the polyData from .obj file with vtkOBJReader.
// VTK doesn't make the differences between the texture coordinates of each image: it just stores everything in one big array.
// So we have to re-read the file by ourselves, to know how many TCoords points are allocated to each image, and then
// create as many smaller arrays than necessary, filling them with the right values at the right place, putting "-1"'s on all the
// points indexes that aren't supposed to be covered by a texture.
// This process also assumes the files are in the right order (i.e. the order in which this->texturesFiles_ has been filled matches
// the order in which the images' texture coordinates are given in the .obj file).
// This may change in the future if this class implements the .mtl file parsing (which would even avoid us to have to specify the
// image files' names manually).
void		vtkTexturingHelper::retrieveOBJFileTCoords()
{
	std::string		prevWord = "";
	std::ifstream	objFile;
	std::string		line;
	unsigned int	texPointsCount = 0;

	objFile.open(this->geoFile_);
	if (!objFile.is_open())
	{
		std::cerr << "Unable to open OBJ file " << this->geoFile_ << std::endl;
	}
	while ( objFile.good() )
	{
		std::stringstream	ss;
		std::string			word;
		float				x, y;

		getline(objFile, line);
		ss << line;
		ss >> word >> x >> y; // assumes the line is well made (in case of a "vt line" it should be like "vt 42.84 42.84")
		if (word == "vt") {
			if (prevWord != "vt") {
				insertNewTCoordsArray(); // if we find a vertex texture line and it's the first of a row: create a new TCoords array
			}
			int arrayNbr;
			// In a Obj file, texture coordinates are listed by texture, so we want to put it in the TCoords array of the right texture
			// but not in the array of other textures. But every TCoords array musts also have the same number of points than the mesh!
			// So to do this we append the coordinates to the concerned TCoords array (the last one created)
			// and put (-1.0, -1.0) in the others instead.
			for (arrayNbr = 0; arrayNbr != this->TCoordsArrays_.size() - 1; arrayNbr++) {
				this->TCoordsArrays_[arrayNbr]->SetTuple2(texPointsCount, -1.0, -1.0);
			}
			this->TCoordsArrays_[arrayNbr]->SetTuple2(texPointsCount, x, y);
			texPointsCount++;
		}
		prevWord = word;
	}
	objFile.close();
}

// Method to obtain a PolyData out of a Wavefront OBJ file
void		vtkTexturingHelper::readOBJFile()
{
	vtkOBJReader* reader = vtkOBJReader::New();

	reader->SetFileName(this->geoFile_.c_str());
	reader->Update();
	this->thePolyData_ = reader->GetOutput();
	this->retrieveOBJFileTCoords();
}

void		vtkTexturingHelper::addTextureFile(std::string imageFile)
{
	this->texturesFiles_.push_back(imageFile);
}

//This method avoids the user to call the addTextureFile function a lot of times, when you have a lot of texture files that follow the
// same naming convention,
//	since it permits to simply tell to " get *number* images which name begins by *rootName* ", which will be actually followed by
//	an underscore and the number of the image (starting from 0), and ended by the file extension.
//	e.g. passing it ("sasha", ".jpg", 3) as parameters will make it add "sasha_0.jpg", "sasha_1.jpg", and "sasha_2.jpg" to the
//	list of the texture files to use.
// This is a filename convention since you usually have a geometry file (like "sasha.obj"), and its texture files with the same name,
// an underscore and a number appended to it.
void		vtkTexturingHelper::associateTextureFiles(std::string rootName, std::string extension, int numberOfFiles)
{
	std::string textureFile;

	for (int i = 0; i < numberOfFiles; i++)
	{
		std::stringstream	ss;

		ss << i;
		textureFile = rootName + "_" + ss.str() + extension;
		this->addTextureFile(textureFile);
	}
}

void		vtkTexturingHelper::readGeometryFile()
{
	std::string	ext = this->geoFile_.substr(geoFile_.find_last_of("."));
	if (this->geoExtensionsMap_.find(ext) != this->geoExtensionsMap_.end()) {
		(this->*geoExtensionsMap_[ext])();
	}
}

void	vtkTexturingHelper::clearTexturesList()
{
	this->texturesFiles_.clear();
}

vtkPolyData*	vtkTexturingHelper::getPolyData() const
{
	return this->thePolyData_;
}

vtkActor*	vtkTexturingHelper::getActor() const
{
	return this->theActor_;
}

void	vtkTexturingHelper::setPolyData(vtkPolyData *polyData)
{
	this->thePolyData_ = polyData;
}

void	vtkTexturingHelper::setGeometryFile(std::string file)
{
	this->geoFile_ = file;
}<|endoftext|>


<commit_before>
#include "HuboRT/Manager.hpp"

int main(int argc, char* argv[])
{
    HuboRT::Manager mgr;

    mgr.launch();

    return 0;
}
<commit_msg>trying to debug the manager launch<commit_after>
#include "HuboRT/Manager.hpp"
#include <syslog.h>

int main(int argc, char* argv[])
{
    syslog( LOG_NOTICE, "About to instantiate manager" );
    HuboRT::Manager mgr;

    syslog( LOG_NOTICE, "About to launch manager" );
//    mgr.launch();
    mgr.run();

    return 0;
}
<|endoftext|>


<commit_before>//python3 module for tinyobjloader
//
//usage:
// import tinyobjloader as tol
// model = tol.LoadObj(name)
// print(model["shapes"])
// print(model["materials"]

#include <Python.h>
#include <vector>
#include "../tiny_obj_loader.h"

typedef std::vector<double> vectd;

PyObject*
pyTupleFromfloat3 (float array[3])
{
    int i;
    PyObject* tuple = PyTuple_New(3);

    for(i=0; i<=2 ; i++){
        PyTuple_SetItem(tuple, i, PyFloat_FromDouble(array[i]));
    }

    return tuple;
}

extern "C"
{

static PyObject*
pyLoadObj(PyObject* self, PyObject* args)
{
    PyObject *rtndict, *pyshapes, *pymaterials,
             *current, *meshobj;

    char const* filename;
    char *current_name;
    vectd vect;

    std::vector<tinyobj::shape_t> shapes;
    std::vector<tinyobj::material_t> materials;

    if(!PyArg_ParseTuple(args, "s", &filename))
        return NULL;

    tinyobj::LoadObj(shapes, materials, filename);

    pyshapes = PyDict_New();
    pymaterials = PyDict_New();
    rtndict = PyDict_New();

    for (std::vector<tinyobj::shape_t>::iterator shape = shapes.begin() ;
         shape != shapes.end(); shape++)
    {
         meshobj = PyDict_New();
         tinyobj::mesh_t cm  = (*shape).mesh;

         for (int i = 0; i <= 4; i++ )
         {
            current = PyList_New(0);

           switch(i) {

           case 0:
                current_name = "positions";
                vect = vectd(cm.positions.begin(), cm.positions.end()); break;
           case 1:
                current_name = "normals";
                vect = vectd(cm.normals.begin(), cm.normals.end()); break;
           case 2:
                current_name = "texcoords";
                vect = vectd(cm.texcoords.begin(), cm.texcoords.end()); break;
           case 3:
                current_name = "indicies";
                vect = vectd(cm.indices.begin(), cm.indices.end()); break;
           case 4:
                current_name = "material_ids";
                vect = vectd(cm.material_ids.begin(), cm.material_ids.end()); break;

            }

           for (vectd::iterator it = vect.begin() ;
                it != vect.end(); it++)
            {
                PyList_Insert(current, it - vect.begin(), PyFloat_FromDouble(*it));
            }

            PyDict_SetItemString(meshobj, current_name, current);

         }

         PyDict_SetItemString(pyshapes, (*shape).name.c_str(), meshobj);
    }

    for (std::vector<tinyobj::material_t>::iterator mat = materials.begin() ;
         mat != materials.end(); mat++)
    {
        PyObject *matobj = PyDict_New();
        PyObject *unknown_parameter = PyDict_New();

        for (std::map<std::string, std::string>::iterator p = (*mat).unknown_parameter.begin() ;
          p != (*mat).unknown_parameter.end(); ++p)
        {
            PyDict_SetItemString(unknown_parameter, p->first.c_str(), PyUnicode_FromString(p->second.c_str()));
        }

        PyDict_SetItemString(matobj, "shininess",  PyFloat_FromDouble((*mat).shininess));
        PyDict_SetItemString(matobj, "ior",  PyFloat_FromDouble((*mat).ior));
        PyDict_SetItemString(matobj, "dissolve",  PyFloat_FromDouble((*mat).dissolve));
        PyDict_SetItemString(matobj, "illum",  PyLong_FromLong((*mat).illum));
        PyDict_SetItemString(matobj, "ambient_texname", PyUnicode_FromString((*mat).ambient_texname.c_str()));
        PyDict_SetItemString(matobj, "diffuse_texname", PyUnicode_FromString((*mat).diffuse_texname.c_str()));
        PyDict_SetItemString(matobj, "specular_texname", PyUnicode_FromString((*mat).specular_texname.c_str()));
        PyDict_SetItemString(matobj, "specular_highlight_texname", PyUnicode_FromString((*mat).specular_highlight_texname.c_str()));
        PyDict_SetItemString(matobj, "bump_texname", PyUnicode_FromString((*mat).bump_texname.c_str()));
        PyDict_SetItemString(matobj, "displacement_texname", PyUnicode_FromString((*mat).displacement_texname.c_str()));
        PyDict_SetItemString(matobj, "alpha_texname", PyUnicode_FromString((*mat).alpha_texname.c_str()));
        PyDict_SetItemString(matobj, "ambient", pyTupleFromfloat3((*mat).ambient));
        PyDict_SetItemString(matobj, "diffuse", pyTupleFromfloat3((*mat).diffuse));
        PyDict_SetItemString(matobj, "specular", pyTupleFromfloat3((*mat).specular));
        PyDict_SetItemString(matobj, "transmittance", pyTupleFromfloat3((*mat).transmittance));
        PyDict_SetItemString(matobj, "emission", pyTupleFromfloat3((*mat).emission));
        PyDict_SetItemString(matobj, "unknown_parameter", unknown_parameter);

        PyDict_SetItemString(pymaterials, (*mat).name.c_str(), matobj);
    }

    PyDict_SetItemString(rtndict, "shapes", pyshapes);
    PyDict_SetItemString(rtndict, "materials", pymaterials);

    return rtndict;
}

static PyMethodDef mMethods[] = {

{"LoadObj", pyLoadObj, METH_VARARGS},
{NULL, NULL, 0, NULL}

};

static struct PyModuleDef moduledef = {
    PyModuleDef_HEAD_INIT,
    "tinyobjloader",
    NULL,
    -1,
    mMethods
};

PyMODINIT_FUNC
PyInit_tinyobjloader(void)
{
    return PyModule_Create(&moduledef);
}

}
<commit_msg>Update python binding to match new API.<commit_after>//python3 module for tinyobjloader
//
//usage:
// import tinyobjloader as tol
// model = tol.LoadObj(name)
// print(model["shapes"])
// print(model["materials"]

#include <Python.h>
#include <vector>
#include "../tiny_obj_loader.h"

typedef std::vector<double> vectd;

PyObject*
pyTupleFromfloat3 (float array[3])
{
    int i;
    PyObject* tuple = PyTuple_New(3);

    for(i=0; i<=2 ; i++){
        PyTuple_SetItem(tuple, i, PyFloat_FromDouble(array[i]));
    }

    return tuple;
}

extern "C"
{

static PyObject*
pyLoadObj(PyObject* self, PyObject* args)
{
    PyObject *rtndict, *pyshapes, *pymaterials,
             *current, *meshobj;

    char const* filename;
    char *current_name;
    vectd vect;

    std::vector<tinyobj::shape_t> shapes;
    std::vector<tinyobj::material_t> materials;

    if(!PyArg_ParseTuple(args, "s", &filename))
        return NULL;

    std::string err;
    tinyobj::LoadObj(shapes, materials, err, filename);

    pyshapes = PyDict_New();
    pymaterials = PyDict_New();
    rtndict = PyDict_New();

    for (std::vector<tinyobj::shape_t>::iterator shape = shapes.begin() ;
         shape != shapes.end(); shape++)
    {
         meshobj = PyDict_New();
         tinyobj::mesh_t cm  = (*shape).mesh;

         for (int i = 0; i <= 4; i++ )
         {
            current = PyList_New(0);

           switch(i) {

           case 0:
                current_name = "positions";
                vect = vectd(cm.positions.begin(), cm.positions.end()); break;
           case 1:
                current_name = "normals";
                vect = vectd(cm.normals.begin(), cm.normals.end()); break;
           case 2:
                current_name = "texcoords";
                vect = vectd(cm.texcoords.begin(), cm.texcoords.end()); break;
           case 3:
                current_name = "indicies";
                vect = vectd(cm.indices.begin(), cm.indices.end()); break;
           case 4:
                current_name = "material_ids";
                vect = vectd(cm.material_ids.begin(), cm.material_ids.end()); break;

            }

           for (vectd::iterator it = vect.begin() ;
                it != vect.end(); it++)
            {
                PyList_Insert(current, it - vect.begin(), PyFloat_FromDouble(*it));
            }

            PyDict_SetItemString(meshobj, current_name, current);

         }

         PyDict_SetItemString(pyshapes, (*shape).name.c_str(), meshobj);
    }

    for (std::vector<tinyobj::material_t>::iterator mat = materials.begin() ;
         mat != materials.end(); mat++)
    {
        PyObject *matobj = PyDict_New();
        PyObject *unknown_parameter = PyDict_New();

        for (std::map<std::string, std::string>::iterator p = (*mat).unknown_parameter.begin() ;
          p != (*mat).unknown_parameter.end(); ++p)
        {
            PyDict_SetItemString(unknown_parameter, p->first.c_str(), PyUnicode_FromString(p->second.c_str()));
        }

        PyDict_SetItemString(matobj, "shininess",  PyFloat_FromDouble((*mat).shininess));
        PyDict_SetItemString(matobj, "ior",  PyFloat_FromDouble((*mat).ior));
        PyDict_SetItemString(matobj, "dissolve",  PyFloat_FromDouble((*mat).dissolve));
        PyDict_SetItemString(matobj, "illum",  PyLong_FromLong((*mat).illum));
        PyDict_SetItemString(matobj, "ambient_texname", PyUnicode_FromString((*mat).ambient_texname.c_str()));
        PyDict_SetItemString(matobj, "diffuse_texname", PyUnicode_FromString((*mat).diffuse_texname.c_str()));
        PyDict_SetItemString(matobj, "specular_texname", PyUnicode_FromString((*mat).specular_texname.c_str()));
        PyDict_SetItemString(matobj, "specular_highlight_texname", PyUnicode_FromString((*mat).specular_highlight_texname.c_str()));
        PyDict_SetItemString(matobj, "bump_texname", PyUnicode_FromString((*mat).bump_texname.c_str()));
        PyDict_SetItemString(matobj, "displacement_texname", PyUnicode_FromString((*mat).displacement_texname.c_str()));
        PyDict_SetItemString(matobj, "alpha_texname", PyUnicode_FromString((*mat).alpha_texname.c_str()));
        PyDict_SetItemString(matobj, "ambient", pyTupleFromfloat3((*mat).ambient));
        PyDict_SetItemString(matobj, "diffuse", pyTupleFromfloat3((*mat).diffuse));
        PyDict_SetItemString(matobj, "specular", pyTupleFromfloat3((*mat).specular));
        PyDict_SetItemString(matobj, "transmittance", pyTupleFromfloat3((*mat).transmittance));
        PyDict_SetItemString(matobj, "emission", pyTupleFromfloat3((*mat).emission));
        PyDict_SetItemString(matobj, "unknown_parameter", unknown_parameter);

        PyDict_SetItemString(pymaterials, (*mat).name.c_str(), matobj);
    }

    PyDict_SetItemString(rtndict, "shapes", pyshapes);
    PyDict_SetItemString(rtndict, "materials", pymaterials);

    return rtndict;
}

static PyMethodDef mMethods[] = {

{"LoadObj", pyLoadObj, METH_VARARGS},
{NULL, NULL, 0, NULL}

};

static struct PyModuleDef moduledef = {
    PyModuleDef_HEAD_INIT,
    "tinyobjloader",
    NULL,
    -1,
    mMethods
};

PyMODINIT_FUNC
PyInit_tinyobjloader(void)
{
    return PyModule_Create(&moduledef);
}

}
<|endoftext|>


<commit_before>//===-- ClangdFuzzer.cpp - Fuzz clangd ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file implements a function that runs clangd on a single input.
/// This function is then linked into the Fuzzer library.
///
//===----------------------------------------------------------------------===//

#include "ClangdLSPServer.h"
#include "ClangdServer.h"
#include "CodeComplete.h"
#include <cstdio>
#include <sstream>

using namespace clang::clangd;

extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
  if (size == 0)
    return 0;

  // fmemopen isn't portable, but I think we only run the fuzzer on Linux.
  std::FILE *In = fmemopen(data, size, "r");
  auto Transport = newJSONTransport(In, llvm::nulls(),
                                    /*InMirror=*/nullptr, /*Pretty=*/false,
                                    /*Style=*/JSONStreamStyle::Standard);
  CodeCompleteOptions CCOpts;
  CCOpts.EnableSnippets = false;
  ClangdServer::Options Opts;

  // Initialize and run ClangdLSPServer.
  ClangdLSPServer LSPServer(*Transport, CCOpts, llvm::None, false, Opts);
  LSPServer.run();
  return 0;
}
<commit_msg>[clangd] Unbreak fuzzer target<commit_after>//===-- ClangdFuzzer.cpp - Fuzz clangd ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file implements a function that runs clangd on a single input.
/// This function is then linked into the Fuzzer library.
///
//===----------------------------------------------------------------------===//

#include "ClangdLSPServer.h"
#include "ClangdServer.h"
#include "CodeComplete.h"
#include "FSProvider.h"
#include <cstdio>
#include <sstream>

using namespace clang::clangd;

extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
  if (size == 0)
    return 0;

  // fmemopen isn't portable, but I think we only run the fuzzer on Linux.
  std::FILE *In = fmemopen(data, size, "r");
  auto Transport = newJSONTransport(In, llvm::nulls(),
                                    /*InMirror=*/nullptr, /*Pretty=*/false,
                                    /*Style=*/JSONStreamStyle::Standard);
  RealFileSystemProvider FS;
  CodeCompleteOptions CCOpts;
  CCOpts.EnableSnippets = false;
  ClangdServer::Options Opts;

  // Initialize and run ClangdLSPServer.
  ClangdLSPServer LSPServer(*Transport, FS, CCOpts, llvm::None, false, Opts);
  LSPServer.run();
  return 0;
}
<|endoftext|>


<commit_before>#include "stats.h"

Stats::Stats() {
	this->allocCount = 0;
	this->freeCount = 0;
	this->invalidReadCount = 0;
	this->invalidWriteCount = 0;
	this->fenceHitCount = 0;
	this->invalidFreeCount = 0;
	this->midFreeChunkCount = 0;
	this->freeNullCount = 0;
	this->invalidReturnCount = 0;
	this->fenceOverflowHitCount = 0;
	this->fenceUnderflowHitCount = 0;
}

void Stats::reset() {
	this->allocCount = 0;
	this->freeCount = 0;
	this->invalidReadCount = 0;
	this->invalidWriteCount = 0;
	this->fenceHitCount = 0;
	this->invalidFreeCount = 0;
	this->midFreeChunkCount = 0;
	this->freeNullCount = 0;
	this->invalidReturnCount = 0;
	this->fenceOverflowHitCount = 0;
	this->fenceUnderflowHitCount = 0;
}

unsigned int Stats::getAllocCount() {
	return this->allocCount;
}
unsigned int Stats::getFreeCount() {
	return this->freeCount;
}
unsigned int Stats::getInvalidReadCount() {
	return this->invalidReadCount;
}

unsigned int Stats::getInvalidWriteCount() {
	return this->invalidWriteCount;
}

unsigned int Stats::getFenceHitCount() {
	return this->fenceHitCount;
}

unsigned int Stats::getInvalidFreeCount() {
	return this->invalidFreeCount;
}

unsigned int Stats::getMidFreeChunkCount() {
	return this->midFreeChunkCount;
}

unsigned int Stats::getFreeNullCount() {
	return this->freeNullCount;
}

unsigned int Stats::getFreeNotFoundCount() {
	return this->freeNotFoundCount;
}

unsigned int Stats::getInvalidReturnCount() {
	return this->invalidReturnCount;
}

unsigned int Stats::getFenceOverflowHitCount() {
	return this->fenceOverflowHitCount;
}

unsigned int Stats::getFenceUnderflowHitCount() {
	return this->fenceUnderflowHitCount;
}

void Stats::setAllocCount(unsigned int count) {
	this->allocCount = count;
}

void Stats::setFreeCount(unsigned int count) {
	this->freeCount = count;
}

void Stats::setInvalidReadCount(unsigned int count) {
	this->invalidReadCount = count;
}

void Stats::setInvalidWriteCount(unsigned int count) {
	this->invalidWriteCount = count;
}

void Stats::setFenceHitCount(unsigned int count) {
	this->fenceHitCount = count;
}

void Stats::setInvalidFreeCount(unsigned int count) {
	this->invalidFreeCount = count;
}

void Stats::setMidFreeChunkCount(unsigned int count) {
	this->midFreeChunkCount = count;
}

void Stats::setFreeNullCount(unsigned int count) {
	this->freeNullCount = count;
}

void Stats::setInvalidReturnCount(unsigned int count) {
	this->invalidReturnCount = count;
}

void Stats::setFenceOverflowHitCount(unsigned int count) {
	this->fenceOverflowHitCount = count;
}

void Stats::setFenceUnderflowHitCount(unsigned int count) {
	this->fenceUnderflowHitCount = count;
}

void Stats::setFreeNotFoundCount(unsigned int count) {
	this->freeNotFoundCount = count;
}

void Stats::incAllocCount() {
	this->allocCount++;
}

void Stats::incFreeCount() {
	this->freeCount++;
}

void Stats::incInvalidReadCount() {
	this->invalidReadCount++;
}

void Stats::incInvalidWriteCount() {
	this->invalidWriteCount++;
}

void Stats::incFenceHitCount() {
	this->fenceHitCount++;
}

void Stats::incInvalidFreeCount() {
	this->invalidFreeCount++;
}

void Stats::incMidFreeChunkCount() {
	this->midFreeChunkCount++;
}

void Stats::incFreeNullCount() {
	this->freeNullCount++;
}

void Stats::incInvalidReturnCount() {
	this->invalidReturnCount++;
}

void Stats::incFenceOverflowHitCount() {
	this->fenceOverflowHitCount++;
}

void Stats::incFenceUnderflowHitCount() {
	this->fenceUnderflowHitCount++;
}

void Stats::incFreeNotFoundCount() {
	this->freeNotFoundCount++;
}

void Stats::displayResults(MemList memlist, FILE *fp) {
	if(fp == NULL) {
		fp = stdin;
	}
	// Print out the initial object
	fprintf(fp, "==================================\n");
	fprintf(fp, "%-20s %s\n", "ACTIONS ", "COUNT");
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "allocations: ", this->allocCount);
	fprintf(fp, "%-20s %d\n", "    malloc", 0);
	fprintf(fp, "%-20s %d\n", "    calloc", 0);
	fprintf(fp, "%-20s %d\n", "    realloc", 0);
	fprintf(fp, "%-20s %d\n", "deallocations: ", this->freeCount);
	fprintf(fp, "%-20s %d\n", "    free ", this->freeCount);
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "invalid reads: ", this->invalidReadCount);
	fprintf(fp, "%-20s %d\n", "invalid writes: ", this->invalidWriteCount);
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "invalid frees: ", this->invalidFreeCount);
	fprintf(fp, "%-20s %d\n", "    not found: ", this->freeNotFoundCount);
	fprintf(fp, "%-20s %d\n", "    null free: ", this->freeNullCount);
	fprintf(fp, "%-20s %d\n", "    midchunk free: ", this->midFreeChunkCount);
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "fence hit: ", this->fenceHitCount);
	fprintf(fp, "%-20s %d\n", "    underflow: ", this->fenceUnderflowHitCount);
	fprintf(fp, "%-20s %d\n", "    overflow: ", this->fenceOverflowHitCount);
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "invalid returns: ", this->invalidReturnCount);
	fprintf(fp, "==================================\n");
	// Print out the contents of memlist if it was provided.
	fprintf(fp, "%-20s\n", "MEMLIST CONTENTS");
	char buffer[2048];
	int lostMemory = 0;
	for(int i = 0; i < memlist.size(); i++) {
		MemoryAlloc alloc = memlist.get(i);
		fprintf(fp, "%s\n", alloc.toString(buffer, 2048));
		lostMemory += alloc.getTotalSize();
	}
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "list size: ", memlist.size());
	fprintf(fp, "%-20s %d %s\n", "total loss: ", lostMemory, "bytes");
	fprintf(fp, "==================================\n");
}
<commit_msg>Added the implementation of the accessor functions and increment functions for mallocCount, callocCount, reallocCount, readFenceOverflow, readFenceUnderflow, writeFenceOverflow, and writeFenceUnderflow.<commit_after>#include "stats.h"

Stats::Stats() {
	this->reset();
}

void Stats::reset() {
	/* Allocation Stats */
	this->allocCount = 0;
	this->mallocCount = 0;
	this->callocCount = 0;
	this->reallocCount = 0;
	/* Deallocation Stats */
	this->freeCount = 0;
	/* Invalid Free Stats*/
	this->invalidFreeCount = 0;
	this->midFreeChunkCount = 0;
	this->freeNullCount = 0;
	/* Invalid Read Stats */
	this->invalidReadCount = 0;
	this->readFenceOverflow = 0;
	this->readFenceUnderflow = 0;
	/* Invalid Write Stats */
	this->invalidWriteCount = 0;
	this->writeFenceOverflow = 0;
	this->writeFenceUnderflow = 0;
	/* Stack Smashing Stats */
	this->invalidReturnCount = 0;
}
/* Getters */
unsigned int Stats::getAllocCount() {
	return this->allocCount;
}

unsigned int Stats::getMallocCount() {
	return this->mallocCount;
}

unsigned int Stats::getCallocCount() {
	return this->callocCount;
}

unsigned int Stats::getReallocCount() {
	return this->reallocCount;
}

unsigned int Stats::getFreeCount() {
	return this->freeCount;
}
unsigned int Stats::getInvalidReadCount() {
	return this->invalidReadCount;
}

unsigned int Stats::getReadFenceOverflow() {
	return this->readFenceOverflow;
}

unsigned int Stats::getReadFenceUnderflow() {
	return this->readFenceUnderflow;
}

unsigned int Stats::getInvalidWriteCount() {
	return this->invalidWriteCount;
}

unsigned int Stats::getWriteFenceOverflow() {
	return this->writeFenceOverflow;
}

unsigned int Stats::getWriteFenceUnderflow() {
	return this->writeFenceUnderflow;
}

unsigned int Stats::getInvalidFreeCount() {
	return this->invalidFreeCount;
}

unsigned int Stats::getMidFreeChunkCount() {
	return this->midFreeChunkCount;
}

unsigned int Stats::getFreeNullCount() {
	return this->freeNullCount;
}

unsigned int Stats::getFreeNotFoundCount() {
	return this->freeNotFoundCount;
}

unsigned int Stats::getInvalidReturnCount() {
	return this->invalidReturnCount;
}

/* Setters */

void Stats::setAllocCount(unsigned int count) {
	this->allocCount = count;
}

void Stats::setMallocCount(unsigned int count) {
	this->allocCount = count;
}

void Stats::setCallocCount(unsigned int count) {
	this->allocCount = count;
}

void Stats::setReallocCount(unsigned int count) {
	this->allocCount = count;
}

void Stats::setFreeCount(unsigned int count) {
	this->freeCount = count;
}

void Stats::setInvalidReadCount(unsigned int count) {
	this->invalidReadCount = count;
}

void Stats::setReadFenceOverflow(unsigned int count) {
	this->readFenceOverflow = count;
}

void Stats::setReadFenceUnderflow(unsigned int count) {
	this->readFenceUnderflow = count;
}

void Stats::setInvalidWriteCount(unsigned int count) {
	this->invalidWriteCount = count;
}

void Stats::setWriteFenceOverflow(unsigned int count) {
	this->writeFenceOverflow = count;
}

void Stats::setWriteFenceUnderflow(unsigned int count) {
	this->writeFenceUnderflow = count;
}

void Stats::setFenceHitCount(unsigned int count) {
	this->fenceHitCount = count;
}

void Stats::setInvalidFreeCount(unsigned int count) {
	this->invalidFreeCount = count;
}

void Stats::setMidFreeChunkCount(unsigned int count) {
	this->midFreeChunkCount = count;
}

void Stats::setFreeNullCount(unsigned int count) {
	this->freeNullCount = count;
}

void Stats::setInvalidReturnCount(unsigned int count) {
	this->invalidReturnCount = count;
}

void Stats::setFenceOverflowHitCount(unsigned int count) {
	this->fenceOverflowHitCount = count;
}

void Stats::setFenceUnderflowHitCount(unsigned int count) {
	this->fenceUnderflowHitCount = count;
}

void Stats::setFreeNotFoundCount(unsigned int count) {
	this->freeNotFoundCount = count;
}

/* Increment Count Functions */

void Stats::incAllocCount() {
	this->allocCount++;
}

void Stats::incMallocCount() {
	this->mallocCount++;
}

void Stats::incCallocCount() {
	this->callocCount++;
}

void Stats::incReallocCount() {
	this->reallocCount++;
}

void Stats::incFreeCount() {
	this->freeCount++;
}

void Stats::incInvalidReadCount() {
	this->invalidReadCount++;
}

void Stats::incReadFenceOverflow() {
	this->readFenceOverflow++;
}

void Stats::incReadFenceUnderflow() {
	this->readFenceUnderflow++;
}

void Stats::incInvalidWriteCount() {
	this->invalidWriteCount++;
}

void Stats::incWriteFenceOverflow() {
	this->writeFenceOverflow++;
}

void Stats::incWriteFenceUnderflow() {
	this->writeFenceUnderflow++;
}

void Stats::incInvalidFreeCount() {
	this->invalidFreeCount++;
}

void Stats::incMidFreeChunkCount() {
	this->midFreeChunkCount++;
}

void Stats::incFreeNullCount() {
	this->freeNullCount++;
}

void Stats::incFreeNotFoundCount() {
	this->freeNotFoundCount++;
}

void Stats::incInvalidReturnCount() {
	this->invalidReturnCount++;
}

/**
 * Display All information tracked by the pintool.
 */
void Stats::displayResults(MemList memlist, FILE *fp) {
	if(fp == NULL) {
		fp = stdin;
	}
	// Print out the initial object
	fprintf(fp, "==================================\n");
	fprintf(fp, "%-20s %s\n", "ACTIONS ", "COUNT");
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "allocations: ", this->allocCount);
	fprintf(fp, "%-20s %d\n", "    malloc", this->mallocCount);
	fprintf(fp, "%-20s %d\n", "    calloc", this->callocCount);
	fprintf(fp, "%-20s %d\n", "    realloc", this->reallocCount);
	fprintf(fp, "%-20s %d\n", "deallocations: ", this->freeCount);
	fprintf(fp, "%-20s %d\n", "    free ", this->freeCount);
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "invalid reads: ", this->invalidReadCount);
	fprintf(fp, "%-20s %d\n", "    underflow: ", this->readFenceUnderflow);
	fprintf(fp, "%-20s %d\n", "    overflow: ", this->readFenceOverflow);
	fprintf(fp, "%-20s %d\n", "invalid writes: ", this->invalidWriteCount);
	fprintf(fp, "%-20s %d\n", "    underflow: ", this->writeFenceUnderflow);
	fprintf(fp, "%-20s %d\n", "    overflow: ", this->writeFenceOverflow);
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "invalid frees: ", this->invalidFreeCount);
	fprintf(fp, "%-20s %d\n", "    not found: ", this->freeNotFoundCount);
	fprintf(fp, "%-20s %d\n", "    null free: ", this->freeNullCount);
	fprintf(fp, "%-20s %d\n", "    midchunk free: ", this->midFreeChunkCount);
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "invalid returns: ", this->invalidReturnCount);
	fprintf(fp, "==================================\n");
	// Print out the contents of memlist if it was provided.
	fprintf(fp, "%-20s\n", "MEMLIST CONTENTS");
	char buffer[2048];
	int lostMemory = 0;
	for(int i = 0; i < memlist.size(); i++) {
		MemoryAlloc alloc = memlist.get(i);
		fprintf(fp, "%s\n", alloc.toString(buffer, 2048));
		lostMemory += alloc.getTotalSize();
	}
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "list size: ", memlist.size());
	fprintf(fp, "%-20s %d %s\n", "total loss: ", lostMemory, "bytes");
	fprintf(fp, "==================================\n");
}
<|endoftext|>


<commit_before>#include "stats.h"

Stats::Stats() {
	this->mallocCount = 0;
	this->freeCount = 0;
	this->invalidReadCount = 0;
	this->invalidWriteCount = 0;
	this->fenceHitCount = 0;
	this->invalidFreeCount = 0;
	this->midFreeChunkCount = 0;
	this->freeNullCount = 0;
	this->invalidReturnCount = 0;
	this->fenceOverflowHitCount = 0;
	this->fenceUnderflowHitCount = 0;
}

void Stats::reset() {
	this->mallocCount = 0;
	this->freeCount = 0;
	this->invalidReadCount = 0;
	this->invalidWriteCount = 0;
	this->fenceHitCount = 0;
	this->invalidFreeCount = 0;
	this->midFreeChunkCount = 0;
	this->freeNullCount = 0;
	this->invalidReturnCount = 0;
	this->fenceOverflowHitCount = 0;
	this->fenceUnderflowHitCount = 0;
}

unsigned int Stats::getMallocCount() {
	return this->mallocCount;
}
unsigned int Stats::getFreeCount() {
	return this->freeCount;
}
unsigned int Stats::getInvalidReadCount() {
	return this->invalidReadCount;
}

unsigned int Stats::getInvalidWriteCount() {
	return this->invalidWriteCount;
}

unsigned int Stats::getFenceHitCount() {
	return this->fenceHitCount;
}

unsigned int Stats::getInvalidFreeCount() {
	return this->invalidFreeCount;
}

unsigned int Stats::getMidFreeChunkCount() {
	return this->midFreeChunkCount;
}

unsigned int Stats::getFreeNullCount() {
	return this->freeNullCount;
}

unsigned int Stats::getFreeNotFoundCount() {
	return this->freeNotFoundCount;
}

unsigned int Stats::getInvalidReturnCount() {
	return this->invalidReturnCount;
}

unsigned int Stats::getFenceOverflowHitCount() {
	return this->fenceOverflowHitCount;
}

unsigned int Stats::getFenceUnderflowHitCount() {
	return this->fenceUnderflowHitCount;
}

void Stats::setMallocCount(unsigned int count) {
	this->mallocCount = count;
}

void Stats::setFreeCount(unsigned int count) {
	this->freeCount = count;
}

void Stats::setInvalidReadCount(unsigned int count) {
	this->invalidReadCount = count;
}

void Stats::setInvalidWriteCount(unsigned int count) {
	this->invalidWriteCount = count;
}

void Stats::setFenceHitCount(unsigned int count) {
	this->fenceHitCount = count;
}

void Stats::setInvalidFreeCount(unsigned int count) {
	this->invalidFreeCount = count;
}

void Stats::setMidFreeChunkCount(unsigned int count) {
	this->midFreeChunkCount = count;
}

void Stats::setFreeNullCount(unsigned int count) {
	this->freeNullCount = count;
}

void Stats::setInvalidReturnCount(unsigned int count) {
	this->invalidReturnCount = count;
}

void Stats::setFenceOverflowHitCount(unsigned int count) {
	this->fenceOverflowHitCount = count;
}

void Stats::setFenceUnderflowHitCount(unsigned int count) {
	this->fenceUnderflowHitCount = count;
}

void Stats::setFreeNotFoundCount(unsigned int count) {
	this->freeNotFoundCount = count;
}

void Stats::incMallocCount() {
	this->mallocCount++;
}

void Stats::incFreeCount() {
	this->freeCount++;
}

void Stats::incInvalidReadCount() {
	this->invalidReadCount++;
}

void Stats::incInvalidWriteCount() {
	this->invalidWriteCount++;
}

void Stats::incFenceHitCount() {
	this->fenceHitCount++;
}

void Stats::incInvalidFreeCount() {
	this->invalidFreeCount++;
}

void Stats::incMidFreeChunkCount() {
	this->midFreeChunkCount++;
}

void Stats::incFreeNullCount() {
	this->freeNullCount++;
}

void Stats::incInvalidReturnCount() {
	this->invalidReturnCount++;
}

void Stats::incFenceOverflowHitCount() {
	this->fenceOverflowHitCount++;
}

void Stats::incFenceUnderflowHitCount() {
	this->fenceUnderflowHitCount++;
}

void Stats::incFreeNotFoundCount() {
	this->freeNotFoundCount++;
}

void Stats::displayResults(MemList memlist, FILE *fp) {
	if(fp == NULL) {
		fp = stdin;
	}
	// Print out the initial object
	fprintf(fp, "==================================\n");
	fprintf(fp, "%-20s %s\n", "ACTIONS ", "COUNT");
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "allocations: ", this->mallocCount);
	fprintf(fp, "%-20s %d\n", "    malloc", 0);
	fprintf(fp, "%-20s %d\n", "    calloc", 0);
	fprintf(fp, "%-20s %d\n", "    realloc", 0);
	fprintf(fp, "%-20s %d\n", "deallocations: ", this->freeCount);
	fprintf(fp, "%-20s %d\n", "    free ", this->freeCount);
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "invalid reads: ", this->invalidReadCount);
	fprintf(fp, "%-20s %d\n", "invalid writes: ", this->invalidWriteCount);
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "invalid frees: ", this->invalidFreeCount);
	fprintf(fp, "%-20s %d\n", "    not found: ", this->freeNotFoundCount);
	fprintf(fp, "%-20s %d\n", "    null free: ", this->freeNullCount);
	fprintf(fp, "%-20s %d\n", "    midchunk free: ", this->midFreeChunkCount);
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "fence hit: ", this->fenceHitCount);
	fprintf(fp, "%-20s %d\n", "    underflow: ", this->fenceUnderflowHitCount);
	fprintf(fp, "%-20s %d\n", "    overflow: ", this->fenceOverflowHitCount);
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "invalid returns: ", this->invalidReturnCount);
	fprintf(fp, "==================================\n");
	// Print out the contents of memlist if it was provided.
	fprintf(fp, "%-20s\n", "MEMLIST CONTENTS");
	char buffer[2048];
	int lostMemory = 0;
	for(int i = 0; i < memlist.size(); i++) {
		MemoryAlloc alloc = memlist.get(i);
		fprintf(fp, "%s\n", alloc.toString(buffer, 2048));
		lostMemory += alloc.getTotalSize();
	}
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "list size: ", memlist.size());
	fprintf(fp, "%-20s %d %s\n", "total loss: ", lostMemory, "bytes");
	fprintf(fp, "==================================\n");
}
<commit_msg>Adjutsed all mallocCount functions to use allocCount instead in preperation for tracking malloc, calloc, and realloc function calls..<commit_after>#include "stats.h"

Stats::Stats() {
	this->allocCount = 0;
	this->freeCount = 0;
	this->invalidReadCount = 0;
	this->invalidWriteCount = 0;
	this->fenceHitCount = 0;
	this->invalidFreeCount = 0;
	this->midFreeChunkCount = 0;
	this->freeNullCount = 0;
	this->invalidReturnCount = 0;
	this->fenceOverflowHitCount = 0;
	this->fenceUnderflowHitCount = 0;
}

void Stats::reset() {
	this->allocCount = 0;
	this->freeCount = 0;
	this->invalidReadCount = 0;
	this->invalidWriteCount = 0;
	this->fenceHitCount = 0;
	this->invalidFreeCount = 0;
	this->midFreeChunkCount = 0;
	this->freeNullCount = 0;
	this->invalidReturnCount = 0;
	this->fenceOverflowHitCount = 0;
	this->fenceUnderflowHitCount = 0;
}

unsigned int Stats::getAllocCount() {
	return this->allocCount;
}
unsigned int Stats::getFreeCount() {
	return this->freeCount;
}
unsigned int Stats::getInvalidReadCount() {
	return this->invalidReadCount;
}

unsigned int Stats::getInvalidWriteCount() {
	return this->invalidWriteCount;
}

unsigned int Stats::getFenceHitCount() {
	return this->fenceHitCount;
}

unsigned int Stats::getInvalidFreeCount() {
	return this->invalidFreeCount;
}

unsigned int Stats::getMidFreeChunkCount() {
	return this->midFreeChunkCount;
}

unsigned int Stats::getFreeNullCount() {
	return this->freeNullCount;
}

unsigned int Stats::getFreeNotFoundCount() {
	return this->freeNotFoundCount;
}

unsigned int Stats::getInvalidReturnCount() {
	return this->invalidReturnCount;
}

unsigned int Stats::getFenceOverflowHitCount() {
	return this->fenceOverflowHitCount;
}

unsigned int Stats::getFenceUnderflowHitCount() {
	return this->fenceUnderflowHitCount;
}

void Stats::setAllocCount(unsigned int count) {
	this->allocCount = count;
}

void Stats::setFreeCount(unsigned int count) {
	this->freeCount = count;
}

void Stats::setInvalidReadCount(unsigned int count) {
	this->invalidReadCount = count;
}

void Stats::setInvalidWriteCount(unsigned int count) {
	this->invalidWriteCount = count;
}

void Stats::setFenceHitCount(unsigned int count) {
	this->fenceHitCount = count;
}

void Stats::setInvalidFreeCount(unsigned int count) {
	this->invalidFreeCount = count;
}

void Stats::setMidFreeChunkCount(unsigned int count) {
	this->midFreeChunkCount = count;
}

void Stats::setFreeNullCount(unsigned int count) {
	this->freeNullCount = count;
}

void Stats::setInvalidReturnCount(unsigned int count) {
	this->invalidReturnCount = count;
}

void Stats::setFenceOverflowHitCount(unsigned int count) {
	this->fenceOverflowHitCount = count;
}

void Stats::setFenceUnderflowHitCount(unsigned int count) {
	this->fenceUnderflowHitCount = count;
}

void Stats::setFreeNotFoundCount(unsigned int count) {
	this->freeNotFoundCount = count;
}

void Stats::incAllocCount() {
	this->allocCount++;
}

void Stats::incFreeCount() {
	this->freeCount++;
}

void Stats::incInvalidReadCount() {
	this->invalidReadCount++;
}

void Stats::incInvalidWriteCount() {
	this->invalidWriteCount++;
}

void Stats::incFenceHitCount() {
	this->fenceHitCount++;
}

void Stats::incInvalidFreeCount() {
	this->invalidFreeCount++;
}

void Stats::incMidFreeChunkCount() {
	this->midFreeChunkCount++;
}

void Stats::incFreeNullCount() {
	this->freeNullCount++;
}

void Stats::incInvalidReturnCount() {
	this->invalidReturnCount++;
}

void Stats::incFenceOverflowHitCount() {
	this->fenceOverflowHitCount++;
}

void Stats::incFenceUnderflowHitCount() {
	this->fenceUnderflowHitCount++;
}

void Stats::incFreeNotFoundCount() {
	this->freeNotFoundCount++;
}

void Stats::displayResults(MemList memlist, FILE *fp) {
	if(fp == NULL) {
		fp = stdin;
	}
	// Print out the initial object
	fprintf(fp, "==================================\n");
	fprintf(fp, "%-20s %s\n", "ACTIONS ", "COUNT");
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "allocations: ", this->allocCount);
	fprintf(fp, "%-20s %d\n", "    malloc", 0);
	fprintf(fp, "%-20s %d\n", "    calloc", 0);
	fprintf(fp, "%-20s %d\n", "    realloc", 0);
	fprintf(fp, "%-20s %d\n", "deallocations: ", this->freeCount);
	fprintf(fp, "%-20s %d\n", "    free ", this->freeCount);
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "invalid reads: ", this->invalidReadCount);
	fprintf(fp, "%-20s %d\n", "invalid writes: ", this->invalidWriteCount);
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "invalid frees: ", this->invalidFreeCount);
	fprintf(fp, "%-20s %d\n", "    not found: ", this->freeNotFoundCount);
	fprintf(fp, "%-20s %d\n", "    null free: ", this->freeNullCount);
	fprintf(fp, "%-20s %d\n", "    midchunk free: ", this->midFreeChunkCount);
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "fence hit: ", this->fenceHitCount);
	fprintf(fp, "%-20s %d\n", "    underflow: ", this->fenceUnderflowHitCount);
	fprintf(fp, "%-20s %d\n", "    overflow: ", this->fenceOverflowHitCount);
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "invalid returns: ", this->invalidReturnCount);
	fprintf(fp, "==================================\n");
	// Print out the contents of memlist if it was provided.
	fprintf(fp, "%-20s\n", "MEMLIST CONTENTS");
	char buffer[2048];
	int lostMemory = 0;
	for(int i = 0; i < memlist.size(); i++) {
		MemoryAlloc alloc = memlist.get(i);
		fprintf(fp, "%s\n", alloc.toString(buffer, 2048));
		lostMemory += alloc.getTotalSize();
	}
	fprintf(fp, "----------------------------------\n");
	fprintf(fp, "%-20s %d\n", "list size: ", memlist.size());
	fprintf(fp, "%-20s %d %s\n", "total loss: ", lostMemory, "bytes");
	fprintf(fp, "==================================\n");
}
<|endoftext|>


<commit_before>/*
    kopeteviewmanager.cpp - View Manager

    Copyright (c) 2003      by Jason Keirstead       <jason@keirstead.org>
    Kopete    (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * 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; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include <QList>
#include <QTextDocument>
#include <QtAlgorithms>

#include <kapplication.h>
#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <kplugininfo.h>
#include <knotification.h>
#include <kglobal.h>
#include <kwin.h>

#include "kopetebehaviorsettings.h"
#include "kopeteaccount.h"
#include "kopetepluginmanager.h"
#include "kopeteviewplugin.h"
#include "kopetechatsessionmanager.h"
#include "kopetemetacontact.h"
#include "kopetemessageevent.h"
#include "kopeteview.h"
#include "kopetechatsession.h"
#include "kopetegroup.h"

#include "kopeteviewmanager.h"

typedef QMap<Kopete::ChatSession*,KopeteView*> ManagerMap;
typedef QList<Kopete::MessageEvent*> EventList;

struct KopeteViewManagerPrivate
{
    ~KopeteViewManagerPrivate()
    {
        qDeleteAll(managerMap);
        managerMap.clear();
        qDeleteAll(eventList);
        eventList.clear();
    }

    ManagerMap managerMap;
    EventList eventList;
    KopeteView *activeView;

    bool useQueueOrStack;
    bool raiseWindow;
    bool queueUnreadMessages;
    bool queueOnlyHighlightedMessagesInGroupChats;
    bool queueOnlyMessagesOnAnotherDesktop;
    bool balloonNotifyIgnoreClosesChatView;
    bool foreignMessage;
};

KopeteViewManager *KopeteViewManager::s_viewManager = 0L;

KopeteViewManager *KopeteViewManager::viewManager()
{
    if( !s_viewManager )
            s_viewManager = new KopeteViewManager();
    return s_viewManager;
}

KopeteViewManager::KopeteViewManager()
{
    s_viewManager=this;
    d = new KopeteViewManagerPrivate;
    d->activeView = 0L;
    d->foreignMessage=false;

    connect( Kopete::BehaviorSettings::self(), SIGNAL( configChanged() ), this, SLOT( slotPrefsChanged() ) );

    connect( Kopete::ChatSessionManager::self() , SIGNAL( display( Kopete::Message &, Kopete::ChatSession *) ),
            this, SLOT ( messageAppended( Kopete::Message &, Kopete::ChatSession *) ) );

    connect( Kopete::ChatSessionManager::self() , SIGNAL( readMessage() ),
            this, SLOT ( nextEvent() ) );

    slotPrefsChanged();
}

KopeteViewManager::~KopeteViewManager()
{
// 	kDebug(14000) << k_funcinfo << endl;

    //delete all open chatwindow.
    ManagerMap::Iterator it;
    for ( it = d->managerMap.begin(); it != d->managerMap.end(); ++it )
    {
        it.value()->closeView( true ); //this does not clean the map, but we don't care
    }

    delete d;
}

void KopeteViewManager::slotPrefsChanged()
{
	d->useQueueOrStack = Kopete::BehaviorSettings::self()->useMessageQueue() || Kopete::BehaviorSettings::self()->useMessageStack();
    d->raiseWindow = Kopete::BehaviorSettings::self()->raiseMessageWindow();
    d->queueUnreadMessages = Kopete::BehaviorSettings::self()->queueUnreadMessages();
    d->queueOnlyHighlightedMessagesInGroupChats = Kopete::BehaviorSettings::self()->queueOnlyHighlightedMessagesInGroupChats();
    d->queueOnlyMessagesOnAnotherDesktop = Kopete::BehaviorSettings::self()->queueOnlyMessagesOnAnotherDesktop();
    d->balloonNotifyIgnoreClosesChatView = Kopete::BehaviorSettings::self()->balloonNotifyIgnoreClosesChatView();
}

KopeteView *KopeteViewManager::view( Kopete::ChatSession* session, const QString &requestedPlugin )
{
    // kDebug(14000) << k_funcinfo << endl;

    if( d->managerMap.contains( session ) && d->managerMap[ session ] )
    {
        return d->managerMap[ session ];
    }
    else
    {
        Kopete::PluginManager *pluginManager = Kopete::PluginManager::self();
        Kopete::ViewPlugin *viewPlugin = 0L;

        QString pluginName = requestedPlugin.isEmpty() ? Kopete::BehaviorSettings::self()->viewPlugin() : requestedPlugin;
        if( !pluginName.isEmpty() )
        {
            viewPlugin = (Kopete::ViewPlugin*)pluginManager->loadPlugin( pluginName );

            if( !viewPlugin )
            {
                kWarning(14000) << "Requested view plugin, " << pluginName
                                 << ", was not found. Falling back to chat window plugin" << endl;
            }
        }

        if( !viewPlugin )
        {
            viewPlugin = (Kopete::ViewPlugin*)pluginManager->loadPlugin( QString::fromLatin1("kopete_chatwindow") );
        }

        if( viewPlugin )
        {
            KopeteView *newView = viewPlugin->createView(session);

            d->foreignMessage = false;
            d->managerMap.insert( session, newView );

            connect( session, SIGNAL( closing(Kopete::ChatSession *) ),
                            this, SLOT(slotChatSessionDestroyed(Kopete::ChatSession*)) );

            return newView;
        }
        else
        {
            kError(14000) << "Could not create a view, no plugins available!" << endl;
            return 0L;
        }
    }
}

void KopeteViewManager::messageAppended( Kopete::Message &msg, Kopete::ChatSession *manager)
{
    // kDebug(14000) << k_funcinfo << endl;

    bool outgoingMessage = ( msg.direction() == Kopete::Message::Outbound );

    if( !outgoingMessage || d->managerMap.contains( manager ) )
    {
        d->foreignMessage=!outgoingMessage; //let know for the view we are about to create
        manager->view(true,msg.requestedPlugin())->appendMessage( msg );
        d->foreignMessage=false; //the view is created, reset the flag

		bool appendMessageEvent = d->useQueueOrStack;

		QWidget *w;
		if( d->queueUnreadMessages && ( w = dynamic_cast<QWidget*>(view( manager )) ) )
		{
			// append msg event to queue if chat window is active but not the chat view in it...
			appendMessageEvent = appendMessageEvent && !(w->isActiveWindow() && manager->view() == d->activeView);
			// ...and chat window is on another desktop
			appendMessageEvent = appendMessageEvent && (!d->queueOnlyMessagesOnAnotherDesktop || !KWin::windowInfo( w->topLevelWidget()->winId(), NET::WMDesktop ).isOnCurrentDesktop());
		}
		else
		{
			// append if no chat window exists already
			appendMessageEvent = appendMessageEvent && !view( manager )->isVisible();
		}

		// in group chats always append highlighted messages to queue
		appendMessageEvent = appendMessageEvent && (!d->queueOnlyHighlightedMessagesInGroupChats || manager->members().count() == 1 || msg.importance() == Kopete::Message::Highlight);

        if( appendMessageEvent )
        {
            if ( !outgoingMessage )
            {
                Kopete::MessageEvent *event=new Kopete::MessageEvent(msg,manager);
                d->eventList.append( event );
                connect(event, SIGNAL(done(Kopete::MessageEvent *)), this, SLOT(slotEventDeleted(Kopete::MessageEvent *)));
                Kopete::ChatSessionManager::self()->postNewEvent(event);
            }
        }
        else if( d->eventList.isEmpty() )
        {
            readMessages( manager, outgoingMessage );
        }

		if ( !outgoingMessage && ( !manager->account()->isAway() || Kopete::BehaviorSettings::self()->enableEventsWhileAway() ) )
		{
			QWidget *w=dynamic_cast<QWidget*>(manager->view(false));
			if( (!manager->view(false) || !w || manager->view() != d->activeView ||
						   Kopete::BehaviorSettings::self()->showEventsIfActive() || !w->isActiveWindow())
						   && msg.from())
			{
				QString msgFrom;
				msgFrom.clear();
				if( msg.from()->metaContact() )
					msgFrom = msg.from()->metaContact()->displayName();
				else
					msgFrom = msg.from()->contactId();

				QString msgText = msg.plainBody();
				if( msgText.length() > 90 )
					msgText = msgText.left(88) + QString::fromLatin1("...");

				QString event;
				KLocalizedString body = ki18n( "<qt>Incoming message from %1
\"%2\"</qt>" );
				switch( msg.importance() )
				{
					case Kopete::Message::Low:
						event = QString::fromLatin1( "kopete_contact_lowpriority" );
						break;
					case Kopete::Message::Highlight:
						event = QString::fromLatin1( "kopete_contact_highlight" );
						body = ki18n( "<qt>A highlighted message arrived from %1
\"%2\"</qt>" );
						break;
					default:
						event = QString::fromLatin1( "kopete_contact_incoming" );
				}
				KNotification::ContextList contexts;
				Kopete::MetaContact *mc= msg.from()->metaContact();
				if(mc)
				{
					contexts.append( qMakePair( QString::fromLatin1("metacontact") , mc->metaContactId()) );
					foreach( Kopete::Group *g , mc->groups() )
					{
						contexts.append( qMakePair( QString::fromLatin1("group") , QString::number(g->groupId())) );
					}
				}
                KNotification *notify=KNotification::event( event,
						body.subs( Qt::escape(msgFrom) ).subs( Qt::escape(msgText) ).toString(),
						QPixmap(), w, QStringList( i18n( "View" ) ) , contexts );

				connect(notify,SIGNAL(activated(unsigned int )), manager , SLOT(raiseView()) );
			}
		}
	}
}

void KopeteViewManager::readMessages( Kopete::ChatSession *manager, bool outgoingMessage, bool activate )
{
    // kDebug( 14000 ) << k_funcinfo << endl;
    d->foreignMessage=!outgoingMessage; //let know for the view we are about to create
    KopeteView *thisView = manager->view( true );
    d->foreignMessage=false; //the view is created, reset the flag
    if( ( outgoingMessage && !thisView->isVisible() ) || d->raiseWindow || activate )
            thisView->raise( activate );
    else if( !thisView->isVisible() )
            thisView->makeVisible();

    foreach (Kopete::MessageEvent *event, d->eventList)
    {
        if ( event->message().manager() == manager )
        {
            event->apply();
            d->eventList.removeAll(event);
        }
    }
}

void KopeteViewManager::slotEventDeleted( Kopete::MessageEvent *event )
{
    // kDebug(14000) << k_funcinfo << endl;
    Kopete::ChatSession *kmm=event->message().manager();
    if(!kmm)
            return;

    // d->eventList.remove( event );
    d->eventList.removeAll(event);

    if ( event->state() == Kopete::MessageEvent::Applied )
    {
        readMessages( kmm, false, true );
    }
    else if ( event->state() == Kopete::MessageEvent::Ignored && d->balloonNotifyIgnoreClosesChatView )
    {
        bool bAnotherWithThisManager = false;
        foreach (Kopete::MessageEvent *event, d->eventList)
        {
            if ( event->message().manager() == kmm )
            {
                bAnotherWithThisManager = true;
            }
        }
        if ( !bAnotherWithThisManager && kmm->view( false ) )
            kmm->view()->closeView( true );
    }
}

void KopeteViewManager::nextEvent()
{
    // kDebug( 14000 ) << k_funcinfo << endl;

    if( d->eventList.isEmpty() )
        return;

    Kopete::MessageEvent* event = d->eventList.first();

    if ( event )
        event->apply();
}

void KopeteViewManager::slotViewActivated( KopeteView *view )
{
    // kDebug( 14000 ) << k_funcinfo << endl;
    d->activeView = view;

    foreach (Kopete::MessageEvent *event, d->eventList)
    {
        if ( event->message().manager() == view->msgManager() )
        {
            event->deleteLater();
        }
    }
}

void KopeteViewManager::slotViewDestroyed( KopeteView *closingView )
{
    // kDebug( 14000 ) << k_funcinfo << endl;

    if( d->managerMap.contains( closingView->msgManager() ) )
    {
        d->managerMap.remove( closingView->msgManager() );
        // closingView->msgManager()->setCanBeDeleted( true );
    }

    if( closingView == d->activeView )
        d->activeView = 0L;
}

void KopeteViewManager::slotChatSessionDestroyed( Kopete::ChatSession *manager )
{
    // kDebug( 14000 ) << k_funcinfo << endl;

    if( d->managerMap.contains( manager ) )
    {
        d->managerMap[ manager ]->closeView( true );
    }
}

KopeteView* KopeteViewManager::activeView() const
{
    return d->activeView;
}

#include "kopeteviewmanager.moc"

// vim: set noet ts=4 sts=4 sw=4:

<commit_msg>port to new snapshot<commit_after>/*
    kopeteviewmanager.cpp - View Manager

    Copyright (c) 2003      by Jason Keirstead       <jason@keirstead.org>
    Kopete    (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * 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; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include <QList>
#include <QTextDocument>
#include <QtAlgorithms>

#include <kapplication.h>
#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <kplugininfo.h>
#include <knotification.h>
#include <kglobal.h>
#include <kwin.h>

#include "kopetebehaviorsettings.h"
#include "kopeteaccount.h"
#include "kopetepluginmanager.h"
#include "kopeteviewplugin.h"
#include "kopetechatsessionmanager.h"
#include "kopetemetacontact.h"
#include "kopetemessageevent.h"
#include "kopeteview.h"
#include "kopetechatsession.h"
#include "kopetegroup.h"

#include "kopeteviewmanager.h"

typedef QMap<Kopete::ChatSession*,KopeteView*> ManagerMap;
typedef QList<Kopete::MessageEvent*> EventList;

struct KopeteViewManagerPrivate
{
    ~KopeteViewManagerPrivate()
    {
        qDeleteAll(managerMap);
        managerMap.clear();
        qDeleteAll(eventList);
        eventList.clear();
    }

    ManagerMap managerMap;
    EventList eventList;
    KopeteView *activeView;

    bool useQueueOrStack;
    bool raiseWindow;
    bool queueUnreadMessages;
    bool queueOnlyHighlightedMessagesInGroupChats;
    bool queueOnlyMessagesOnAnotherDesktop;
    bool balloonNotifyIgnoreClosesChatView;
    bool foreignMessage;
};

KopeteViewManager *KopeteViewManager::s_viewManager = 0L;

KopeteViewManager *KopeteViewManager::viewManager()
{
    if( !s_viewManager )
            s_viewManager = new KopeteViewManager();
    return s_viewManager;
}

KopeteViewManager::KopeteViewManager()
{
    s_viewManager=this;
    d = new KopeteViewManagerPrivate;
    d->activeView = 0L;
    d->foreignMessage=false;

    connect( Kopete::BehaviorSettings::self(), SIGNAL( configChanged() ), this, SLOT( slotPrefsChanged() ) );

    connect( Kopete::ChatSessionManager::self() , SIGNAL( display( Kopete::Message &, Kopete::ChatSession *) ),
            this, SLOT ( messageAppended( Kopete::Message &, Kopete::ChatSession *) ) );

    connect( Kopete::ChatSessionManager::self() , SIGNAL( readMessage() ),
            this, SLOT ( nextEvent() ) );

    slotPrefsChanged();
}

KopeteViewManager::~KopeteViewManager()
{
// 	kDebug(14000) << k_funcinfo << endl;

    //delete all open chatwindow.
    ManagerMap::Iterator it;
    for ( it = d->managerMap.begin(); it != d->managerMap.end(); ++it )
    {
        it.value()->closeView( true ); //this does not clean the map, but we don't care
    }

    delete d;
}

void KopeteViewManager::slotPrefsChanged()
{
	d->useQueueOrStack = Kopete::BehaviorSettings::self()->useMessageQueue() || Kopete::BehaviorSettings::self()->useMessageStack();
    d->raiseWindow = Kopete::BehaviorSettings::self()->raiseMessageWindow();
    d->queueUnreadMessages = Kopete::BehaviorSettings::self()->queueUnreadMessages();
    d->queueOnlyHighlightedMessagesInGroupChats = Kopete::BehaviorSettings::self()->queueOnlyHighlightedMessagesInGroupChats();
    d->queueOnlyMessagesOnAnotherDesktop = Kopete::BehaviorSettings::self()->queueOnlyMessagesOnAnotherDesktop();
    d->balloonNotifyIgnoreClosesChatView = Kopete::BehaviorSettings::self()->balloonNotifyIgnoreClosesChatView();
}

KopeteView *KopeteViewManager::view( Kopete::ChatSession* session, const QString &requestedPlugin )
{
    // kDebug(14000) << k_funcinfo << endl;

    if( d->managerMap.contains( session ) && d->managerMap[ session ] )
    {
        return d->managerMap[ session ];
    }
    else
    {
        Kopete::PluginManager *pluginManager = Kopete::PluginManager::self();
        Kopete::ViewPlugin *viewPlugin = 0L;

        QString pluginName = requestedPlugin.isEmpty() ? Kopete::BehaviorSettings::self()->viewPlugin() : requestedPlugin;
        if( !pluginName.isEmpty() )
        {
            viewPlugin = (Kopete::ViewPlugin*)pluginManager->loadPlugin( pluginName );

            if( !viewPlugin )
            {
                kWarning(14000) << "Requested view plugin, " << pluginName
                                 << ", was not found. Falling back to chat window plugin" << endl;
            }
        }

        if( !viewPlugin )
        {
            viewPlugin = (Kopete::ViewPlugin*)pluginManager->loadPlugin( QString::fromLatin1("kopete_chatwindow") );
        }

        if( viewPlugin )
        {
            KopeteView *newView = viewPlugin->createView(session);

            d->foreignMessage = false;
            d->managerMap.insert( session, newView );

            connect( session, SIGNAL( closing(Kopete::ChatSession *) ),
                            this, SLOT(slotChatSessionDestroyed(Kopete::ChatSession*)) );

            return newView;
        }
        else
        {
            kError(14000) << "Could not create a view, no plugins available!" << endl;
            return 0L;
        }
    }
}

void KopeteViewManager::messageAppended( Kopete::Message &msg, Kopete::ChatSession *manager)
{
    // kDebug(14000) << k_funcinfo << endl;

    bool outgoingMessage = ( msg.direction() == Kopete::Message::Outbound );

    if( !outgoingMessage || d->managerMap.contains( manager ) )
    {
        d->foreignMessage=!outgoingMessage; //let know for the view we are about to create
        manager->view(true,msg.requestedPlugin())->appendMessage( msg );
        d->foreignMessage=false; //the view is created, reset the flag

		bool appendMessageEvent = d->useQueueOrStack;

		QWidget *w;
		if( d->queueUnreadMessages && ( w = dynamic_cast<QWidget*>(view( manager )) ) )
		{
			// append msg event to queue if chat window is active but not the chat view in it...
			appendMessageEvent = appendMessageEvent && !(w->isActiveWindow() && manager->view() == d->activeView);
			// ...and chat window is on another desktop
			appendMessageEvent = appendMessageEvent && (!d->queueOnlyMessagesOnAnotherDesktop || !KWin::windowInfo( w->topLevelWidget()->winId(), NET::WMDesktop ).isOnCurrentDesktop());
		}
		else
		{
			// append if no chat window exists already
			appendMessageEvent = appendMessageEvent && !view( manager )->isVisible();
		}

		// in group chats always append highlighted messages to queue
		appendMessageEvent = appendMessageEvent && (!d->queueOnlyHighlightedMessagesInGroupChats || manager->members().count() == 1 || msg.importance() == Kopete::Message::Highlight);

        if( appendMessageEvent )
        {
            if ( !outgoingMessage )
            {
                Kopete::MessageEvent *event=new Kopete::MessageEvent(msg,manager);
                d->eventList.append( event );
                connect(event, SIGNAL(done(Kopete::MessageEvent *)), this, SLOT(slotEventDeleted(Kopete::MessageEvent *)));
                Kopete::ChatSessionManager::self()->postNewEvent(event);
            }
        }
        else if( d->eventList.isEmpty() )
        {
            readMessages( manager, outgoingMessage );
        }

		if ( !outgoingMessage && ( !manager->account()->isAway() || Kopete::BehaviorSettings::self()->enableEventsWhileAway() ) )
		{
			QWidget *w=dynamic_cast<QWidget*>(manager->view(false));
			if( (!manager->view(false) || !w || manager->view() != d->activeView ||
						   Kopete::BehaviorSettings::self()->showEventsIfActive() || !w->isActiveWindow())
						   && msg.from())
			{
				QString msgFrom;
				msgFrom.clear();
				if( msg.from()->metaContact() )
					msgFrom = msg.from()->metaContact()->displayName();
				else
					msgFrom = msg.from()->contactId();

				QString msgText = msg.plainBody();
				if( msgText.length() > 90 )
					msgText = msgText.left(88) + QString::fromLatin1("...");

				QString event;
				KLocalizedString body = ki18n( "<qt>Incoming message from %1
\"%2\"</qt>" );
				switch( msg.importance() )
				{
					case Kopete::Message::Low:
						event = QString::fromLatin1( "kopete_contact_lowpriority" );
						break;
					case Kopete::Message::Highlight:
						event = QString::fromLatin1( "kopete_contact_highlight" );
						body = ki18n( "<qt>A highlighted message arrived from %1
\"%2\"</qt>" );
						break;
					default:
						event = QString::fromLatin1( "kopete_contact_incoming" );
				}
				KNotification *notify=new KNotification(event, w);
				notify->setText(body.subs( Qt::escape(msgFrom) ).subs( Qt::escape(msgText) ).toString());
				notify->setActions(QStringList( i18n( "View" ) ));

				Kopete::MetaContact *mc= msg.from()->metaContact();
				if(mc)
				{
					notify->addContext( qMakePair( QString::fromLatin1("metacontact") , mc->metaContactId()) );
					foreach( Kopete::Group *g , mc->groups() )
					{
						notify->addContext( qMakePair( QString::fromLatin1("group") , QString::number(g->groupId())) );
					}
				}
				connect(notify,SIGNAL(activated(unsigned int )), manager , SLOT(raiseView()) );
				notify->sendEvent();
			}
		}
	}
}

void KopeteViewManager::readMessages( Kopete::ChatSession *manager, bool outgoingMessage, bool activate )
{
    // kDebug( 14000 ) << k_funcinfo << endl;
    d->foreignMessage=!outgoingMessage; //let know for the view we are about to create
    KopeteView *thisView = manager->view( true );
    d->foreignMessage=false; //the view is created, reset the flag
    if( ( outgoingMessage && !thisView->isVisible() ) || d->raiseWindow || activate )
            thisView->raise( activate );
    else if( !thisView->isVisible() )
            thisView->makeVisible();

    foreach (Kopete::MessageEvent *event, d->eventList)
    {
        if ( event->message().manager() == manager )
        {
            event->apply();
            d->eventList.removeAll(event);
        }
    }
}

void KopeteViewManager::slotEventDeleted( Kopete::MessageEvent *event )
{
    // kDebug(14000) << k_funcinfo << endl;
    Kopete::ChatSession *kmm=event->message().manager();
    if(!kmm)
            return;

    // d->eventList.remove( event );
    d->eventList.removeAll(event);

    if ( event->state() == Kopete::MessageEvent::Applied )
    {
        readMessages( kmm, false, true );
    }
    else if ( event->state() == Kopete::MessageEvent::Ignored && d->balloonNotifyIgnoreClosesChatView )
    {
        bool bAnotherWithThisManager = false;
        foreach (Kopete::MessageEvent *event, d->eventList)
        {
            if ( event->message().manager() == kmm )
            {
                bAnotherWithThisManager = true;
            }
        }
        if ( !bAnotherWithThisManager && kmm->view( false ) )
            kmm->view()->closeView( true );
    }
}

void KopeteViewManager::nextEvent()
{
    // kDebug( 14000 ) << k_funcinfo << endl;

    if( d->eventList.isEmpty() )
        return;

    Kopete::MessageEvent* event = d->eventList.first();

    if ( event )
        event->apply();
}

void KopeteViewManager::slotViewActivated( KopeteView *view )
{
    // kDebug( 14000 ) << k_funcinfo << endl;
    d->activeView = view;

    foreach (Kopete::MessageEvent *event, d->eventList)
    {
        if ( event->message().manager() == view->msgManager() )
        {
            event->deleteLater();
        }
    }
}

void KopeteViewManager::slotViewDestroyed( KopeteView *closingView )
{
    // kDebug( 14000 ) << k_funcinfo << endl;

    if( d->managerMap.contains( closingView->msgManager() ) )
    {
        d->managerMap.remove( closingView->msgManager() );
        // closingView->msgManager()->setCanBeDeleted( true );
    }

    if( closingView == d->activeView )
        d->activeView = 0L;
}

void KopeteViewManager::slotChatSessionDestroyed( Kopete::ChatSession *manager )
{
    // kDebug( 14000 ) << k_funcinfo << endl;

    if( d->managerMap.contains( manager ) )
    {
        d->managerMap[ manager ]->closeView( true );
    }
}

KopeteView* KopeteViewManager::activeView() const
{
    return d->activeView;
}

#include "kopeteviewmanager.moc"

// vim: set noet ts=4 sts=4 sw=4:

<|endoftext|>