<commit_before>#include "Device.h"

map<string,pfunc> device_api_list;

Device::Device(){
    this->mysql = new MysqlHelper();
    this->mysql->init("127.0.0.1", "root", "root", "smart_car");
    this->initApiList();
}

Device::~Device(){

}

void Device::initApiList() {
  device_api_list[API_DEVICE_INFO] = &Device::handlerDeverInfo;
  device_api_list[API_DEVICE_BASE_INFO] = &Device::handlerGetDeviceBaseInfo;
}

void Device::call(Conn* &conn, Json::Value &request_data,const string func){
  if(func.length() == 0){
    Json::Value root;
    Json::Value data;
    root["protocol"] = API_NOT_FIND;
    root["data"] = data;
    this->sendData(conn,root.toStyledString());
    return;
  }
  if (device_api_list.count(func)) {
    (this->*(device_api_list[func]))(conn,request_data);
  } else {
    Json::Value root;
    Json::Value data;
    root["protocol"] = API_NOT_FIND;
    root["data"] = data;
    this->sendData(conn,root.toStyledString());
  }
}

void Device::sendData(Conn* &conn,const string resp_data){
    char* data = new char[resp_data.length()+1];
    resp_data.copy(data,resp_data.length(),0);
    conn->AddToWriteBuffer(data, resp_data.length());
    delete[] data;
}

void Device::handlerGetDeviceBaseInfo(Conn* &conn, Json::Value &request_data){
    if(request_data["data"]["is_api"].asBool()){
        this->sendData(conn,request_data.toStyledString().c_str());
    }else{
        this->sendApiData(request_data.toStyledString().c_str());
    }
}

void Device::handlerDeverInfo(Conn* &conn, Json::Value &request_data){
    Json::Value root;
    Json::Value data;
    string sql = "select * from device where ";
    string name = request_data["name"].asString();
    string mac = request_data["mac"].asString();
    //获取fd并转string
    int fd = conn->GetFd();
    char intToStr[12];
    sprintf(intToStr,"%d",fd);
    string str_fd = string(intToStr);
    //检查设备是否存在
    sql = sql+"name=\""+name+"\" and mac=\""+mac+"\"";
    MysqlHelper::MysqlData dataSet = this->mysql->queryRecord(sql);
    if (dataSet.size() == 0) {
        //不存在,新增
        MysqlHelper::RECORD_DATA record;
        record.insert(make_pair("name",make_pair(MysqlHelper::DB_STR,name)));
        record.insert(make_pair("mac",make_pair(MysqlHelper::DB_STR,mac)));
        record.insert(make_pair("online",make_pair(MysqlHelper::DB_INT,"1")));
        record.insert(make_pair("status",make_pair(MysqlHelper::DB_INT,"1")));
        record.insert(make_pair("sock_fd",make_pair(MysqlHelper::DB_INT,str_fd)));
        int insert_id = this->mysql->insertRecord("device",record);
        data["id"] = insert_id;
    }else{
        //存在,更新状态
        string up_sql = "where  mac = \""+mac+"\"";
        MysqlHelper::RECORD_DATA recordChange;
        recordChange.insert(make_pair("online",make_pair(MysqlHelper::DB_INT,"1")));
        recordChange.insert(make_pair("status",make_pair(MysqlHelper::DB_INT,"1")));
        recordChange.insert(make_pair("sock_fd",make_pair(MysqlHelper::DB_INT,str_fd)));
        this->mysql->updateRecord("device",recordChange,up_sql);
        data["id"] = dataSet[0]["id"];
    }
    root["protocol"] = API_DEVICE_INFO;
    root["data"] = data;
    this->sendData(conn,root.toStyledString());
}

void Device::start(const char* ip,unsigned int port){
    this->AddSignalEvent(SIGINT, Device::QuitCb);
    this->SetPort(port);
    this->SetAddress(ip);
    this->StartRun();
}

void Device::ReadApiEvent(const char *str){
    Json::Reader reader;
    Json::Value data;
    if(reader.parse(str, data)){
        string func = data["protocol"].asString();
        int sock_fd = atoi(data["data"]["sockfd"].asString.c_str());
        Conn* conn = this->getConnBaySocketFd(sock_fd);
        if(conn != NULL){
            this->call(conn,data,func);
        }else{
            Json::Value root;
            Json::Value data;
            root["protocol"] = API_NOT_FIND_DEVICE;
            root["data"] = data;
            this->sendApiData(root.toStyledString().c_str());
        }
    }else{
        Json::Value root;
        Json::Value data;
        root["protocol"] = API_NOT_FIND;
        root["data"] = data;
        this->sendApiData(root.toStyledString().c_str());
    }
}

void Device::ReadEvent(Conn *conn){
    Json::Reader reader;
    Json::Value data;
    //读取客户端数据
    int len = conn->GetReadBufferLen();
    char* str = new char[len+1];
    conn->GetReadBuffer(str,len);
    //解析数据
    if(reader.parse(str, data)){
        string func = data["protocol"].asString();
        this->call(conn,data["data"],func);
    }else{
        Json::Value root;
        Json::Value data;
        root["protocol"] = API_NOT_FIND;
        root["data"] = data;
        this->sendData(conn,root.toStyledString());
    }
}

void Device::WriteEvent(Conn *conn){

}

void Device::ConnectionEvent(Conn *conn){
    int sock_fd = conn->GetFd();
    this->sock_list[sock_fd] = conn;
}

Conn* Device::getConnBaySocketFd(int sock_fd){
    Conn* conn = NULL;
    map<int,Conn*>::iterator iter;
    for(iter=this->sock_list.begin(); iter!=this->sock_list.end(); iter++){
        if (iter->first == sock_fd){
            conn = iter->second;
        }
    }
    return conn;
}

void Device::CloseEvent(Conn *conn, short events){
    char str_fd[12];
    sprintf(str_fd,"%d",conn->GetFd());
    string sql = "select * from device where sock_fd = "+string(str_fd);
    MysqlHelper::MysqlData dataSet = this->mysql->queryRecord(sql);
    if (dataSet.size() != 0) {
        string up_sql = "where  mac = \""+dataSet[0]["mac"]+"\"";
        MysqlHelper::RECORD_DATA recordChange;
        recordChange.insert(make_pair("online",make_pair(MysqlHelper::DB_INT,"2")));
        recordChange.insert(make_pair("sock_fd",make_pair(MysqlHelper::DB_INT,"0")));
        this->mysql->updateRecord("device",recordChange,up_sql);
    }else{
        printf("close sock_fd error,not find mysql socke_fd !!\n");
    }
    map<int,Conn*>::iterator iter;
    for(iter=this->sock_list.begin(); iter!=this->sock_list.end(); iter++){
        if (iter->first == conn->GetFd()){
            this->sock_list.erase(iter);
        }
    }
}

void Device::QuitCb(int sig, short events, void *data)
{
    Device *me = (Device*)data;
    me->StopRun(NULL);
}
<commit_msg>完善进程通信<commit_after>#include "Device.h"

map<string,pfunc> device_api_list;

Device::Device(){
    this->mysql = new MysqlHelper();
    this->mysql->init("127.0.0.1", "root", "root", "smart_car");
    this->initApiList();
}

Device::~Device(){

}

void Device::initApiList() {
  device_api_list[API_DEVICE_INFO] = &Device::handlerDeverInfo;
  device_api_list[API_DEVICE_BASE_INFO] = &Device::handlerGetDeviceBaseInfo;
}

void Device::call(Conn* &conn, Json::Value &request_data,const string func){
  if(func.length() == 0){
    Json::Value root;
    Json::Value data;
    root["protocol"] = API_NOT_FIND;
    root["data"] = data;
    this->sendData(conn,root.toStyledString());
    return;
  }
  if (device_api_list.count(func)) {
    (this->*(device_api_list[func]))(conn,request_data);
  } else {
    Json::Value root;
    Json::Value data;
    root["protocol"] = API_NOT_FIND;
    root["data"] = data;
    this->sendData(conn,root.toStyledString());
  }
}

void Device::sendData(Conn* &conn,const string resp_data){
    char* data = new char[resp_data.length()+1];
    resp_data.copy(data,resp_data.length(),0);
    conn->AddToWriteBuffer(data, resp_data.length());
    delete[] data;
}

void Device::handlerGetDeviceBaseInfo(Conn* &conn, Json::Value &request_data){
    if(request_data["data"]["is_api"].asBool()){
        this->sendData(conn,request_data.toStyledString().c_str());
    }else{
        this->sendApiData(request_data.toStyledString().c_str());
    }
}

void Device::handlerDeverInfo(Conn* &conn, Json::Value &request_data){
    Json::Value root;
    Json::Value data;
    string sql = "select * from device where ";
    string name = request_data["name"].asString();
    string mac = request_data["mac"].asString();
    //获取fd并转string
    int fd = conn->GetFd();
    char intToStr[12];
    sprintf(intToStr,"%d",fd);
    string str_fd = string(intToStr);
    //检查设备是否存在
    sql = sql+"name=\""+name+"\" and mac=\""+mac+"\"";
    MysqlHelper::MysqlData dataSet = this->mysql->queryRecord(sql);
    if (dataSet.size() == 0) {
        //不存在,新增
        MysqlHelper::RECORD_DATA record;
        record.insert(make_pair("name",make_pair(MysqlHelper::DB_STR,name)));
        record.insert(make_pair("mac",make_pair(MysqlHelper::DB_STR,mac)));
        record.insert(make_pair("online",make_pair(MysqlHelper::DB_INT,"1")));
        record.insert(make_pair("status",make_pair(MysqlHelper::DB_INT,"1")));
        record.insert(make_pair("sock_fd",make_pair(MysqlHelper::DB_INT,str_fd)));
        int insert_id = this->mysql->insertRecord("device",record);
        data["id"] = insert_id;
    }else{
        //存在,更新状态
        string up_sql = "where  mac = \""+mac+"\"";
        MysqlHelper::RECORD_DATA recordChange;
        recordChange.insert(make_pair("online",make_pair(MysqlHelper::DB_INT,"1")));
        recordChange.insert(make_pair("status",make_pair(MysqlHelper::DB_INT,"1")));
        recordChange.insert(make_pair("sock_fd",make_pair(MysqlHelper::DB_INT,str_fd)));
        this->mysql->updateRecord("device",recordChange,up_sql);
        data["id"] = dataSet[0]["id"];
    }
    root["protocol"] = API_DEVICE_INFO;
    root["data"] = data;
    this->sendData(conn,root.toStyledString());
}

void Device::start(const char* ip,unsigned int port){
    this->AddSignalEvent(SIGINT, Device::QuitCb);
    this->SetPort(port);
    this->SetAddress(ip);
    this->StartRun();
}

