<commit_before>#include "easypr/core/plate_detect.h"
#include "easypr/util/util.h"

namespace easypr {

  CPlateDetect::CPlateDetect() {
    m_plateLocate = new CPlateLocate();

    m_maxPlates = 3;
    m_type = 0;

    m_showDetect = false;
  }

  CPlateDetect::~CPlateDetect() { SAFE_RELEASE(m_plateLocate); }

  int CPlateDetect::plateDetect(Mat src, std::vector<CPlate> &resultVec, int type,
    bool showDetectArea, int img_index) {

    std::vector<CPlate> color_Plates;
    std::vector<CPlate> sobel_Plates;
    std::vector<CPlate> mser_Plates;

    std::vector<CPlate> all_result_Plates;
    if ( !type || type & PR_DETECT_SOBEL) {
      m_plateLocate->plateSobelLocate(src, sobel_Plates, img_index);
      std::vector<CPlate>& sobel_result_Plates = sobel_Plates;

      for (size_t i = 0; i < sobel_result_Plates.size(); i++) {
        CPlate plate = sobel_result_Plates[i];
        plate.setPlateLocateType(SOBEL);

        all_result_Plates.push_back(plate);
      }
    }

    if ( !type || type & PR_DETECT_COLOR) {
      m_plateLocate->plateColorLocate(src, color_Plates, img_index);
      std::vector<CPlate>& color_result_Plates = color_Plates;

      for (size_t i = 0; i < color_result_Plates.size(); i++) {
        CPlate plate = color_result_Plates[i];

        plate.setPlateLocateType(COLOR);
        all_result_Plates.push_back(plate);
      }
    }

    if ( !type || type & PR_DETECT_CMSER) {
      m_plateLocate->plateMserLocate(src, mser_Plates, img_index);
      std::vector<CPlate>& mser_result_Plates = mser_Plates;

      for (size_t i = 0; i < mser_result_Plates.size(); i++) {
        CPlate plate = mser_result_Plates[i];

        plate.setPlateLocateType(CMSER);
        all_result_Plates.push_back(plate);
      }
    }

    // ʹ÷Ǽֵжϳ
    PlateJudge::instance()->plateJudgeUsingNMS(all_result_Plates, resultVec, m_maxPlates);

    if (showDetectArea || getDetectShow()) {
      int index = 0;

      Mat result;
      src.copyTo(result);

      for (size_t j = 0; j < resultVec.size(); j++) {
        CPlate item = resultVec[j];
        Mat plate = item.getPlateMat();

        int height = 36;
        int width = 136;
        if (height * index + height < result.rows) {
          Mat imageRoi = result(Rect(0, 0 + height * index, width, height));
          addWeighted(imageRoi, 0, plate, 1, 0, imageRoi);
        }
        index++;

        RotatedRect minRect = item.getPlatePos();
        Point2f rect_points[4];
        minRect.points(rect_points);

        Scalar lineColor = Scalar(255, 255, 255);

        if (item.getPlateLocateType() == SOBEL) lineColor = Scalar(255, 0, 0);
        if (item.getPlateLocateType() == COLOR) lineColor = Scalar(0, 255, 0);
        if (item.getPlateLocateType() == CMSER) lineColor = Scalar(0, 0, 255);

        for (int j = 0; j < 4; j++)
          line(result, rect_points[j], rect_points[(j + 1) % 4], lineColor, 2, 8);
      }

      //ʾλͼƬ
      showResult(result, img_index);
    }

    /*if (0) {
      Mat result = src.clone();
      for (size_t i = 0; i < all_result_Plates.size(); i++) {
        CPlate plate = all_result_Plates.at(i);

        Rect_<float> outputRect;
        calcSafeRect(plate.getPlatePos(), src, outputRect);
        cv::rectangle(result, outputRect, Scalar(0, 0, 255));

        if (0){
          std::stringstream ss(std::stringstream::in | std::stringstream::out);
          ss << "resources/image/tmp/plate_" << index << "_" << i << ".jpg";
          imwrite(ss.str(), src(outputRect));
        }
      }

      if (0) {
        imshow("result", result);
        waitKey(0);
        destroyWindow("result");
      }
    }*/

    return 0;
  }

  int CPlateDetect::plateDetect(Mat src, std::vector<CPlate> &resultVec, int img_index) {
    int result = plateDetect(src, resultVec, m_type, false, img_index);
    return result;
  }

  void CPlateDetect::LoadSVM(std::string path) {
    PlateJudge::instance()->LoadModel(path);
  }

  int CPlateDetect::showResult(const Mat &result, int img_index) {
    namedWindow("EasyPR", CV_WINDOW_AUTOSIZE);

    const int RESULTWIDTH = 640;   // 640 930
    const int RESULTHEIGHT = 540;  // 540 710

    Mat img_window;
    img_window.create(RESULTHEIGHT, RESULTWIDTH, CV_8UC3);

    int nRows = result.rows;
    int nCols = result.cols;

    Mat result_resize;
    if (nCols <= img_window.cols && nRows <= img_window.rows) {
      result_resize = result;

    }
    else if (nCols > img_window.cols && nRows <= img_window.rows) {
      float scale = float(img_window.cols) / float(nCols);
      resize(result, result_resize, Size(), scale, scale, CV_INTER_AREA);

    }
    else if (nCols <= img_window.cols && nRows > img_window.rows) {
      float scale = float(img_window.rows) / float(nRows);
      resize(result, result_resize, Size(), scale, scale, CV_INTER_AREA);

    }
    else if (nCols > img_window.cols && nRows > img_window.rows) {
      Mat result_middle;
      float scale = float(img_window.cols) / float(nCols);
      resize(result, result_middle, Size(), scale, scale, CV_INTER_AREA);

      if (result_middle.rows > img_window.rows) {
        float scale = float(img_window.rows) / float(result_middle.rows);
        resize(result_middle, result_resize, Size(), scale, scale, CV_INTER_AREA);
      }
      else {
        result_resize = result_middle;
      }
    }
    else {
      result_resize = result;
    }

    Mat imageRoi = img_window(Rect((RESULTWIDTH - result_resize.cols) / 2,
      (RESULTHEIGHT - result_resize.rows) / 2,
      result_resize.cols, result_resize.rows));
    addWeighted(imageRoi, 0, result_resize, 1, 0, imageRoi);

    if (1) {
      imshow("EasyPR", img_window);
      waitKey(0);
      destroyWindow("EasyPR");
    }

    if (1) {
      std::stringstream ss(std::stringstream::in | std::stringstream::out);
      ss << "resources/image/tmp/Result/plate_" << img_index << ".jpg";
      imwrite(ss.str(), img_window);
    }

    return 0;
  }
}<commit_msg>* fix #32.<commit_after>#include "easypr/core/plate_detect.h"
#include "easypr/util/util.h"

namespace easypr {

  CPlateDetect::CPlateDetect() {
    m_plateLocate = new CPlateLocate();

    m_maxPlates = 3;
    m_type = 0;

    m_showDetect = false;
  }

  CPlateDetect::~CPlateDetect() { SAFE_RELEASE(m_plateLocate); }

  int CPlateDetect::plateDetect(Mat src, std::vector<CPlate> &resultVec, int type,
    bool showDetectArea, int img_index) {

    std::vector<CPlate> color_Plates;
    std::vector<CPlate> sobel_Plates;
    std::vector<CPlate> mser_Plates;

    std::vector<CPlate> all_result_Plates;
    if ( !type || type & PR_DETECT_SOBEL) {
      m_plateLocate->plateSobelLocate(src, sobel_Plates, img_index);
      std::vector<CPlate>& sobel_result_Plates = sobel_Plates;

      for (size_t i = 0; i < sobel_result_Plates.size(); i++) {
        CPlate plate = sobel_result_Plates[i];
        plate.setPlateLocateType(SOBEL);

        all_result_Plates.push_back(plate);
      }
    }

    if ( !type || type & PR_DETECT_COLOR) {
      m_plateLocate->plateColorLocate(src, color_Plates, img_index);
      std::vector<CPlate>& color_result_Plates = color_Plates;

      for (size_t i = 0; i < color_result_Plates.size(); i++) {
        CPlate plate = color_result_Plates[i];

        plate.setPlateLocateType(COLOR);
        all_result_Plates.push_back(plate);
      }
    }

    if ( !type || type & PR_DETECT_CMSER) {
      m_plateLocate->plateMserLocate(src, mser_Plates, img_index);
      std::vector<CPlate>& mser_result_Plates = mser_Plates;

      for (size_t i = 0; i < mser_result_Plates.size(); i++) {
        CPlate plate = mser_result_Plates[i];

        plate.setPlateLocateType(CMSER);
        all_result_Plates.push_back(plate);
      }
    }

    // ʹ÷Ǽֵжϳ
    PlateJudge::instance()->plateJudgeUsingNMS(all_result_Plates, resultVec, m_maxPlates);

    if (showDetectArea || getDetectShow()) {
      int index = 0;

      Mat result;
      src.copyTo(result);

      for (size_t j = 0; j < resultVec.size(); j++) {
        CPlate item = resultVec[j];
        Mat plate = item.getPlateMat();

        int height = 36;
        int width = 136;
        if (height * index + height < result.rows) {
          Mat imageRoi = result(Rect(0, 0 + height * index, width, height));
          addWeighted(imageRoi, 0, plate, 1, 0, imageRoi);
        }
        index++;

        RotatedRect minRect = item.getPlatePos();
        Point2f rect_points[4];
        minRect.points(rect_points);

        Scalar lineColor = Scalar(255, 255, 255);

        if (item.getPlateLocateType() == SOBEL) lineColor = Scalar(255, 0, 0);
        if (item.getPlateLocateType() == COLOR) lineColor = Scalar(0, 255, 0);
        if (item.getPlateLocateType() == CMSER) lineColor = Scalar(0, 0, 255);

        for (int j = 0; j < 4; j++)
          line(result, rect_points[j], rect_points[(j + 1) % 4], lineColor, 2, 8);
      }

      //ʾλͼƬ
      showResult(result, img_index);
    }

    /*if (0) {
      Mat result = src.clone();
      for (size_t i = 0; i < all_result_Plates.size(); i++) {
        CPlate plate = all_result_Plates.at(i);

        Rect_<float> outputRect;
        calcSafeRect(plate.getPlatePos(), src, outputRect);
        cv::rectangle(result, outputRect, Scalar(0, 0, 255));

        if (0){
          std::stringstream ss(std::stringstream::in | std::stringstream::out);
          ss << "resources/image/tmp/plate_" << index << "_" << i << ".jpg";
          imwrite(ss.str(), src(outputRect));
        }
      }

      if (0) {
        imshow("result", result);
        waitKey(0);
        destroyWindow("result");
      }
    }*/

    return 0;
  }

  int CPlateDetect::plateDetect(Mat src, std::vector<CPlate> &resultVec, int img_index) {
    int result = plateDetect(src, resultVec, m_type, false, img_index);
    return result;
  }

  void CPlateDetect::LoadSVM(std::string path) {
    PlateJudge::instance()->LoadModel(path);
  }

  int CPlateDetect::showResult(const Mat &result, int img_index) {
    namedWindow("EasyPR", CV_WINDOW_AUTOSIZE);

    const int RESULTWIDTH = 640;   // 640 930
    const int RESULTHEIGHT = 540;  // 540 710

    Mat img_window;
    img_window.create(RESULTHEIGHT, RESULTWIDTH, CV_8UC3);

    int nRows = result.rows;
    int nCols = result.cols;

    Mat result_resize;
    if (nCols <= img_window.cols && nRows <= img_window.rows) {
      result_resize = result;

    }
    else if (nCols > img_window.cols && nRows <= img_window.rows) {
      float scale = float(img_window.cols) / float(nCols);
      resize(result, result_resize, Size(), scale, scale, CV_INTER_AREA);

    }
    else if (nCols <= img_window.cols && nRows > img_window.rows) {
      float scale = float(img_window.rows) / float(nRows);
      resize(result, result_resize, Size(), scale, scale, CV_INTER_AREA);

    }
    else if (nCols > img_window.cols && nRows > img_window.rows) {
      Mat result_middle;
      float scale = float(img_window.cols) / float(nCols);
      resize(result, result_middle, Size(), scale, scale, CV_INTER_AREA);

      if (result_middle.rows > img_window.rows) {
        float scale = float(img_window.rows) / float(result_middle.rows);
        resize(result_middle, result_resize, Size(), scale, scale, CV_INTER_AREA);
      }
      else {
        result_resize = result_middle;
      }
    }
    else {
      result_resize = result;
    }

    Mat imageRoi = img_window(Rect((RESULTWIDTH - result_resize.cols) / 2,
      (RESULTHEIGHT - result_resize.rows) / 2,
      result_resize.cols, result_resize.rows));
    addWeighted(imageRoi, 0, result_resize, 1, 0, imageRoi);

    if (1) {
      imshow("EasyPR", img_window);
      waitKey(0);
      destroyWindow("EasyPR");
    }

    if (1) {
      std::stringstream ss(std::stringstream::in | std::stringstream::out);
      ss << "resources/image/tmp/Result/plate_" << img_index << ".jpg";
      imwrite(ss.str(), img_window);
    }

    return 0;
  }
}<|endoftext|>


