<commit_before>// this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-

// -- BEGIN LICENSE BLOCK ----------------------------------------------
// Copyright 2019 FZI Forschungszentrum Informatik
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Many parts from this (Most of the URScript program) comes from the ur_modern_driver
// Copyright 2017, 2018 Simon Rasmussen (refactor)
// Copyright 2015, 2016 Thomas Timm Andersen (original version)
//
// -- END LICENSE BLOCK ------------------------------------------------

//----------------------------------------------------------------------
/*!\file
 *
 * \author  Felix Mauch mauch@fzi.de
 * \date    2019-04-11
 *
 */
//----------------------------------------------------------------------

#include "ur_rtde_driver/ur/ur_driver.h"
#include <memory>

namespace ur_driver
{
static const int32_t MULT_JOINTSTATE_ = 1000000;
static const std::string JOINT_STATE_REPLACE("{{JOINT_STATE_REPLACE}}");
static const std::string SERVO_J_REPLACE("{{SERVO_J_REPLACE}}");
static const std::string SERVER_IP_REPLACE("{{SERVER_IP_REPLACE}}");
static const std::string SERVER_PORT_REPLACE("{{SERVER_PORT_REPLACE}}");
static const std::string POSITION_PROGRAM = R"(
def myProg():
  global steptime = get_steptime()
  textmsg("steptime=", steptime)
  MULT_jointstate = {{JOINT_STATE_REPLACE}}

  SERVO_IDLE = 0
  SERVO_RUNNING = 1
  cmd_servo_state = SERVO_IDLE
  cmd_servo_q = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
  def set_servo_setpoint(q):
    enter_critical
    cmd_servo_state = SERVO_RUNNING
    cmd_servo_q = q
    exit_critical
  end

  thread servoThread():
    state = SERVO_IDLE
    while True:
      enter_critical
      q = cmd_servo_q
      do_brake = False
      if (state == SERVO_RUNNING) and (cmd_servo_state == SERVO_IDLE):
        do_brake = True
      end
      state = cmd_servo_state
      cmd_servo_state = SERVO_IDLE
      exit_critical
      if do_brake:
        textmsg("No new setpoint received. Stopping robot.")
        stopj(1.0)
        sync()
      elif state == SERVO_RUNNING:
        servoj(q, t=steptime, {{SERVO_J_REPLACE}})
      else:
        sync()
      end
    end
  end
  socket_open("{{SERVER_IP_REPLACE}}", {{SERVER_PORT_REPLACE}}, "reverse_socket")

  thread_servo = run servoThread()
  keepalive = -2
  params_mult = socket_read_binary_integer(6+1, "reverse_socket")
  keepalive = params_mult[7]
  while keepalive > 0:
    params_mult = socket_read_binary_integer(6+1, "reverse_socket", 0.012)
    if params_mult[0] > 0:
      keepalive = params_mult[7]
      q = [params_mult[1] / MULT_jointstate, params_mult[2] / MULT_jointstate, params_mult[3] / MULT_jointstate, params_mult[4] / MULT_jointstate, params_mult[5] / MULT_jointstate, params_mult[6] / MULT_jointstate]
      set_servo_setpoint(q)
    else:
      # TODO: Extrapolation goes here
      keepalive = keepalive - 1
    end
    sync()
  end
  stopj(1.0)
  sleep(.1)
  socket_close()
  kill thread_servo
end
)";

ur_driver::UrDriver::UrDriver(const std::string& ROBOT_IP)
  : servoj_time_(0.008), servoj_gain_(750), servoj_lookahead_time_(0.03)
{
  ROS_INFO_STREAM("Initializing RTDE client");
  rtde_client_.reset(new rtde_interface::RTDEClient(ROBOT_IP, notifier_));

  if (!rtde_client_->init())
  {
    throw std::runtime_error("initialization went wrong");  // TODO: be less harsh
  }

  rtde_frequency_ = rtde_client_->getMaxFrequency();
  servoj_time_ = 1.0 / rtde_frequency_;

  comm::URStream<rtde_interface::PackageHeader> stream(ROBOT_IP, 30001);
  stream.connect();
  std::string local_ip = stream.getIP();

  uint32_t reverse_port = 50001;  // TODO: Make this a parameter

  std::string prog = POSITION_PROGRAM;
  prog.replace(prog.find(JOINT_STATE_REPLACE), JOINT_STATE_REPLACE.length(), std::to_string(MULT_JOINTSTATE_));
  std::ostringstream out;
  out << "lookahead_time=" << servoj_lookahead_time_ << ", gain=" << servoj_gain_;
  prog.replace(prog.find(SERVO_J_REPLACE), SERVO_J_REPLACE.length(), out.str());
  prog.replace(prog.find(SERVER_IP_REPLACE), SERVER_IP_REPLACE.length(), local_ip);
  prog.replace(prog.find(SERVER_PORT_REPLACE), SERVER_PORT_REPLACE.length(), std::to_string(reverse_port));
  size_t len = prog.size();
  const uint8_t* data = reinterpret_cast<const uint8_t*>(prog.c_str());
  size_t written;

  if (stream.write(data, len, written))
  {
    LOG_INFO("Sent program to robot");
  }
  else
  {
    LOG_ERROR("Could not send program to robot");
  }

  reverse_interface_.reset(new comm::ReverseInterface(reverse_port));

  ROS_INFO_STREAM("Created reverse interface");

  rtde_client_->start();  // TODO: Add extra start method (also to HW-Interface)
  ROS_INFO_STREAM("Initialization done");
}

std::unique_ptr<rtde_interface::DataPackage> ur_driver::UrDriver::getDataPackage()
{
  // TODO: This goes into the rtde_client
  std::unique_ptr<comm::URPackage<rtde_interface::PackageHeader>> urpackage;
  uint32_t period_ms = (1.0 / rtde_frequency_) * 1000;
  // std::chrono::milliseconds timeout(period_ms);
  std::chrono::milliseconds timeout(100);
  if (rtde_client_->getDataPackage(urpackage, timeout))
  {
    rtde_interface::DataPackage* tmp = dynamic_cast<rtde_interface::DataPackage*>(urpackage.get());
    if (tmp != nullptr)
    {
      urpackage.release();
      return std::unique_ptr<rtde_interface::DataPackage>(tmp);
    }
  }
  return nullptr;
}

bool UrDriver::writeJointCommand(const vector6d_t& values)
{
  if (reverse_interface_)
  {
    reverse_interface_->write(values);
  }
  else
  {
    return false;
  }

  return true;
}
}  // namespace ur_driver
<commit_msg>extrapolate on missing packages<commit_after>// this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-

// -- BEGIN LICENSE BLOCK ----------------------------------------------
// Copyright 2019 FZI Forschungszentrum Informatik
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Many parts from this (Most of the URScript program) comes from the ur_modern_driver
// Copyright 2017, 2018 Simon Rasmussen (refactor)
// Copyright 2015, 2016 Thomas Timm Andersen (original version)
//
// -- END LICENSE BLOCK ------------------------------------------------

//----------------------------------------------------------------------
/*!\file
 *
 * \author  Felix Mauch mauch@fzi.de
 * \date    2019-04-11
 *
 */
//----------------------------------------------------------------------

#include "ur_rtde_driver/ur/ur_driver.h"
#include <memory>

namespace ur_driver
{
static const int32_t MULT_JOINTSTATE_ = 1000000;
static const std::string JOINT_STATE_REPLACE("{{JOINT_STATE_REPLACE}}");
static const std::string SERVO_J_REPLACE("{{SERVO_J_REPLACE}}");
static const std::string SERVER_IP_REPLACE("{{SERVER_IP_REPLACE}}");
static const std::string SERVER_PORT_REPLACE("{{SERVER_PORT_REPLACE}}");
static const std::string POSITION_PROGRAM = R"(
def myProg():
  global steptime = get_steptime()
  textmsg("steptime=", steptime)
  MULT_jointstate = {{JOINT_STATE_REPLACE}}

  SERVO_UNINITIALIZED = -1
  SERVO_IDLE = 0
  SERVO_RUNNING = 1
  cmd_servo_state = SERVO_UNINITIALIZED
  cmd_servo_q = get_actual_joint_positions()
  cmd_servo_q_last = get_actual_joint_positions()
  def set_servo_setpoint(q):
    enter_critical
    cmd_servo_state = SERVO_RUNNING
    cmd_servo_q_last = cmd_servo_q
    cmd_servo_q = q
    exit_critical
  end

  def extrapolate():
    enter_critical
    diff = [cmd_servo_q[0] - cmd_servo_q_last[0], cmd_servo_q[1] - cmd_servo_q_last[1], cmd_servo_q[2] - cmd_servo_q_last[2], cmd_servo_q[3] - cmd_servo_q_last[3], cmd_servo_q[4] - cmd_servo_q_last[4], cmd_servo_q[5] - cmd_servo_q_last[5]]
    cmd_servo_q_last = cmd_servo_q
    cmd_servo_q = [cmd_servo_q[0] + diff[0], cmd_servo_q[1] + diff[1], cmd_servo_q[2] + diff[2], cmd_servo_q[3] + diff[3], cmd_servo_q[4] + diff[4], cmd_servo_q[5] + diff[5]]
    exit_critical

    return cmd_servo_q
  end

  thread servoThread():
    state = SERVO_IDLE
    while True:
      enter_critical
      q = cmd_servo_q
      do_extrapolate = False
      if (cmd_servo_state == SERVO_IDLE):
        do_extrapolate = True
      end
      state = cmd_servo_state
      cmd_servo_state = SERVO_IDLE
      exit_critical
      if do_extrapolate:
        textmsg("No new setpoint received. Extrapolating.")
        q = extrapolate()
        servoj(q, t=steptime, {{SERVO_J_REPLACE}})
      elif state == SERVO_RUNNING:
        servoj(q, t=steptime, {{SERVO_J_REPLACE}})
      else:
        textmsg("Should not be here")
        sync()
      end
    end
    stopj(0.1)
  end
  socket_open("{{SERVER_IP_REPLACE}}", {{SERVER_PORT_REPLACE}}, "reverse_socket")

  thread_servo = run servoThread()
  keepalive = -2
  params_mult = socket_read_binary_integer(6+1, "reverse_socket")
  keepalive = params_mult[7]
  while keepalive > 0:
    params_mult = socket_read_binary_integer(6+1, "reverse_socket", steptime)
    if params_mult[0] > 0:
      keepalive = params_mult[7]
      q = [params_mult[1] / MULT_jointstate, params_mult[2] / MULT_jointstate, params_mult[3] / MULT_jointstate, params_mult[4] / MULT_jointstate, params_mult[5] / MULT_jointstate, params_mult[6] / MULT_jointstate]
      set_servo_setpoint(q)
    else:
      # TODO: Extrapolation goes here
      keepalive = keepalive - 1
    end
  end
  sleep(.1)
  socket_close()
  kill thread_servo
end
)";