void Device::ReadApiEvent(const char *str){
    Json::Reader reader;
    Json::Value data;
    if(reader.parse(str, data)){
        string func = data["protocol"].asString();
        int sock_fd = atoi(data["data"]["sockfd"].asString().c_str());
        Conn* conn = this->getConnBaySocketFd(sock_fd);
        if(conn != NULL){
            this->call(conn,data,func);
        }else{
            Json::Value root;
            Json::Value data;
            root["protocol"] = API_NOT_FIND_DEVICE;
            root["data"] = data;
            this->sendApiData(root.toStyledString().c_str());
        }
    }else{
        Json::Value root;
        Json::Value data;
        root["protocol"] = API_NOT_FIND;
        root["data"] = data;
        this->sendApiData(root.toStyledString().c_str());
    }
}

void Device::ReadEvent(Conn *conn){
    Json::Reader reader;
    Json::Value data;
    //读取客户端数据
    int len = conn->GetReadBufferLen();
    char* str = new char[len+1];
    conn->GetReadBuffer(str,len);
    //解析数据
    if(reader.parse(str, data)){
        string func = data["protocol"].asString();
        this->call(conn,data["data"],func);
    }else{
        Json::Value root;
        Json::Value data;
        root["protocol"] = API_NOT_FIND;
        root["data"] = data;
        this->sendData(conn,root.toStyledString());
    }
}

void Device::WriteEvent(Conn *conn){

}

void Device::ConnectionEvent(Conn *conn){
    int sock_fd = conn->GetFd();
    this->sock_list[sock_fd] = conn;
}

Conn* Device::getConnBaySocketFd(int sock_fd){
    Conn* conn = NULL;
    map<int,Conn*>::iterator iter;
    for(iter=this->sock_list.begin(); iter!=this->sock_list.end(); iter++){
        if (iter->first == sock_fd){
            conn = iter->second;
        }
    }
    return conn;
}

void Device::CloseEvent(Conn *conn, short events){
    char str_fd[12];
    sprintf(str_fd,"%d",conn->GetFd());
    string sql = "select * from device where sock_fd = "+string(str_fd);
    MysqlHelper::MysqlData dataSet = this->mysql->queryRecord(sql);
    if (dataSet.size() != 0) {
        string up_sql = "where  mac = \""+dataSet[0]["mac"]+"\"";
        MysqlHelper::RECORD_DATA recordChange;
        recordChange.insert(make_pair("online",make_pair(MysqlHelper::DB_INT,"2")));
        recordChange.insert(make_pair("sock_fd",make_pair(MysqlHelper::DB_INT,"0")));
        this->mysql->updateRecord("device",recordChange,up_sql);
    }else{
        printf("close sock_fd error,not find mysql socke_fd !!\n");
    }
    map<int,Conn*>::iterator iter;
    for(iter=this->sock_list.begin(); iter!=this->sock_list.end(); iter++){
        if (iter->first == conn->GetFd()){
            this->sock_list.erase(iter);
        }
    }
}

void Device::QuitCb(int sig, short events, void *data)
{
    Device *me = (Device*)data;
    me->StopRun(NULL);
}
<|endoftext|>


<commit_before>/* ===========================
 *
 * Copyright (c) 2013 Philippe Tillet - National Chiao Tung University
 *
 * FMinCL - Unconstrained Function Minimization on OpenCL
 *
 * License : MIT X11 - See the LICENSE file in the root folder
 * ===========================*/

#ifndef FMINCL_DIRECTIONS_CONJUGATE_GRADIENT_HPP_
#define FMINCL_DIRECTIONS_CONJUGATE_GRADIENT_HPP_

#include "fmincl/utils.hpp"

#include "fmincl/mapping.hpp"

#include "fmincl/tools/shared_ptr.hpp"
#include "fmincl/directions/forwards.h"

#include "conjugate_gradient/restarts.hpp"
#include "conjugate_gradient/updates.hpp"

namespace fmincl{

struct conjugate_gradient : public direction{
    template<class BackendType>
    class implementation : public direction::implementation<BackendType>{
        typedef typename BackendType::VectorType VectorType;
        typedef implementation_of<BackendType,cg_update,polak_ribiere,fletcher_reeves> update_mapping;

    public:
        implementation(conjugate_gradient const & cg_params, detail::optimization_context<BackendType> & context) : context_(context), update_implementation_(update_mapping::create(*cg_params.update, context)){ }
        void operator()(){
          double eps = 1e-9;
          VectorType const & g = context_.g();
          VectorType & p = context_.p();
          std::size_t N = context_.dim();
          bool restart = std::abs(BackendType::dot(N,g,context_.gm1()))/BackendType::dot(N,g,g) > 0.2;
          double beta = restart?0:(*update_implementation_)();
          //p = -g + beta*p;
          BackendType::scale(N,beta,p);
          BackendType::axpy(N,-1,g,p);
          //Restart

        }
    private:
        detail::optimization_context<BackendType> & context_;

        tools::shared_ptr<cg_update::implementation<BackendType> > update_implementation_;
    };

    conjugate_gradient(cg_update * _update = new fletcher_reeves()) : update(_update){ }
    tools::shared_ptr<cg_update> update;
};

}

#endif
<commit_msg>Implementation : Removed unused variable<commit_after>/* ===========================
 *
 * Copyright (c) 2013 Philippe Tillet - National Chiao Tung University
 *
 * FMinCL - Unconstrained Function Minimization on OpenCL
 *
 * License : MIT X11 - See the LICENSE file in the root folder
 * ===========================*/

#ifndef FMINCL_DIRECTIONS_CONJUGATE_GRADIENT_HPP_
#define FMINCL_DIRECTIONS_CONJUGATE_GRADIENT_HPP_

#include "fmincl/utils.hpp"

#include "fmincl/mapping.hpp"

#include "fmincl/tools/shared_ptr.hpp"
#include "fmincl/directions/forwards.h"

#include "conjugate_gradient/restarts.hpp"
#include "conjugate_gradient/updates.hpp"

namespace fmincl{

struct conjugate_gradient : public direction{
    template<class BackendType>
    class implementation : public direction::implementation<BackendType>{
        typedef typename BackendType::VectorType VectorType;
        typedef implementation_of<BackendType,cg_update,polak_ribiere,fletcher_reeves> update_mapping;

    public:
        implementation(conjugate_gradient const & cg_params, detail::optimization_context<BackendType> & context) : context_(context), update_implementation_(update_mapping::create(*cg_params.update, context)){ }
        void operator()(){
          double orthogonality_threshold = 0.2;
          VectorType const & g = context_.g();
          VectorType & p = context_.p();
          std::size_t N = context_.dim();
          bool restart = std::abs(BackendType::dot(N,g,context_.gm1()))/BackendType::dot(N,g,g) > orthogonality_threshold;
          double beta = restart?0:(*update_implementation_)();
          //p = -g + beta*p;
          BackendType::scale(N,beta,p);
          BackendType::axpy(N,-1,g,p);
          //Restart

        }
    private:
        detail::optimization_context<BackendType> & context_;

        tools::shared_ptr<cg_update::implementation<BackendType> > update_implementation_;
    };

    conjugate_gradient(cg_update * _update = new fletcher_reeves()) : update(_update){ }
    tools::shared_ptr<cg_update> update;
};

}

#endif
<|endoftext|>


<commit_before>/*
 * (C) 2015-2016 Augustin Cavalier
 * All rights reserved. Distributed under the terms of the MIT license.
 */
#include "FSUtil.h"

#include "OSUtil.h"
#include "StringUtil.h"

#include <algorithm>
#include <fstream>
#include <vector>

#include <ctype.h>
#include <stdlib.h>

#ifndef _MSC_VER
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <cstring>
#else /* _MSC_VER */
#define WIN32_LEAN_AND_MEAN
#include <direct.h>
#include <windows.h>
#endif

using std::string;
using std::vector;

bool FSUtil::exists(const string& path)
{
	string filename = path;
#ifdef _WIN32
	StringUtil::replaceAll(filename, "/", "\\");
#endif

	std::ifstream f(filename);
	return static_cast<bool>(f);
}

bool FSUtil::isFile(const string& path)
{
	struct ::stat statbuf;
	if (::stat(path.c_str(), &statbuf) == -1)
		return false;
	if (statbuf.st_mode & S_IFREG)
		return true;
	return false;
}

bool FSUtil::isDir(const string& path)
{
	struct ::stat statbuf;
	if (::stat(path.c_str(), &statbuf) == -1)
		return false;
	if (statbuf.st_mode & S_IFDIR)
		return true;
	return false;
}

std::string FSUtil::getContents(const string& file)
{
	std::ifstream filestream(file);
	// extra ()s here are mandatory
	return string((std::istreambuf_iterator<char>(filestream)),
		std::istreambuf_iterator<char>());
}

void FSUtil::putContents(const std::string& file, const std::string& contents)
{
	std::ofstream filestream(file);
	filestream << contents;
}

void FSUtil::deleteFile(const std::string& file)
{
	::remove(file.c_str());
}

#ifndef _MSC_VER
void FSUtil_fileSearchHelper(vector<string>& ret, const string& dir,
	const vector<string>& exts, bool recursive)
{
	DIR* dp = ::opendir(dir.c_str());
	if (dp == nullptr) {
		// Path does not exist or could not be read
		return;
	}

	struct ::dirent* entry;
	while ((entry = ::readdir(dp)) != nullptr) {
		if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
			continue;
		std::string fullPath = FSUtil::combinePaths({dir, entry->d_name});
		if (recursive && FSUtil::isDir(fullPath))
			FSUtil_fileSearchHelper(ret, fullPath, exts, recursive);
		else {
			for (string ext : exts) {
				if (StringUtil::endsWith(fullPath, ext)) {
					ret.push_back(fullPath);
					break;
				}
			}
		}
	}

	closedir(dp);
}
#else /* _MSC_VER  */
void FSUtil_fileSearchHelper(vector<string>& ret, const string& dir,
	const vector<string>& exts, bool recursive)
{
	// Specify a file mask.
	std::string path = dir + "\\*";

	WIN32_FIND_DATAA file;
	HANDLE findHndl = nullptr;
	if ((findHndl = FindFirstFileA(path.c_str(), &file)) == INVALID_HANDLE_VALUE) {
		// Path not found
		return;
	}

	do {
		if (strcmp(file.cFileName, ".") == 0 || strcmp(file.cFileName, "..") == 0)
			continue;
		// Build the path
		path = dir + "\\" + file.cFileName;

		if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
			FSUtil_fileSearchHelper(ret, path, exts, recursive);
		} else {
			for (string ext : exts) {
				if (StringUtil::endsWith(path, ext)) {
					ret.push_back(FSUtil::normalizePath(path));
					break;
				}
			}
		}
	} while (FindNextFileA(findHndl, &file));

	FindClose(findHndl);
}
#endif