<commit_before>#include "UmbralActor.h"
#include "string_format.h"
#include "StdStream.h"
#include "UmbralModel.h"
#include "UmbralMesh.h"
#include "../dataobjects/FileManager.h"
#include "WeaponVars.h"

CUmbralActor::CUmbralActor()
{

}

CUmbralActor::~CUmbralActor()
{

}

const CSphere& CUmbralActor::GetBoundingSphere() const
{
	return m_boundingSphere;
}

void CUmbralActor::SetBaseModelId(uint32 baseModelId)
{
	m_baseModelId = baseModelId;
	m_renderableDirty = true;
}

void CUmbralActor::SetTopModelId(uint32 topModelId)
{
	m_topModelId = topModelId;
	m_renderableDirty = true;
}

void CUmbralActor::Update(float dt)
{
	CSceneNode::Update(dt);
	if(m_renderableDirty)
	{
		RebuildActorRenderables();
		assert(m_renderableDirty == false);
	}
}

void ReplaceMaterialParam(const Palleon::MaterialPtr& material, const char* paramName, const CVector4& newParamValue)
{
	auto param = material->GetEffectParameter(paramName);
	CVector4 paramValue(0, 0, 0, 0);
	if(param.IsVector3())
	{
		paramValue = CVector4(param.GetVector3(), 0);
	}
	else
	{
		paramValue = param.GetVector4();
	}
	paramValue.x = (newParamValue.x == 1000.f) ? paramValue.x : newParamValue.x;
	paramValue.y = (newParamValue.y == 1000.f) ? paramValue.y : newParamValue.y;
	paramValue.z = (newParamValue.z == 1000.f) ? paramValue.z : newParamValue.z;
	paramValue.w = (newParamValue.w == 1000.f) ? paramValue.w : newParamValue.w;
	if(param.IsVector3())
	{
		param.SetVector3(paramValue.xyz());
	}
	else
	{
		param.SetVector4(paramValue);
	}
	material->SetEffectParameter(paramName, param);
}

void ReplaceMaterialParam(const Palleon::MaterialPtr& material, const char* paramName, float newParamValue)
{
	auto param = material->GetEffectParameter(paramName);
	float paramValue = param.GetScalar();
	paramValue = (newParamValue == 1000.f) ? paramValue : newParamValue;
	param.SetScalar(paramValue);
	material->SetEffectParameter(paramName, param);
}

void CUmbralActor::RebuildActorRenderables()
{
	RemoveAllChildren();

	try
	{
		uint32 modelFolder = m_baseModelId % 10000;
		uint32 modelClass = m_baseModelId / 10000;
		const char* charaFolder = "";
		const char* charaPrefix = "";
		switch(modelClass)
		{
		case 1:
			charaFolder = "mon";
			charaPrefix = "m";
			break;
		case 2:
			charaFolder = "bgobj";
			charaPrefix = "b";
			break;
		case 4:
			charaFolder = "wep";
			charaPrefix = "w";
			break;
		default:
			assert(0);
			break;
		}

		uint32 subModelId = m_topModelId >> 10;
		uint32 variation = m_topModelId & 0x3FF;

		auto gamePath = CFileManager::GetGamePath();

		uint32 textureId = 0;
		if(modelClass == 4)
		{
			uint32 varWepId = 1000000000 + (modelFolder * 1000000) + (subModelId * 1000) + variation;
			auto var = CWeaponVars::GetInstance().GetVarForId(varWepId);
			textureId = var.textureId;
		}

		auto textureResource = ResourceNodePtr();

		//Load texture
		{
			auto texturePath = string_format("%s/client/chara/%s/%s%0.3d/equ/e%0.3d/top_tex2/%0.4d",
				gamePath.string().c_str(), charaFolder, charaPrefix, modelFolder, subModelId, textureId);

			Framework::CStdStream inputStream(texturePath.c_str(), "rb");
			textureResource = CSectionLoader::ReadSection(ResourceNodePtr(), inputStream);
		}

		//Load model
		auto modelPath = string_format("%s/client/chara/%s/%s%0.3d/equ/e%0.3d/top_mdl/0001",
			gamePath.string().c_str(), charaFolder, charaPrefix, modelFolder, subModelId);

		Framework::CStdStream inputStream(modelPath.c_str(), "rb");

		auto modelResource = CSectionLoader::ReadSection(ResourceNodePtr(), inputStream);

		auto modelChunks = modelResource->SelectNodes<CModelChunk>();
		assert(!modelChunks.empty());
		for(const auto& modelChunk : modelChunks)
		{
			auto model = CreateModel(modelChunk);
			AppendChild(model);

			if(modelClass == 4)
			{
				uint32 varWepId = 1000000000 + (modelFolder * 1000000) + (subModelId * 1000) + variation;
				auto var = CWeaponVars::GetInstance().GetVarForId(varWepId);

				for(const auto& meshNode : model->GetChildren())
				{
					if(auto mesh = std::dynamic_pointer_cast<CUmbralMesh>(meshNode))
					{
						auto meshName = mesh->GetName();
						int materialId = 0;
						if(meshName.find("_a") != std::string::npos)
						{
							materialId = 0;
						}
						if(meshName.find("_b") != std::string::npos)
						{
							materialId = 1;
						}
						if(meshName.find("_c") != std::string::npos)
						{
							materialId = 2;
						}
						if(meshName.find("_d") != std::string::npos)
						{
							assert(0);
						}
						const auto& varWepMaterial = var.materials[materialId];
						auto material = mesh->GetMaterial();
						ReplaceMaterialParam(material, "ps_diffuseColor", varWepMaterial.diffuseColor);
						ReplaceMaterialParam(material, "ps_multiDiffuseColor", varWepMaterial.multiDiffuseColor);
						ReplaceMaterialParam(material, "ps_specularColor", varWepMaterial.specularColor);
						ReplaceMaterialParam(material, "ps_multiSpecularColor", varWepMaterial.multiSpecularColor);
						ReplaceMaterialParam(material, "ps_reflectivity", varWepMaterial.specularColor);
						ReplaceMaterialParam(material, "ps_multiReflectivity", varWepMaterial.multiSpecularColor);
						ReplaceMaterialParam(material, "ps_shininess", varWepMaterial.shininess);
						ReplaceMaterialParam(material, "ps_multiShininess", varWepMaterial.multiShininess);
						mesh->SetActivePolyGroups(var.polyGroupState);
					}
				}
			}

			model->SetLocalTexture(textureResource);
		}
	}
	catch(...)
	{
		//Use dummy model?
		RemoveAllChildren();
	}

	m_renderableDirty = false;
}

UmbralModelPtr CUmbralActor::CreateModel(const ModelChunkPtr& modelChunk)
{
	auto boundingBox = modelChunk->SelectNode<CCompChunk>();

	CVector3 boxMin(boundingBox->GetMinX(), boundingBox->GetMinY(), boundingBox->GetMinZ());
	CVector3 boxMax(boundingBox->GetMaxX(), boundingBox->GetMaxY(), boundingBox->GetMaxZ());

	CVector3 modelSize = (boxMax - boxMin) / 2;
	CVector3 modelPos = (boxMax + boxMin) / 2;

	auto model = std::make_shared<CUmbralModel>(modelChunk);
	model->SetPosition(modelPos);
	model->SetScale(modelSize);

	auto modelBoundingSphere = model->GetBoundingSphere();
	modelBoundingSphere.radius *= std::max(std::max(modelSize.x, modelSize.y), modelSize.z);
	modelBoundingSphere.position += modelPos;
	m_boundingSphere = modelBoundingSphere;

	return model;
}
<commit_msg>Fixed build.<commit_after>#include "UmbralActor.h"
#include "string_format.h"
#include "StdStream.h"
#include "UmbralModel.h"
#include "UmbralMesh.h"
#include "../dataobjects/FileManager.h"
#include "../dataobjects/itemvar/WeaponVars.h"

CUmbralActor::CUmbralActor()
{

}

CUmbralActor::~CUmbralActor()
{

}

const CSphere& CUmbralActor::GetBoundingSphere() const
{
	return m_boundingSphere;
}

void CUmbralActor::SetBaseModelId(uint32 baseModelId)
{
	m_baseModelId = baseModelId;
	m_renderableDirty = true;
}

void CUmbralActor::SetTopModelId(uint32 topModelId)
{
	m_topModelId = topModelId;
	m_renderableDirty = true;
}

void CUmbralActor::Update(float dt)
{
	CSceneNode::Update(dt);
	if(m_renderableDirty)
	{
		RebuildActorRenderables();
		assert(m_renderableDirty == false);
	}
}

void ReplaceMaterialParam(const Palleon::MaterialPtr& material, const char* paramName, const CVector4& newParamValue)
{
	auto param = material->GetEffectParameter(paramName);
	CVector4 paramValue(0, 0, 0, 0);
	if(param.IsVector3())
	{
		paramValue = CVector4(param.GetVector3(), 0);
	}
	else
	{
		paramValue = param.GetVector4();
	}
	paramValue.x = (newParamValue.x == 1000.f) ? paramValue.x : newParamValue.x;
	paramValue.y = (newParamValue.y == 1000.f) ? paramValue.y : newParamValue.y;
	paramValue.z = (newParamValue.z == 1000.f) ? paramValue.z : newParamValue.z;
	paramValue.w = (newParamValue.w == 1000.f) ? paramValue.w : newParamValue.w;
	if(param.IsVector3())
	{
		param.SetVector3(paramValue.xyz());
	}
	else
	{
		param.SetVector4(paramValue);
	}
	material->SetEffectParameter(paramName, param);
}

void ReplaceMaterialParam(const Palleon::MaterialPtr& material, const char* paramName, float newParamValue)
{
	auto param = material->GetEffectParameter(paramName);
	float paramValue = param.GetScalar();
	paramValue = (newParamValue == 1000.f) ? paramValue : newParamValue;
	param.SetScalar(paramValue);
	material->SetEffectParameter(paramName, param);
}

void CUmbralActor::RebuildActorRenderables()
{
	RemoveAllChildren();

	try
	{
		uint32 modelFolder = m_baseModelId % 10000;
		uint32 modelClass = m_baseModelId / 10000;
		const char* charaFolder = "";
		const char* charaPrefix = "";
		switch(modelClass)
		{
		case 1:
			charaFolder = "mon";
			charaPrefix = "m";
			break;
		case 2:
			charaFolder = "bgobj";
			charaPrefix = "b";
			break;
		case 4:
			charaFolder = "wep";
			charaPrefix = "w";
			break;
		default:
			assert(0);
			break;
		}

		uint32 subModelId = m_topModelId >> 10;
		uint32 variation = m_topModelId & 0x3FF;

		auto gamePath = CFileManager::GetGamePath();

		uint32 textureId = 0;
		if(modelClass == 4)
		{
			uint32 varWepId = 1000000000 + (modelFolder * 1000000) + (subModelId * 1000) + variation;
			auto var = CWeaponVars::GetInstance().GetVarForId(varWepId);
			textureId = var.textureId;
		}

		auto textureResource = ResourceNodePtr();

		//Load texture
		{
			auto texturePath = string_format("%s/client/chara/%s/%s%0.3d/equ/e%0.3d/top_tex2/%0.4d",
				gamePath.string().c_str(), charaFolder, charaPrefix, modelFolder, subModelId, textureId);

			Framework::CStdStream inputStream(texturePath.c_str(), "rb");
			textureResource = CSectionLoader::ReadSection(ResourceNodePtr(), inputStream);
		}

		//Load model
		auto modelPath = string_format("%s/client/chara/%s/%s%0.3d/equ/e%0.3d/top_mdl/0001",
			gamePath.string().c_str(), charaFolder, charaPrefix, modelFolder, subModelId);

		Framework::CStdStream inputStream(modelPath.c_str(), "rb");

		auto modelResource = CSectionLoader::ReadSection(ResourceNodePtr(), inputStream);

		auto modelChunks = modelResource->SelectNodes<CModelChunk>();
		assert(!modelChunks.empty());
		for(const auto& modelChunk : modelChunks)
		{
			auto model = CreateModel(modelChunk);
			AppendChild(model);

			if(modelClass == 4)
			{
				uint32 varWepId = 1000000000 + (modelFolder * 1000000) + (subModelId * 1000) + variation;
				auto var = CWeaponVars::GetInstance().GetVarForId(varWepId);

				for(const auto& meshNode : model->GetChildren())
				{
					if(auto mesh = std::dynamic_pointer_cast<CUmbralMesh>(meshNode))
					{
						auto meshName = mesh->GetName();
						int materialId = 0;
						if(meshName.find("_a") != std::string::npos)
						{
							materialId = 0;
						}
						if(meshName.find("_b") != std::string::npos)
						{
							materialId = 1;
						}
						if(meshName.find("_c") != std::string::npos)
						{
							materialId = 2;
						}
						if(meshName.find("_d") != std::string::npos)
						{
							assert(0);
						}
						const auto& varWepMaterial = var.materials[materialId];
						auto material = mesh->GetMaterial();
						ReplaceMaterialParam(material, "ps_diffuseColor", varWepMaterial.diffuseColor);
						ReplaceMaterialParam(material, "ps_multiDiffuseColor", varWepMaterial.multiDiffuseColor);
						ReplaceMaterialParam(material, "ps_specularColor", varWepMaterial.specularColor);
						ReplaceMaterialParam(material, "ps_multiSpecularColor", varWepMaterial.multiSpecularColor);
						ReplaceMaterialParam(material, "ps_reflectivity", varWepMaterial.specularColor);
						ReplaceMaterialParam(material, "ps_multiReflectivity", varWepMaterial.multiSpecularColor);
						ReplaceMaterialParam(material, "ps_shininess", varWepMaterial.shininess);
						ReplaceMaterialParam(material, "ps_multiShininess", varWepMaterial.multiShininess);
						mesh->SetActivePolyGroups(var.polyGroupState);
					}
				}
			}

			model->SetLocalTexture(textureResource);
		}
	}
	catch(...)
	{
		//Use dummy model?
		RemoveAllChildren();
	}

	m_renderableDirty = false;
}