ur_driver::UrDriver::UrDriver(const std::string& ROBOT_IP)
  : servoj_time_(0.008), servoj_gain_(750), servoj_lookahead_time_(0.03)
{
  ROS_INFO_STREAM("Initializing RTDE client");
  rtde_client_.reset(new rtde_interface::RTDEClient(ROBOT_IP, notifier_));

  if (!rtde_client_->init())
  {
    throw std::runtime_error("initialization went wrong");  // TODO: be less harsh
  }

  rtde_frequency_ = rtde_client_->getMaxFrequency();
  servoj_time_ = 1.0 / rtde_frequency_;

  comm::URStream<rtde_interface::PackageHeader> stream(ROBOT_IP, 30001);
  stream.connect();
  std::string local_ip = stream.getIP();

  uint32_t reverse_port = 50001;  // TODO: Make this a parameter

  std::string prog = POSITION_PROGRAM;
  prog.replace(prog.find(JOINT_STATE_REPLACE), JOINT_STATE_REPLACE.length(), std::to_string(MULT_JOINTSTATE_));
  std::ostringstream out;
  out << "lookahead_time=" << servoj_lookahead_time_ << ", gain=" << servoj_gain_;
  prog.replace(prog.find(SERVO_J_REPLACE), SERVO_J_REPLACE.length(), out.str());
  prog.replace(prog.find(SERVO_J_REPLACE), SERVO_J_REPLACE.length(), out.str());
  prog.replace(prog.find(SERVER_IP_REPLACE), SERVER_IP_REPLACE.length(), local_ip);
  prog.replace(prog.find(SERVER_PORT_REPLACE), SERVER_PORT_REPLACE.length(), std::to_string(reverse_port));
  size_t len = prog.size();
  const uint8_t* data = reinterpret_cast<const uint8_t*>(prog.c_str());
  size_t written;

  if (stream.write(data, len, written))
  {
    LOG_INFO("Sent program to robot");
  }
  else
  {
    LOG_ERROR("Could not send program to robot");
  }

  reverse_interface_.reset(new comm::ReverseInterface(reverse_port));

  ROS_INFO_STREAM("Created reverse interface");

  rtde_client_->start();  // TODO: Add extra start method (also to HW-Interface)
  ROS_INFO_STREAM("Initialization done");
}

std::unique_ptr<rtde_interface::DataPackage> ur_driver::UrDriver::getDataPackage()
{
  // TODO: This goes into the rtde_client
  std::unique_ptr<comm::URPackage<rtde_interface::PackageHeader>> urpackage;
  uint32_t period_ms = (1.0 / rtde_frequency_) * 1000;
  // std::chrono::milliseconds timeout(period_ms);
  std::chrono::milliseconds timeout(100);
  if (rtde_client_->getDataPackage(urpackage, timeout))
  {
    rtde_interface::DataPackage* tmp = dynamic_cast<rtde_interface::DataPackage*>(urpackage.get());
    if (tmp != nullptr)
    {
      urpackage.release();
      return std::unique_ptr<rtde_interface::DataPackage>(tmp);
    }
  }
  return nullptr;
}

bool UrDriver::writeJointCommand(const vector6d_t& values)
{
  if (reverse_interface_)
  {
    reverse_interface_->write(values);
  }
  else
  {
    return false;
  }

  return true;
}
}  // namespace ur_driver
<|endoftext|>


<commit_before>#include "RansomwareCanary.h"
#include <thread>
#include "../stringtools.h"
#include "../urbackupcommon/os_functions.h"
#include "../Interface/Server.h"
#include "../Interface/File.h"
#include "../urbackupcommon/glob.h"
#include "../common/miniz.h"
#include "clientdao.h"
#include "database.h"
#ifdef _WIN32
#include <aclapi.h>
#endif

struct SOwner
{
	bool has_owner = false;
#ifdef _WIN32
	PSID Owner = nullptr;
	PSECURITY_DESCRIPTOR sec_d = nullptr;

	~SOwner() {
		if (sec_d != nullptr)
			LocalFree(sec_d);
	}
#endif
};

static bool getOwner(const std::string& fn, SOwner& owner)
{
	PSID newOwner = nullptr;
	PSECURITY_DESCRIPTOR new_sec_d = nullptr;
	DWORD rc = GetNamedSecurityInfoW(Server->ConvertToWchar(os_file_prefix(fn)).c_str(),
		SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &newOwner, NULL, NULL,
		NULL, &new_sec_d);

	if (rc == ERROR_SUCCESS)
	{
		if (owner.sec_d != nullptr)
			LocalFree(owner.sec_d);

		owner.Owner = newOwner;
		owner.sec_d = new_sec_d;
		owner.has_owner = true;
	}
	else if (new_sec_d != nullptr)
	{
		LocalFree(new_sec_d);
	}
	return rc == ERROR_SUCCESS;
}

#ifdef _WIN32
HRESULT ModifyPrivilege(
	IN LPCTSTR szPrivilege,
	IN BOOL fEnable)
{
	HRESULT hr = S_OK;
	TOKEN_PRIVILEGES NewState;
	LUID             luid;
	HANDLE hToken = NULL;

	if (!OpenProcessToken(GetCurrentProcess(),
		TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
		&hToken))
	{
		return ERROR_FUNCTION_FAILED;
	}

	if (!LookupPrivilegeValue(NULL,
		szPrivilege,
		&luid))
	{
		CloseHandle(hToken);
		return ERROR_FUNCTION_FAILED;
	}

	NewState.PrivilegeCount = 1;
	NewState.Privileges[0].Luid = luid;
	NewState.Privileges[0].Attributes =
		(fEnable ? SE_PRIVILEGE_ENABLED : 0);

	if (!AdjustTokenPrivileges(hToken,
		FALSE,
		&NewState,
		0,
		NULL,
		NULL))
	{
		hr = ERROR_FUNCTION_FAILED;
	}

	CloseHandle(hToken);

	return hr;
}
#endif

static bool setOwner(const std::string& fn, const SOwner& owner)
{
	if (!owner.has_owner || owner.Owner == nullptr)
		return false;

	HRESULT hr = ModifyPrivilege(SE_TAKE_OWNERSHIP_NAME, TRUE);
	if (!SUCCEEDED(hr))
		return false;

	std::wstring wfn = Server->ConvertToWchar(os_file_prefix(fn)).c_str();
	DWORD rc = SetNamedSecurityInfoW(&wfn[0],
		SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, owner.Owner, NULL, NULL,
		NULL);

	return rc == ERROR_SUCCESS;
}

static size_t zipWrite(void* pOpaque, mz_uint64 file_ofs, const void* pBuf, size_t n)
{
	IFsFile* out_file = reinterpret_cast<IFsFile*>(pOpaque);
	return out_file->Write(file_ofs, reinterpret_cast<const char*>(pBuf), n);
}

static void setupRansomwareCanaryFile(const std::string& curr_path, const std::string& fn_prefix,
	const std::string& server_token, SOwner& owner)
{
	std::string out_fn = os_file_prefix(curr_path + fn_prefix + "-" + server_token + ".docx");
	if (os_get_file_type(out_fn) != 0)
	{
		Server->Log("Ransomware canary at \"" + out_fn + "\" already exists");
		return;
	}

	if (!curr_path.empty())
	{
		std::vector<SFile> sib_files = getFiles(curr_path.substr(0, curr_path.size()-1));

		for (SFile& sib_file : sib_files)
		{
			if (getOwner(curr_path + sib_file.name, owner))
				break;
		}
	}

	const std::string canary_path = Server->getServerWorkingDir() + os_file_sep() +
		"urbackup" + os_file_sep() + "canary.docx";

	mz_zip_archive canary_doc = {};
	if (!mz_zip_reader_init_file(&canary_doc, canary_path.c_str(), 0))
	{
		Server->Log("Error opening canary.docx file for extraction", LL_ERROR);
		return;
	}

	ScopedDeleteFn delete_fn(out_fn+".new");
	std::unique_ptr<IFsFile> out_file(Server->openFile(out_fn+".new", MODE_WRITE));

	if (out_file.get() == nullptr)
	{
		Server->Log("Error opening canary out at \"" + out_fn + ".new\". " + os_last_error_str(), LL_ERROR);
		return;
	}

	mz_zip_archive canary_doc_out = {};
	canary_doc_out.m_pWrite = zipWrite;
	canary_doc_out.m_pIO_opaque = out_file.get();
	if (!mz_zip_writer_init(&canary_doc_out, 0))
	{
		Server->Log("Error init zip at \"" + out_fn + ".new\"", LL_ERROR);
		return;
	}

	for (unsigned int i = 0, num_files = mz_zip_reader_get_num_files(&canary_doc); i < num_files; ++i)
	{
		std::vector<char> buf(100);
		mz_zip_reader_get_filename(&canary_doc, i, buf.data(), buf.size());
		std::string curr_fn = buf.data();

		if (curr_fn == "word/document.xml")
		{
			size_t fsize;
			void* buf = mz_zip_reader_extract_to_heap(&canary_doc, i, &fsize, 0);

			if (buf == nullptr)
			{
				Server->Log("Error extracting word/document.xml", LL_ERROR);
				return;
			}

			std::string bdata(reinterpret_cast<char*>(buf), fsize);

			std::string uuid;
			uuid.resize(16);
			Server->secureRandomFill(&uuid[0], 16);

			bdata = greplace("$RAND$", bytesToHex(uuid), bdata);

			if (!mz_zip_writer_add_mem(&canary_doc_out, curr_fn.c_str(),
				bdata.data(), bdata.size(), MZ_DEFAULT_COMPRESSION))
			{
				Server->Log("Error adding modified word/document.xml to doc", LL_ERROR);
				return;
			}
		}
		else
		{
			if (!mz_zip_writer_add_from_zip_reader(&canary_doc_out, &canary_doc, i))
			{
				Server->Log("Error adding file \"" + curr_fn + "\" to canary out doc", LL_ERROR);
				return;
			}
		}
	}

	delete_fn.release();
	out_file->Sync();
	out_file.reset();

	if (!os_rename_file(out_fn + ".new", out_fn))
	{
		Server->Log("Error renaming canary " + out_fn + ".new", LL_ERROR);
		return;
	}

	setOwner(out_fn, owner);
}

static std::string getBackupPath(const std::string& name, int facet, int group)
{
	ClientDAO clientdao(Server->getDatabase(Server->getThreadID(), URBACKUPDB_CLIENT));

	std::vector<SBackupDir> backupdirs = clientdao.getBackupDirs();

	for (SBackupDir& bd: backupdirs)
	{
		if (bd.facet != facet || bd.group != group)
			continue;

		if (bd.tname == name)
			return bd.path;
	}

	return std::string();
}