vector<string> FSUtil::searchForFiles(const string& dir, const vector<string>& exts,
	bool recursive)
{
	// TODO: report errors?
	vector<string> ret;
	FSUtil_fileSearchHelper(ret, dir, exts, recursive);
	return ret;
}

string FSUtil::which(const string& prog)
{
	if (prog.empty())
		return prog;

	const string program = normalizePath(prog);
	if (program[0] == '/'
#ifdef _WIN32
		|| (program.length() > 2 && program[1] == ':' && program[2] == '/') // "C:/"
#endif
		)
		return program; // already an absolute path

#ifdef _WIN32
	const vector<string> pathExts = StringUtil::split(OSUtil::getEnv("PATHEXT"), ";");
	auto permutePathExt = [&](const string& path) {
		for (string ext : pathExts) {
			string fullPath = path + ext;
			if (exists(fullPath))
				return fullPath;
		}
		return string();
	};
#endif

	// The program's name contains a slash, ignore PATH
	if (program.find('/') != string::npos) {
		string normd = normalizePath(program);
		if (exists(normd)) {
			// TODO: check if 'program' is executable
			// TODO: return absolute path
			return normd;
		}
#ifdef _WIN32
		else
			return permutePathExt(normalizePath(program));
#endif
		return "";
	}

	vector<string> PATHs =
#ifdef _WIN32
		StringUtil::split(OSUtil::getEnv("PATH"), ";");
#else
		StringUtil::split(OSUtil::getEnv("PATH"), ":");
#endif

	if (PATHs.empty())
		return "";
	for (string path : PATHs) {
		string fullPath =
#ifdef _WIN32
			permutePathExt(combinePaths({path, program}));
#else
			combinePaths({path, program});
#endif
		if (exists(fullPath))
			return fullPath;
	}
	return "";
}

string FSUtil::normalizePath(const string& path)
{
	if (path.empty())
		return path;

	string ret = path;
#ifdef _WIN32
	StringUtil::replaceAll(ret, "\\", "/");
#endif
	vector<string> orig = StringUtil::split(ret, "/"), normd;
	for (string i : orig) {
		if (i == ".")
			continue;
		else if (i.empty() && normd.size() > 0) // preserve the opening '/'
			continue;
		else if (i == ".." && normd.size() > 0 && normd[normd.size() - 1] != "..")
			normd.pop_back();
		else
			normd.push_back(i);
	}

	// Now that we've normalized the vector containing the individual components,
	// rebuild the actual path string.
	ret = "";
	for (vector<string>::size_type i = 0; i < normd.size(); i++) {
		if (i != 0)
			ret += "/";
		ret += normd[i];
	}

#ifdef _WIN32
	// Turn Cygwin/MSYS-style paths (e.g. '/c/Windows/') into drive+path format
	// (e.g. "C:/Windows/").
	if (ret[0] == '/' && ret[2] == '/') {
		ret[0] = ::toupper(ret[1]);
		ret[1] = ':';
	}
#endif
	return ret;
}

string FSUtil::combinePaths(const vector<string>& paths)
{
	string ret;
	for (string path : paths) {
		bool endsInSeparator =
			ret.length() == 0 ||
			StringUtil::endsWith(ret, "/")
#ifdef _WIN32
			|| StringUtil::endsWith(ret, "\\")
#endif
			;

		if (!endsInSeparator) {
			ret += "/";
		}
		ret += path;
	}
	return normalizePath(ret);
}

string FSUtil::absolutePath(const string& path)
{
	string ret = normalizePath(path);
	if (path[0] == '/'
#ifdef _WIN32
		|| (path.size() > 2 && path[1] == ':' && path[2] == '/')
#endif
		)
		return ret;
	char cwd[PATH_MAX];
	if (getcwd(cwd, sizeof(cwd)) != NULL)
		ret = FSUtil::combinePaths({cwd, path});
	return ret;
}

string FSUtil::parentDirectory(const string& path)
{
	string ret = normalizePath(path);
	string::size_type pos = ret.rfind("/", ret.length() - 1 /* in case it ends with a '/' */);
	if (pos == string::npos)
		return "."; // No '/'s in the path; so it's just a single file.
	return ret.substr(0, pos);
}

void FSUtil::mkdir(const string& path)
{
	// TODO: error handling?
#ifdef _MSC_VER
	::_mkdir(path.c_str());
#else
	::mkdir(path.c_str()
#ifndef _WIN32
		, 0755 // mode
#endif
		);
#endif
}
void FSUtil::rmdir(const string& path)
{
	::rmdir(path.c_str());
}
<commit_msg>FSUtil: Fix build on MSVC.<commit_after>/*
 * (C) 2015-2016 Augustin Cavalier
 * All rights reserved. Distributed under the terms of the MIT license.
 */
#include "FSUtil.h"

#include "OSUtil.h"
#include "StringUtil.h"

#include <algorithm>
#include <fstream>
#include <vector>

#include <ctype.h>
#include <stdlib.h>

#ifndef _MSC_VER
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <cstring>
#else /* _MSC_VER */
#define WIN32_LEAN_AND_MEAN
#include <direct.h>
#include <windows.h>
#define PATH_MAX MAX_PATH
#endif

using std::string;
using std::vector;

bool FSUtil::exists(const string& path)
{
	string filename = path;
#ifdef _WIN32
	StringUtil::replaceAll(filename, "/", "\\");
#endif

	std::ifstream f(filename);
	return static_cast<bool>(f);
}

bool FSUtil::isFile(const string& path)
{
	struct ::stat statbuf;
	if (::stat(path.c_str(), &statbuf) == -1)
		return false;
	if (statbuf.st_mode & S_IFREG)
		return true;
	return false;
}

bool FSUtil::isDir(const string& path)
{
	struct ::stat statbuf;
	if (::stat(path.c_str(), &statbuf) == -1)
		return false;
	if (statbuf.st_mode & S_IFDIR)
		return true;
	return false;
}

std::string FSUtil::getContents(const string& file)
{
	std::ifstream filestream(file);
	// extra ()s here are mandatory
	return string((std::istreambuf_iterator<char>(filestream)),
		std::istreambuf_iterator<char>());
}

void FSUtil::putContents(const std::string& file, const std::string& contents)
{
	std::ofstream filestream(file);
	filestream << contents;
}

void FSUtil::deleteFile(const std::string& file)
{
	::remove(file.c_str());
}

#ifndef _MSC_VER
void FSUtil_fileSearchHelper(vector<string>& ret, const string& dir,
	const vector<string>& exts, bool recursive)
{
	DIR* dp = ::opendir(dir.c_str());
	if (dp == nullptr) {
		// Path does not exist or could not be read
		return;
	}

	struct ::dirent* entry;
	while ((entry = ::readdir(dp)) != nullptr) {
		if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
			continue;
		std::string fullPath = FSUtil::combinePaths({dir, entry->d_name});
		if (recursive && FSUtil::isDir(fullPath))
			FSUtil_fileSearchHelper(ret, fullPath, exts, recursive);
		else {
			for (string ext : exts) {
				if (StringUtil::endsWith(fullPath, ext)) {
					ret.push_back(fullPath);
					break;
				}
			}
		}
	}

	closedir(dp);
}
#else /* _MSC_VER  */
void FSUtil_fileSearchHelper(vector<string>& ret, const string& dir,
	const vector<string>& exts, bool recursive)
{
	// Specify a file mask.
	std::string path = dir + "\\*";

	WIN32_FIND_DATAA file;
	HANDLE findHndl = nullptr;
	if ((findHndl = FindFirstFileA(path.c_str(), &file)) == INVALID_HANDLE_VALUE) {
		// Path not found
		return;
	}

	do {
		if (strcmp(file.cFileName, ".") == 0 || strcmp(file.cFileName, "..") == 0)
			continue;
		// Build the path
		path = dir + "\\" + file.cFileName;

		if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
			FSUtil_fileSearchHelper(ret, path, exts, recursive);
		} else {
			for (string ext : exts) {
				if (StringUtil::endsWith(path, ext)) {
					ret.push_back(FSUtil::normalizePath(path));
					break;
				}
			}
		}
	} while (FindNextFileA(findHndl, &file));

	FindClose(findHndl);
}
#endif

vector<string> FSUtil::searchForFiles(const string& dir, const vector<string>& exts,
	bool recursive)
{
	// TODO: report errors?
	vector<string> ret;
	FSUtil_fileSearchHelper(ret, dir, exts, recursive);
	return ret;
}

string FSUtil::which(const string& prog)
{
	if (prog.empty())
		return prog;

	const string program = normalizePath(prog);
	if (program[0] == '/'
#ifdef _WIN32
		|| (program.length() > 2 && program[1] == ':' && program[2] == '/') // "C:/"
#endif
		)
		return program; // already an absolute path

#ifdef _WIN32
	const vector<string> pathExts = StringUtil::split(OSUtil::getEnv("PATHEXT"), ";");
	auto permutePathExt = [&](const string& path) {
		for (string ext : pathExts) {
			string fullPath = path + ext;
			if (exists(fullPath))
				return fullPath;
		}
		return string();
	};
#endif

	// The program's name contains a slash, ignore PATH
	if (program.find('/') != string::npos) {
		string normd = normalizePath(program);
		if (exists(normd)) {
			// TODO: check if 'program' is executable
			// TODO: return absolute path
			return normd;
		}
#ifdef _WIN32
		else
			return permutePathExt(normalizePath(program));
#endif
		return "";
	}

	vector<string> PATHs =
#ifdef _WIN32
		StringUtil::split(OSUtil::getEnv("PATH"), ";");
#else
		StringUtil::split(OSUtil::getEnv("PATH"), ":");
#endif

	if (PATHs.empty())
		return "";
	for (string path : PATHs) {
		string fullPath =
#ifdef _WIN32
			permutePathExt(combinePaths({path, program}));
#else
			combinePaths({path, program});
#endif
		if (exists(fullPath))
			return fullPath;
	}
	return "";
}