UmbralModelPtr CUmbralActor::CreateModel(const ModelChunkPtr& modelChunk)
{
	auto boundingBox = modelChunk->SelectNode<CCompChunk>();

	CVector3 boxMin(boundingBox->GetMinX(), boundingBox->GetMinY(), boundingBox->GetMinZ());
	CVector3 boxMax(boundingBox->GetMaxX(), boundingBox->GetMaxY(), boundingBox->GetMaxZ());

	CVector3 modelSize = (boxMax - boxMin) / 2;
	CVector3 modelPos = (boxMax + boxMin) / 2;

	auto model = std::make_shared<CUmbralModel>(modelChunk);
	model->SetPosition(modelPos);
	model->SetScale(modelSize);

	auto modelBoundingSphere = model->GetBoundingSphere();
	modelBoundingSphere.radius *= std::max(std::max(modelSize.x, modelSize.y), modelSize.z);
	modelBoundingSphere.position += modelPos;
	m_boundingSphere = modelBoundingSphere;

	return model;
}
<|endoftext|>


<commit_before>/*****************************************************************************
 * ctrl_checkbox.cpp
 *****************************************************************************
 * Copyright (C) 2003 VideoLAN
 * $Id: ctrl_checkbox.cpp,v 1.3 2004/02/29 16:49:55 asmax Exp $
 *
 * Authors: Cyril Deguet     <asmax@via.ecp.fr>
 *          Olivier Teulire <ipkiss@via.ecp.fr>
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

#include "ctrl_checkbox.hpp"
#include "../events/evt_generic.hpp"
#include "../commands/cmd_generic.hpp"
#include "../src/generic_bitmap.hpp"
#include "../src/os_factory.hpp"
#include "../src/os_graphics.hpp"
#include "../utils/var_bool.hpp"

CtrlCheckbox::CtrlCheckbox( intf_thread_t *pIntf,
                            const GenericBitmap &rBmpUp1,
                            const GenericBitmap &rBmpOver1,
                            const GenericBitmap &rBmpDown1,
                            const GenericBitmap &rBmpUp2,
                            const GenericBitmap &rBmpOver2,
                            const GenericBitmap &rBmpDown2,
                            CmdGeneric &rCommand1, CmdGeneric &rCommand2,
                            const UString &rTooltip1,
                            const UString &rTooltip2,
                            VarBool &rVariable, const UString &rHelp,
                            VarBool *pVisible ):
    CtrlGeneric( pIntf, rHelp, pVisible ), m_fsm( pIntf ),
    m_rVariable( rVariable ),
    m_rCommand1( rCommand1 ), m_rCommand2( rCommand2 ),
    m_tooltip1( rTooltip1 ), m_tooltip2( rTooltip2 ),
    m_cmdUpOverDownOver( this, &transUpOverDownOver ),
    m_cmdDownOverUpOver( this, &transDownOverUpOver ),
    m_cmdDownOverDown( this, &transDownOverDown ),
    m_cmdDownDownOver( this, &transDownDownOver ),
    m_cmdUpOverUp( this, &transUpOverUp ),
    m_cmdUpUpOver( this, &transUpUpOver ),
    m_cmdDownUp( this, &transDownUp ),
    m_cmdUpHidden( this, &transUpHidden ),
    m_cmdHiddenUp( this, &transHiddenUp )
{
    // Build the images of the checkbox
    OSFactory *pOsFactory = OSFactory::instance( pIntf );
    m_pImgUp1 = pOsFactory->createOSGraphics( rBmpUp1.getWidth(),
                                              rBmpUp1.getHeight() );
    m_pImgUp1->drawBitmap( rBmpUp1, 0, 0 );
    m_pImgDown1 = pOsFactory->createOSGraphics( rBmpDown1.getWidth(),
                                                rBmpDown1.getHeight() );
    m_pImgDown1->drawBitmap( rBmpDown1, 0, 0 );
    m_pImgOver1 = pOsFactory->createOSGraphics( rBmpOver1.getWidth(),
                                                rBmpOver1.getHeight() );
    m_pImgOver1->drawBitmap( rBmpOver1, 0, 0 );

    m_pImgUp2 = pOsFactory->createOSGraphics( rBmpUp2.getWidth(),
                                              rBmpUp2.getHeight() );
    m_pImgUp2->drawBitmap( rBmpUp2, 0, 0 );
    m_pImgDown2 = pOsFactory->createOSGraphics( rBmpDown2.getWidth(),
                                                rBmpDown2.getHeight() );
    m_pImgDown2->drawBitmap( rBmpDown2, 0, 0 );
    m_pImgOver2 = pOsFactory->createOSGraphics( rBmpOver2.getWidth(),
                                                rBmpOver2.getHeight() );
    m_pImgOver2->drawBitmap( rBmpOver2, 0, 0 );

    // States
    m_fsm.addState( "up" );
    m_fsm.addState( "down" );
    m_fsm.addState( "upOver" );
    m_fsm.addState( "downOver" );
    m_fsm.addState( "hidden" );

    // Transitions
    m_fsm.addTransition( "upOver", "mouse:left:down", "downOver",
                         &m_cmdUpOverDownOver );
    m_fsm.addTransition( "downOver", "mouse:left:up", "upOver",
                         &m_cmdDownOverUpOver );
    m_fsm.addTransition( "downOver", "leave", "down", &m_cmdDownOverDown );
    m_fsm.addTransition( "down", "enter", "downOver", &m_cmdDownDownOver );
    m_fsm.addTransition( "upOver", "leave", "up", &m_cmdUpOverUp );
    m_fsm.addTransition( "up", "enter", "upOver", &m_cmdUpUpOver );
    m_fsm.addTransition( "down", "mouse:left:up", "up", &m_cmdDownUp );
    // XXX: It would be easy to use a "ANY" initial state to handle these
    // four lines in only one. But till now it isn't worthwhile...
    m_fsm.addTransition( "up", "special:hide", "hidden", &m_cmdUpHidden );
    m_fsm.addTransition( "down", "special:hide", "hidden", &m_cmdUpHidden );
    m_fsm.addTransition( "upOver", "special:hide", "hidden", &m_cmdUpHidden );
    m_fsm.addTransition( "downOver", "special:hide", "hidden", &m_cmdUpHidden );
    m_fsm.addTransition( "hidden", "special:show", "up", &m_cmdHiddenUp );

    // Observe the variable
    m_rVariable.addObserver( this );

    // Initial state
    m_fsm.setState( "up" );
    if( !m_rVariable.get() )
    {
        m_pImgUp = m_pImgUp1;
        m_pImgOver = m_pImgOver1;
        m_pImgDown = m_pImgDown1;
        m_pImgCurrent = m_pImgUp;
        m_pCommand = &m_rCommand1;
        m_pTooltip = &m_tooltip1;
    }
    else
    {
        m_pImgUp = m_pImgUp2;
        m_pImgOver = m_pImgOver2;
        m_pImgDown = m_pImgDown2;
        m_pImgCurrent = m_pImgDown;
        m_pCommand = &m_rCommand2;
        m_pTooltip = &m_tooltip2;
    }
}

CtrlCheckbox::~CtrlCheckbox()
{
    m_rVariable.delObserver( this );
    SKINS_DELETE( m_pImgUp1 );
    SKINS_DELETE( m_pImgDown1 );
    SKINS_DELETE( m_pImgOver1 );
    SKINS_DELETE( m_pImgUp2 );
    SKINS_DELETE( m_pImgDown2 );
    SKINS_DELETE( m_pImgOver2 );
}

void CtrlCheckbox::handleEvent( EvtGeneric &rEvent )
{
    m_fsm.handleTransition( rEvent.getAsString() );
}

bool CtrlCheckbox::mouseOver( int x, int y ) const
{
    if( m_pImgCurrent )
    {
        return m_pImgCurrent->hit( x, y );
    }
    else
    {
        return false;
    }
}

void CtrlCheckbox::draw( OSGraphics &rImage, int xDest, int yDest )
{
    if( m_pImgCurrent )
    {
        // Draw the current image
        rImage.drawGraphics( *m_pImgCurrent, 0, 0, xDest, yDest );
    }
}

void CtrlCheckbox::transUpOverDownOver( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->captureMouse();
    pThis->m_pImgCurrent = pThis->m_pImgDown;
    pThis->notifyLayout();
}

void CtrlCheckbox::transDownOverUpOver( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->releaseMouse();

    // Invert the state variable
    pThis->m_pImgCurrent = pThis->m_pImgUp;
    pThis->notifyLayout();

    // Execute the command
    pThis->m_pCommand->execute();
}

void CtrlCheckbox::transDownOverDown( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->m_pImgCurrent = pThis->m_pImgUp;
    pThis->notifyLayout();
}

void CtrlCheckbox::transDownDownOver( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->m_pImgCurrent = pThis->m_pImgDown;
    pThis->notifyLayout();
}

void CtrlCheckbox::transUpUpOver( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->m_pImgCurrent = pThis->m_pImgOver;
    pThis->notifyLayout();
}

void CtrlCheckbox::transUpOverUp( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->m_pImgCurrent = pThis->m_pImgUp;
    pThis->notifyLayout();
}

void CtrlCheckbox::transDownUp( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->releaseMouse();
}

void CtrlCheckbox::transUpHidden( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->m_pImgCurrent = NULL;
    pThis->notifyLayout();
}

void CtrlCheckbox::transHiddenUp( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->m_pImgCurrent = pThis->m_pImgUp;
    pThis->notifyLayout();
}

void CtrlCheckbox::onVarBoolUpdate( VarBool &rVariable )
{
    changeButton();
}

void CtrlCheckbox::changeButton()
{
    // Are we using the first set of images or the second one?
    if( m_pImgUp == m_pImgUp1 )
    {
        m_pImgUp = m_pImgUp2;
        m_pImgOver = m_pImgOver2;
        m_pImgDown = m_pImgDown2;
        m_pTooltip = &m_tooltip2;
        m_pCommand = &m_rCommand2;
    }
    else
    {
        m_pImgUp = m_pImgUp1;
        m_pImgOver = m_pImgOver1;
        m_pImgDown = m_pImgDown1;
        m_pTooltip = &m_tooltip1;
        m_pCommand = &m_rCommand1;
    }
    // XXX: We assume that the checkbox is up
    m_pImgCurrent = m_pImgUp;

    // Notify the window the tooltip has changed
    notifyTooltipChange();
    // Refresh
    notifyLayout();
}

<commit_msg>* modules/gui/skins2/controls/ctrl_checkbox.cpp: handle double click events too<commit_after>/*****************************************************************************
 * ctrl_checkbox.cpp
 *****************************************************************************
 * Copyright (C) 2003 VideoLAN
 * $Id$
 *
 * Authors: Cyril Deguet     <asmax@via.ecp.fr>
 *          Olivier Teulire <ipkiss@via.ecp.fr>
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

#include "ctrl_checkbox.hpp"
#include "../events/evt_generic.hpp"
#include "../commands/cmd_generic.hpp"
#include "../src/generic_bitmap.hpp"
#include "../src/os_factory.hpp"
#include "../src/os_graphics.hpp"
#include "../utils/var_bool.hpp"

CtrlCheckbox::CtrlCheckbox( intf_thread_t *pIntf,
                            const GenericBitmap &rBmpUp1,
                            const GenericBitmap &rBmpOver1,
                            const GenericBitmap &rBmpDown1,
                            const GenericBitmap &rBmpUp2,
                            const GenericBitmap &rBmpOver2,
                            const GenericBitmap &rBmpDown2,
                            CmdGeneric &rCommand1, CmdGeneric &rCommand2,
                            const UString &rTooltip1,
                            const UString &rTooltip2,
                            VarBool &rVariable, const UString &rHelp,
                            VarBool *pVisible ):
    CtrlGeneric( pIntf, rHelp, pVisible ), m_fsm( pIntf ),
    m_rVariable( rVariable ),
    m_rCommand1( rCommand1 ), m_rCommand2( rCommand2 ),
    m_tooltip1( rTooltip1 ), m_tooltip2( rTooltip2 ),
    m_cmdUpOverDownOver( this, &transUpOverDownOver ),
    m_cmdDownOverUpOver( this, &transDownOverUpOver ),
    m_cmdDownOverDown( this, &transDownOverDown ),
    m_cmdDownDownOver( this, &transDownDownOver ),
    m_cmdUpOverUp( this, &transUpOverUp ),
    m_cmdUpUpOver( this, &transUpUpOver ),
    m_cmdDownUp( this, &transDownUp ),
    m_cmdUpHidden( this, &transUpHidden ),
    m_cmdHiddenUp( this, &transHiddenUp )
{
    // Build the images of the checkbox
    OSFactory *pOsFactory = OSFactory::instance( pIntf );
    m_pImgUp1 = pOsFactory->createOSGraphics( rBmpUp1.getWidth(),
                                              rBmpUp1.getHeight() );
    m_pImgUp1->drawBitmap( rBmpUp1, 0, 0 );
    m_pImgDown1 = pOsFactory->createOSGraphics( rBmpDown1.getWidth(),
                                                rBmpDown1.getHeight() );
    m_pImgDown1->drawBitmap( rBmpDown1, 0, 0 );
    m_pImgOver1 = pOsFactory->createOSGraphics( rBmpOver1.getWidth(),
                                                rBmpOver1.getHeight() );
    m_pImgOver1->drawBitmap( rBmpOver1, 0, 0 );

    m_pImgUp2 = pOsFactory->createOSGraphics( rBmpUp2.getWidth(),
                                              rBmpUp2.getHeight() );
    m_pImgUp2->drawBitmap( rBmpUp2, 0, 0 );
    m_pImgDown2 = pOsFactory->createOSGraphics( rBmpDown2.getWidth(),
                                                rBmpDown2.getHeight() );
    m_pImgDown2->drawBitmap( rBmpDown2, 0, 0 );
    m_pImgOver2 = pOsFactory->createOSGraphics( rBmpOver2.getWidth(),
                                                rBmpOver2.getHeight() );
    m_pImgOver2->drawBitmap( rBmpOver2, 0, 0 );

    // States
    m_fsm.addState( "up" );
    m_fsm.addState( "down" );
    m_fsm.addState( "upOver" );
    m_fsm.addState( "downOver" );
    m_fsm.addState( "hidden" );

    // Transitions
    m_fsm.addTransition( "upOver", "mouse:left:down", "downOver",
                         &m_cmdUpOverDownOver );
    m_fsm.addTransition( "upOver", "mouse:left:dblclick", "downOver",
                         &m_cmdUpOverDownOver );
    m_fsm.addTransition( "downOver", "mouse:left:up", "upOver",
                         &m_cmdDownOverUpOver );
    m_fsm.addTransition( "downOver", "leave", "down", &m_cmdDownOverDown );
    m_fsm.addTransition( "down", "enter", "downOver", &m_cmdDownDownOver );
    m_fsm.addTransition( "upOver", "leave", "up", &m_cmdUpOverUp );
    m_fsm.addTransition( "up", "enter", "upOver", &m_cmdUpUpOver );
    m_fsm.addTransition( "down", "mouse:left:up", "up", &m_cmdDownUp );
    // XXX: It would be easy to use a "ANY" initial state to handle these
    // four lines in only one. But till now it isn't worthwhile...
    m_fsm.addTransition( "up", "special:hide", "hidden", &m_cmdUpHidden );
    m_fsm.addTransition( "down", "special:hide", "hidden", &m_cmdUpHidden );
    m_fsm.addTransition( "upOver", "special:hide", "hidden", &m_cmdUpHidden );
    m_fsm.addTransition( "downOver", "special:hide", "hidden", &m_cmdUpHidden );
    m_fsm.addTransition( "hidden", "special:show", "up", &m_cmdHiddenUp );

    // Observe the variable
    m_rVariable.addObserver( this );

    // Initial state
    m_fsm.setState( "up" );
    if( !m_rVariable.get() )
    {
        m_pImgUp = m_pImgUp1;
        m_pImgOver = m_pImgOver1;
        m_pImgDown = m_pImgDown1;
        m_pImgCurrent = m_pImgUp;
        m_pCommand = &m_rCommand1;
        m_pTooltip = &m_tooltip1;
    }
    else
    {
        m_pImgUp = m_pImgUp2;
        m_pImgOver = m_pImgOver2;
        m_pImgDown = m_pImgDown2;
        m_pImgCurrent = m_pImgDown;
        m_pCommand = &m_rCommand2;
        m_pTooltip = &m_tooltip2;
    }
}

CtrlCheckbox::~CtrlCheckbox()
{
    m_rVariable.delObserver( this );
    SKINS_DELETE( m_pImgUp1 );
    SKINS_DELETE( m_pImgDown1 );
    SKINS_DELETE( m_pImgOver1 );
    SKINS_DELETE( m_pImgUp2 );
    SKINS_DELETE( m_pImgDown2 );
    SKINS_DELETE( m_pImgOver2 );
}

void CtrlCheckbox::handleEvent( EvtGeneric &rEvent )
{
    m_fsm.handleTransition( rEvent.getAsString() );
}

bool CtrlCheckbox::mouseOver( int x, int y ) const
{
    if( m_pImgCurrent )
    {
        return m_pImgCurrent->hit( x, y );
    }
    else
    {
        return false;
    }
}

void CtrlCheckbox::draw( OSGraphics &rImage, int xDest, int yDest )
{
    if( m_pImgCurrent )
    {
        // Draw the current image
        rImage.drawGraphics( *m_pImgCurrent, 0, 0, xDest, yDest );
    }
}

void CtrlCheckbox::transUpOverDownOver( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->captureMouse();
    pThis->m_pImgCurrent = pThis->m_pImgDown;
    pThis->notifyLayout();
}

void CtrlCheckbox::transDownOverUpOver( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->releaseMouse();

    // Invert the state variable
    pThis->m_pImgCurrent = pThis->m_pImgUp;
    pThis->notifyLayout();

    // Execute the command
    pThis->m_pCommand->execute();
}

void CtrlCheckbox::transDownOverDown( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->m_pImgCurrent = pThis->m_pImgUp;
    pThis->notifyLayout();
}

void CtrlCheckbox::transDownDownOver( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->m_pImgCurrent = pThis->m_pImgDown;
    pThis->notifyLayout();
}

void CtrlCheckbox::transUpUpOver( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->m_pImgCurrent = pThis->m_pImgOver;
    pThis->notifyLayout();
}

void CtrlCheckbox::transUpOverUp( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->m_pImgCurrent = pThis->m_pImgUp;
    pThis->notifyLayout();
}

void CtrlCheckbox::transDownUp( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->releaseMouse();
}

void CtrlCheckbox::transUpHidden( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->m_pImgCurrent = NULL;
    pThis->notifyLayout();
}

void CtrlCheckbox::transHiddenUp( SkinObject *pCtrl )
{
    CtrlCheckbox *pThis = (CtrlCheckbox*)pCtrl;
    pThis->m_pImgCurrent = pThis->m_pImgUp;
    pThis->notifyLayout();
}

void CtrlCheckbox::onVarBoolUpdate( VarBool &rVariable )
{
    changeButton();
}

void CtrlCheckbox::changeButton()
{
    // Are we using the first set of images or the second one?
    if( m_pImgUp == m_pImgUp1 )
    {
        m_pImgUp = m_pImgUp2;
        m_pImgOver = m_pImgOver2;
        m_pImgDown = m_pImgDown2;
        m_pTooltip = &m_tooltip2;
        m_pCommand = &m_rCommand2;
    }
    else
    {
        m_pImgUp = m_pImgUp1;
        m_pImgOver = m_pImgOver1;
        m_pImgDown = m_pImgDown1;
        m_pTooltip = &m_tooltip1;
        m_pCommand = &m_rCommand1;
    }
    // XXX: We assume that the checkbox is up
    m_pImgCurrent = m_pImgUp;

    // Notify the window the tooltip has changed
    notifyTooltipChange();
    // Refresh
    notifyLayout();
}

<|endoftext|>


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

#include <dlfcn.h>
#include <errno.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include "api/app/renderdoc_app.h"
#include "api/replay/capture_options.h"
#include "os/os_specific.h"
#include "serialise/string_utils.h"

// defined in foo/foo_process.cpp
char **GetCurrentEnvironment();
int GetIdentPort(pid_t childPid);

static vector<Process::EnvironmentModification> &GetEnvModifications()
{
  static vector<Process::EnvironmentModification> envCallbacks;
  return envCallbacks;
}

static map<string, string> EnvStringToEnvMap(const char **envstring)
{
  map<string, string> ret;

  const char **e = envstring;

  while(*e)
  {
    const char *equals = strchr(*e, '=');

    string name;
    string value;

    name.assign(*e, equals);
    value = equals + 1;

    ret[name] = value;

    e++;
  }

  return ret;
}

static string expandHome(const string &in)
{
  string path = trim(in);

  // if it's ~/... then replace with $HOME and return
  if(path[0] == '~' && path[1] == '/')
    return string(getenv("HOME")) + path.substr(1);

  // if it's ~user/... then use getpwname
  if(path[0] == '~')
  {
    size_t slash = path.find('/');

    string username;

    if(slash != string::npos)
    {
      RDCASSERT(slash > 1);
      username = path.substr(1, slash - 1);
    }
    else
    {
      username = path.substr(1);
    }

    passwd *pwdata = getpwnam(username.c_str());

    if(pwdata)
    {
      if(slash != string::npos)
        return string(pwdata->pw_dir) + path.substr(slash);

      return string(pwdata->pw_dir);
    }
  }

  return path;
}

void Process::RegisterEnvironmentModification(Process::EnvironmentModification modif)
{
  GetEnvModifications().push_back(modif);
}

// on linux we apply environment changes before launching the program, as
// there is no support for injecting/loading renderdoc into a running program
// in any way, and we also have some environment changes that we *have* to make
// for correct hooking (LD_LIBRARY_PATH/LD_PRELOAD)
//
// However we still set environment variables so that we can modify variables while
// in process (e.g. if we notice a setting and want to enable an env var as a result)
void Process::ApplyEnvironmentModification()
{
  // turn environment string to a UTF-8 map
  char **currentEnvironment = GetCurrentEnvironment();
  map<string, string> currentEnv = EnvStringToEnvMap((const char **)currentEnvironment);
  vector<EnvironmentModification> &modifications = GetEnvModifications();

  for(size_t i = 0; i < modifications.size(); i++)
  {
    EnvironmentModification &m = modifications[i];

    string value = currentEnv[m.name];

    switch(m.type)
    {
      case eEnvModification_Replace: value = m.value; break;
      case eEnvModification_Append: value += m.value; break;
      case eEnvModification_AppendPlatform:
      case eEnvModification_AppendColon:
        if(!value.empty())
          value += ":";
        value += m.value;
        break;
      case eEnvModification_AppendSemiColon:
        if(!value.empty())
          value += ";";
        value += m.value;
        break;
      case eEnvModification_Prepend: value = m.value + value; break;
      case eEnvModification_PrependColon:
        if(!value.empty())
          value = m.value + ":" + value;
        else
          value = m.value;
        break;
      case eEnvModification_PrependPlatform:
      case eEnvModification_PrependSemiColon:
        if(!value.empty())
          value = m.value + ";" + value;
        else
          value = m.value;
        break;
      default: RDCERR("Unexpected environment modification type");
    }

    setenv(m.name.c_str(), value.c_str(), true);
  }

  // these have been applied to the current process
  modifications.clear();
}

static pid_t RunProcess(const char *app, const char *workingDir, const char *cmdLine,
                        char *const *envp)
{
  if(!app)
    return (pid_t)0;

  string appName = app;
  string workDir = (workingDir && workingDir[0]) ? workingDir : dirname(appName);

  // do very limited expansion. wordexp(3) does too much for our needs, so we just expand ~
  // since that could be quite a common case.
  appName = expandHome(appName);
  workDir = expandHome(workDir);

  // it is safe to use app directly as execve never modifies argv
  char *emptyargv[] = {(char *)appName.c_str(), NULL};
  char **argv = emptyargv;

  const char *c = cmdLine;

  // parse command line into argv[], similar to how bash would
  if(cmdLine)
  {
    int argc = 1;

    // get a rough upper bound on the number of arguments
    while(*c)
    {
      if(*c == ' ' || *c == '\t')
        argc++;
      c++;
    }

    argv = new char *[argc + 2];

    c = cmdLine;

    string a;

    argc = 0;    // current argument we're fetching

    // argv[0] is the application name, by convention
    size_t len = appName.length() + 1;
    argv[argc] = new char[len];
    strcpy(argv[argc], appName.c_str());

    argc++;

    bool dquot = false, squot = false;    // are we inside ''s or ""s
    while(*c)
    {
      if(!dquot && !squot && (*c == ' ' || *c == '\t'))
      {
        if(!a.empty())
        {
          // if we've fetched some number of non-space characters
          argv[argc] = new char[a.length() + 1];
          memcpy(argv[argc], a.c_str(), a.length() + 1);
          argc++;
        }

        a = "";
      }
      else if(!dquot && *c == '"')
      {
        dquot = true;
      }
      else if(!squot && *c == '\'')
      {
        squot = true;
      }
      else if(dquot && *c == '"')
      {
        dquot = false;
      }
      else if(squot && *c == '\'')
      {
        squot = false;
      }
      else if(squot)
      {
        // single quotes don't escape, just copy literally until we leave single quote mode
        a.push_back(*c);
      }
      else if(dquot)
      {
        // handle escaping
        if(*c == '\\')
        {
          c++;
          if(*c)
          {
            a.push_back(*c);
          }
          else
          {
            RDCERR("Malformed command line:\n%s", cmdLine);
            return 0;
          }
        }
        else
        {
          a.push_back(*c);
        }
      }
      else
      {
        a.push_back(*c);
      }

      c++;
    }

    if(!a.empty())
    {
      // if we've fetched some number of non-space characters
      argv[argc] = new char[a.length() + 1];
      memcpy(argv[argc], a.c_str(), a.length() + 1);
      argc++;
    }

    argv[argc] = NULL;

    if(squot || dquot)
    {
      RDCERR("Malformed command line\n%s", cmdLine);
      return 0;
    }
  }

  pid_t childPid = fork();
  if(childPid == 0)
  {
    chdir(workDir.c_str());

    execve(appName.c_str(), argv, envp);
    RDCERR("Failed to execute %s: %s", appName.c_str(), strerror(errno));
    exit(0);
  }

  char **argv_delete = argv;

  if(argv != emptyargv)
  {
    while(*argv)
    {
      delete[] * argv;
      argv++;
    }

    delete[] argv_delete;
  }

  return childPid;
}

uint32_t Process::InjectIntoProcess(uint32_t pid, const char *logfile, const CaptureOptions *opts,
                                    bool waitForExit)
{
  RDCUNIMPLEMENTED("Injecting into already running processes on linux");
  return 0;
}

uint32_t Process::LaunchProcess(const char *app, const char *workingDir, const char *cmdLine)
{
  if(app == NULL || app[0] == 0)
  {
    RDCERR("Invalid empty 'app'");
    return 0;
  }

  char **currentEnvironment = GetCurrentEnvironment();
  return (uint32_t)RunProcess(app, workingDir, cmdLine, currentEnvironment);
}

uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workingDir,
                                             const char *cmdLine, const char *logfile,
                                             const CaptureOptions *opts, bool waitForExit)
{
  if(app == NULL || app[0] == 0)
  {
    RDCERR("Invalid empty 'app'");
    return 0;
  }

  // turn environment string to a UTF-8 map
  char **currentEnvironment = GetCurrentEnvironment();
  map<string, string> env = EnvStringToEnvMap((const char **)currentEnvironment);
  vector<EnvironmentModification> &modifications = GetEnvModifications();

  if(logfile == NULL)
    logfile = "";

  string libpath;
  {
    FileIO::GetExecutableFilename(libpath);
    libpath = dirname(libpath);
  }

  string optstr;
  {
    optstr.reserve(sizeof(CaptureOptions) * 2 + 1);
    byte *b = (byte *)opts;
    for(size_t i = 0; i < sizeof(CaptureOptions); i++)
    {
      optstr.push_back(char('a' + ((b[i] >> 4) & 0xf)));
      optstr.push_back(char('a' + ((b[i]) & 0xf)));
    }
  }

  modifications.push_back(
      EnvironmentModification(eEnvModification_AppendPlatform, "LD_LIBRARY_PATH", libpath.c_str()));
  modifications.push_back(
      EnvironmentModification(eEnvModification_AppendPlatform, "LD_PRELOAD", "librenderdoc.so"));
  modifications.push_back(
      EnvironmentModification(eEnvModification_Replace, "RENDERDOC_LOGFILE", logfile));
  modifications.push_back(
      EnvironmentModification(eEnvModification_Replace, "RENDERDOC_CAPTUREOPTS", optstr.c_str()));

  for(size_t i = 0; i < modifications.size(); i++)
  {
    EnvironmentModification &m = modifications[i];

    string &value = env[m.name];

    switch(m.type)
    {
      case eEnvModification_Replace: value = m.value; break;
      case eEnvModification_Append: value += m.value; break;
      case eEnvModification_AppendPlatform:
      case eEnvModification_AppendColon:
        if(!value.empty())
          value += ":";
        value += m.value;
        break;
      case eEnvModification_AppendSemiColon:
        if(!value.empty())
          value += ";";
        value += m.value;
        break;
      case eEnvModification_Prepend: value = m.value + value; break;
      case eEnvModification_PrependColon:
        if(!value.empty())
          value = m.value + ":" + value;
        else
          value = m.value;
        break;
      case eEnvModification_PrependPlatform:
      case eEnvModification_PrependSemiColon:
        if(!value.empty())
          value = m.value + ";" + value;
        else
          value = m.value;
        break;
      default: RDCERR("Unexpected environment modification type");
    }
  }

  char **envp = new char *[env.size() + 1];
  envp[env.size()] = NULL;

  int i = 0;
  for(auto it = env.begin(); it != env.end(); it++)
  {
    string envline = it->first + "=" + it->second;
    envp[i] = new char[envline.size() + 1];
    memcpy(envp[i], envline.c_str(), envline.size() + 1);
    i++;
  }

  pid_t childPid = RunProcess(app, workingDir, cmdLine, envp);

  int ret = 0;

  if(childPid != (pid_t)0)
  {
    // wait for child to have opened its socket
    usleep(1000);

    ret = GetIdentPort(childPid);

    if(waitForExit)
    {
      int dummy = 0;
      waitpid(childPid, &dummy, 0);
    }
  }

  char **envp_delete = envp;

  while(*envp)
  {
    delete[] * envp;
    envp++;
  }

  delete[] envp_delete;

  return ret;
}

void Process::StartGlobalHook(const char *pathmatch, const char *logfile, const CaptureOptions *opts)
{
  RDCUNIMPLEMENTED("Global hooking of all processes on linux");
}

void *Process::LoadModule(const char *module)
{
  return dlopen(module, RTLD_NOW);
}

void *Process::GetFunctionAddress(void *module, const char *function)
{
  if(module == NULL)
    return NULL;

  return dlsym(module, function);
}

uint32_t Process::GetCurrentPID()
{
  return (uint32_t)getpid();
}
<commit_msg>Use execvp so that the PATH variable is checked for programs<commit_after>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2016 Baldur Karlsson
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/

#include <dlfcn.h>
#include <errno.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include "api/app/renderdoc_app.h"
#include "api/replay/capture_options.h"
#include "os/os_specific.h"
#include "serialise/string_utils.h"

// defined in foo/foo_process.cpp
char **GetCurrentEnvironment();
int GetIdentPort(pid_t childPid);

static vector<Process::EnvironmentModification> &GetEnvModifications()
{
  static vector<Process::EnvironmentModification> envCallbacks;
  return envCallbacks;
}

static map<string, string> EnvStringToEnvMap(const char **envstring)
{
  map<string, string> ret;

  const char **e = envstring;

  while(*e)
  {
    const char *equals = strchr(*e, '=');

    string name;
    string value;

    name.assign(*e, equals);
    value = equals + 1;

    ret[name] = value;

    e++;
  }

  return ret;
}

static string expandHome(const string &in)
{
  string path = trim(in);

  // if it's ~/... then replace with $HOME and return
  if(path[0] == '~' && path[1] == '/')
    return string(getenv("HOME")) + path.substr(1);

  // if it's ~user/... then use getpwname
  if(path[0] == '~')
  {
    size_t slash = path.find('/');

    string username;

    if(slash != string::npos)
    {
      RDCASSERT(slash > 1);
      username = path.substr(1, slash - 1);
    }
    else
    {
      username = path.substr(1);
    }

    passwd *pwdata = getpwnam(username.c_str());

    if(pwdata)
    {
      if(slash != string::npos)
        return string(pwdata->pw_dir) + path.substr(slash);

      return string(pwdata->pw_dir);
    }
  }

  return path;
}

void Process::RegisterEnvironmentModification(Process::EnvironmentModification modif)
{
  GetEnvModifications().push_back(modif);
}

// on linux we apply environment changes before launching the program, as
// there is no support for injecting/loading renderdoc into a running program
// in any way, and we also have some environment changes that we *have* to make
// for correct hooking (LD_LIBRARY_PATH/LD_PRELOAD)
//
// However we still set environment variables so that we can modify variables while
// in process (e.g. if we notice a setting and want to enable an env var as a result)
void Process::ApplyEnvironmentModification()
{
  // turn environment string to a UTF-8 map
  char **currentEnvironment = GetCurrentEnvironment();
  map<string, string> currentEnv = EnvStringToEnvMap((const char **)currentEnvironment);
  vector<EnvironmentModification> &modifications = GetEnvModifications();

  for(size_t i = 0; i < modifications.size(); i++)
  {
    EnvironmentModification &m = modifications[i];

    string value = currentEnv[m.name];

    switch(m.type)
    {
      case eEnvModification_Replace: value = m.value; break;
      case eEnvModification_Append: value += m.value; break;
      case eEnvModification_AppendPlatform:
      case eEnvModification_AppendColon:
        if(!value.empty())
          value += ":";
        value += m.value;
        break;
      case eEnvModification_AppendSemiColon:
        if(!value.empty())
          value += ";";
        value += m.value;
        break;
      case eEnvModification_Prepend: value = m.value + value; break;
      case eEnvModification_PrependColon:
        if(!value.empty())
          value = m.value + ":" + value;
        else
          value = m.value;
        break;
      case eEnvModification_PrependPlatform:
      case eEnvModification_PrependSemiColon:
        if(!value.empty())
          value = m.value + ";" + value;
        else
          value = m.value;
        break;
      default: RDCERR("Unexpected environment modification type");
    }

    setenv(m.name.c_str(), value.c_str(), true);
  }

  // these have been applied to the current process
  modifications.clear();
}

static pid_t RunProcess(const char *app, const char *workingDir, const char *cmdLine, char **envp)
{
  if(!app)
    return (pid_t)0;

  string appName = app;
  string workDir = (workingDir && workingDir[0]) ? workingDir : dirname(appName);

  // do very limited expansion. wordexp(3) does too much for our needs, so we just expand ~
  // since that could be quite a common case.
  appName = expandHome(appName);
  workDir = expandHome(workDir);

  // it is safe to use app directly as execve never modifies argv
  char *emptyargv[] = {(char *)appName.c_str(), NULL};
  char **argv = emptyargv;

  const char *c = cmdLine;

  // parse command line into argv[], similar to how bash would
  if(cmdLine)
  {
    int argc = 1;

    // get a rough upper bound on the number of arguments
    while(*c)
    {
      if(*c == ' ' || *c == '\t')
        argc++;
      c++;
    }

    argv = new char *[argc + 2];

    c = cmdLine;

    string a;

    argc = 0;    // current argument we're fetching

    // argv[0] is the application name, by convention
    size_t len = appName.length() + 1;
    argv[argc] = new char[len];
    strcpy(argv[argc], appName.c_str());

    argc++;

    bool dquot = false, squot = false;    // are we inside ''s or ""s
    while(*c)
    {
      if(!dquot && !squot && (*c == ' ' || *c == '\t'))
      {
        if(!a.empty())
        {
          // if we've fetched some number of non-space characters
          argv[argc] = new char[a.length() + 1];
          memcpy(argv[argc], a.c_str(), a.length() + 1);
          argc++;
        }

        a = "";
      }
      else if(!dquot && *c == '"')
      {
        dquot = true;
      }
      else if(!squot && *c == '\'')
      {
        squot = true;
      }
      else if(dquot && *c == '"')
      {
        dquot = false;
      }
      else if(squot && *c == '\'')
      {
        squot = false;
      }
      else if(squot)
      {
        // single quotes don't escape, just copy literally until we leave single quote mode
        a.push_back(*c);
      }
      else if(dquot)
      {
        // handle escaping
        if(*c == '\\')
        {
          c++;
          if(*c)
          {
            a.push_back(*c);
          }
          else
          {
            RDCERR("Malformed command line:\n%s", cmdLine);
            return 0;
          }
        }
        else
        {
          a.push_back(*c);
        }
      }
      else
      {
        a.push_back(*c);
      }

      c++;
    }

    if(!a.empty())
    {
      // if we've fetched some number of non-space characters
      argv[argc] = new char[a.length() + 1];
      memcpy(argv[argc], a.c_str(), a.length() + 1);
      argc++;
    }

    argv[argc] = NULL;

    if(squot || dquot)
    {
      RDCERR("Malformed command line\n%s", cmdLine);
      return 0;
    }
  }

  pid_t childPid = fork();
  if(childPid == 0)
  {
    chdir(workDir.c_str());

    // in child process, so we can change environment
    environ = envp;
    execvp(appName.c_str(), argv);

    RDCERR("Failed to execute %s: %s", appName.c_str(), strerror(errno));
    exit(0);
  }

  char **argv_delete = argv;

  if(argv != emptyargv)
  {
    while(*argv)
    {
      delete[] * argv;
      argv++;
    }

    delete[] argv_delete;
  }

  return childPid;
}

uint32_t Process::InjectIntoProcess(uint32_t pid, const char *logfile, const CaptureOptions *opts,
                                    bool waitForExit)
{
  RDCUNIMPLEMENTED("Injecting into already running processes on linux");
  return 0;
}

uint32_t Process::LaunchProcess(const char *app, const char *workingDir, const char *cmdLine)
{
  if(app == NULL || app[0] == 0)
  {
    RDCERR("Invalid empty 'app'");
    return 0;
  }

  char **currentEnvironment = GetCurrentEnvironment();
  return (uint32_t)RunProcess(app, workingDir, cmdLine, currentEnvironment);
}

uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workingDir,
                                             const char *cmdLine, const char *logfile,
                                             const CaptureOptions *opts, bool waitForExit)
{
  if(app == NULL || app[0] == 0)
  {
    RDCERR("Invalid empty 'app'");
    return 0;
  }

  // turn environment string to a UTF-8 map
  char **currentEnvironment = GetCurrentEnvironment();
  map<string, string> env = EnvStringToEnvMap((const char **)currentEnvironment);
  vector<EnvironmentModification> &modifications = GetEnvModifications();

  if(logfile == NULL)
    logfile = "";

  string libpath;
  {
    FileIO::GetExecutableFilename(libpath);
    libpath = dirname(libpath);
  }

  string optstr;
  {
    optstr.reserve(sizeof(CaptureOptions) * 2 + 1);
    byte *b = (byte *)opts;
    for(size_t i = 0; i < sizeof(CaptureOptions); i++)
    {
      optstr.push_back(char('a' + ((b[i] >> 4) & 0xf)));
      optstr.push_back(char('a' + ((b[i]) & 0xf)));
    }
  }

  modifications.push_back(
      EnvironmentModification(eEnvModification_AppendPlatform, "LD_LIBRARY_PATH", libpath.c_str()));
  modifications.push_back(
      EnvironmentModification(eEnvModification_AppendPlatform, "LD_PRELOAD", "librenderdoc.so"));
  modifications.push_back(
      EnvironmentModification(eEnvModification_Replace, "RENDERDOC_LOGFILE", logfile));
  modifications.push_back(
      EnvironmentModification(eEnvModification_Replace, "RENDERDOC_CAPTUREOPTS", optstr.c_str()));

  for(size_t i = 0; i < modifications.size(); i++)
  {
    EnvironmentModification &m = modifications[i];

    string &value = env[m.name];

    switch(m.type)
    {
      case eEnvModification_Replace: value = m.value; break;
      case eEnvModification_Append: value += m.value; break;
      case eEnvModification_AppendPlatform:
      case eEnvModification_AppendColon:
        if(!value.empty())
          value += ":";
        value += m.value;
        break;
      case eEnvModification_AppendSemiColon:
        if(!value.empty())
          value += ";";
        value += m.value;
        break;
      case eEnvModification_Prepend: value = m.value + value; break;
      case eEnvModification_PrependColon:
        if(!value.empty())
          value = m.value + ":" + value;
        else
          value = m.value;
        break;
      case eEnvModification_PrependPlatform:
      case eEnvModification_PrependSemiColon:
        if(!value.empty())
          value = m.value + ";" + value;
        else
          value = m.value;
        break;
      default: RDCERR("Unexpected environment modification type");
    }
  }

  char **envp = new char *[env.size() + 1];
  envp[env.size()] = NULL;

  int i = 0;
  for(auto it = env.begin(); it != env.end(); it++)
  {
    string envline = it->first + "=" + it->second;
    envp[i] = new char[envline.size() + 1];
    memcpy(envp[i], envline.c_str(), envline.size() + 1);
    i++;
  }

  pid_t childPid = RunProcess(app, workingDir, cmdLine, envp);

  int ret = 0;

  if(childPid != (pid_t)0)
  {
    // wait for child to have opened its socket
    usleep(1000);

    ret = GetIdentPort(childPid);

    if(waitForExit)
    {
      int dummy = 0;
      waitpid(childPid, &dummy, 0);
    }
  }

  char **envp_delete = envp;

  while(*envp)
  {
    delete[] * envp;
    envp++;
  }

  delete[] envp_delete;

  return ret;
}

void Process::StartGlobalHook(const char *pathmatch, const char *logfile, const CaptureOptions *opts)
{
  RDCUNIMPLEMENTED("Global hooking of all processes on linux");
}

void *Process::LoadModule(const char *module)
{
  return dlopen(module, RTLD_NOW);
}

void *Process::GetFunctionAddress(void *module, const char *function)
{
  if(module == NULL)
    return NULL;

  return dlsym(module, function);
}

uint32_t Process::GetCurrentPID()
{
  return (uint32_t)getpid();
}
<|endoftext|>


<commit_before>//!
//! @file   HydraulicTurbulentOrifice.hpp
//! @author Karl Pettersson
//! @date   2009-12-21
//!
//! @brief Contains a Hydraulic Turbulent Orifice
//! @ingroup HydraulicComponents
//!
#ifndef HYDRAULICTURBULENTORIFICE_HPP_INCLUDED
#define HYDRAULICTURBULENTORIFICE_HPP_INCLUDED

#include "../../ComponentEssentials.h"
#include "../../ComponentUtilities.h"
#include "math.h"

namespace hopsan {

    //!
    //! @brief Hydraulic orifice with turbulent flow of Q-Type. Uses TurbulentFlowFunction to calculate the flow.
    //! @ingroup HydraulicComponents
    //!
    class HydraulicTurbulentOrifice : public ComponentQ
    {
    private:
        double Cq;
        double A;
        double Kc;
        bool cav;
        TurbulentFlowFunction qTurb;

        double *mpND_p1, *mpND_q1, *mpND_c1, *mpND_Zc1, *mpND_p2, *mpND_q2, *mpND_c2, *mpND_Zc2, *mpND_A;
        double p1,q1, p2, q2, c1, Zc1, c2, Zc2;

        Port *mpP1, *mpP2, *mpIn;

    public:
        static Component *Creator()
        {
            return new HydraulicTurbulentOrifice("TurbulentOrifice");
        }

        HydraulicTurbulentOrifice(const std::string name) : ComponentQ(name)
        {
            mTypeName = "HydraulicTurbulentOrificeName";
            Cq = 0.67;
            A = 0.00001;
            Kc = Cq*A*sqrt(2.0/890.0);

            mpP1 = addPowerPort("P1", "NodeHydraulic");
            mpP2 = addPowerPort("P2", "NodeHydraulic");
            mpIn = addReadPort("A", "NodeSignal", Port::NOTREQUIRED);

            registerParameter("Cq", "Flow coefficient", "[-]", Cq);
            registerParameter("A", "Area", "m^3", A);
        }

        void initialize()
        {
            mpND_p1 = getSafeNodeDataPtr(mpP1, NodeHydraulic::PRESSURE);
            mpND_q1 = getSafeNodeDataPtr(mpP1, NodeHydraulic::FLOW);
            mpND_c1 = getSafeNodeDataPtr(mpP1, NodeHydraulic::WAVEVARIABLE);
            mpND_Zc1 = getSafeNodeDataPtr(mpP1, NodeHydraulic::CHARIMP);

            mpND_p2 = getSafeNodeDataPtr(mpP2, NodeHydraulic::PRESSURE);
            mpND_q2 = getSafeNodeDataPtr(mpP2, NodeHydraulic::FLOW);
            mpND_c2 = getSafeNodeDataPtr(mpP2, NodeHydraulic::WAVEVARIABLE);
            mpND_Zc2 = getSafeNodeDataPtr(mpP2, NodeHydraulic::CHARIMP);

            mpND_A = getSafeNodeDataPtr(mpIn, NodeSignal::VALUE, A);
        }

        void simulateOneTimestep()
        {
            //Get variable values from nodes
            c1 = (*mpND_c1);
            Zc1 = (*mpND_Zc1);
            c2 = (*mpND_c2);
            Zc2 = (*mpND_Zc2);
            A = (*mpND_A);

            //Orifice equations
            Kc = Cq*A*sqrt(2.0/890.0);
            qTurb.setFlowCoefficient(Kc);
            q2 = qTurb.getFlow(c1,c2,Zc1,Zc2);
            q1 = -q2;
            p1 = c1 + q1*Zc1;
            p2 = c2 + q2*Zc2;

            //Cavitation check
            cav = false;
            if(p1 < 0.0)
            {
                c1 = 0.0;
                Zc1 = 0.0;
                cav = true;
            }
            if(p2 < 0.0)
            {
                c2 = 0.0;
                Zc2 = 0.0;
                cav = true;
            }
            if(p1 < 0.0 && p2 < 0.0)
            {
                p1 = 0.0;
                q1 = 0.0;
                p2 = 0.0;
                q2 = 0.0;
            }
            if(cav)
            {
                q2 = qTurb.getFlow(c1,c2,Zc1,Zc2);
                q1 = -q2;
                p1 = c1 + q1*Zc1;
                p2 = c2 + q2*Zc2;
                if(p1 < 0.0) { p1 = 0.0; }
                if(p2 < 0.0) { p2 = 0.0; }
            }

            //Write new variables to nodes
            (*mpND_p1) = p1;
            (*mpND_q1) = q1;
            (*mpND_p2) = p2;
            (*mpND_q2) = q2;
        }
    };
}

#endif // HYDRAULICTURBULENTORIFICE_HPP_INCLUDED
<commit_msg>Fixed wrong unit in orifice<commit_after>//!
//! @file   HydraulicTurbulentOrifice.hpp
//! @author Karl Pettersson
//! @date   2009-12-21
//!
//! @brief Contains a Hydraulic Turbulent Orifice
//! @ingroup HydraulicComponents
//!
//$Id$

#ifndef HYDRAULICTURBULENTORIFICE_HPP_INCLUDED
#define HYDRAULICTURBULENTORIFICE_HPP_INCLUDED

#include "../../ComponentEssentials.h"
#include "../../ComponentUtilities.h"
#include "math.h"

namespace hopsan {

    //!
    //! @brief Hydraulic orifice with turbulent flow of Q-Type. Uses TurbulentFlowFunction to calculate the flow.
    //! @ingroup HydraulicComponents
    //!
    class HydraulicTurbulentOrifice : public ComponentQ
    {
    private:
        double Cq;
        double A;
        double Kc;
        bool cav;
        TurbulentFlowFunction qTurb;

        double *mpND_p1, *mpND_q1, *mpND_c1, *mpND_Zc1, *mpND_p2, *mpND_q2, *mpND_c2, *mpND_Zc2, *mpND_A;
        double p1,q1, p2, q2, c1, Zc1, c2, Zc2;

        Port *mpP1, *mpP2, *mpIn;

    public:
        static Component *Creator()
        {
            return new HydraulicTurbulentOrifice("TurbulentOrifice");
        }

        HydraulicTurbulentOrifice(const std::string name) : ComponentQ(name)
        {
            mTypeName = "HydraulicTurbulentOrificeName";
            Cq = 0.67;
            A = 0.00001;
            Kc = Cq*A*sqrt(2.0/890.0);

            mpP1 = addPowerPort("P1", "NodeHydraulic");
            mpP2 = addPowerPort("P2", "NodeHydraulic");
            mpIn = addReadPort("A", "NodeSignal", Port::NOTREQUIRED);

            registerParameter("Cq", "Flow coefficient", "[-]", Cq);
            registerParameter("A", "Area", "[m^2]", A);
        }

        void initialize()
        {
            mpND_p1 = getSafeNodeDataPtr(mpP1, NodeHydraulic::PRESSURE);
            mpND_q1 = getSafeNodeDataPtr(mpP1, NodeHydraulic::FLOW);
            mpND_c1 = getSafeNodeDataPtr(mpP1, NodeHydraulic::WAVEVARIABLE);
            mpND_Zc1 = getSafeNodeDataPtr(mpP1, NodeHydraulic::CHARIMP);

            mpND_p2 = getSafeNodeDataPtr(mpP2, NodeHydraulic::PRESSURE);
            mpND_q2 = getSafeNodeDataPtr(mpP2, NodeHydraulic::FLOW);
            mpND_c2 = getSafeNodeDataPtr(mpP2, NodeHydraulic::WAVEVARIABLE);
            mpND_Zc2 = getSafeNodeDataPtr(mpP2, NodeHydraulic::CHARIMP);

            mpND_A = getSafeNodeDataPtr(mpIn, NodeSignal::VALUE, A);
        }

        void simulateOneTimestep()
        {
            //Get variable values from nodes
            c1 = (*mpND_c1);
            Zc1 = (*mpND_Zc1);
            c2 = (*mpND_c2);
            Zc2 = (*mpND_Zc2);
            A = (*mpND_A);

            //Orifice equations
            Kc = Cq*A*sqrt(2.0/890.0);
            qTurb.setFlowCoefficient(Kc);
            q2 = qTurb.getFlow(c1,c2,Zc1,Zc2);
            q1 = -q2;
            p1 = c1 + q1*Zc1;
            p2 = c2 + q2*Zc2;

            //Cavitation check
            cav = false;
            if(p1 < 0.0)
            {
                c1 = 0.0;
                Zc1 = 0.0;
                cav = true;
            }
            if(p2 < 0.0)
            {
                c2 = 0.0;
                Zc2 = 0.0;
                cav = true;
            }
            if(p1 < 0.0 && p2 < 0.0)
            {
                p1 = 0.0;
                q1 = 0.0;
                p2 = 0.0;
                q2 = 0.0;
            }
            if(cav)
            {
                q2 = qTurb.getFlow(c1,c2,Zc1,Zc2);
                q1 = -q2;
                p1 = c1 + q1*Zc1;
                p2 = c2 + q2*Zc2;
                if(p1 < 0.0) { p1 = 0.0; }
                if(p2 < 0.0) { p2 = 0.0; }
            }

            //Write new variables to nodes
            (*mpND_p1) = p1;
            (*mpND_q1) = q1;
            (*mpND_p2) = p2;
            (*mpND_q2) = q2;
        }
    };
}

#endif // HYDRAULICTURBULENTORIFICE_HPP_INCLUDED
<|endoftext|>


<commit_before>/*
    This file is part of kdepim.

    Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
    Copyright (c) 2004 Till Adam <adam@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

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

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#include "ogoglobals.h"
#include "groupwaredataadaptor.h"
#include <webdavhandler.h>
#include <libemailfunctions/idmapper.h>
#include <calendaradaptor.h>
#include <addressbookadaptor.h>

#include <libkcal/calendarlocal.h>
#include <libkcal/icalformat.h>
#include <libkcal/resourcecached.h>
#include <kabc/vcardconverter.h>

#include <kdebug.h>
#include <kio/davjob.h>
#include <kio/job.h>

QString OGoGlobals::extractFingerprint( KIO::Job *job, const QString &/*jobData*/ )
{
  const QString& headers = job->queryMetaData( "HTTP-Headers" );
  return WebdavHandler::getEtagFromHeaders( headers );
}