static void setupRansomwareCanariesPath(const std::string& curr_path, const std::vector<std::string> path_components, size_t idx,
	const std::string& server_token, int facet, int group, SOwner& owner)
{
	if (idx >= path_components.size())
		return;

	bool last_comp = idx + 1 >= path_components.size();
	std::string comp = path_components[idx];

	bool create = false;

	if (comp[0] == '^'
		&& comp.find("*") == std::string::npos)
	{
		create = true;
		comp = comp.substr(1);
	}

	if (idx == 0)
	{
		comp = getBackupPath(comp, facet, group);

		if (comp.empty())
			return;
	}

	if (!last_comp
		&& comp.find("*") != std::string::npos)
	{
		std::vector<SFile> files = getFiles(curr_path);
		for (size_t i = 0; i < files.size(); ++i)
		{
			if (files[i].isdir
				&& amatch(files[i].name.c_str(), comp.c_str()))
			{
				getOwner(curr_path + files[i].name, owner);

				setupRansomwareCanariesPath(curr_path + files[i].name + os_file_sep(),
					path_components, idx + 1, server_token, facet, group, owner);
			}
		}
	}
	else
	{
		if (!create
			&& !last_comp)
		{
			getOwner(curr_path + comp, owner);
		}

		if (!last_comp &&
			create &&
			!os_directory_exists(os_file_prefix(curr_path + comp)))
		{
			if (!os_create_dir(os_file_prefix(curr_path + comp)))
			{
				Server->Log("Error creating directory \"" + curr_path + comp +
					"\" for ransomware canary. " + os_last_error_str(), LL_ERROR);
			}
		}
		else if (last_comp)
		{
			setupRansomwareCanaryFile(curr_path,
				comp, server_token, owner);
		}

		if(!last_comp)
			setupRansomwareCanariesPath(curr_path + comp + os_file_sep(), path_components,
				idx + 1, server_token, facet, group, owner);
	}
}

static void setupRansomwareCanariesInt(const std::string& ransomware_canary_paths, const std::string& server_token,
	int facet, int group)
{
	std::vector<std::string> paths;
	Tokenize(ransomware_canary_paths, paths, ";");

	for (std::string path : paths)
	{
		std::vector<std::string> path_components;
		Tokenize(path, path_components, "/");

		if (!path_components.empty())
		{
			SOwner owner;
			setupRansomwareCanariesPath(std::string(), path_components, 0, server_token, facet, group, owner);
		}
	}
}

void setupRansomwareCanaries(const std::string& ransomware_canary_paths, const std::string& server_token,
	int facet, int group)
{
	std::thread t([ransomware_canary_paths, server_token, facet, group]()
		{
			setupRansomwareCanariesInt(ransomware_canary_paths, server_token, facet, group);
		});

	t.detach();
}
<commit_msg>Fix docx writing<commit_after>#include "RansomwareCanary.h"
#include <thread>
#include "../stringtools.h"
#include "../urbackupcommon/os_functions.h"
#include "../Interface/Server.h"
#include "../Interface/File.h"
#include "../urbackupcommon/glob.h"
#include "../common/miniz.h"
#include "clientdao.h"
#include "database.h"
#ifdef _WIN32
#include <aclapi.h>
#endif

struct SOwner
{
	bool has_owner = false;
#ifdef _WIN32
	PSID Owner = nullptr;
	PSECURITY_DESCRIPTOR sec_d = nullptr;

	~SOwner() {
		if (sec_d != nullptr)
			LocalFree(sec_d);
	}
#endif
};

static bool getOwner(const std::string& fn, SOwner& owner)
{
	PSID newOwner = nullptr;
	PSECURITY_DESCRIPTOR new_sec_d = nullptr;
	DWORD rc = GetNamedSecurityInfoW(Server->ConvertToWchar(os_file_prefix(fn)).c_str(),
		SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &newOwner, NULL, NULL,
		NULL, &new_sec_d);

	if (rc == ERROR_SUCCESS)
	{
		if (owner.sec_d != nullptr)
			LocalFree(owner.sec_d);

		owner.Owner = newOwner;
		owner.sec_d = new_sec_d;
		owner.has_owner = true;
	}
	else if (new_sec_d != nullptr)
	{
		LocalFree(new_sec_d);
	}
	return rc == ERROR_SUCCESS;
}

#ifdef _WIN32
HRESULT ModifyPrivilege(
	IN LPCTSTR szPrivilege,
	IN BOOL fEnable)
{
	HRESULT hr = S_OK;
	TOKEN_PRIVILEGES NewState;
	LUID             luid;
	HANDLE hToken = NULL;

	if (!OpenProcessToken(GetCurrentProcess(),
		TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
		&hToken))
	{
		return ERROR_FUNCTION_FAILED;
	}

	if (!LookupPrivilegeValue(NULL,
		szPrivilege,
		&luid))
	{
		CloseHandle(hToken);
		return ERROR_FUNCTION_FAILED;
	}

	NewState.PrivilegeCount = 1;
	NewState.Privileges[0].Luid = luid;
	NewState.Privileges[0].Attributes =
		(fEnable ? SE_PRIVILEGE_ENABLED : 0);

	if (!AdjustTokenPrivileges(hToken,
		FALSE,
		&NewState,
		0,
		NULL,
		NULL))
	{
		hr = ERROR_FUNCTION_FAILED;
	}

	CloseHandle(hToken);

	return hr;
}
#endif

static bool setOwner(const std::string& fn, const SOwner& owner)
{
	if (!owner.has_owner || owner.Owner == nullptr)
		return false;

	HRESULT hr = ModifyPrivilege(SE_TAKE_OWNERSHIP_NAME, TRUE);
	if (!SUCCEEDED(hr))
		return false;

	std::wstring wfn = Server->ConvertToWchar(os_file_prefix(fn)).c_str();
	DWORD rc = SetNamedSecurityInfoW(&wfn[0],
		SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, owner.Owner, NULL, NULL,
		NULL);

	return rc == ERROR_SUCCESS;
}

static size_t zipWrite(void* pOpaque, mz_uint64 file_ofs, const void* pBuf, size_t n)
{
	IFsFile* out_file = reinterpret_cast<IFsFile*>(pOpaque);
	return out_file->Write(file_ofs, reinterpret_cast<const char*>(pBuf), n);
}

static void setupRansomwareCanaryFile(const std::string& curr_path, const std::string& fn_prefix,
	const std::string& server_token, SOwner& owner)
{
	std::string out_fn = os_file_prefix(curr_path + fn_prefix + "-" + server_token + ".docx");
	if (os_get_file_type(out_fn) != 0)
	{
		Server->Log("Ransomware canary at \"" + out_fn + "\" already exists");
		return;
	}

	if (!curr_path.empty())
	{
		std::vector<SFile> sib_files = getFiles(curr_path.substr(0, curr_path.size()-1));

		for (SFile& sib_file : sib_files)
		{
			if (getOwner(curr_path + sib_file.name, owner))
				break;
		}
	}

	const std::string canary_path = Server->getServerWorkingDir() + os_file_sep() +
		"urbackup" + os_file_sep() + "canary.docx";

	mz_zip_archive canary_doc = {};
	if (!mz_zip_reader_init_file(&canary_doc, canary_path.c_str(), 0))
	{
		Server->Log("Error opening canary.docx file for extraction", LL_ERROR);
		return;
	}

	ScopedDeleteFn delete_fn(out_fn+".new");
	std::unique_ptr<IFsFile> out_file(Server->openFile(out_fn+".new", MODE_WRITE));

	if (out_file.get() == nullptr)
	{
		Server->Log("Error opening canary out at \"" + out_fn + ".new\". " + os_last_error_str(), LL_ERROR);
		return;
	}

	mz_zip_archive canary_doc_out = {};
	canary_doc_out.m_pWrite = zipWrite;
	canary_doc_out.m_pIO_opaque = out_file.get();
	if (!mz_zip_writer_init(&canary_doc_out, 0))
	{
		Server->Log("Error init zip at \"" + out_fn + ".new\"", LL_ERROR);
		return;
	}

	for (unsigned int i = 0, num_files = mz_zip_reader_get_num_files(&canary_doc); i < num_files; ++i)
	{
		std::vector<char> buf(100);
		mz_zip_reader_get_filename(&canary_doc, i, buf.data(), buf.size());
		std::string curr_fn = buf.data();

		if (curr_fn == "word/document.xml")
		{
			size_t fsize;
			void* buf = mz_zip_reader_extract_to_heap(&canary_doc, i, &fsize, 0);

			if (buf == nullptr)
			{
				Server->Log("Error extracting word/document.xml", LL_ERROR);
				return;
			}

			std::string bdata(reinterpret_cast<char*>(buf), fsize);

			std::string uuid;
			uuid.resize(16);
			Server->secureRandomFill(&uuid[0], 16);

			bdata = greplace("$RAND$", bytesToHex(uuid), bdata);

			if (!mz_zip_writer_add_mem(&canary_doc_out, curr_fn.c_str(),
				bdata.data(), bdata.size(), MZ_DEFAULT_COMPRESSION))
			{
				Server->Log("Error adding modified word/document.xml to doc", LL_ERROR);
				return;
			}
		}
		else
		{
			if (!mz_zip_writer_add_from_zip_reader(&canary_doc_out, &canary_doc, i))
			{
				Server->Log("Error adding file \"" + curr_fn + "\" to canary out doc", LL_ERROR);
				return;
			}
		}
	}

	if (!mz_zip_writer_finalize_archive(&canary_doc_out))
	{
		Server->Log("Error finalizing archive \"" + out_fn + "\"", LL_ERROR);
		return;
	}

	mz_zip_writer_end(&canary_doc_out);
	mz_zip_reader_end(&canary_doc);

	delete_fn.release();
	out_file->Sync();
	out_file.reset();

	if (!os_rename_file(out_fn + ".new", out_fn))
	{
		Server->Log("Error renaming canary " + out_fn + ".new", LL_ERROR);
		return;
	}

	setOwner(out_fn, owner);
}

static std::string getBackupPath(const std::string& name, int facet, int group)
{
	ClientDAO clientdao(Server->getDatabase(Server->getThreadID(), URBACKUPDB_CLIENT));

	std::vector<SBackupDir> backupdirs = clientdao.getBackupDirs();

	for (SBackupDir& bd: backupdirs)
	{
		if (bd.facet != facet || bd.group != group)
			continue;

		if (bd.tname == name)
			return bd.path;
	}

	return std::string();
}

static void setupRansomwareCanariesPath(const std::string& curr_path, const std::vector<std::string> path_components, size_t idx,
	const std::string& server_token, int facet, int group, SOwner& owner)
{
	if (idx >= path_components.size())
		return;

	bool last_comp = idx + 1 >= path_components.size();
	std::string comp = path_components[idx];

	bool create = false;

	if (comp[0] == '^'
		&& comp.find("*") == std::string::npos)
	{
		create = true;
		comp = comp.substr(1);
	}

	if (idx == 0)
	{
		comp = getBackupPath(comp, facet, group);

		if (comp.empty())
			return;
	}

	if (!last_comp
		&& comp.find("*") != std::string::npos)
	{
		std::vector<SFile> files = getFiles(curr_path);
		for (size_t i = 0; i < files.size(); ++i)
		{
			if (files[i].isdir
				&& amatch(files[i].name.c_str(), comp.c_str()))
			{
				getOwner(curr_path + files[i].name, owner);

				setupRansomwareCanariesPath(curr_path + files[i].name + os_file_sep(),
					path_components, idx + 1, server_token, facet, group, owner);
			}
		}
	}
	else
	{
		if (!create
			&& !last_comp)
		{
			getOwner(curr_path + comp, owner);
		}

		if (!last_comp &&
			create &&
			!os_directory_exists(os_file_prefix(curr_path + comp)))
		{
			if (!os_create_dir(os_file_prefix(curr_path + comp)))
			{
				Server->Log("Error creating directory \"" + curr_path + comp +
					"\" for ransomware canary. " + os_last_error_str(), LL_ERROR);
			}
		}
		else if (last_comp)
		{
			setupRansomwareCanaryFile(curr_path,
				comp, server_token, owner);
		}

		if(!last_comp)
			setupRansomwareCanariesPath(curr_path + comp + os_file_sep(), path_components,
				idx + 1, server_token, facet, group, owner);
	}
}