string FSUtil::normalizePath(const string& path)
{
	if (path.empty())
		return path;

	string ret = path;
#ifdef _WIN32
	StringUtil::replaceAll(ret, "\\", "/");
#endif
	vector<string> orig = StringUtil::split(ret, "/"), normd;
	for (string i : orig) {
		if (i == ".")
			continue;
		else if (i.empty() && normd.size() > 0) // preserve the opening '/'
			continue;
		else if (i == ".." && normd.size() > 0 && normd[normd.size() - 1] != "..")
			normd.pop_back();
		else
			normd.push_back(i);
	}

	// Now that we've normalized the vector containing the individual components,
	// rebuild the actual path string.
	ret = "";
	for (vector<string>::size_type i = 0; i < normd.size(); i++) {
		if (i != 0)
			ret += "/";
		ret += normd[i];
	}

#ifdef _WIN32
	// Turn Cygwin/MSYS-style paths (e.g. '/c/Windows/') into drive+path format
	// (e.g. "C:/Windows/").
	if (ret[0] == '/' && ret[2] == '/') {
		ret[0] = ::toupper(ret[1]);
		ret[1] = ':';
	}
#endif
	return ret;
}

string FSUtil::combinePaths(const vector<string>& paths)
{
	string ret;
	for (string path : paths) {
		bool endsInSeparator =
			ret.length() == 0 ||
			StringUtil::endsWith(ret, "/")
#ifdef _WIN32
			|| StringUtil::endsWith(ret, "\\")
#endif
			;

		if (!endsInSeparator) {
			ret += "/";
		}
		ret += path;
	}
	return normalizePath(ret);
}

string FSUtil::absolutePath(const string& path)
{
	string ret = normalizePath(path);
	if (path[0] == '/'
#ifdef _WIN32
		|| (path.size() > 2 && path[1] == ':' && path[2] == '/')
#endif
		)
		return ret;
	char cwd[PATH_MAX];
	if (getcwd(cwd, sizeof(cwd)) != NULL)
		ret = FSUtil::combinePaths({cwd, path});
	return ret;
}

string FSUtil::parentDirectory(const string& path)
{
	string ret = normalizePath(path);
	string::size_type pos = ret.rfind("/", ret.length() - 1 /* in case it ends with a '/' */);
	if (pos == string::npos)
		return "."; // No '/'s in the path; so it's just a single file.
	return ret.substr(0, pos);
}

void FSUtil::mkdir(const string& path)
{
	// TODO: error handling?
#ifdef _MSC_VER
	::_mkdir(path.c_str());
#else
	::mkdir(path.c_str()
#ifndef _WIN32
		, 0755 // mode
#endif
		);
#endif
}
void FSUtil::rmdir(const string& path)
{
	::rmdir(path.c_str());
}
<|endoftext|>


<commit_before>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * CompressMGARD.cpp :
 *
 *  Created on: Aug 3, 2018
 *      Author: Jason Wang jason.ruonan.wang@gmail.com
 */

#include "CompressMGARD.h"
#include "adios2/helper/adiosFunctions.h"
#include <cstring>
#include <mgard/MGARDConfig.hpp>
#include <mgard/compress_cuda.hpp>

namespace adios2
{
namespace core
{
namespace compress
{

CompressMGARD::CompressMGARD(const Params &parameters)
: Operator("mgard", COMPRESS_MGARD, parameters)
{
}

size_t CompressMGARD::Operate(const char *dataIn, const Dims &blockStart,
                              const Dims &blockCount, const DataType type,
                              char *bufferOut)
{
    const uint8_t bufferVersion = 1;
    size_t bufferOutOffset = 0;

    MakeCommonHeader(bufferOut, bufferOutOffset, bufferVersion);

    const size_t ndims = blockCount.size();
    if (ndims > 5)
    {
        throw std::invalid_argument("ERROR: ADIOS2 MGARD compression: MGARG "
                                    "only supports up to 5 dimensions");
    }

    // mgard V1 metadata
    PutParameter(bufferOut, bufferOutOffset, ndims);
    for (const auto &d : blockCount)
    {
        PutParameter(bufferOut, bufferOutOffset, d);
    }
    PutParameter(bufferOut, bufferOutOffset, type);
    PutParameter(bufferOut, bufferOutOffset,
                 static_cast<uint8_t>(MGARD_VERSION_MAJOR));
    PutParameter(bufferOut, bufferOutOffset,
                 static_cast<uint8_t>(MGARD_VERSION_MINOR));
    PutParameter(bufferOut, bufferOutOffset,
                 static_cast<uint8_t>(MGARD_VERSION_PATCH));
    // mgard V1 metadata end

    // set type
    mgard_cuda::data_type mgardType;
    if (type == helper::GetDataType<float>())
    {
        mgardType = mgard_cuda::data_type::Float;
    }
    else if (type == helper::GetDataType<double>())
    {
        mgardType = mgard_cuda::data_type::Double;
    }
    else
    {
        throw std::invalid_argument("ERROR: ADIOS2 operator MGARD only "
                                    "supports float and double types");
    }
    // set type end

    // set mgard style dim info
    mgard_cuda::DIM mgardDim = ndims;
    std::vector<mgard_cuda::SIZE> mgardCount;
    for (const auto &c : blockCount)
    {
        mgardCount.push_back(c);
    }
    // set mgard style dim info end

    // Parameters
    bool hasTolerance = false;
    double tolerance = 0.0;
    double s = 0.0;
    auto errorBoundType = mgard_cuda::error_bound_type::REL;

    auto itAccuracy = parameters.find("accuracy");
    if (itAccuracy != parameters.end())
    {
        tolerance = std::stod(itAccuracy->second);
        hasTolerance = true;
    }
    auto itTolerance = m_Parameters.find("tolerance");
    if (itTolerance != m_Parameters.end())
    {
        tolerance = std::stod(itTolerance->second);
        hasTolerance = true;
    }
    if (!hasTolerance)
    {
        throw std::invalid_argument("ERROR: missing mandatory parameter "
                                    "tolerance for MGARD compression "
                                    "operator\n");
    }
    auto itSParameter = m_Parameters.find("s");
    if (itSParameter != m_Parameters.end())
    {
        s = std::stod(itSParameter->second);
    }
    auto itMode = parameters.find("mode");
    if (itMode != parameters.end())
    {
        if (itMode->second == "ABS")
        {
            errorBoundType = mgard_cuda::error_bound_type::ABS;
        }
        else if (itMode->second == "REL")
        {
            errorBoundType = mgard_cuda::error_bound_type::REL;
        }
    }

    size_t sizeOut = 0;
    void *compressedData = nullptr;
    mgard_cuda::compress(mgardDim, mgardType, mgardCount, tolerance, s,
                         errorBoundType, dataIn, compressedData, sizeOut);
    std::memcpy(bufferOut + bufferOutOffset, compressedData, sizeOut);
    bufferOutOffset += sizeOut;

    if (compressedData)
    {
        free(compressedData);
    }

    return bufferOutOffset;
}

size_t CompressMGARD::DecompressV1(const char *bufferIn, const size_t sizeIn,
                                   char *dataOut)
{
    // Do NOT remove even if the buffer version is updated. Data might be still
    // in lagacy formats. This function must be kept for backward compatibility.
    // If a newer buffer format is implemented, create another function, e.g.
    // DecompressV2 and keep this function for decompressing lagacy data.

    size_t bufferInOffset = 0;

    const size_t ndims = GetParameter<size_t, size_t>(bufferIn, bufferInOffset);
    Dims blockCount(ndims);
    for (size_t i = 0; i < ndims; ++i)
    {
        blockCount[i] = GetParameter<size_t, size_t>(bufferIn, bufferInOffset);
    }
    const DataType type = GetParameter<DataType>(bufferIn, bufferInOffset);
    m_VersionInfo =
        " Data is compressed using MGARD Version " +
        std::to_string(GetParameter<uint8_t>(bufferIn, bufferInOffset)) + "." +
        std::to_string(GetParameter<uint8_t>(bufferIn, bufferInOffset)) + "." +
        std::to_string(GetParameter<uint8_t>(bufferIn, bufferInOffset)) +
        ". Please make sure a compatible version is used for decompression.";

    const size_t sizeOut =
        helper::GetTotalSize(blockCount, helper::GetDataTypeSize(type));

    try
    {
        void *dataOutVoid = nullptr;
        mgard_cuda::decompress(bufferIn + bufferInOffset,
                               sizeIn - bufferInOffset, dataOutVoid);
        std::memcpy(dataOut, dataOutVoid, sizeOut);
        if (dataOutVoid)
        {
            free(dataOutVoid);
        }
    }
    catch (...)
    {
        throw(m_VersionInfo);
    }

    return sizeOut;
}

size_t CompressMGARD::InverseOperate(const char *bufferIn, const size_t sizeIn,
                                     char *dataOut)
{
    size_t bufferInOffset = 1; // skip operator type
    const uint8_t bufferVersion =
        GetParameter<uint8_t>(bufferIn, bufferInOffset);
    bufferInOffset += 2; // skip two reserved bytes

    if (bufferVersion == 1)
    {
        return DecompressV1(bufferIn + bufferInOffset, sizeIn - bufferInOffset,
                            dataOut);
    }
    else if (bufferVersion == 2)
    {
        // TODO: if a Version 2 mgard buffer is being implemented, put it here
        // and keep the DecompressV1 routine for backward compatibility
    }
    else
    {
        throw("unknown mgard buffer version");
    }

    return 0;
}

bool CompressMGARD::IsDataTypeValid(const DataType type) const
{
    if (type == DataType::Double)
    {
        return true;
    }
    return false;
}

} // end namespace compress
} // end namespace core
} // end namespace adios2
<commit_msg>mgard_x API worked<commit_after>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * CompressMGARD.cpp :
 *
 *  Created on: Aug 3, 2018
 *      Author: Jason Wang jason.ruonan.wang@gmail.com
 */

#include "CompressMGARD.h"
#include "adios2/helper/adiosFunctions.h"
#include <cstring>
#include <mgard/MGARDConfig.hpp>
#include <mgard/compress_x.hpp>