KPIM::GroupwareJob::ContentType OGoGlobals::getContentType( const QDomElement &prop )
{
  QDomElement ctype = prop.namedItem("getcontenttype").toElement();
  if ( ctype.isNull() ) return KPIM::GroupwareJob::Unknown;
  const QString &type = ctype.text();
kdDebug()<<"Found content type: "<<type<<endl;
  /// TODO: Not yet implemented in OGo!
  return KPIM::GroupwareJob::Unknown;
}

KPIM::FolderLister::FolderType OGoGlobals::getFolderType( const QDomNode &folderNode )
{
  QDomNode n4;
kdDebug()<<"OGoGlobals::getFolderType(...)"<<endl;
  for( n4 = folderNode.firstChild(); !n4.isNull(); n4 = n4.nextSibling() ) {
    QDomElement e = n4.toElement();

    if ( e.tagName() == "resourcetype" ) {
      if ( !e.namedItem( "vevent-collection" ).isNull() )
        return KPIM::FolderLister::CalendarFolder;
      if ( !e.namedItem( "vtodo-collection" ).isNull() )
        return KPIM::FolderLister::TasksFolder;
      if ( !e.namedItem( "vjournal-collection" ).isNull() )
        return KPIM::FolderLister::JournalsFolder;
      if ( !e.namedItem( "vcard-collection" ).isNull() )
        return KPIM::FolderLister::ContactsFolder;
      if ( !e.namedItem( "collection" ).isNull() )
        return KPIM::FolderLister::Folder;
    }
  }
  return KPIM::FolderLister::Unknown;
}