static void setupRansomwareCanariesInt(const std::string& ransomware_canary_paths, const std::string& server_token,
	int facet, int group)
{
	std::vector<std::string> paths;
	Tokenize(ransomware_canary_paths, paths, ";");

	for (std::string path : paths)
	{
		std::vector<std::string> path_components;
		Tokenize(path, path_components, "/");

		if (!path_components.empty())
		{
			SOwner owner;
			setupRansomwareCanariesPath(std::string(), path_components, 0, server_token, facet, group, owner);
		}
	}
}

void setupRansomwareCanaries(const std::string& ransomware_canary_paths, const std::string& server_token,
	int facet, int group)
{
	std::thread t([ransomware_canary_paths, server_token, facet, group]()
		{
			setupRansomwareCanariesInt(ransomware_canary_paths, server_token, facet, group);
		});

	t.detach();
}
<|endoftext|>


<commit_before>#include "TextureLoader.h"

TextureLoader::TextureLoader(std::string const & url) :
m_objectsTexture(new sf::Texture()),
m_floorTexture(new sf::Texture()),
m_characterTexture(new sf::Texture())
{
	loadTexture(url);
}

TextureLoader::~TextureLoader()
{
	delete(m_floorTexture);
	delete(m_objectsTexture);
	delete(m_characterTexture);
}

sf::Texture * TextureLoader::getFloorTexture() const
{
	return m_floorTexture;
}

sf::Texture * TextureLoader::getObjectsTexture() const
{
	return m_objectsTexture;
}

sf::Texture * TextureLoader::getCharacterTexture() const
{
	return m_characterTexture;
}

//On passe l'url du dossier de Textures
void TextureLoader::loadTexture(std::string const & url)
{
	if(!m_floorTexture->loadFromFile((url + "floor/tileset.png").c_str()))
    {
		std::cerr << "Error when loading the texture of the floor" << std::endl;
        throw LoadingErrorException;
    }

	if(!m_objectsTexture->loadFromFile((url + "mobilier/tileset.png").c_str()))
    {
		std::cerr << "Error when loading the texture of the objects" << std::endl;
        throw LoadingErrorException;
    }

	if(!m_characterTexture->loadFromFile((url + "character/.png").c_str()))
    {
		std::cerr << "Error when loading the texture of the character" << std::endl;
        throw LoadingErrorException;
    }
}
<commit_msg>tileset for spooky<commit_after>#include "TextureLoader.h"

TextureLoader::TextureLoader(std::string const & url) :
m_objectsTexture(new sf::Texture()),
m_floorTexture(new sf::Texture()),
m_characterTexture(new sf::Texture())
{
	loadTexture(url);
}

TextureLoader::~TextureLoader()
{
	delete(m_floorTexture);
	delete(m_objectsTexture);
	delete(m_characterTexture);
}

sf::Texture * TextureLoader::getFloorTexture() const
{
	return m_floorTexture;
}

sf::Texture * TextureLoader::getObjectsTexture() const
{
	return m_objectsTexture;
}

sf::Texture * TextureLoader::getCharacterTexture() const
{
	return m_characterTexture;
}