namespace adios2
{
namespace core
{
namespace compress
{

CompressMGARD::CompressMGARD(const Params &parameters)
: Operator("mgard", COMPRESS_MGARD, parameters)
{
}

size_t CompressMGARD::Operate(const char *dataIn, const Dims &blockStart,
                              const Dims &blockCount, const DataType type,
                              char *bufferOut)
{
    const uint8_t bufferVersion = 1;
    size_t bufferOutOffset = 0;

    MakeCommonHeader(bufferOut, bufferOutOffset, bufferVersion);

    const size_t ndims = blockCount.size();
    if (ndims > 5)
    {
        throw std::invalid_argument("ERROR: ADIOS2 MGARD compression: MGARG "
                                    "only supports up to 5 dimensions");
    }

    // mgard V1 metadata
    PutParameter(bufferOut, bufferOutOffset, ndims);
    for (const auto &d : blockCount)
    {
        PutParameter(bufferOut, bufferOutOffset, d);
    }
    PutParameter(bufferOut, bufferOutOffset, type);
    PutParameter(bufferOut, bufferOutOffset,
                 static_cast<uint8_t>(MGARD_VERSION_MAJOR));
    PutParameter(bufferOut, bufferOutOffset,
                 static_cast<uint8_t>(MGARD_VERSION_MINOR));
    PutParameter(bufferOut, bufferOutOffset,
                 static_cast<uint8_t>(MGARD_VERSION_PATCH));
    // mgard V1 metadata end

    // set type
    mgard_x::data_type mgardType;
    if (type == helper::GetDataType<float>())
    {
        mgardType = mgard_x::data_type::Float;
    }
    else if (type == helper::GetDataType<double>())
    {
        mgardType = mgard_x::data_type::Double;
    }
    else
    {
        throw std::invalid_argument("ERROR: ADIOS2 operator MGARD only "
                                    "supports float and double types");
    }
    // set type end

    // set mgard style dim info
    mgard_x::DIM mgardDim = ndims;
    std::vector<mgard_x::SIZE> mgardCount;
    for (const auto &c : blockCount)
    {
        mgardCount.push_back(c);
    }
    // set mgard style dim info end

    // Parameters
    bool hasTolerance = false;
    double tolerance = 0.0;
    double s = 0.0;
    auto errorBoundType = mgard_x::error_bound_type::REL;

    auto itAccuracy = m_Parameters.find("accuracy");
    if (itAccuracy != m_Parameters.end())
    {
        tolerance = std::stod(itAccuracy->second);
        hasTolerance = true;
    }
    auto itTolerance = m_Parameters.find("tolerance");
    if (itTolerance != m_Parameters.end())
    {
        tolerance = std::stod(itTolerance->second);
        hasTolerance = true;
    }
    if (!hasTolerance)
    {
        throw std::invalid_argument("ERROR: missing mandatory parameter "
                                    "tolerance for MGARD compression "
                                    "operator\n");
    }
    auto itSParameter = m_Parameters.find("s");
    if (itSParameter != m_Parameters.end())
    {
        s = std::stod(itSParameter->second);
    }
    auto itMode = m_Parameters.find("mode");
    if (itMode != m_Parameters.end())
    {
        if (itMode->second == "ABS")
        {
            errorBoundType = mgard_x::error_bound_type::ABS;
        }
        else if (itMode->second == "REL")
        {
            errorBoundType = mgard_x::error_bound_type::REL;
        }
    }

    size_t sizeOut = 0;
    void *compressedData = nullptr;
    mgard_x::compress(mgardDim, mgardType, mgardCount, tolerance, s,
                      errorBoundType, dataIn, compressedData, sizeOut, false);
    std::memcpy(bufferOut + bufferOutOffset, compressedData, sizeOut);
    bufferOutOffset += sizeOut;

    if (compressedData)
    {
        free(compressedData);
    }

    return bufferOutOffset;
}

size_t CompressMGARD::DecompressV1(const char *bufferIn, const size_t sizeIn,
                                   char *dataOut)
{
    // Do NOT remove even if the buffer version is updated. Data might be still
    // in lagacy formats. This function must be kept for backward compatibility.
    // If a newer buffer format is implemented, create another function, e.g.
    // DecompressV2 and keep this function for decompressing lagacy data.

    size_t bufferInOffset = 0;

    const size_t ndims = GetParameter<size_t, size_t>(bufferIn, bufferInOffset);
    Dims blockCount(ndims);
    for (size_t i = 0; i < ndims; ++i)
    {
        blockCount[i] = GetParameter<size_t, size_t>(bufferIn, bufferInOffset);
    }
    const DataType type = GetParameter<DataType>(bufferIn, bufferInOffset);
    m_VersionInfo =
        " Data is compressed using MGARD Version " +
        std::to_string(GetParameter<uint8_t>(bufferIn, bufferInOffset)) + "." +
        std::to_string(GetParameter<uint8_t>(bufferIn, bufferInOffset)) + "." +
        std::to_string(GetParameter<uint8_t>(bufferIn, bufferInOffset)) +
        ". Please make sure a compatible version is used for decompression.";

    const size_t sizeOut =
        helper::GetTotalSize(blockCount, helper::GetDataTypeSize(type));

    try
    {
        void *dataOutVoid = nullptr;
        mgard_x::decompress(bufferIn + bufferInOffset, sizeIn - bufferInOffset,
                            dataOutVoid, false);
        std::memcpy(dataOut, dataOutVoid, sizeOut);
        if (dataOutVoid)
        {
            free(dataOutVoid);
        }
    }
    catch (...)
    {
        throw(m_VersionInfo);
    }

    return sizeOut;
}

size_t CompressMGARD::InverseOperate(const char *bufferIn, const size_t sizeIn,
                                     char *dataOut)
{
    size_t bufferInOffset = 1; // skip operator type
    const uint8_t bufferVersion =
        GetParameter<uint8_t>(bufferIn, bufferInOffset);
    bufferInOffset += 2; // skip two reserved bytes

    if (bufferVersion == 1)
    {
        return DecompressV1(bufferIn + bufferInOffset, sizeIn - bufferInOffset,
                            dataOut);
    }
    else if (bufferVersion == 2)
    {
        // TODO: if a Version 2 mgard buffer is being implemented, put it here
        // and keep the DecompressV1 routine for backward compatibility
    }
    else
    {
        throw("unknown mgard buffer version");
    }

    return 0;
}

bool CompressMGARD::IsDataTypeValid(const DataType type) const
{
    if (type == DataType::Double || type == DataType::Float)
    {
        return true;
    }
    return false;
}

} // end namespace compress
} // end namespace core
} // end namespace adios2
<|endoftext|>


<commit_before>/*****************************************************************************************
*                                                                                *
* OpenSpace                                                                             *
*                                                                                *
* Copyright (c) 2014-2016                                                               *
*                                                                                *
* 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.                                         *
****************************************************************************************/

// open space includes
#include <openspace/util/camera.h>
#include <openspace/util/syncbuffer.h>
#include <openspace/query/query.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/interaction/interactionhandler.h>

#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/vector_angle.hpp>

namespace openspace {

    //////////////////////////////////////////////////////////////////////////////////////
    //								        CAMERA	                                    //
    //////////////////////////////////////////////////////////////////////////////////////

    namespace {
        const std::string _loggerCat = "Camera";
    }

    const Camera::Vec3 Camera::_VIEW_DIRECTION_CAMERA_SPACE = Camera::Vec3(0, 0, -1);
    const Camera::Vec3 Camera::_LOOKUP_VECTOR_CAMERA_SPACE = Camera::Vec3(0, 1, 0);

    Camera::Camera()
        : _maxFov(0.f)
        , _focusPosition()
    {
        _scaling.local = glm::vec2(1.f, 0.f);
        _position.local = Vec3(1.0, 1.0, 1.0);
        Vec3 eulerAngles(1.0, 1.0, 1.0);
        _rotation.local = Quat(eulerAngles);
    }

    Camera::Camera(const Camera& o)
        : sgctInternal(o.sgctInternal)
        , _focusPosition(o._focusPosition)
        , _cachedViewDirection(o._cachedViewDirection)
        , _cachedLookupVector(o._cachedLookupVector)
        , _rotation(o._rotation)
        , _scaling(o._scaling)
        , _position(o._position)
        , _maxFov(o._maxFov)
    { }

    Camera::~Camera() { }

    // Mutators
    void Camera::setPositionVec3(Vec3 pos) {
        std::lock_guard<std::mutex> _lock(_mutex);
        _position.local = pos;
    }

    void Camera::setFocusPositionVec3(Vec3 pos) {
        std::lock_guard<std::mutex> _lock(_mutex);
        _focusPosition = pos;
    }

    void Camera::setRotation(Quat rotation) {
        std::lock_guard<std::mutex> _lock(_mutex);
        _rotation.local = rotation;
        _cachedViewRotationMatrix.isDirty = true;
        _cachedCombinedViewMatrix.isDirty = true;
    }

    void Camera::setScaling(glm::vec2 scaling) {
        std::lock_guard<std::mutex> _lock(_mutex);
        _scaling.local = std::move(scaling);
    }

    void Camera::setMaxFov(float fov) {
        std::lock_guard<std::mutex> _lock(_mutex);
        _maxFov = fov;
        _cachedSinMaxFov.isDirty = true;
    }

    // Relative mutators
    void Camera::rotate(Quat rotation) {
        std::lock_guard<std::mutex> _lock(_mutex);
        _rotation.local = rotation * _rotation.local;
    }

    // Accessors
    const Camera::Vec3& Camera::positionVec3() const {
        return _position.synced;
    }

    const Camera::Vec3& Camera::unsynchedPositionVec3() const {
        return _position.local;
    }

    const Camera::Vec3& Camera::focusPositionVec3() const {
        return _focusPosition;
    }

    const Camera::Vec3& Camera::viewDirectionWorldSpace() const {
        if (_cachedViewDirection.isDirty) {
            _cachedViewDirection.datum =
                _rotation.synced * Vec3(_VIEW_DIRECTION_CAMERA_SPACE);
            _cachedViewDirection.datum = glm::normalize(_cachedViewDirection.datum);
        }
        return _cachedViewDirection.datum;
    }

    const Camera::Vec3& Camera::lookUpVectorCameraSpace() const {
        return _LOOKUP_VECTOR_CAMERA_SPACE;
    }

    const Camera::Vec3& Camera::lookUpVectorWorldSpace() const {
        if (_cachedLookupVector.isDirty) {
            _cachedLookupVector.datum =
                _rotation.synced * Vec3(_LOOKUP_VECTOR_CAMERA_SPACE);
            _cachedLookupVector.datum = glm::normalize(_cachedLookupVector.datum);
        }
        return _cachedLookupVector.datum;
    }

    const glm::vec2& Camera::scaling() const {
        return _scaling.synced;
    }

    float Camera::maxFov() const {
        return _maxFov;
    }

    float Camera::sinMaxFov() const {
        if (_cachedSinMaxFov.isDirty) {
            _cachedSinMaxFov.datum = sin(_maxFov);
        }
        return _cachedSinMaxFov.datum;
    }

    const Camera::Mat4& Camera::viewRotationMatrix() const {
        if (_cachedViewRotationMatrix.isDirty) {
            _cachedViewRotationMatrix.datum = glm::mat4_cast(glm::inverse(_rotation.synced));
        }
        return _cachedViewRotationMatrix.datum;
    }

    const Camera::Quat& Camera::rotationQuaternion() const {
        return _rotation.synced;
    }

    const Camera::Mat4& Camera::combinedViewMatrix() const {
        if (_cachedCombinedViewMatrix.isDirty) {
            Mat4 cameraTranslation =
                glm::inverse(glm::translate(Mat4(1.0), _position.synced));
            _cachedCombinedViewMatrix.datum =
                Mat4(sgctInternal.viewMatrix()) *
                Mat4(viewRotationMatrix()) *
                cameraTranslation;
        }
        return _cachedCombinedViewMatrix.datum;
    }