bool OGoGlobals::getFolderHasSubs( const QDomNode &folderNode )
{
  // a folder is identified by the collection item in the resourcetype:
  // <a:resourcetype xmlns:a="DAV:"><a:collection xmlns:a="DAV:"/>...</a:resourcetype>
  QDomElement e = folderNode.namedItem("resourcetype").toElement();
  if ( !e.namedItem( "collection" ).isNull() )
    return true;
  else return false;
}

KIO::Job *OGoGlobals::createListFoldersJob( const KURL &url )
{
  QDomDocument doc;
  QDomElement root = WebdavHandler::addDavElement(  doc, doc, "d:propfind" );
  QDomElement prop = WebdavHandler::addElement(  doc, root, "d:prop" );
  WebdavHandler::addElement( doc, prop, "d:displayname" );
  WebdavHandler::addElement( doc, prop, "d:resourcetype" );
//  WebdavHandler::addElement( doc, prop, "d:hassubs" );

  kdDebug(7000) << "props: " << doc.toString() << endl;
  return KIO::davPropFind( url, doc, "1", false );
}

KIO::TransferJob *OGoGlobals::createListItemsJob( const KURL &url )
{
  QDomDocument doc;
  QDomElement root = WebdavHandler::addDavElement(  doc, doc, "propfind" );
  QDomElement prop = WebdavHandler::addDavElement(  doc, root, "prop" );
  WebdavHandler::addDavElement( doc, prop, "getetag" );
//  WebdavHandler::addDavElement( doc, prop, "getcontenttype" );
  kdDebug(5800) << "props = "<< doc.toString() << endl;
  return KIO::davPropFind( url, doc, "1", false );
}