//On passe l'url du dossier de Textures
void TextureLoader::loadTexture(std::string const & url)
{
	if(!m_floorTexture->loadFromFile((url + "floor/tileset.png").c_str()))
    {
		std::cerr << "Error when loading the texture of the floor" << std::endl;
        throw LoadingErrorException;
    }

	if(!m_objectsTexture->loadFromFile((url + "mobilier/tileset.png").c_str()))
    {
		std::cerr << "Error when loading the texture of the objects" << std::endl;
        throw LoadingErrorException;
    }

	if(!m_characterTexture->loadFromFile((url + "spooky/sprite.png").c_str()))
    {
		std::cerr << "Error when loading the texture of the character" << std::endl;
        throw LoadingErrorException;
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: NameContainer.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-25 08:58:49 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#include "NameContainer.hxx"

/*
//SvXMLUnitConverter
#ifndef _XMLOFF_XMLUCONV_HXX
#include <xmloff/xmluconv.hxx>
#endif
*/

#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif

using namespace ::com::sun::star;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Any;
using ::rtl::OUString;

//.............................................................................
namespace chart
{
//.............................................................................

NameContainer::NameContainer( const ::com::sun::star::uno::Type& rType, const OUString& rServicename, const OUString& rImplementationName )
    : m_aType( rType )
    , m_aServicename( rServicename )
    , m_aImplementationName( rImplementationName )
    , m_aMap()
{
}

NameContainer::NameContainer(
    const NameContainer & rOther )
    : impl::NameContainer_Base()
    , m_aType( rOther.m_aType )
    , m_aServicename( rOther.m_aServicename )
    , m_aImplementationName( rOther.m_aImplementationName )
    , m_aMap( rOther.m_aMap )
{
}

NameContainer::~NameContainer()
{
}

//XServiceInfo
OUString SAL_CALL NameContainer::getImplementationName()
    throw( ::com::sun::star::uno::RuntimeException )
{
    return m_aImplementationName;
}

sal_Bool SAL_CALL NameContainer::supportsService( const OUString& ServiceName )
    throw( ::com::sun::star::uno::RuntimeException )
{
    Sequence< OUString > aSNL = getSupportedServiceNames();
    const OUString* pArray = aSNL.getArray();
    for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
    {
        if( pArray[ i ] == ServiceName )
            return sal_True;
    }
    return sal_False;
}

Sequence< OUString > SAL_CALL NameContainer::getSupportedServiceNames()
    throw( ::com::sun::star::uno::RuntimeException )
{
    Sequence< OUString > aSNS( 1 );
    aSNS.getArray()[ 0 ] = m_aServicename;
    return aSNS;
}

//-----------------------------------------------------------------
//-----------------------------------------------------------------
//-----------------------------------------------------------------

// XNameContainer
void SAL_CALL NameContainer::insertByName( const OUString& rName, const Any& rElement )
    throw( lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException )
{
    if( m_aMap.find( rName ) != m_aMap.end() )
        throw container::ElementExistException();
    m_aMap.insert( tContentMap::value_type( rName, rElement ));
}

void SAL_CALL NameContainer::removeByName( const OUString& Name )
    throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
{
    tContentMap::iterator aIt( m_aMap.find( Name ));
    if( aIt == m_aMap.end())
        throw container::NoSuchElementException();
    m_aMap.erase( aIt );
}

// XNameReplace
void SAL_CALL NameContainer::replaceByName( const OUString& rName, const Any& rElement )
    throw( lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
{
    tContentMap::iterator aIt( m_aMap.find( rName ));
    if( aIt == m_aMap.end() )
        throw container::NoSuchElementException();
    aIt->second = rElement;
}

// XNameAccess
Any SAL_CALL NameContainer::getByName( const OUString& rName )
    throw( container::NoSuchElementException,  lang::WrappedTargetException, uno::RuntimeException)
{
    tContentMap::iterator aIter( m_aMap.find( rName ) );
    if( aIter == m_aMap.end() )
        throw container::NoSuchElementException();
    return aIter->second;
}

Sequence< OUString > SAL_CALL NameContainer::getElementNames()
    throw( uno::RuntimeException )
{
    sal_Int32 nCount = m_aMap.size();
    Sequence< OUString > aSeq(nCount);
    sal_Int32 nN = 0;
    for( tContentMap::iterator aIter = m_aMap.begin(); aIter != m_aMap.end(), nN < nCount; aIter++, nN++ )
        aSeq[nN]=aIter->first;
    return aSeq;
}

sal_Bool SAL_CALL NameContainer::hasByName( const OUString& rName )
    throw( uno::RuntimeException )
{
    return ( m_aMap.find( rName ) != m_aMap.end() );
}

// XElementAccess
sal_Bool SAL_CALL NameContainer::hasElements()
    throw( uno::RuntimeException )
{
    return ! m_aMap.empty();
}

uno::Type SAL_CALL NameContainer::getElementType()
    throw( uno::RuntimeException )
{
    return m_aType;
}

// XCloneable
uno::Reference< util::XCloneable > SAL_CALL NameContainer::createClone()
    throw ( uno::RuntimeException )
{
    return uno::Reference< util::XCloneable >( new NameContainer( *this ));
}

//.............................................................................
} //namespace chart
//.............................................................................
<commit_msg>INTEGRATION: CWS changefileheader (1.3.94); FILE MERGED 2008/04/01 15:04:23 thb 1.3.94.2: #i85898# Stripping all external header guards 2008/03/28 16:44:23 rt 1.3.94.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: NameContainer.cxx,v $
 * $Revision: 1.4 $
 *
 * 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_chart2.hxx"

#include "NameContainer.hxx"

/*
//SvXMLUnitConverter
#include <xmloff/xmluconv.hxx>
*/
#include <com/sun/star/uno/Any.hxx>

using namespace ::com::sun::star;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Any;
using ::rtl::OUString;

//.............................................................................
namespace chart
{
//.............................................................................

NameContainer::NameContainer( const ::com::sun::star::uno::Type& rType, const OUString& rServicename, const OUString& rImplementationName )
    : m_aType( rType )
    , m_aServicename( rServicename )
    , m_aImplementationName( rImplementationName )
    , m_aMap()
{
}

NameContainer::NameContainer(
    const NameContainer & rOther )
    : impl::NameContainer_Base()
    , m_aType( rOther.m_aType )
    , m_aServicename( rOther.m_aServicename )
    , m_aImplementationName( rOther.m_aImplementationName )
    , m_aMap( rOther.m_aMap )
{
}

NameContainer::~NameContainer()
{
}

//XServiceInfo
OUString SAL_CALL NameContainer::getImplementationName()
    throw( ::com::sun::star::uno::RuntimeException )
{
    return m_aImplementationName;
}

sal_Bool SAL_CALL NameContainer::supportsService( const OUString& ServiceName )
    throw( ::com::sun::star::uno::RuntimeException )
{
    Sequence< OUString > aSNL = getSupportedServiceNames();
    const OUString* pArray = aSNL.getArray();
    for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
    {
        if( pArray[ i ] == ServiceName )
            return sal_True;
    }
    return sal_False;
}

Sequence< OUString > SAL_CALL NameContainer::getSupportedServiceNames()
    throw( ::com::sun::star::uno::RuntimeException )
{
    Sequence< OUString > aSNS( 1 );
    aSNS.getArray()[ 0 ] = m_aServicename;
    return aSNS;
}

//-----------------------------------------------------------------
//-----------------------------------------------------------------
//-----------------------------------------------------------------

// XNameContainer
void SAL_CALL NameContainer::insertByName( const OUString& rName, const Any& rElement )
    throw( lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException )
{
    if( m_aMap.find( rName ) != m_aMap.end() )
        throw container::ElementExistException();
    m_aMap.insert( tContentMap::value_type( rName, rElement ));
}

void SAL_CALL NameContainer::removeByName( const OUString& Name )
    throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
{
    tContentMap::iterator aIt( m_aMap.find( Name ));
    if( aIt == m_aMap.end())
        throw container::NoSuchElementException();
    m_aMap.erase( aIt );
}

// XNameReplace
void SAL_CALL NameContainer::replaceByName( const OUString& rName, const Any& rElement )
    throw( lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
{
    tContentMap::iterator aIt( m_aMap.find( rName ));
    if( aIt == m_aMap.end() )
        throw container::NoSuchElementException();
    aIt->second = rElement;
}

// XNameAccess
Any SAL_CALL NameContainer::getByName( const OUString& rName )
    throw( container::NoSuchElementException,  lang::WrappedTargetException, uno::RuntimeException)
{
    tContentMap::iterator aIter( m_aMap.find( rName ) );
    if( aIter == m_aMap.end() )
        throw container::NoSuchElementException();
    return aIter->second;
}

Sequence< OUString > SAL_CALL NameContainer::getElementNames()
    throw( uno::RuntimeException )
{
    sal_Int32 nCount = m_aMap.size();
    Sequence< OUString > aSeq(nCount);
    sal_Int32 nN = 0;
    for( tContentMap::iterator aIter = m_aMap.begin(); aIter != m_aMap.end(), nN < nCount; aIter++, nN++ )
        aSeq[nN]=aIter->first;
    return aSeq;
}

sal_Bool SAL_CALL NameContainer::hasByName( const OUString& rName )
    throw( uno::RuntimeException )
{
    return ( m_aMap.find( rName ) != m_aMap.end() );
}

// XElementAccess
sal_Bool SAL_CALL NameContainer::hasElements()
    throw( uno::RuntimeException )
{
    return ! m_aMap.empty();
}

uno::Type SAL_CALL NameContainer::getElementType()
    throw( uno::RuntimeException )
{
    return m_aType;
}

// XCloneable
uno::Reference< util::XCloneable > SAL_CALL NameContainer::createClone()
    throw ( uno::RuntimeException )
{
    return uno::Reference< util::XCloneable >( new NameContainer( *this ));
}

//.............................................................................
} //namespace chart
//.............................................................................
<|endoftext|>


<commit_before>#include <Poco/AutoPtr.h>

#include <gtest/gtest.h>
#include <exception>
#include <iostream>
#include <string>
#include <strstream>

#include "db.h"

#ifdef ENABLE_SQLITE3

extern "C" {
    extern DB::Connection *create_sqlite3_connection(void);
};

class SqliteInvalidTest : public ::testing::Test {
    protected:
        virtual void SetUp() {
            connection = create_sqlite3_connection();
            connection->open(".", NULL, 0, NULL, NULL);
        }

        virtual void TearDown() {
            connection->release();
        }

        Poco::AutoPtr <DB::Connection> connection;
};

TEST_F(SqliteInvalidTest, CannotConnectToDatabase) {
    ASSERT_EQ(connection->isConnected(), false);
}

class SqliteDefaultTest : public ::testing::Test {
    protected:
        virtual void SetUp() {
            connection = create_sqlite3_connection();
            connection->open("test.db", NULL, 0, NULL, NULL);
        }

        virtual void TearDown() {
            connection->release();
        }

        Poco::AutoPtr <DB::Connection> connection;
};

TEST_F(SqliteDefaultTest, CanConnectToDatabase) {
    EXPECT_EQ(connection->isConnected(), true);
}

TEST_F(SqliteDefaultTest, CanExecuteSimpleQuery) {
    EXPECT_EQ(connection->execute("CREATE TABLE testing (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, text VARCHAR(128), num INTEGER, fl FLOAT, createdOn TIMESTAMP, updatedOn TIMESTAMP)"), true);
    EXPECT_EQ(connection->execute("DROP TABLE testing"), true);
}

TEST_F(SqliteDefaultTest, CannotExecuteSimpleQuery) {
    EXPECT_EQ(connection->execute("BYE"), false);
}

TEST_F(SqliteDefaultTest, EscapeCharacters) {
    EXPECT_STREQ(connection->escape("be'nden"), "'be''nden'");
}

TEST_F(SqliteDefaultTest, UnixTimeToSQL) {
    const char *t = connection->unixtimeToSql((time_t) 1414965631);
    EXPECT_STREQ(t, "'2014-11-02 22:00:31'");
}

TEST_F(SqliteDefaultTest, ErrorNumberAndMessage) {
    EXPECT_EQ(connection->errorno(), 0);
    EXPECT_STREQ(connection->errormsg(), "not an error");
}

TEST_F(SqliteDefaultTest, VersionString) {
    const char *v = connection->version();
    bool correct = false;
    if (strstr(v, "Sqlite3 Driver v0.2")) {
        correct = true;
    }
    EXPECT_EQ(correct, true);
}

class SqliteTransactionTest : public ::testing::Test {
    protected:
        virtual void SetUp() {
            connection = create_sqlite3_connection();
            connection->open("test.db", NULL, 0, NULL, NULL);
            EXPECT_EQ(connection->execute("CREATE TABLE testing (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, text VARCHAR(128), num INTEGER, fl FLOAT, createdOn TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updatedOn TIMESTAMP)"), true);
            connection->beginTrans();
        }

        virtual void TearDown() {
            connection->commitTrans();
            connection->execute("DROP TABLE testing");
            connection->close();
            connection->release();
        }

        Poco::AutoPtr <DB::Connection> connection;
};

TEST_F(SqliteTransactionTest, SingleInsert) {
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',42)"), true);
}

TEST_F(SqliteTransactionTest, SingleSelect) {
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',42)"), true);
    EXPECT_EQ(connection->commitTrans(), true);
    EXPECT_EQ(connection->beginTrans(), true);

    DB::Query q(*connection);
    q << "SELECT * FROM testing";
    DB::ResultSet *rs = connection->executeQuery(q.str());
    EXPECT_NE(rs, (DB::ResultSet *) NULL);
    if (rs) {
    rs->next();
    EXPECT_EQ(rs->findColumn("text"), 1);
    EXPECT_STREQ(rs->getString(1), "benden");
    EXPECT_EQ(rs->findColumn("fl"), 3);
    EXPECT_EQ(rs->findColumn("r"), 6);
    EXPECT_EQ(rs->getInteger(3), 42);
    EXPECT_EQ(rs->getFloat(3), 42.0f);
    EXPECT_EQ(rs->getDouble(3), 42.0F);
    EXPECT_EQ(rs->getLong(3), 42l);
    EXPECT_EQ(rs->getBool(3), false);
    EXPECT_EQ(rs->getShort(3), (short) 42);
    EXPECT_NE(rs->getUnixTime(4), -1);
    EXPECT_EQ(rs->getUnixTime(5), 0);
    EXPECT_EQ(rs->recordCount(), 0);
    rs->close();
    }
}

TEST_F(SqliteTransactionTest, DoubleSelect) {
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',1)"), true);
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',1)"), true);
    EXPECT_EQ(connection->commitTrans(), true);

    DB::Query q(*connection);
    q << "SELECT * FROM testing;";
    DB::ResultSet *rs = connection->executeQuery(q.str());
    EXPECT_NE(rs, (DB::ResultSet *) NULL);
    if (rs) {
    rs->next();
    EXPECT_EQ(rs->findColumn("text"), 1);
    EXPECT_STREQ(rs->getString(1), "benden");
    EXPECT_EQ(rs->findColumn("fl"), 3);
    EXPECT_EQ(rs->findColumn("r"), 6);
    EXPECT_EQ(rs->getInteger(3), 1);
    EXPECT_EQ(rs->getFloat(3), 1.0f);
    EXPECT_EQ(rs->getDouble(3), 1.0F);
    EXPECT_EQ(rs->getLong(3), 1l);
    EXPECT_EQ(rs->getBool(3), true);
    EXPECT_EQ(rs->getShort(3), (short) 1);
    EXPECT_NE(rs->getUnixTime(4), -1);
    EXPECT_EQ(rs->getUnixTime(5), 0);
    rs->close();
    }
}

TEST_F(SqliteTransactionTest, QueryString) {
    connection->setTransactionMode(DB::Connection::READ_UNCOMMITTED);
    connection->setTransactionMode(DB::Connection::READ_COMMITTED);
    connection->setTransactionMode(DB::Connection::REPEATABLE_READ);
    connection->setTransactionMode(DB::Connection::SERIALIZABLE);

    DB::Query q(*connection);
    q << "INSERT INTO testing (text,fl) VALUES (" << DB::qstr("benden");
    q << "," << 42.0f << ");";
    EXPECT_EQ(connection->execute(q.str()), true);
    unsigned long id = connection->insertId();
    EXPECT_EQ(id, 1);
    EXPECT_EQ(connection->commitTrans(), true);
}

TEST_F(SqliteTransactionTest, RollbackTransaction) {
    EXPECT_EQ(connection->execute("INSERT INTO testing (text) VALUES ('benden');"), true);
    EXPECT_EQ(connection->rollbackTrans(), true);
}

TEST_F(SqliteTransactionTest, QueryStringTypes) {
    DB::Query q(*connection);

    q << "INSERT INTO test (text,fl,updatedOn) VALUES (";
    q << DB::qstr("benden") << "," << 42l << "," << DB::unixtime(time(NULL)) << ");";
    EXPECT_EQ(strlen(q.str()), 80);
}

TEST_F(SqliteTransactionTest, QueryStringTypes2) {
    DB::Query q(*connection);
    std::stringstream world;
    world << " World" << std::ends;

    q << std::string("Hello") << world;

    EXPECT_EQ(strlen(q.str()), 11);
}

TEST_F(SqliteTransactionTest, QueryNumberTypes) {
    DB::Query q(*connection);
    double d = 42.2;
    short s = 42;
    unsigned short su = 42;

    q << 42 << " " << d << " " << s << (const unsigned char *) " ";
    q << 42u << " " << 42ul << " " << su;
}

#endif

<commit_msg>Fixed schema for older sqlite3.<commit_after>#include <Poco/AutoPtr.h>

#include <gtest/gtest.h>
#include <exception>
#include <iostream>
#include <string>
#include <strstream>

#include "db.h"

#ifdef ENABLE_SQLITE3

extern "C" {
    extern DB::Connection *create_sqlite3_connection(void);
};

class SqliteInvalidTest : public ::testing::Test {
    protected:
        virtual void SetUp() {
            connection = create_sqlite3_connection();
            connection->open(".", NULL, 0, NULL, NULL);
        }

        virtual void TearDown() {
            connection->release();
        }

        Poco::AutoPtr <DB::Connection> connection;
};

TEST_F(SqliteInvalidTest, CannotConnectToDatabase) {
    ASSERT_EQ(connection->isConnected(), false);
}

class SqliteDefaultTest : public ::testing::Test {
    protected:
        virtual void SetUp() {
            connection = create_sqlite3_connection();
            connection->open("test.db", NULL, 0, NULL, NULL);
        }

        virtual void TearDown() {
            connection->release();
        }

        Poco::AutoPtr <DB::Connection> connection;
};

TEST_F(SqliteDefaultTest, CanConnectToDatabase) {
    EXPECT_EQ(connection->isConnected(), true);
}

TEST_F(SqliteDefaultTest, CanExecuteSimpleQuery) {
    EXPECT_EQ(connection->execute("CREATE TABLE testing (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, text VARCHAR(128), num INTEGER, fl FLOAT, createdOn TIMESTAMP, updatedOn TIMESTAMP)"), true);
    EXPECT_EQ(connection->execute("DROP TABLE testing"), true);
}

TEST_F(SqliteDefaultTest, CannotExecuteSimpleQuery) {
    EXPECT_EQ(connection->execute("BYE"), false);
}

TEST_F(SqliteDefaultTest, EscapeCharacters) {
    EXPECT_STREQ(connection->escape("be'nden"), "'be''nden'");
}

TEST_F(SqliteDefaultTest, UnixTimeToSQL) {
    const char *t = connection->unixtimeToSql((time_t) 1414965631);
    EXPECT_STREQ(t, "'2014-11-02 22:00:31'");
}

TEST_F(SqliteDefaultTest, ErrorNumberAndMessage) {
    EXPECT_EQ(connection->errorno(), 0);
    EXPECT_STREQ(connection->errormsg(), "not an error");
}

TEST_F(SqliteDefaultTest, VersionString) {
    const char *v = connection->version();
    bool correct = false;
    if (strstr(v, "Sqlite3 Driver v0.2")) {
        correct = true;
    }
    EXPECT_EQ(correct, true);
}

class SqliteTransactionTest : public ::testing::Test {
    protected:
        virtual void SetUp() {
            connection = create_sqlite3_connection();
            connection->open("test.db", NULL, 0, NULL, NULL);
            EXPECT_EQ(connection->execute("CREATE TABLE testing (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, text VARCHAR(128), num INTEGER, fl FLOAT, createdOn TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updatedOn TIMESTAMP)"), true);
            connection->beginTrans();
        }

        virtual void TearDown() {
            connection->commitTrans();
            connection->execute("DROP TABLE testing");
            connection->close();
            connection->release();
        }

        Poco::AutoPtr <DB::Connection> connection;
};

TEST_F(SqliteTransactionTest, SingleInsert) {
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',42)"), true);
}

TEST_F(SqliteTransactionTest, SingleSelect) {
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',42)"), true);
    //EXPECT_EQ(connection->commitTrans(), true);

    DB::Query q(*connection);
    q << "SELECT * FROM testing;";
    DB::ResultSet *rs = connection->executeQuery(q.str());
    EXPECT_NE(rs, (DB::ResultSet *) NULL);
    if (rs) {
    rs->next();
    EXPECT_EQ(rs->findColumn("text"), 1);
    EXPECT_STREQ(rs->getString(1), "benden");
    EXPECT_EQ(rs->findColumn("fl"), 3);
    EXPECT_EQ(rs->findColumn("r"), 6);
    EXPECT_EQ(rs->getInteger(3), 42);
    EXPECT_EQ(rs->getFloat(3), 42.0f);
    EXPECT_EQ(rs->getDouble(3), 42.0F);
    EXPECT_EQ(rs->getLong(3), 42l);
    EXPECT_EQ(rs->getBool(3), false);
    EXPECT_EQ(rs->getShort(3), (short) 42);
    EXPECT_NE(rs->getUnixTime(4), -1);
    EXPECT_EQ(rs->getUnixTime(5), 0);
    EXPECT_EQ(rs->recordCount(), 0);
    rs->close();
    }
}

TEST_F(SqliteTransactionTest, DoubleSelect) {
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',1)"), true);
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',1)"), true);
    EXPECT_EQ(connection->commitTrans(), true);

    DB::Query q(*connection);
    q << "SELECT * FROM testing;";
    DB::ResultSet *rs = connection->executeQuery(q.str());
    EXPECT_NE(rs, (DB::ResultSet *) NULL);
    if (rs) {
    rs->next();
    EXPECT_EQ(rs->findColumn("text"), 1);
    EXPECT_STREQ(rs->getString(1), "benden");
    EXPECT_EQ(rs->findColumn("fl"), 3);
    EXPECT_EQ(rs->findColumn("r"), 6);
    EXPECT_EQ(rs->getInteger(3), 1);
    EXPECT_EQ(rs->getFloat(3), 1.0f);
    EXPECT_EQ(rs->getDouble(3), 1.0F);
    EXPECT_EQ(rs->getLong(3), 1l);
    EXPECT_EQ(rs->getBool(3), true);
    EXPECT_EQ(rs->getShort(3), (short) 1);
    EXPECT_NE(rs->getUnixTime(4), -1);
    EXPECT_EQ(rs->getUnixTime(5), 0);
    rs->close();
    }
}

TEST_F(SqliteTransactionTest, QueryString) {
    connection->setTransactionMode(DB::Connection::READ_UNCOMMITTED);
    connection->setTransactionMode(DB::Connection::READ_COMMITTED);
    connection->setTransactionMode(DB::Connection::REPEATABLE_READ);
    connection->setTransactionMode(DB::Connection::SERIALIZABLE);

    DB::Query q(*connection);
    q << "INSERT INTO testing (text,fl) VALUES (" << DB::qstr("benden");
    q << "," << 42.0f << ");";
    EXPECT_EQ(connection->execute(q.str()), true);
    unsigned long id = connection->insertId();
    EXPECT_EQ(id, 1);
    EXPECT_EQ(connection->commitTrans(), true);
}

TEST_F(SqliteTransactionTest, RollbackTransaction) {
    EXPECT_EQ(connection->execute("INSERT INTO testing (text) VALUES ('benden');"), true);
    EXPECT_EQ(connection->rollbackTrans(), true);
}

TEST_F(SqliteTransactionTest, QueryStringTypes) {
    DB::Query q(*connection);

    q << "INSERT INTO test (text,fl,updatedOn) VALUES (";
    q << DB::qstr("benden") << "," << 42l << "," << DB::unixtime(time(NULL)) << ");";
    EXPECT_EQ(strlen(q.str()), 80);
}

TEST_F(SqliteTransactionTest, QueryStringTypes2) {
    DB::Query q(*connection);
    std::stringstream world;
    world << " World" << std::ends;

    q << std::string("Hello") << world;

    EXPECT_EQ(strlen(q.str()), 11);
}

TEST_F(SqliteTransactionTest, QueryNumberTypes) {
    DB::Query q(*connection);
    double d = 42.2;
    short s = 42;
    unsigned short su = 42;

    q << 42 << " " << d << " " << s << (const unsigned char *) " ";
    q << 42u << " " << 42ul << " " << su;
}

#endif

<|endoftext|>


<commit_before>/// This file is part of the KDE libraries
/// Copyright (C) 2008 Paul Giannaros <paul@giannaros.org>
/// Copyright (C) 2008 Christoph Cullmann <cullmann@kde.org>
///
/// This library is free software; you can redistribute it and/or
/// modify it under the terms of the GNU Library General Public
/// License as published by the Free Software Foundation; either
/// version 2 of the License, or (at your option) version 3.
///
/// This library is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
/// Library General Public License for more details.
///
/// You should have received a copy of the GNU Library General Public License
/// along with this library; see the file COPYING.LIB.  If not, write to
/// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
/// Boston, MA 02110-1301, USA.

#include "katescriptview.h"

#include "katedocument.h"
#include "kateview.h"
#include "katerenderer.h"
#include "katehighlight.h"
#include "katescript.h"

KateScriptView::KateScriptView(QObject *parent)
  : QObject(parent), m_view(0)
{
}

void KateScriptView::setView (KateView *view)
{
  m_view = view;
}

KateView *KateScriptView::view()
{
  return m_view;
}

KTextEditor::Cursor KateScriptView::cursorPosition ()
{
  return m_view->cursorPosition();
}

void KateScriptView::setCursorPosition(int line, int column)
{
  KTextEditor::Cursor c(line, column);
  m_view->setCursorPosition(c);
}

void KateScriptView::setCursorPosition (const KTextEditor::Cursor& cursor)
{
  m_view->setCursorPosition(cursor);
}

KTextEditor::Cursor KateScriptView::virtualCursorPosition()
{
  return m_view->cursorPositionVirtual();
}

void KateScriptView::setVirtualCursorPosition(int line, int column)
{
  setVirtualCursorPosition(KTextEditor::Cursor(line, column));
}

void KateScriptView::setVirtualCursorPosition(const KTextEditor::Cursor& cursor)
{
  m_view->setCursorPositionVisual(cursor);
}

QString KateScriptView::selectedText()
{
  return m_view->selectionText();
}

bool KateScriptView::hasSelection()
{
  return m_view->selection();
}

KTextEditor::Range KateScriptView::selection()
{
  return m_view->selectionRange();
}

void KateScriptView::setSelection(const KTextEditor::Range& range)
{
  m_view->setSelection(range);
}

void KateScriptView::removeSelectedText()
{
  m_view->removeSelectedText();
}

void KateScriptView::selectAll()
{
  m_view->selectAll();
}

void KateScriptView::clearSelection()
{
  m_view->clearSelection();
}

// kate: space-indent on; indent-width 2; replace-tabs on;

<commit_msg>cleanup include<commit_after>/// This file is part of the KDE libraries
/// Copyright (C) 2008 Paul Giannaros <paul@giannaros.org>
/// Copyright (C) 2008 Christoph Cullmann <cullmann@kde.org>
///
/// This library is free software; you can redistribute it and/or
/// modify it under the terms of the GNU Library General Public
/// License as published by the Free Software Foundation; either
/// version 2 of the License, or (at your option) version 3.
///
/// This library is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
/// Library General Public License for more details.
///
/// You should have received a copy of the GNU Library General Public License
/// along with this library; see the file COPYING.LIB.  If not, write to
/// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
/// Boston, MA 02110-1301, USA.

#include "katescriptview.h"

#include "katedocument.h"
#include "kateview.h"
#include "katerenderer.h"
#include "katescript.h"

KateScriptView::KateScriptView(QObject *parent)
  : QObject(parent), m_view(0)
{
}

void KateScriptView::setView (KateView *view)
{
  m_view = view;
}

KateView *KateScriptView::view()
{
  return m_view;
}

KTextEditor::Cursor KateScriptView::cursorPosition ()
{
  return m_view->cursorPosition();
}

void KateScriptView::setCursorPosition(int line, int column)
{
  KTextEditor::Cursor c(line, column);
  m_view->setCursorPosition(c);
}

void KateScriptView::setCursorPosition (const KTextEditor::Cursor& cursor)
{
  m_view->setCursorPosition(cursor);
}

KTextEditor::Cursor KateScriptView::virtualCursorPosition()
{
  return m_view->cursorPositionVirtual();
}

void KateScriptView::setVirtualCursorPosition(int line, int column)
{
  setVirtualCursorPosition(KTextEditor::Cursor(line, column));
}

void KateScriptView::setVirtualCursorPosition(const KTextEditor::Cursor& cursor)
{
  m_view->setCursorPositionVisual(cursor);
}

QString KateScriptView::selectedText()
{
  return m_view->selectionText();
}

bool KateScriptView::hasSelection()
{
  return m_view->selection();
}

KTextEditor::Range KateScriptView::selection()
{
  return m_view->selectionRange();
}

void KateScriptView::setSelection(const KTextEditor::Range& range)
{
  m_view->setSelection(range);
}

void KateScriptView::removeSelectedText()
{
  m_view->removeSelectedText();
}

void KateScriptView::selectAll()
{
  m_view->selectAll();
}

void KateScriptView::clearSelection()
{
  m_view->clearSelection();
}

// kate: space-indent on; indent-width 2; replace-tabs on;

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: salgdiutils.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: hr $ $Date: 2007-08-03 14:02:31 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#ifndef _SV_SALGDI_H
#include <salgdi.h>
#endif

#include <basebmp/scanlineformats.hxx>
#include <basebmp/color.hxx>
#include <basegfx/range/b2drectangle.hxx>
#include <basegfx/range/b2irange.hxx>
#include <basegfx/vector/b2ivector.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <boost/bind.hpp>

#include <vcl/svapp.hxx>

#include "saldata.hxx"

// ----------------------------------------------------------------------

void AquaSalGraphics::SetWindowGraphics( CarbonViewRef rView, CarbonWindowRef rWindow, bool bScreenCompatible )
{
    mrView      = rView;
    mrWindow    = rWindow;
    mbScreen    = bScreenCompatible;

    mbWindow    = true;
    mbPrinter   = false;
    mbVirDev    = false;
}

void AquaSalGraphics::SetPrinterGraphics( CGContextRef xContext, long nDPIX, long nDPIY )
{
    mrView      = 0;
    mbScreen    = false;

    mbWindow    = false;
    mbPrinter   = true;
    mbVirDev    = false;

    mrContext   = xContext;
    mnDPIX      = nDPIX;
    mnDPIY      = nDPIY;

    if( mrContext )
    {
        CGContextSetFillColorSpace( mrContext, GetSalData()->mxRGBSpace );
        CGContextSetStrokeColorSpace( mrContext, GetSalData()->mxRGBSpace );
        CGContextSaveGState( mrContext );
        SetState();
    }
}

static void nil_free( void* )
{
}

void AquaSalGraphics::SetVirDevGraphics( CGContextRef xContext, bool bScreenCompatible )
{
    mrView      = 0;
    mbScreen    = bScreenCompatible;

    mbWindow    = false;
    mbPrinter   = false;
    mbVirDev    = true;

    mrContext   = xContext;
    sal_uInt8* pMemory = NULL;
    if( mrContext )
    {
        pMemory = reinterpret_cast<sal_uInt8*>(CGBitmapContextGetData( mrContext ));
        CGContextSetFillColorSpace( mrContext, GetSalData()->mxRGBSpace );
        CGContextSetStrokeColorSpace( mrContext, GetSalData()->mxRGBSpace );
        CGContextSaveGState( mrContext );
        SetState();
    }
    maContextMemory.reset( pMemory, boost::bind( nil_free, _1 ) );
}

// ----------------------------------------------------------------------

void AquaSalGraphics::SetState()
{
    CGContextRestoreGState( mrContext );
    CGContextSaveGState( mrContext );
    // set up clipping area
    if( mrClippingPath )
    {
        CGContextBeginPath( mrContext );                // discard any existing path
        CGContextAddPath( mrContext, mrClippingPath );  // set the current path to the clipping path
        CGContextClip( mrContext );                     // use it for clipping
    }

    // set RGB colorspace and line and fill colors
    CGContextSetFillColor( mrContext, mpFillColor );
    CGContextSetStrokeColor( mrContext, mpLineColor );
    if( mbXORMode && (mbWindow || mbVirDev) )
    {
        CGContextSetBlendMode(mrContext, kCGBlendModeDifference);
        int nWidth  = CGBitmapContextGetWidth(mrContext);
        int nHeight = CGBitmapContextGetHeight(mrContext);
        if( ! maXORDevice )
        {
            maXORDevice = basebmp::createBitmapDevice( basegfx::B2IVector( nWidth, nHeight ),
                                                       mbWindow,
                                                       basebmp::Format::THIRTYTWO_BIT_TC_MASK_ARGB,
                                                       maContextMemory,
                                                       basebmp::PaletteMemorySharedVector() );
            if( mrClippingPath && maClippingRects.size() == 1 )
            {
                /*
                * optimization: the case with only one clip rectangle is quite common
                * in this case it is much cheaper to constrain the XOR device to a smaller
                * area than to clip every pixel with the mask
                */
                maXORClipMask.reset();
                CGRect aBounds( maClippingRects.front() );
                basegfx::B2IRange aRect( aBounds.origin.x, aBounds.origin.y,
                                         aBounds.origin.x+aBounds.size.width,
                                         aBounds.origin.y+aBounds.size.height );
                maXORDevice = basebmp::subsetBitmapDevice( maXORDevice, aRect );
            }
        }
        if( mrClippingPath )
        {
            if( ! maXORClipMask && maClippingRects.size() > 1 )
            {
                maXORClipMask = basebmp::createBitmapDevice( basegfx::B2IVector( nWidth, nHeight ),
                                                             mbWindow,
                                                             basebmp::Format::ONE_BIT_MSB_GREY );
                maXORClipMask->clear( basebmp::Color(0xffffffff) );
                for( std::vector<CGRect>::const_iterator it = maClippingRects.begin(); it != maClippingRects.end(); ++it )
                {
                    basegfx::B2DRectangle aRect( it->origin.x, it->origin.y,
                                                 it->origin.x+it->size.width,
                                                 it->origin.y+it->size.height );
                    maXORClipMask->fillPolyPolygon( basegfx::B2DPolyPolygon( basegfx::tools::createPolygonFromRect( aRect ) ),
                                                    basebmp::Color( 0 ),
                                                    basebmp::DrawMode_PAINT
                                                    );
                }
            }
        }
        else
            maXORClipMask.reset();
    }

    CGContextSetShouldAntialias( mrContext, false );

}

// ----------------------------------------------------------------------

bool AquaSalGraphics::CheckContext()
{
    if( mrWindow != NULL )
    {
        Rect windowBounds;
        GetWindowPortBounds( mrWindow, &windowBounds );
        const unsigned int nWidth = windowBounds.right - windowBounds.left;
        const unsigned int nHeight = windowBounds.bottom - windowBounds.top;

        CGContextRef rReleaseContext = 0;
        unsigned int nReleaseContextWidth = 0;
        unsigned int nReleaseContextHeight = 0;

        boost::shared_array<sal_uInt8> aOldMem;
        if( mrContext )
        {
            nReleaseContextWidth = CGBitmapContextGetWidth(mrContext);
            nReleaseContextHeight = CGBitmapContextGetHeight(mrContext);
            // check if window size changed and we need to create a new bitmap context
            if( (nReleaseContextWidth != nWidth)  || (nReleaseContextHeight != nHeight) )
            {
                rReleaseContext = mrContext;
                mrContext = 0;
                aOldMem = maContextMemory;
                maXORDevice.reset();
                maXORClipMask.reset();
            }
        }

        if( !mrContext )
        {
            maContextMemory.reset( reinterpret_cast<sal_uInt8*>( rtl_allocateMemory( nWidth * 4 * nHeight ) ),
                                   boost::bind( rtl_freeMemory, _1 ) );
            if( maContextMemory )
            {
                mrContext = CGBitmapContextCreate( maContextMemory.get(), nWidth, nHeight, 8, nWidth * 4, GetSalData()->mxRGBSpace, kCGImageAlphaNoneSkipFirst );

                if( mrContext )
                {
                    // copy bitmap data to new context
                    if( rReleaseContext )
                    {
                        CGRect aBounds;
                        aBounds.origin.x = aBounds.origin.y = 0;
                        aBounds.size.width = nReleaseContextWidth;
                        aBounds.size.height = nReleaseContextHeight;
                        CGImageRef xImage = CGBitmapContextCreateImage( rReleaseContext );
                        CGContextDrawImage( mrContext, aBounds, xImage );
                        CGImageRelease(xImage);
                    }

                    CGContextTranslateCTM( mrContext, 0, nHeight );
                    CGContextScaleCTM( mrContext, 1.0, -1.0 );
                    CGContextSetFillColorSpace( mrContext, GetSalData()->mxRGBSpace );
                    CGContextSetStrokeColorSpace( mrContext, GetSalData()->mxRGBSpace );
                    CGContextSaveGState( mrContext );
                    SetState();
                }
                else
                {
                    maContextMemory.reset(); // free memory again
                }
            }
        }

        if( rReleaseContext ) // released memory runs out of scope and is then freed
            CFRelease( rReleaseContext );
    }
    if( mrContext )
    {
        if( mbXORMode )
        {
            if( ! maXORDevice )
                SetState();
        }
        return true;
    }
    else
    {
        AquaLog("<<<WARNING>>> AquaSalGraphics::CheckContext() FAILED!!!!\n" );
        return false;
    }
}

void AquaSalGraphics::RefreshRect(float lX, float lY, float lWidth, float lHeight)
{
    if( ! mbWindow ) // view only on Window graphics
        return;

    AquaLog("-->%s refresh %d - %d - %d - %d\n", __func__, static_cast<int>(lX), static_cast<int>(lY), static_cast<int>(lWidth), static_cast<int>(lHeight));

    // Refresh windows rect content
    HIRect aHIRect;
    aHIRect.origin.x = static_cast<int>(lX);
    aHIRect.origin.y = static_cast<int>(lY);
    aHIRect.size.width = static_cast<int>(lWidth);
    aHIRect.size.height = static_cast<int>(lHeight);
    OSStatus retVal = HIViewSetNeedsDisplayInRect(mrView,&aHIRect,true);
    if (retVal)
        AquaLog( "FIXME: HIViewSetNeedsDisplayInRect returned %d (mrView is %p)\n", (int) retVal, mrView);

    Rect aRect;
    aRect.left   = (short)lX;
    aRect.top    = (short)lY;
    aRect.right  = (short)(lX + lWidth );
    aRect.bottom = (short)(lY + lHeight );
    InvalWindowRect(mrWindow, &aRect);
}

void AquaSalGraphics::Flush()
{
    if( mbWindow )
    {
        UpdateWindow();
    }
}

CGPoint* AquaSalGraphics::makeCGptArray(ULONG nPoints, const SalPoint*  pPtAry)
{
    AquaLog("-->%s\n",__func__);
    CGPoint *CGpoints = new (CGPoint[nPoints]);
    if ( CGpoints )
      {
        for(ULONG i=0;i<nPoints;i++)
          {
            CGpoints[i].x = (float)(pPtAry[i].mnX);
            CGpoints[i].y = (float)(pPtAry[i].mnY);
          }
      }
    return CGpoints;
}

// -----------------------------------------------------------------------

void AquaSalGraphics::UpdateWindow()
{
    if( mrContext != NULL && mrWindow != NULL )
    {
        SetPortWindowPort(mrWindow);
        CGContextRef xWindowContext = 0;
        if( noErr == QDBeginCGContext (GetWindowPort (mrWindow), &xWindowContext))
        {
            Rect windowBounds;
            GetWindowPortBounds( mrWindow, &windowBounds);
            CGImageRef xImage = CGBitmapContextCreateImage( mrContext );
            CGContextDrawImage(xWindowContext, CGRectMake(windowBounds.left, windowBounds.top, windowBounds.right - windowBounds.left, windowBounds.bottom - windowBounds.top ), xImage);
            CGImageRelease(xImage);
            CGContextFlush( xWindowContext );
            QDEndCGContext (GetWindowPort(mrWindow), &xWindowContext);
        }
    }
}

// -----------------------------------------------------------------------

<commit_msg>INTEGRATION: CWS aquavcl03 (1.10.4); FILE MERGED 2007/09/14 15:44:39 pl 1.10.4.4: header cleanup 2007/08/13 11:42:03 hdu 1.10.4.3: Aqua: reintroduce device-resolution 2007/08/07 10:32:49 pl 1.10.4.2: RESYNC: (1.10-1.11); FILE MERGED 2007/07/26 11:02:26 pl 1.10.4.1: #i80025# initial checking for carbon to cocoa migration<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: salgdiutils.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: kz $ $Date: 2007-10-09 15:15:12 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#include "salgdi.h"
#include "salframe.h"

#include "basebmp/scanlineformats.hxx"
#include "basebmp/color.hxx"
#include "basegfx/range/b2drectangle.hxx"
#include "basegfx/range/b2irange.hxx"
#include "basegfx/vector/b2ivector.hxx"
#include "basegfx/polygon/b2dpolygon.hxx"
#include "basegfx/polygon/b2dpolygontools.hxx"
#include <boost/bind.hpp>

#include "vcl/svapp.hxx"
#include "saldata.hxx"

// ----------------------------------------------------------------------

void AquaSalGraphics::SetWindowGraphics( AquaSalFrame* pFrame )
{
    mpFrame     = pFrame;

    mbWindow    = true;
    mbPrinter   = false;
    mbVirDev    = false;
}

void AquaSalGraphics::SetPrinterGraphics( CGContextRef xContext, long nDPIX, long nDPIY, double fScale )
{
    mbWindow    = false;
    mbPrinter   = true;
    mbVirDev    = false;

    mrContext   = xContext;
    mfFakeDPIScale = fScale;
    mnRealDPIX  = nDPIX;
    mnRealDPIY  = nDPIY;

    if( mrContext )
    {
        CGContextSetFillColorSpace( mrContext, GetSalData()->mxRGBSpace );
        CGContextSetStrokeColorSpace( mrContext, GetSalData()->mxRGBSpace );
        CGContextSaveGState( mrContext );
        SetState();
    }
}

static void nil_free( void* )
{
}

void AquaSalGraphics::SetVirDevGraphics( CGContextRef xContext, bool bScreenCompatible )
{
    mbWindow    = false;
    mbPrinter   = false;
    mbVirDev    = true;

    mrContext   = xContext;
    sal_uInt8* pMemory = NULL;
    if( mrContext )
    {
        pMemory = reinterpret_cast<sal_uInt8*>(CGBitmapContextGetData( mrContext ));
        CGContextSetFillColorSpace( mrContext, GetSalData()->mxRGBSpace );
        CGContextSetStrokeColorSpace( mrContext, GetSalData()->mxRGBSpace );
        CGContextSaveGState( mrContext );
        SetState();
    }
    maContextMemory.reset( pMemory, boost::bind( nil_free, _1 ) );
}

// ----------------------------------------------------------------------

void AquaSalGraphics::SetState()
{
    CGContextRestoreGState( mrContext );
    CGContextSaveGState( mrContext );
    // set up clipping area
    if( mrClippingPath )
    {
        CGContextBeginPath( mrContext );                // discard any existing path
        CGContextAddPath( mrContext, mrClippingPath );  // set the current path to the clipping path
        CGContextClip( mrContext );                     // use it for clipping
    }

    // set RGB colorspace and line and fill colors
    CGContextSetFillColor( mrContext, mpFillColor );
    CGContextSetStrokeColor( mrContext, mpLineColor );
    if( mbXORMode && (mbWindow || mbVirDev) )
    {
        CGContextSetBlendMode(mrContext, kCGBlendModeDifference);
        int nWidth  = CGBitmapContextGetWidth(mrContext);
        int nHeight = CGBitmapContextGetHeight(mrContext);
        if( ! maXORDevice )
        {
            maXORDevice = basebmp::createBitmapDevice( basegfx::B2IVector( nWidth, nHeight ),
                                                       mbWindow,
                                                       basebmp::Format::THIRTYTWO_BIT_TC_MASK_ARGB,
                                                       maContextMemory,
                                                       basebmp::PaletteMemorySharedVector() );
            if( mrClippingPath && maClippingRects.size() == 1 )
            {
                /*
                * optimization: the case with only one clip rectangle is quite common
                * in this case it is much cheaper to constrain the XOR device to a smaller
                * area than to clip every pixel with the mask
                */
                maXORClipMask.reset();
                CGRect aBounds( maClippingRects.front() );
                basegfx::B2IRange aRect( aBounds.origin.x, aBounds.origin.y,
                                         aBounds.origin.x+aBounds.size.width,
                                         aBounds.origin.y+aBounds.size.height );
                maXORDevice = basebmp::subsetBitmapDevice( maXORDevice, aRect );
            }
        }
        if( mrClippingPath )
        {
            if( ! maXORClipMask && maClippingRects.size() > 1 )
            {
                maXORClipMask = basebmp::createBitmapDevice( basegfx::B2IVector( nWidth, nHeight ),
                                                             mbWindow,
                                                             basebmp::Format::ONE_BIT_MSB_GREY );
                maXORClipMask->clear( basebmp::Color(0xffffffff) );
                for( std::vector<CGRect>::const_iterator it = maClippingRects.begin(); it != maClippingRects.end(); ++it )
                {
                    basegfx::B2DRectangle aRect( it->origin.x, it->origin.y,
                                                 it->origin.x+it->size.width,
                                                 it->origin.y+it->size.height );
                    maXORClipMask->fillPolyPolygon( basegfx::B2DPolyPolygon( basegfx::tools::createPolygonFromRect( aRect ) ),
                                                    basebmp::Color( 0 ),
                                                    basebmp::DrawMode_PAINT
                                                    );
                }
            }
        }
        else
            maXORClipMask.reset();
    }

    CGContextSetShouldAntialias( mrContext, false );
}

// ----------------------------------------------------------------------

bool AquaSalGraphics::CheckContext()
{
    if( mpFrame != NULL )
    {
        const unsigned int nWidth = mpFrame->maGeometry.nWidth;
        const unsigned int nHeight = mpFrame->maGeometry.nHeight;

        CGContextRef rReleaseContext = 0;
        unsigned int nReleaseContextWidth = 0;
        unsigned int nReleaseContextHeight = 0;

        boost::shared_array<sal_uInt8> aOldMem;
        if( mrContext )
        {
            nReleaseContextWidth = CGBitmapContextGetWidth(mrContext);
            nReleaseContextHeight = CGBitmapContextGetHeight(mrContext);
            // check if window size changed and we need to create a new bitmap context
            if( (nReleaseContextWidth != nWidth)  || (nReleaseContextHeight != nHeight) )
            {
                rReleaseContext = mrContext;
                mrContext = 0;
                aOldMem = maContextMemory;
                maXORDevice.reset();
                maXORClipMask.reset();
            }
        }

        if( !mrContext )
        {
            maContextMemory.reset( reinterpret_cast<sal_uInt8*>( rtl_allocateMemory( nWidth * 4 * nHeight ) ),
                                   boost::bind( rtl_freeMemory, _1 ) );
            if( maContextMemory )
            {
                mrContext = CGBitmapContextCreate( maContextMemory.get(), nWidth, nHeight, 8, nWidth * 4, GetSalData()->mxRGBSpace, kCGImageAlphaNoneSkipFirst );

                if( mrContext )
                {
                    // copy bitmap data to new context
                    if( rReleaseContext )
                    {
                        CGRect aBounds;
                        aBounds.origin.x = aBounds.origin.y = 0;
                        aBounds.size.width = nReleaseContextWidth;
                        aBounds.size.height = nReleaseContextHeight;
                        CGImageRef xImage = CGBitmapContextCreateImage( rReleaseContext );
                        CGContextDrawImage( mrContext, aBounds, xImage );
                        CGImageRelease(xImage);
                    }

                    CGContextTranslateCTM( mrContext, 0, nHeight );
                    CGContextScaleCTM( mrContext, 1.0, -1.0 );
                    CGContextSetFillColorSpace( mrContext, GetSalData()->mxRGBSpace );
                    CGContextSetStrokeColorSpace( mrContext, GetSalData()->mxRGBSpace );
                    CGContextSaveGState( mrContext );
                    SetState();
                }
                else
                {
                    maContextMemory.reset(); // free memory again
                }
            }
        }

        if( rReleaseContext ) // released memory runs out of scope and is then freed
            CFRelease( rReleaseContext );
    }
    if( mrContext )
    {
        if( mbXORMode )
        {
            if( ! maXORDevice )
                SetState();
        }
        return true;
    }
    else
    {
        AquaLog("<<<WARNING>>> AquaSalGraphics::CheckContext() FAILED!!!!\n" );
        return false;
    }
}

void AquaSalGraphics::RefreshRect(float lX, float lY, float lWidth, float lHeight)
{
    if( ! mbWindow ) // view only on Window graphics
        return;

    if( mpFrame )
    {
        // update a little more around the designated rectangle
        // this helps with antialiased rendering
        NSRect aRect = { { lX-1, lY-1 }, { lWidth+2, lHeight+2 } };
        mpFrame->VCLToCocoa( aRect, false );
        [mpFrame->getView() setNeedsDisplayInRect: aRect];
    }
}

CGPoint* AquaSalGraphics::makeCGptArray(ULONG nPoints, const SalPoint*  pPtAry)
{
    AquaLog("-->%s\n",__func__);
    CGPoint *CGpoints = new (CGPoint[nPoints]);
    if ( CGpoints )
      {
        for(ULONG i=0;i<nPoints;i++)
          {
            CGpoints[i].x = (float)(pPtAry[i].mnX);
            CGpoints[i].y = (float)(pPtAry[i].mnY);
          }
      }
    return CGpoints;
}

// -----------------------------------------------------------------------

void AquaSalGraphics::UpdateWindow( NSGraphicsContext* pContext )
{
    if( mrContext != NULL && mpFrame != NULL && pContext != nil )
    {
        CGContextRef rCGContext = reinterpret_cast<CGContextRef>([pContext graphicsPort]);
        CGRect aBitmapRect = {
            { 0, 0 },
            { CGBitmapContextGetWidth(mrContext), CGBitmapContextGetHeight(mrContext) }
        };

        CGImageRef xImage = CGBitmapContextCreateImage( mrContext );
        CGContextDrawImage( rCGContext, aBitmapRect, xImage );
        CGImageRelease( xImage );
        CGContextFlush( rCGContext );
    }
}

// -----------------------------------------------------------------------

<|endoftext|>