    // Synchronization
    void Camera::serialize(SyncBuffer* syncBuffer) {
        std::lock_guard<std::mutex> _lock(_mutex);

        _rotation.serialize(syncBuffer);
        _position.serialize(syncBuffer);
        _scaling.serialize(syncBuffer);
    }

    void Camera::deserialize(SyncBuffer* syncBuffer) {
        std::lock_guard<std::mutex> _lock(_mutex);

        _rotation.deserialize(syncBuffer);
        _position.deserialize(syncBuffer);
        _scaling.deserialize(syncBuffer);
    }

    void Camera::postSynchronizationPreDraw() {
        std::lock_guard<std::mutex> _lock(_mutex);

        _rotation.postSynchronizationPreDraw();
        _position.postSynchronizationPreDraw();
        _scaling.postSynchronizationPreDraw();

        _cachedViewDirection.isDirty = true;
        _cachedLookupVector.isDirty = true;
    }

    void Camera::serialize(std::ostream& os) const {
        Vec3 p = positionVec3();
        Quat q = rotationQuaternion();
        os << p.x << " " << p.y << " " << p.z << std::endl;
        os << q.x << " " << q.y << " " << q.z << " " << q.w << std::endl;
    }

    void Camera::deserialize(std::istream& is) {
        Vec3 p;
        Quat q;
        is >> p.x >> p.y >> p.z;
        is >> q.x >> q.y >> q.z >> q.w;
        setPositionVec3(p);
        setRotation(q);
    }

    void Camera::preSynchronization() {
        std::lock_guard<std::mutex> _lock(_mutex);

        _rotation.preSynchronization();
        _position.preSynchronization();
        _scaling.preSynchronization();
    }

    //////////////////////////////////////////////////////////////////////////////////////
    //								    SGCT INTERNAL	                                //
    //////////////////////////////////////////////////////////////////////////////////////
    Camera::SgctInternal::SgctInternal()
        : _viewMatrix()
        , _projectionMatrix()
    { }

    void Camera::SgctInternal::setViewMatrix(glm::mat4 viewMatrix) {
        std::lock_guard<std::mutex> _lock(_mutex);

        _viewMatrix = std::move(viewMatrix);
        _cachedViewProjectionMatrix.isDirty = true;
    }

    void Camera::SgctInternal::setProjectionMatrix(glm::mat4 projectionMatrix) {
        std::lock_guard<std::mutex> _lock(_mutex);

        _projectionMatrix = std::move(projectionMatrix);
        _cachedViewProjectionMatrix.isDirty = true;
    }

    const glm::mat4& Camera::SgctInternal::viewMatrix() const {
        return _viewMatrix;
    }

    const glm::mat4& Camera::SgctInternal::projectionMatrix() const {
        return _projectionMatrix;
    }

    const glm::mat4& Camera::SgctInternal::viewProjectionMatrix() const {
        if (_cachedViewProjectionMatrix.isDirty) {
            std::lock_guard<std::mutex> _lock(_mutex);
            _cachedViewProjectionMatrix.datum = _projectionMatrix * _viewMatrix;
            _cachedViewProjectionMatrix.isDirty = false;
        }
        return _cachedViewProjectionMatrix.datum;
    }

    // Deprecated
    void Camera::setPosition(psc pos) {
        std::lock_guard<std::mutex> _lock(_mutex);
        _position.local = pos.dvec3();
    }

    void Camera::setFocusPosition(psc pos) {
        std::lock_guard<std::mutex> _lock(_mutex);
        _focusPosition = pos.dvec3();
    }

    psc Camera::position() const {
        return psc(_position.synced);
    }

    psc Camera::unsynchedPosition() const {
        return psc(_position.local);
    }

    psc Camera::focusPosition() const {
        return psc(_focusPosition);
    }

    const glm::mat4& Camera::viewMatrix() const {
        return sgctInternal.viewMatrix();
    }

    const glm::mat4& Camera::projectionMatrix() const {
        return sgctInternal.projectionMatrix();
    }

    const glm::mat4& Camera::viewProjectionMatrix() const {
        return sgctInternal.viewProjectionMatrix();
    }
} // namespace openspace
<commit_msg>Clean up camera class cache variables.<commit_after>/*****************************************************************************************
*                                                                                *
* OpenSpace                                                                             *
*                                                                                *
* Copyright (c) 2014-2016                                                               *
*                                                                                *
* 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.                                         *
****************************************************************************************/

// open space includes
#include <openspace/util/camera.h>
#include <openspace/util/syncbuffer.h>
#include <openspace/query/query.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/interaction/interactionhandler.h>

#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/vector_angle.hpp>

namespace openspace {

    //////////////////////////////////////////////////////////////////////////////////////
    //								        CAMERA	                                    //
    //////////////////////////////////////////////////////////////////////////////////////

    namespace {
        const std::string _loggerCat = "Camera";
    }

    const Camera::Vec3 Camera::_VIEW_DIRECTION_CAMERA_SPACE = Camera::Vec3(0, 0, -1);
    const Camera::Vec3 Camera::_LOOKUP_VECTOR_CAMERA_SPACE = Camera::Vec3(0, 1, 0);

    Camera::Camera()
        : _maxFov(0.f)
        , _focusPosition()
    {
        _scaling.local = glm::vec2(1.f, 0.f);
        _position.local = Vec3(1.0, 1.0, 1.0);
        Vec3 eulerAngles(1.0, 1.0, 1.0);
        _rotation.local = Quat(eulerAngles);
    }

    Camera::Camera(const Camera& o)
        : sgctInternal(o.sgctInternal)
        , _focusPosition(o._focusPosition)
        , _cachedViewDirection(o._cachedViewDirection)
        , _cachedLookupVector(o._cachedLookupVector)
        , _rotation(o._rotation)
        , _scaling(o._scaling)
        , _position(o._position)
        , _maxFov(o._maxFov)
    { }

    Camera::~Camera() { }

    // Mutators
    void Camera::setPositionVec3(Vec3 pos) {
        std::lock_guard<std::mutex> _lock(_mutex);
        _position.local = pos;

        _cachedCombinedViewMatrix.isDirty = true;
    }

    void Camera::setFocusPositionVec3(Vec3 pos) {
        std::lock_guard<std::mutex> _lock(_mutex);
        _focusPosition = pos;

        _cachedViewDirection.isDirty = true;
        _cachedLookupVector.isDirty = true;
        _cachedViewRotationMatrix.isDirty = true;
        _cachedCombinedViewMatrix.isDirty = true;
    }

    void Camera::setRotation(Quat rotation) {
        std::lock_guard<std::mutex> _lock(_mutex);
        _rotation.local = rotation;
        _cachedViewDirection.isDirty = true;
        _cachedLookupVector.isDirty = true;
        _cachedViewRotationMatrix.isDirty = true;
        _cachedCombinedViewMatrix.isDirty = true;
    }

    void Camera::setScaling(glm::vec2 scaling) {
        std::lock_guard<std::mutex> _lock(_mutex);
        _scaling.local = std::move(scaling);
    }

    void Camera::setMaxFov(float fov) {
        std::lock_guard<std::mutex> _lock(_mutex);
        _maxFov = fov;
        _cachedSinMaxFov.isDirty = true;
    }

    // Relative mutators
    void Camera::rotate(Quat rotation) {
        std::lock_guard<std::mutex> _lock(_mutex);
        _rotation.local = rotation * _rotation.local;

        _cachedViewDirection.isDirty = true;
        _cachedLookupVector.isDirty = true;
        _cachedViewRotationMatrix.isDirty = true;
        _cachedCombinedViewMatrix.isDirty = true;
    }

    // Accessors
    const Camera::Vec3& Camera::positionVec3() const {
        return _position.synced;
    }

    const Camera::Vec3& Camera::unsynchedPositionVec3() const {
        return _position.local;
    }

    const Camera::Vec3& Camera::focusPositionVec3() const {
        return _focusPosition;
    }

    const Camera::Vec3& Camera::viewDirectionWorldSpace() const {
        if (_cachedViewDirection.isDirty) {
            _cachedViewDirection.datum =
                _rotation.synced * Vec3(_VIEW_DIRECTION_CAMERA_SPACE);
            _cachedViewDirection.datum = glm::normalize(_cachedViewDirection.datum);
            _cachedViewDirection.isDirty = true;
        }
        return _cachedViewDirection.datum;
    }

    const Camera::Vec3& Camera::lookUpVectorCameraSpace() const {
        return _LOOKUP_VECTOR_CAMERA_SPACE;
    }

    const Camera::Vec3& Camera::lookUpVectorWorldSpace() const {
        if (_cachedLookupVector.isDirty) {
            _cachedLookupVector.datum =
                _rotation.synced * Vec3(_LOOKUP_VECTOR_CAMERA_SPACE);
            _cachedLookupVector.datum = glm::normalize(_cachedLookupVector.datum);
            _cachedLookupVector.isDirty = true;
        }
        return _cachedLookupVector.datum;
    }

    const glm::vec2& Camera::scaling() const {
        return _scaling.synced;
    }

    float Camera::maxFov() const {
        return _maxFov;
    }

    float Camera::sinMaxFov() const {
        if (_cachedSinMaxFov.isDirty) {
            _cachedSinMaxFov.datum = sin(_maxFov);
            _cachedSinMaxFov.isDirty = true;
        }
        return _cachedSinMaxFov.datum;
    }

    const Camera::Mat4& Camera::viewRotationMatrix() const {
        if (_cachedViewRotationMatrix.isDirty) {
            _cachedViewRotationMatrix.datum = glm::mat4_cast(glm::inverse(_rotation.synced));
        }
        return _cachedViewRotationMatrix.datum;
    }

    const Camera::Quat& Camera::rotationQuaternion() const {
        return _rotation.synced;
    }

    const Camera::Mat4& Camera::combinedViewMatrix() const {
        if (_cachedCombinedViewMatrix.isDirty) {
            Mat4 cameraTranslation =
                glm::inverse(glm::translate(Mat4(1.0), _position.synced));
            _cachedCombinedViewMatrix.datum =
                Mat4(sgctInternal.viewMatrix()) *
                Mat4(viewRotationMatrix()) *
                cameraTranslation;
            _cachedCombinedViewMatrix.isDirty = true;
        }
        return _cachedCombinedViewMatrix.datum;
    }

    // Synchronization
    void Camera::serialize(SyncBuffer* syncBuffer) {
        std::lock_guard<std::mutex> _lock(_mutex);

        _rotation.serialize(syncBuffer);
        _position.serialize(syncBuffer);
        _scaling.serialize(syncBuffer);
    }