KIO::TransferJob *OGoGlobals::createDownloadJob( KPIM::GroupwareDataAdaptor *adaptor,
                    const KURL &url, KPIM::GroupwareJob::ContentType /*ctype*/ )
{
kdDebug()<<"OGoGlobals::createDownloadJob, url="<<url.url()<<endl;
  KIO::TransferJob *job = KIO::get( url, false, false );
  if ( adaptor ) {
    QString mt = adaptor->mimeType();
    job->addMetaData( "accept", mt );
  }
  job->addMetaData( "PropagateHttpHeader", "true" );
  return job;
}

KIO::Job *OGoGlobals::createRemoveJob( KPIM::GroupwareDataAdaptor *adaptor, const KURL &uploadurl,
       const KPIM::GroupwareUploadItem::List &deletedItems )
{
  QStringList urls;
  KPIM::GroupwareUploadItem::List::const_iterator it;
  kdDebug(5800) << " OGoGlobals::createRemoveJob: , BaseURL="<<uploadurl.url()<<endl;
  for ( it = deletedItems.constBegin(); it != deletedItems.constEnd(); ++it ) {
    //kdDebug(7000) << "Delete: " << endl << format.toICalString(*it) << endl;
    KURL url( (*it)->url() );
    if ( adaptor ) {
      adaptor->adaptUploadUrl( url );
    }
/*    KURL url( uploadurl );
    url.setPath( (*it)->url().path() );
    if ( !(*it)->url().isEmpty() )*/
    if ( !url.isEmpty() ) {
kdDebug() << "Deleting item at "<< url.url() << endl;
      urls << url.url();
    }
    kdDebug(5700) << "Delete (Mod) : " <<   url.url() << endl;
  }
  return KIO::del( urls, false, false );
}