    void Camera::deserialize(SyncBuffer* syncBuffer) {
        std::lock_guard<std::mutex> _lock(_mutex);

        _rotation.deserialize(syncBuffer);
        _position.deserialize(syncBuffer);
        _scaling.deserialize(syncBuffer);
    }

    void Camera::postSynchronizationPreDraw() {
        std::lock_guard<std::mutex> _lock(_mutex);

        _rotation.postSynchronizationPreDraw();
        _position.postSynchronizationPreDraw();
        _scaling.postSynchronizationPreDraw();

        _cachedViewDirection.isDirty = true;
        _cachedLookupVector.isDirty = true;
        _cachedViewRotationMatrix.isDirty = true;
        _cachedCombinedViewMatrix.isDirty = true;
    }

    void Camera::serialize(std::ostream& os) const {
        Vec3 p = positionVec3();
        Quat q = rotationQuaternion();
        os << p.x << " " << p.y << " " << p.z << std::endl;
        os << q.x << " " << q.y << " " << q.z << " " << q.w << std::endl;
    }

    void Camera::deserialize(std::istream& is) {
        Vec3 p;
        Quat q;
        is >> p.x >> p.y >> p.z;
        is >> q.x >> q.y >> q.z >> q.w;
        setPositionVec3(p);
        setRotation(q);
    }

    void Camera::preSynchronization() {
        std::lock_guard<std::mutex> _lock(_mutex);

        _rotation.preSynchronization();
        _position.preSynchronization();
        _scaling.preSynchronization();
    }

    //////////////////////////////////////////////////////////////////////////////////////
    //								    SGCT INTERNAL	                                //
    //////////////////////////////////////////////////////////////////////////////////////
    Camera::SgctInternal::SgctInternal()
        : _viewMatrix()
        , _projectionMatrix()
    { }

    void Camera::SgctInternal::setViewMatrix(glm::mat4 viewMatrix) {
        std::lock_guard<std::mutex> _lock(_mutex);

        _viewMatrix = std::move(viewMatrix);
        _cachedViewProjectionMatrix.isDirty = true;
    }

    void Camera::SgctInternal::setProjectionMatrix(glm::mat4 projectionMatrix) {
        std::lock_guard<std::mutex> _lock(_mutex);

        _projectionMatrix = std::move(projectionMatrix);
        _cachedViewProjectionMatrix.isDirty = true;
    }

    const glm::mat4& Camera::SgctInternal::viewMatrix() const {
        return _viewMatrix;
    }

    const glm::mat4& Camera::SgctInternal::projectionMatrix() const {
        return _projectionMatrix;
    }

    const glm::mat4& Camera::SgctInternal::viewProjectionMatrix() const {
        if (_cachedViewProjectionMatrix.isDirty) {
            std::lock_guard<std::mutex> _lock(_mutex);
            _cachedViewProjectionMatrix.datum = _projectionMatrix * _viewMatrix;
            _cachedViewProjectionMatrix.isDirty = false;
        }
        return _cachedViewProjectionMatrix.datum;
    }

    // Deprecated
    void Camera::setPosition(psc pos) {
        std::lock_guard<std::mutex> _lock(_mutex);
        _position.local = pos.dvec3();
    }

    void Camera::setFocusPosition(psc pos) {
        std::lock_guard<std::mutex> _lock(_mutex);
        _focusPosition = pos.dvec3();
    }

    psc Camera::position() const {
        return psc(_position.synced);
    }

    psc Camera::unsynchedPosition() const {
        return psc(_position.local);
    }

    psc Camera::focusPosition() const {
        return psc(_focusPosition);
    }

    const glm::mat4& Camera::viewMatrix() const {
        return sgctInternal.viewMatrix();
    }

    const glm::mat4& Camera::projectionMatrix() const {
        return sgctInternal.projectionMatrix();
    }

    const glm::mat4& Camera::viewProjectionMatrix() const {
        return sgctInternal.viewProjectionMatrix();
    }
} // namespace openspace
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_fpicker.hxx"
#include "fpsmartcontent.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/ucb/ContentInfo.hpp>
#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
#include <com/sun/star/ucb/XContent.hpp>
/** === end UNO includes === **/

#include <comphelper/processfactory.hxx>
#include <ucbhelper/commandenvironment.hxx>
#include <tools/solar.h>
#include <tools/debug.hxx>
#include <tools/string.hxx>