bool OGoGlobals::interpretListItemsJob( KPIM::GroupwareDataAdaptor *adaptor,
                                        KIO::Job *job )
{
  KIO::DavJob *davjob = dynamic_cast<KIO::DavJob *>(job);

  if ( !davjob ) {
    return false;
  }
  QDomDocument doc = davjob->response();

  kdDebug(7000) << " Doc: " << doc.toString() << endl;
  kdDebug(7000) << " IdMapper: " << adaptor->idMapper()->asString() << endl;

  QDomElement docElem = doc.documentElement();
  QDomNode n = docElem.firstChild();
  while( !n.isNull() ) {
    QDomElement e = n.toElement(); // try to convert the node to an element.
    n = n.nextSibling();
    if ( e.isNull() )
      continue;

    const QString &entry = e.namedItem("href").toElement().text();
    QDomElement propstat = e.namedItem("propstat").toElement();
    if ( propstat.isNull() )
      continue;
    QDomElement prop = propstat.namedItem( "prop" ).toElement();
    if ( prop.isNull() )
      continue;
    QDomElement elem = prop.namedItem("getetag").toElement();
    const QString &newFingerprint = elem.text();
    if ( elem.isNull() || newFingerprint.isEmpty() )
      continue;

    KPIM::GroupwareJob::ContentType type = getContentType( prop );

    adaptor->processDownloadListItem( entry, newFingerprint, type );
  }

  return true;
}

bool OGoGlobals::interpretCalendarDownloadItemsJob( KCal::CalendarAdaptor *adaptor,
                                         KIO::Job *job, const QString &jobData )
{
kdDebug(5800) << "DAVGroupwareGlobals::interpretCalendarDownloadItemsJob, iCalendar=" << endl;
kdDebug(5800) << jobData << endl;
  if ( !adaptor || !job ) return false;
  KCal::CalendarLocal calendar;
  KCal::ICalFormat ical;
  calendar.setTimeZoneId( adaptor->resource()->timeZoneId() );
  KCal::Incidence::List incidences;
  if ( ical.fromString( &calendar, jobData ) ) {
    KCal::Incidence::List raw = calendar.rawIncidences();
    KCal::Incidence::List::Iterator it = raw.begin();
    if ( raw.count() != 1 ) {
      kdError() << "Parsed iCalendar does not contain exactly one event." << endl;
      return false;
    }

    KCal::Incidence *inc = (raw.front())->clone();
    if ( !inc ) return false;
    KIO::SimpleJob *sjob = dynamic_cast<KIO::SimpleJob *>(job);
    QString remoteId( QString::null );
    if ( sjob ) remoteId = sjob->url().path();
    QString fingerprint = extractFingerprint( job, jobData );
    adaptor->calendarItemDownloaded( inc, inc->uid(), remoteId, fingerprint,
                                     sjob->url().prettyURL() );
    return true;
  } else {
    kdError() << "Unable to parse iCalendar" << endl;
  }
  return false;
}

bool OGoGlobals::interpretAddressBookDownloadItemsJob(
      KABC::AddressBookAdaptor *adaptor, KIO::Job *job, const QString &jobData )
{
kdDebug(5800) << "DAVGroupwareGlobals::interpretAddressBookDownloadItemsJob, vCard=" << endl;
kdDebug(5800) << jobData << endl;
  if ( !adaptor || !job ) return false;

  KABC::VCardConverter conv;
  KABC::Addressee::List addrs( conv.parseVCards( jobData ) );

  if ( addrs.count() != 1 ) {
    kdError() << "Parsed vCard does not contain exactly one addressee." << endl;
    return false;
  }

  KABC::Addressee a = addrs.first();

  KIO::SimpleJob *sjob = dynamic_cast<KIO::SimpleJob*>(job);
  QString remoteId( QString::null );
  if ( sjob ) remoteId = sjob->url().path();
  QString fingerprint = extractFingerprint( job, jobData );
  adaptor->addressbookItemDownloaded( a, a.uid(), remoteId, fingerprint,
                                      sjob->url().prettyURL() );
  return true;
}

<commit_msg>CVS_SILENT: debug output<commit_after>/*
    This file is part of kdepim.

    Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
    Copyright (c) 2004 Till Adam <adam@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

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

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#include "ogoglobals.h"
#include "groupwaredataadaptor.h"
#include <webdavhandler.h>
#include <libemailfunctions/idmapper.h>
#include <calendaradaptor.h>
#include <addressbookadaptor.h>

#include <libkcal/calendarlocal.h>
#include <libkcal/icalformat.h>
#include <libkcal/resourcecached.h>
#include <kabc/vcardconverter.h>

#include <kdebug.h>
#include <kio/davjob.h>
#include <kio/job.h>

QString OGoGlobals::extractFingerprint( KIO::Job *job, const QString &/*jobData*/ )
{
  const QString& headers = job->queryMetaData( "HTTP-Headers" );
  return WebdavHandler::getEtagFromHeaders( headers );
}

KPIM::GroupwareJob::ContentType OGoGlobals::getContentType( const QDomElement &prop )
{
  QDomElement ctype = prop.namedItem("getcontenttype").toElement();
  if ( ctype.isNull() ) return KPIM::GroupwareJob::Unknown;
  const QString &type = ctype.text();
kdDebug()<<"Found content type: "<<type<<endl;
  /// TODO: Not yet implemented in OGo!
  return KPIM::GroupwareJob::Unknown;
}

KPIM::FolderLister::FolderType OGoGlobals::getFolderType( const QDomNode &folderNode )
{
  QDomNode n4;
kdDebug()<<"OGoGlobals::getFolderType(...)"<<endl;
  for( n4 = folderNode.firstChild(); !n4.isNull(); n4 = n4.nextSibling() ) {
    QDomElement e = n4.toElement();

    if ( e.tagName() == "resourcetype" ) {
      if ( !e.namedItem( "vevent-collection" ).isNull() )
        return KPIM::FolderLister::CalendarFolder;
      if ( !e.namedItem( "vtodo-collection" ).isNull() )
        return KPIM::FolderLister::TasksFolder;
      if ( !e.namedItem( "vjournal-collection" ).isNull() )
        return KPIM::FolderLister::JournalsFolder;
      if ( !e.namedItem( "vcard-collection" ).isNull() )
        return KPIM::FolderLister::ContactsFolder;
      if ( !e.namedItem( "collection" ).isNull() )
        return KPIM::FolderLister::Folder;
    }
  }
  return KPIM::FolderLister::Unknown;
}

bool OGoGlobals::getFolderHasSubs( const QDomNode &folderNode )
{
  // a folder is identified by the collection item in the resourcetype:
  // <a:resourcetype xmlns:a="DAV:"><a:collection xmlns:a="DAV:"/>...</a:resourcetype>
  QDomElement e = folderNode.namedItem("resourcetype").toElement();
  if ( !e.namedItem( "collection" ).isNull() )
    return true;
  else return false;
}

KIO::Job *OGoGlobals::createListFoldersJob( const KURL &url )
{
  QDomDocument doc;
  QDomElement root = WebdavHandler::addDavElement(  doc, doc, "d:propfind" );
  QDomElement prop = WebdavHandler::addElement(  doc, root, "d:prop" );
  WebdavHandler::addElement( doc, prop, "d:displayname" );
  WebdavHandler::addElement( doc, prop, "d:resourcetype" );
//  WebdavHandler::addElement( doc, prop, "d:hassubs" );

  kdDebug(7000) << "props: " << doc.toString() << endl;
  return KIO::davPropFind( url, doc, "1", false );
}

KIO::TransferJob *OGoGlobals::createListItemsJob( const KURL &url )
{
  QDomDocument doc;
  QDomElement root = WebdavHandler::addDavElement(  doc, doc, "propfind" );
  QDomElement prop = WebdavHandler::addDavElement(  doc, root, "prop" );
  WebdavHandler::addDavElement( doc, prop, "getetag" );
//  WebdavHandler::addDavElement( doc, prop, "getcontenttype" );
  kdDebug(5800) << "props = "<< doc.toString() << endl;
  return KIO::davPropFind( url, doc, "1", false );
}

KIO::TransferJob *OGoGlobals::createDownloadJob( KPIM::GroupwareDataAdaptor *adaptor,
                    const KURL &url, KPIM::GroupwareJob::ContentType /*ctype*/ )
{
kdDebug()<<"OGoGlobals::createDownloadJob, url="<<url.url()<<endl;
  KIO::TransferJob *job = KIO::get( url, false, false );
  if ( adaptor ) {
    QString mt = adaptor->mimeType();
    job->addMetaData( "accept", mt );
  }
  job->addMetaData( "PropagateHttpHeader", "true" );
  return job;
}

KIO::Job *OGoGlobals::createRemoveJob( KPIM::GroupwareDataAdaptor *adaptor, const KURL &uploadurl,
       const KPIM::GroupwareUploadItem::List &deletedItems )
{
  QStringList urls;
  KPIM::GroupwareUploadItem::List::const_iterator it;
  kdDebug(5800) << " OGoGlobals::createRemoveJob, BaseURL="<<uploadurl.url()<<endl;
  for ( it = deletedItems.constBegin(); it != deletedItems.constEnd(); ++it ) {
    //kdDebug(7000) << "Delete: " << endl << format.toICalString(*it) << endl;
    KURL url( (*it)->url() );
    if ( adaptor ) {
      adaptor->adaptUploadUrl( url );
    }
/*    KURL url( uploadurl );
    url.setPath( (*it)->url().path() );
    if ( !(*it)->url().isEmpty() )*/
    if ( !url.isEmpty() ) {
kdDebug() << "Deleting item at "<< url.url() << endl;
      urls << url.url();
    }
    kdDebug(5700) << "Delete (Mod) : " <<   url.url() << endl;
  }
  return KIO::del( urls, false, false );
}

bool OGoGlobals::interpretListItemsJob( KPIM::GroupwareDataAdaptor *adaptor,
                                        KIO::Job *job )
{
  KIO::DavJob *davjob = dynamic_cast<KIO::DavJob *>(job);

  if ( !davjob ) {
    return false;
  }
  QDomDocument doc = davjob->response();

  kdDebug(7000) << " Doc: " << doc.toString() << endl;
  kdDebug(7000) << " IdMapper: " << adaptor->idMapper()->asString() << endl;

  QDomElement docElem = doc.documentElement();
  QDomNode n = docElem.firstChild();
  while( !n.isNull() ) {
    QDomElement e = n.toElement(); // try to convert the node to an element.
    n = n.nextSibling();
    if ( e.isNull() )
      continue;

    const QString &entry = e.namedItem("href").toElement().text();
    QDomElement propstat = e.namedItem("propstat").toElement();
    if ( propstat.isNull() )
      continue;
    QDomElement prop = propstat.namedItem( "prop" ).toElement();
    if ( prop.isNull() )
      continue;
    QDomElement elem = prop.namedItem("getetag").toElement();
    const QString &newFingerprint = elem.text();
    if ( elem.isNull() || newFingerprint.isEmpty() )
      continue;

    KPIM::GroupwareJob::ContentType type = getContentType( prop );

    adaptor->processDownloadListItem( entry, newFingerprint, type );
  }

  return true;
}

bool OGoGlobals::interpretCalendarDownloadItemsJob( KCal::CalendarAdaptor *adaptor,
                                         KIO::Job *job, const QString &jobData )
{
kdDebug(5800) << "DAVGroupwareGlobals::interpretCalendarDownloadItemsJob, iCalendar=" << endl;
kdDebug(5800) << jobData << endl;
  if ( !adaptor || !job ) return false;
  KCal::CalendarLocal calendar;
  KCal::ICalFormat ical;
  calendar.setTimeZoneId( adaptor->resource()->timeZoneId() );
  KCal::Incidence::List incidences;
  if ( ical.fromString( &calendar, jobData ) ) {
    KCal::Incidence::List raw = calendar.rawIncidences();
    KCal::Incidence::List::Iterator it = raw.begin();
    if ( raw.count() != 1 ) {
      kdError() << "Parsed iCalendar does not contain exactly one event." << endl;
      return false;
    }

    KCal::Incidence *inc = (raw.front())->clone();
    if ( !inc ) return false;
    KIO::SimpleJob *sjob = dynamic_cast<KIO::SimpleJob *>(job);
    QString remoteId( QString::null );
    if ( sjob ) remoteId = sjob->url().path();
    QString fingerprint = extractFingerprint( job, jobData );
    adaptor->calendarItemDownloaded( inc, inc->uid(), remoteId, fingerprint,
                                     sjob->url().prettyURL() );
    return true;
  } else {
    kdError() << "Unable to parse iCalendar" << endl;
  }
  return false;
}

bool OGoGlobals::interpretAddressBookDownloadItemsJob(
      KABC::AddressBookAdaptor *adaptor, KIO::Job *job, const QString &jobData )
{
kdDebug(5800) << "DAVGroupwareGlobals::interpretAddressBookDownloadItemsJob, vCard=" << endl;
kdDebug(5800) << jobData << endl;
  if ( !adaptor || !job ) return false;

  KABC::VCardConverter conv;
  KABC::Addressee::List addrs( conv.parseVCards( jobData ) );

  if ( addrs.count() != 1 ) {
    kdError() << "Parsed vCard does not contain exactly one addressee." << endl;
    return false;
  }

  KABC::Addressee a = addrs.first();

  KIO::SimpleJob *sjob = dynamic_cast<KIO::SimpleJob*>(job);
  QString remoteId( QString::null );
  if ( sjob ) remoteId = sjob->url().path();
  QString fingerprint = extractFingerprint( job, jobData );
  adaptor->addressbookItemDownloaded( a, a.uid(), remoteId, fingerprint,
                                      sjob->url().prettyURL() );
  return true;
}

<|endoftext|>


<commit_before>//===- InputFiles.cpp -----------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "InputFiles.h"
#include "Chunks.h"
#include "Symbols.h"
#include "Driver.h"
#include "llvm/ADT/STLExtras.h"

using namespace llvm::ELF;

using namespace lld;
using namespace lld::elf2;

template <class ELFT> void elf2::ObjectFile<ELFT>::parse() {
  // Parse a memory buffer as a ELF file.
  std::error_code EC;
  ELFObj = llvm::make_unique<ELFFile<ELFT>>(MB.getBuffer(), EC);
  error(EC);

  // Read section and symbol tables.
  initializeChunks();
  initializeSymbols();
}

template <class ELFT> void elf2::ObjectFile<ELFT>::initializeChunks() {
  uint64_t Size = ELFObj->getNumSections();
  Chunks.reserve(Size);
  for (const Elf_Shdr &Sec : ELFObj->sections()) {
    if (Sec.sh_flags & SHF_ALLOC) {
      auto *C = new (Alloc) SectionChunk<ELFT>(this->getObj(), &Sec);
      Chunks.push_back(C);
    }
  }
}

template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() {
  const Elf_Shdr *Symtab = ELFObj->getDotSymtabSec();
  ErrorOr<StringRef> StringTableOrErr =
      ELFObj->getStringTableForSymtab(*Symtab);
  error(StringTableOrErr.getError());
  StringRef StringTable = *StringTableOrErr;

  Elf_Sym_Range Syms = ELFObj->symbols();
  Syms = Elf_Sym_Range(Syms.begin() + 1, Syms.end());
  auto NumSymbols = std::distance(Syms.begin(), Syms.end());
  SymbolBodies.reserve(NumSymbols);
  for (const Elf_Sym &Sym : Syms) {
    if (SymbolBody *Body = createSymbolBody(StringTable, &Sym))
      SymbolBodies.push_back(Body);
  }
}

template <class ELFT>
SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
                                                     const Elf_Sym *Sym) {
  ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable);
  error(NameOrErr.getError());
  StringRef Name = *NameOrErr;
  if (Sym->isUndefined())
    return new (Alloc) Undefined(Name);
  return new (Alloc) DefinedRegular<ELFT>(this, Sym);
}

namespace lld {
namespace elf2 {
template class elf2::ObjectFile<llvm::object::ELF32LE>;
template class elf2::ObjectFile<llvm::object::ELF32BE>;
template class elf2::ObjectFile<llvm::object::ELF64LE>;
template class elf2::ObjectFile<llvm::object::ELF64BE>;
}
}
<commit_msg>This function never returns null, don't check it.<commit_after>//===- InputFiles.cpp -----------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "InputFiles.h"
#include "Chunks.h"
#include "Symbols.h"
#include "Driver.h"
#include "llvm/ADT/STLExtras.h"

using namespace llvm::ELF;

using namespace lld;
using namespace lld::elf2;

template <class ELFT> void elf2::ObjectFile<ELFT>::parse() {
  // Parse a memory buffer as a ELF file.
  std::error_code EC;
  ELFObj = llvm::make_unique<ELFFile<ELFT>>(MB.getBuffer(), EC);
  error(EC);

  // Read section and symbol tables.
  initializeChunks();
  initializeSymbols();
}

template <class ELFT> void elf2::ObjectFile<ELFT>::initializeChunks() {
  uint64_t Size = ELFObj->getNumSections();
  Chunks.reserve(Size);
  for (const Elf_Shdr &Sec : ELFObj->sections()) {
    if (Sec.sh_flags & SHF_ALLOC) {
      auto *C = new (Alloc) SectionChunk<ELFT>(this->getObj(), &Sec);
      Chunks.push_back(C);
    }
  }
}

template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() {
  const Elf_Shdr *Symtab = ELFObj->getDotSymtabSec();
  ErrorOr<StringRef> StringTableOrErr =
      ELFObj->getStringTableForSymtab(*Symtab);
  error(StringTableOrErr.getError());
  StringRef StringTable = *StringTableOrErr;

  Elf_Sym_Range Syms = ELFObj->symbols();
  Syms = Elf_Sym_Range(Syms.begin() + 1, Syms.end());
  auto NumSymbols = std::distance(Syms.begin(), Syms.end());
  SymbolBodies.reserve(NumSymbols);
  for (const Elf_Sym &Sym : Syms)
    SymbolBodies.push_back(createSymbolBody(StringTable, &Sym));
}

template <class ELFT>
SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
                                                     const Elf_Sym *Sym) {
  ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable);
  error(NameOrErr.getError());
  StringRef Name = *NameOrErr;
  if (Sym->isUndefined())
    return new (Alloc) Undefined(Name);
  return new (Alloc) DefinedRegular<ELFT>(this, Sym);
}

namespace lld {
namespace elf2 {
template class elf2::ObjectFile<llvm::object::ELF32LE>;
template class elf2::ObjectFile<llvm::object::ELF32BE>;
template class elf2::ObjectFile<llvm::object::ELF64LE>;
template class elf2::ObjectFile<llvm::object::ELF64BE>;
}
}
<|endoftext|>