//........................................................................
namespace svt
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::task;
    using namespace ::com::sun::star::ucb;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::container;

    //====================================================================
    //= SmartContent
    //====================================================================
    //--------------------------------------------------------------------
    SmartContent::SmartContent()
        :m_pContent( NULL )
        ,m_eState( NOT_BOUND )
        ,m_pOwnInteraction( NULL )
    {
    }

    //--------------------------------------------------------------------
    SmartContent::SmartContent( const ::rtl::OUString& _rInitialURL )
        :m_pContent( NULL )
        ,m_eState( NOT_BOUND )
    {
        bindTo( _rInitialURL );
    }

    //--------------------------------------------------------------------
    SmartContent::~SmartContent()
    {
        //Do not delete the content. Because the content will be used by the cache.
        //DELETEZ( m_pContent );
    }

    //--------------------------------------------------------------------
    void SmartContent::enableOwnInteractionHandler(::svt::OFilePickerInteractionHandler::EInterceptedInteractions eInterceptions)
    {
        Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
        Reference< XInteractionHandler >  xGlobalInteractionHandler = Reference< XInteractionHandler >(
            xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.task.InteractionHandler") ) ), UNO_QUERY );

        m_pOwnInteraction = new ::svt::OFilePickerInteractionHandler(xGlobalInteractionHandler);
        m_pOwnInteraction->enableInterceptions(eInterceptions);
        m_xOwnInteraction = m_pOwnInteraction;

        m_xCmdEnv = new ::ucbhelper::CommandEnvironment( m_xOwnInteraction, Reference< XProgressHandler >() );
    }

    //--------------------------------------------------------------------
    void SmartContent::enableDefaultInteractionHandler()
    {
        // Don't free the memory here! It will be done by the next
        // call automaticly - releasing of the uno reference ...
        m_pOwnInteraction = NULL;
        m_xOwnInteraction = Reference< XInteractionHandler >();

        Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
        Reference< XInteractionHandler >  xGlobalInteractionHandler = Reference< XInteractionHandler >(
            xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.task.InteractionHandler") ) ), UNO_QUERY );
        m_xCmdEnv = new ucbhelper::CommandEnvironment( xGlobalInteractionHandler, Reference< XProgressHandler >() );
    }

    //--------------------------------------------------------------------
    ::svt::OFilePickerInteractionHandler* SmartContent::getOwnInteractionHandler() const
    {
        if (!m_xOwnInteraction.is())
            return NULL;
        return m_pOwnInteraction;
    }

    //--------------------------------------------------------------------
    SmartContent::InteractionHandlerType SmartContent::queryCurrentInteractionHandler() const
    {
        if (m_xOwnInteraction.is())
            return IHT_OWN;

        if (!m_xCmdEnv.is())
            return IHT_NONE;

        return IHT_DEFAULT;
    }

    //--------------------------------------------------------------------
    void SmartContent::disableInteractionHandler()
    {
        // Don't free the memory here! It will be done by the next
        // call automaticly - releasing of the uno reference ...
        m_pOwnInteraction = NULL;
        m_xOwnInteraction.clear();

        m_xCmdEnv.clear();
    }

    //--------------------------------------------------------------------
    void SmartContent::bindTo( const ::rtl::OUString& _rURL )
    {
        if ( getURL() == _rURL )
            // nothing to do, regardless of the state
            return;

        DELETEZ( m_pContent );
        m_eState = INVALID; // default to INVALID
        m_sURL = _rURL;

        if ( m_sURL.getLength() )
        {
            try
            {
                m_pContent = new ::ucbhelper::Content( _rURL, m_xCmdEnv );
                m_eState = UNKNOWN;
                    // from now on, the state is unknown -> we cannot know for sure if the content
                    // is really valid (some UCP's only tell this when asking for properties, not upon
                    // creation)
            }
            catch( ContentCreationException& )
            {
            }
            catch( Exception& )
            {
                OSL_FAIL( "SmartContent::bindTo: unexpected exception caught!" );
            }
        }
        else
        {
            m_eState = NOT_BOUND;
        }

        // don't forget to reset the may internal used interaction handler ...
        // But do it only for our own specialized interaction helper!
        ::svt::OFilePickerInteractionHandler* pHandler = getOwnInteractionHandler();
        if (pHandler)
        {
            pHandler->resetUseState();
            pHandler->forgetRequest();
        }
    }

    //--------------------------------------------------------------------
    sal_Bool SmartContent::implIs( const ::rtl::OUString& _rURL, Type _eType )
    {
        // bind to this content
        bindTo( _rURL );

        // did we survive this?
        if ( isInvalid() || !isBound() )
            return sal_False;

        DBG_ASSERT( m_pContent, "SmartContent::implIs: inconsistence!" );
            // if, after an bindTo, we don't have a content, then we should be INVALID, or at least
            // NOT_BOUND (the latter happens, for example, if somebody tries to ask for an empty URL)

        sal_Bool bIs = sal_False;
        try
        {
            if ( Folder == _eType )
                bIs = m_pContent->isFolder();
            else
                bIs = m_pContent->isDocument();

            // from here on, we definately know that the content is valid
            m_eState = VALID;
        }
        catch( Exception& )
        {
            // now we're definately invalid
            m_eState = INVALID;
        }
        return bIs;
    }

    //--------------------------------------------------------------------
    void SmartContent::getTitle( ::rtl::OUString& /* [out] */ _rTitle )
    {
        if ( !isBound() || isInvalid() )
            return;

        try
        {
            ::rtl::OUString sTitle;
            m_pContent->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Title" )) ) >>= sTitle;
            _rTitle =  sTitle;

            // from here on, we definately know that the content is valid
            m_eState = VALID;
        }
        catch( ::com::sun::star::uno::Exception& )
        {
            // now we're definately invalid
            m_eState = INVALID;
        }
    }

    //--------------------------------------------------------------------
    sal_Bool SmartContent::hasParentFolder( )
    {
        if ( !isBound() || isInvalid() )
            return sal_False;

        sal_Bool bRet = sal_False;
        try
        {
            Reference< XChild > xChild( m_pContent->get(), UNO_QUERY );
            if ( xChild.is() )
            {
                Reference< XContent > xParent( xChild->getParent(), UNO_QUERY );
                if ( xParent.is() )
                {
                    String aParentURL = String( xParent->getIdentifier()->getContentIdentifier() );
                    bRet = ( aParentURL.Len() > 0 && aParentURL != (String)(m_pContent->getURL()) );

                    // now we're definately valid
                    m_eState = VALID;
                }
            }
        }
        catch( const Exception& )
        {
            // now we're definately invalid
            m_eState = INVALID;
        }
        return bRet;
    }

    //--------------------------------------------------------------------
    sal_Bool SmartContent::canCreateFolder( )
    {
        if ( !isBound() || isInvalid() )
            return sal_False;

        sal_Bool bRet = sal_False;
        try
        {
            Sequence< ContentInfo > aInfo = m_pContent->queryCreatableContentsInfo();
            const ContentInfo* pInfo = aInfo.getConstArray();
            sal_Int32 nCount = aInfo.getLength();
            for ( sal_Int32 i = 0; i < nCount; ++i, ++pInfo )
            {
                // Simply look for the first KIND_FOLDER...
                if ( pInfo->Attributes & ContentInfoAttribute::KIND_FOLDER )
                {
                    bRet = sal_True;
                    break;
                }
            }

            // now we're definately valid
            m_eState = VALID;
        }
        catch( Exception& )
        {
            // now we're definately invalid
            m_eState = INVALID;
        }
        return bRet;
    }

//........................................................................
} // namespace svt
//........................................................................

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>use rtl::OUString<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_fpicker.hxx"
#include "fpsmartcontent.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/ucb/ContentInfo.hpp>
#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
#include <com/sun/star/ucb/XContent.hpp>
/** === end UNO includes === **/

#include <comphelper/processfactory.hxx>
#include <ucbhelper/commandenvironment.hxx>
#include <tools/solar.h>
#include <tools/debug.hxx>
#include <tools/string.hxx>

//........................................................................
namespace svt
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::task;
    using namespace ::com::sun::star::ucb;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::container;

    //====================================================================
    //= SmartContent
    //====================================================================
    //--------------------------------------------------------------------
    SmartContent::SmartContent()
        :m_pContent( NULL )
        ,m_eState( NOT_BOUND )
        ,m_pOwnInteraction( NULL )
    {
    }

    //--------------------------------------------------------------------
    SmartContent::SmartContent( const ::rtl::OUString& _rInitialURL )
        :m_pContent( NULL )
        ,m_eState( NOT_BOUND )
    {
        bindTo( _rInitialURL );
    }

    //--------------------------------------------------------------------
    SmartContent::~SmartContent()
    {
        //Do not delete the content. Because the content will be used by the cache.
        //DELETEZ( m_pContent );
    }

    //--------------------------------------------------------------------
    void SmartContent::enableOwnInteractionHandler(::svt::OFilePickerInteractionHandler::EInterceptedInteractions eInterceptions)
    {
        Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
        Reference< XInteractionHandler >  xGlobalInteractionHandler = Reference< XInteractionHandler >(
            xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.task.InteractionHandler") ) ), UNO_QUERY );

        m_pOwnInteraction = new ::svt::OFilePickerInteractionHandler(xGlobalInteractionHandler);
        m_pOwnInteraction->enableInterceptions(eInterceptions);
        m_xOwnInteraction = m_pOwnInteraction;

        m_xCmdEnv = new ::ucbhelper::CommandEnvironment( m_xOwnInteraction, Reference< XProgressHandler >() );
    }

    //--------------------------------------------------------------------
    void SmartContent::enableDefaultInteractionHandler()
    {
        // Don't free the memory here! It will be done by the next
        // call automaticly - releasing of the uno reference ...
        m_pOwnInteraction = NULL;
        m_xOwnInteraction = Reference< XInteractionHandler >();

        Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
        Reference< XInteractionHandler >  xGlobalInteractionHandler = Reference< XInteractionHandler >(
            xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.task.InteractionHandler") ) ), UNO_QUERY );
        m_xCmdEnv = new ucbhelper::CommandEnvironment( xGlobalInteractionHandler, Reference< XProgressHandler >() );
    }

    //--------------------------------------------------------------------
    ::svt::OFilePickerInteractionHandler* SmartContent::getOwnInteractionHandler() const
    {
        if (!m_xOwnInteraction.is())
            return NULL;
        return m_pOwnInteraction;
    }

    //--------------------------------------------------------------------
    SmartContent::InteractionHandlerType SmartContent::queryCurrentInteractionHandler() const
    {
        if (m_xOwnInteraction.is())
            return IHT_OWN;

        if (!m_xCmdEnv.is())
            return IHT_NONE;

        return IHT_DEFAULT;
    }

    //--------------------------------------------------------------------
    void SmartContent::disableInteractionHandler()
    {
        // Don't free the memory here! It will be done by the next
        // call automaticly - releasing of the uno reference ...
        m_pOwnInteraction = NULL;
        m_xOwnInteraction.clear();

        m_xCmdEnv.clear();
    }

    //--------------------------------------------------------------------
    void SmartContent::bindTo( const ::rtl::OUString& _rURL )
    {
        if ( getURL() == _rURL )
            // nothing to do, regardless of the state
            return;

        DELETEZ( m_pContent );
        m_eState = INVALID; // default to INVALID
        m_sURL = _rURL;

        if ( m_sURL.getLength() )
        {
            try
            {
                m_pContent = new ::ucbhelper::Content( _rURL, m_xCmdEnv );
                m_eState = UNKNOWN;
                    // from now on, the state is unknown -> we cannot know for sure if the content
                    // is really valid (some UCP's only tell this when asking for properties, not upon
                    // creation)
            }
            catch( ContentCreationException& )
            {
            }
            catch( Exception& )
            {
                OSL_FAIL( "SmartContent::bindTo: unexpected exception caught!" );
            }
        }
        else
        {
            m_eState = NOT_BOUND;
        }

        // don't forget to reset the may internal used interaction handler ...
        // But do it only for our own specialized interaction helper!
        ::svt::OFilePickerInteractionHandler* pHandler = getOwnInteractionHandler();
        if (pHandler)
        {
            pHandler->resetUseState();
            pHandler->forgetRequest();
        }
    }

    //--------------------------------------------------------------------
    sal_Bool SmartContent::implIs( const ::rtl::OUString& _rURL, Type _eType )
    {
        // bind to this content
        bindTo( _rURL );

        // did we survive this?
        if ( isInvalid() || !isBound() )
            return sal_False;

        DBG_ASSERT( m_pContent, "SmartContent::implIs: inconsistence!" );
            // if, after an bindTo, we don't have a content, then we should be INVALID, or at least
            // NOT_BOUND (the latter happens, for example, if somebody tries to ask for an empty URL)

        sal_Bool bIs = sal_False;
        try
        {
            if ( Folder == _eType )
                bIs = m_pContent->isFolder();
            else
                bIs = m_pContent->isDocument();

            // from here on, we definately know that the content is valid
            m_eState = VALID;
        }
        catch( Exception& )
        {
            // now we're definately invalid
            m_eState = INVALID;
        }
        return bIs;
    }

    //--------------------------------------------------------------------
    void SmartContent::getTitle( ::rtl::OUString& /* [out] */ _rTitle )
    {
        if ( !isBound() || isInvalid() )
            return;

        try
        {
            ::rtl::OUString sTitle;
            m_pContent->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Title" )) ) >>= sTitle;
            _rTitle =  sTitle;

            // from here on, we definately know that the content is valid
            m_eState = VALID;
        }
        catch( ::com::sun::star::uno::Exception& )
        {
            // now we're definately invalid
            m_eState = INVALID;
        }
    }

    //--------------------------------------------------------------------
    sal_Bool SmartContent::hasParentFolder( )
    {
        if ( !isBound() || isInvalid() )
            return sal_False;

        sal_Bool bRet = sal_False;
        try
        {
            Reference< XChild > xChild( m_pContent->get(), UNO_QUERY );
            if ( xChild.is() )
            {
                Reference< XContent > xParent( xChild->getParent(), UNO_QUERY );
                if ( xParent.is() )
                {
                    const ::rtl::OUString aParentURL( xParent->getIdentifier()->getContentIdentifier() );
                    bRet = ( !aParentURL.isEmpty() && aParentURL != m_pContent->getURL() );

                    // now we're definately valid
                    m_eState = VALID;
                }
            }
        }
        catch( const Exception& )
        {
            // now we're definately invalid
            m_eState = INVALID;
        }
        return bRet;
    }

    //--------------------------------------------------------------------
    sal_Bool SmartContent::canCreateFolder( )
    {
        if ( !isBound() || isInvalid() )
            return sal_False;

        sal_Bool bRet = sal_False;
        try
        {
            Sequence< ContentInfo > aInfo = m_pContent->queryCreatableContentsInfo();
            const ContentInfo* pInfo = aInfo.getConstArray();
            sal_Int32 nCount = aInfo.getLength();
            for ( sal_Int32 i = 0; i < nCount; ++i, ++pInfo )
            {
                // Simply look for the first KIND_FOLDER...
                if ( pInfo->Attributes & ContentInfoAttribute::KIND_FOLDER )
                {
                    bRet = sal_True;
                    break;
                }
            }

            // now we're definately valid
            m_eState = VALID;
        }
        catch( Exception& )
        {
            // now we're definately invalid
            m_eState = INVALID;
        }
        return bRet;
    }

//........................................................................
} // namespace svt
//........................................................................

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>// Copyright (c) 2011-2014 Zeex
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#include <vector>
#include <string>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

namespace os {

std::string GetModuleName(void *address) {
  std::vector<char> filename(MAX_PATH);
  if (address != 0) {
    MEMORY_BASIC_INFORMATION mbi;
    if (VirtualQuery(address, &mbi, sizeof(mbi)) != 0) {
      DWORD size = filename.size();
      do {
        size = GetModuleFileName((HMODULE)mbi.AllocationBase,
                                 &filename[0], filename.size());
        if (size < filename.size() ||
            GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
          break;
        }
        filename.resize(size *= 2);
      } while (true);
    }
  }
  return std::string(&filename[0]);
}

} // namespace os
<commit_msg>Fix loop condition in GetModuleName()<commit_after>// Copyright (c) 2011-2014 Zeex
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#include <vector>
#include <string>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

namespace os {

std::string GetModuleName(void *address) {
  std::vector<char> filename(MAX_PATH);
  if (address != 0) {
    MEMORY_BASIC_INFORMATION mbi;
    if (VirtualQuery(address, &mbi, sizeof(mbi)) != 0) {
      DWORD size = filename.size();
      do {
        size = GetModuleFileName((HMODULE)mbi.AllocationBase,
                                 &filename[0], filename.size());
        if (size < filename.size() ||
            GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
          break;
        }
        filename.resize(size *= 2);
      } while (true);
    }
  }
  return std::string(&filename[0]);
}

} // namespace os
<|endoftext|>