<commit_before>/**
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under both the Apache 2.0 license (found in the
 *  LICENSE file in the root directory of this source tree) and the GPLv2 (found
 *  in the COPYING file in the root directory of this source tree).
 *  You may select, at your option, one of the above-listed licenses.
 */

#include <map>
#include <string>

#define _WIN32_DCOM

#include <Windows.h>
#include <iomanip>
#include <psapi.h>
#include <stdlib.h>
#include <tlhelp32.h>

#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/trim.hpp>

#include <osquery/core.h>
#include <osquery/filesystem.h>
#include <osquery/logger.h>
#include <osquery/tables.h>

#include "osquery/core/conversions.h"
#include "osquery/core/windows/wmi.h"
#include "osquery/filesystem/fileops.h"

namespace osquery {
int getUidFromSid(PSID sid);
int getGidFromSid(PSID sid);
namespace tables {

const std::map<unsigned long, std::string> kMemoryConstants = {
    {PAGE_EXECUTE, "PAGE_EXECUTE"},
    {PAGE_EXECUTE_READ, "PAGE_EXECUTE_READ"},
    {PAGE_EXECUTE_READWRITE, "PAGE_EXECUTE_READWRITE"},
    {PAGE_EXECUTE_WRITECOPY, "PAGE_EXECUTE_WRITECOPY"},
    {PAGE_NOACCESS, "PAGE_NOACCESS"},
    {PAGE_READONLY, "PAGE_READONLY"},
    {PAGE_READWRITE, "PAGE_READWRITE"},
    {PAGE_WRITECOPY, "PAGE_WRITECOPY"},
    {PAGE_GUARD, "PAGE_GUARD"},
    {PAGE_NOCACHE, "PAGE_NOCACHE"},
    {PAGE_WRITECOMBINE, "PAGE_WRITECOMBINE"},
};

/// Given a pid, enumerates all loaded modules and memory pages for that process
Status genMemoryMap(unsigned long pid, QueryData& results) {
  auto proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
  if (proc == nullptr) {
    Row r;
    r["pid"] = INTEGER(pid);
    r["start"] = INTEGER(-1);
    r["end"] = INTEGER(-1);
    r["permissions"] = "";
    r["offset"] = INTEGER(-1);
    r["device"] = "-1";
    r["inode"] = INTEGER(-1);
    r["path"] = "";
    r["pseudo"] = INTEGER(-1);
    results.push_back(r);
    return Status(1, "Failed to open handle to process " + std::to_string(pid));
  }
  auto modSnap =
      CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid);
  if (modSnap == INVALID_HANDLE_VALUE) {
    CloseHandle(proc);
    return Status(1, "Failed to enumerate modules for " + std::to_string(pid));
  }

  auto formatMemPerms = [](unsigned long perm) {
    std::vector<std::string> perms;
    for (const auto& kv : kMemoryConstants) {
      if (kv.first & perm) {
        perms.push_back(kv.second);
      }
    }
    return osquery::join(perms, " | ");
  };

  MODULEENTRY32 me;
  MEMORY_BASIC_INFORMATION mInfo;
  me.dwSize = sizeof(MODULEENTRY32);
  auto ret = Module32First(modSnap, &me);
  while (ret != FALSE) {
    for (auto p = me.modBaseAddr;
         VirtualQueryEx(proc, p, &mInfo, sizeof(mInfo)) == sizeof(mInfo) &&
         p < (me.modBaseAddr + me.modBaseSize);
         p += mInfo.RegionSize) {
      Row r;
      r["pid"] = INTEGER(pid);
      std::stringstream ssStart;
      ssStart << std::hex << mInfo.BaseAddress;
      r["start"] = "0x" + ssStart.str();
      std::stringstream ssEnd;
      ssEnd << std::hex << std::setfill('0') << std::setw(16)
            << reinterpret_cast<unsigned long long>(mInfo.BaseAddress) +
                   mInfo.RegionSize;
      r["end"] = "0x" + ssEnd.str();
      r["permissions"] = formatMemPerms(mInfo.Protect);
      r["offset"] =
          BIGINT(reinterpret_cast<unsigned long long>(mInfo.AllocationBase));
      r["device"] = "-1";
      r["inode"] = INTEGER(-1);
      r["path"] = me.szExePath;
      r["pseudo"] = INTEGER(-1);
      results.push_back(r);
    }
    ret = Module32Next(modSnap, &me);
  }
  CloseHandle(proc);
  CloseHandle(modSnap);
  return Status(0, "Ok");
}

/// Helper function for enumerating all active processes on the system
Status getProcList(std::set<long>& pids) {
  auto procSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if (procSnap == INVALID_HANDLE_VALUE) {
    return Status(1, "Failed to open process snapshot");
  }

  PROCESSENTRY32 procEntry;
  procEntry.dwSize = sizeof(PROCESSENTRY32);
  auto ret = Process32First(procSnap, &procEntry);

  if (ret == FALSE) {
    CloseHandle(procSnap);
    return Status(1, "Failed to open first process");
  }

  while (ret != FALSE) {
    pids.insert(procEntry.th32ProcessID);
    ret = Process32Next(procSnap, &procEntry);
  }

  CloseHandle(procSnap);
  return Status(0, "Ok");
}

void genProcess(const WmiResultItem& result, QueryData& results_data) {
  Row r;
  Status s;
  long pid;
  long lPlaceHolder;
  std::string sPlaceHolder;

  /// Store current process pid for more efficient API use.
  auto currentPid = GetCurrentProcessId();

  s = result.GetLong("ProcessId", pid);
  r["pid"] = s.ok() ? BIGINT(pid) : BIGINT(-1);

  long uid = -1;
  long gid = -1;
  HANDLE hProcess = nullptr;
  if (pid == currentPid) {
    hProcess = GetCurrentProcess();
  } else {
    hProcess =
        OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid);
  }

  if (GetLastError() == ERROR_ACCESS_DENIED) {
    uid = 0;
    gid = 0;
  }

  result.GetString("Name", r["name"]);
  result.GetString("ExecutablePath", r["path"]);
  result.GetString("CommandLine", r["cmdline"]);
  result.GetString("ExecutionState", r["state"]);
  result.GetLong("ParentProcessId", lPlaceHolder);
  r["parent"] = BIGINT(lPlaceHolder);
  result.GetLong("Priority", lPlaceHolder);
  r["nice"] = INTEGER(lPlaceHolder);
  r["on_disk"] = osquery::pathExists(r["path"]).toString();
  result.GetLong("ThreadCount", lPlaceHolder);
  r["threads"] = INTEGER(lPlaceHolder);
  result.GetString("PrivatePageCount", sPlaceHolder);
  r["wired_size"] = BIGINT(sPlaceHolder);
  result.GetString("WorkingSetSize", sPlaceHolder);
  r["resident_size"] = sPlaceHolder;
  result.GetString("VirtualSize", sPlaceHolder);
  r["total_size"] = BIGINT(sPlaceHolder);

  std::vector<char> fileName(MAX_PATH + 1, 0x0);
  if (pid == currentPid) {
    GetModuleFileName(nullptr, fileName.data(), MAX_PATH);
  } else {
    GetModuleFileNameEx(hProcess, nullptr, fileName.data(), MAX_PATH);
  }

  r["cwd"] = SQL_TEXT(fileName.data());
  r["root"] = r["cwd"];

  r["pgroup"] = "-1";
  r["euid"] = "-1";
  r["suid"] = "-1";
  r["egid"] = "-1";
  r["sgid"] = "-1";

  FILETIME createTime;
  FILETIME exitTime;
  FILETIME kernelTime;
  FILETIME userTime;
  auto procRet =
      GetProcessTimes(hProcess, &createTime, &exitTime, &kernelTime, &userTime);
  if (procRet == FALSE) {
    r["user_time"] = BIGINT(-1);
    r["system_time"] = BIGINT(-1);
    r["start_time"] = BIGINT(-1);
  } else {
    // Windows stores proc times in 100 nanosecond ticks
    ULARGE_INTEGER utime;
    utime.HighPart = userTime.dwHighDateTime;
    utime.LowPart = userTime.dwLowDateTime;
    r["user_time"] = BIGINT(utime.QuadPart / 10000000);
    utime.HighPart = kernelTime.dwHighDateTime;
    utime.LowPart = kernelTime.dwLowDateTime;
    r["system_time"] = BIGINT(utime.QuadPart / 10000000);
    r["start_time"] = BIGINT(osquery::filetimeToUnixtime(createTime));
  }

  /// Get the process UID and GID from its SID
  HANDLE tok = nullptr;
  std::vector<char> tokOwner(sizeof(TOKEN_OWNER), 0x0);
  auto ret = OpenProcessToken(hProcess, TOKEN_READ, &tok);
  if (ret != 0 && tok != nullptr) {
    unsigned long tokOwnerBuffLen;
    ret = GetTokenInformation(tok, TokenUser, nullptr, 0, &tokOwnerBuffLen);
    if (ret == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
      tokOwner.resize(tokOwnerBuffLen);
      ret = GetTokenInformation(
          tok, TokenUser, tokOwner.data(), tokOwnerBuffLen, &tokOwnerBuffLen);
    }

    // Check if the process is using an elevated token
    auto elevated = FALSE;
    TOKEN_ELEVATION Elevation;
    DWORD cbSize = sizeof(TOKEN_ELEVATION);
    if (GetTokenInformation(
            tok, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)) {
      elevated = Elevation.TokenIsElevated;
    }

    r["is_elevated_token"] = elevated ? INTEGER(1) : INTEGER(0);
  }
  if (uid != 0 && ret != 0 && !tokOwner.empty()) {
    auto sid = PTOKEN_OWNER(tokOwner.data())->Owner;
    r["uid"] = INTEGER(getUidFromSid(sid));
    r["gid"] = INTEGER(getGidFromSid(sid));
  } else {
    r["uid"] = INTEGER(uid);
    r["gid"] = INTEGER(gid);
  }

  if (hProcess != nullptr) {
    CloseHandle(hProcess);
  }
  if (tok != nullptr) {
    CloseHandle(tok);
    tok = nullptr;
  }
  results_data.push_back(r);
}

QueryData genProcesses(QueryContext& context) {
  QueryData results;

  std::string query = "SELECT * FROM Win32_Process";

  std::set<long> pidlist;
  if (context.constraints.count("pid") > 0 &&
      context.constraints.at("pid").exists(EQUALS)) {
    for (const auto& pid : context.constraints.at("pid").getAll<int>(EQUALS)) {
      if (pid > 0) {
        pidlist.insert(pid);
      }
    }
    // None of the constraints returned valid pids, bail out early
    if (pidlist.empty()) {
      return results;
    }
  }

  if (pidlist.size() > 0) {
    std::vector<std::string> constraints;
    for (const auto& pid : pidlist) {
      constraints.push_back("ProcessId=" + std::to_string(pid));
    }
    if (constraints.size() > 0) {
      query += " WHERE " + boost::algorithm::join(constraints, " OR ");
    }
  }

  WmiRequest request(query);
  if (request.getStatus().ok()) {
    for (const auto& item : request.results()) {
      long pid = 0;
      if (item.GetLong("ProcessId", pid).ok()) {
        genProcess(item, results);
      }
    }
  }

  return results;
}

QueryData genProcessMemoryMap(QueryContext& context) {
  QueryData results;

  std::set<long> pidlist;
  if (context.constraints.count("pid") > 0 &&
      context.constraints.at("pid").exists(EQUALS)) {
    for (const auto& pid : context.constraints.at("pid").getAll<int>(EQUALS)) {
      if (pid > 0) {
        pidlist.insert(pid);
      }
    }
  }
  if (pidlist.empty()) {
    getProcList(pidlist);
  }

  for (const auto& pid : pidlist) {
    auto s = genMemoryMap(pid, results);
    if (!s.ok()) {
      VLOG(1) << s.getMessage();
    }
  }

  return results;
}

} // namespace tables
} // namespace osquery
<commit_msg>Using TOKEN_USER instead of TOKEN_OWNER struct (#4651)<commit_after>/**
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under both the Apache 2.0 license (found in the
 *  LICENSE file in the root directory of this source tree) and the GPLv2 (found
 *  in the COPYING file in the root directory of this source tree).
 *  You may select, at your option, one of the above-listed licenses.
 */

#include <map>
#include <string>

#define _WIN32_DCOM

#include <Windows.h>
#include <iomanip>
#include <psapi.h>
#include <stdlib.h>
#include <tlhelp32.h>

#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/trim.hpp>

#include <osquery/core.h>
#include <osquery/filesystem.h>
#include <osquery/logger.h>
#include <osquery/tables.h>

#include "osquery/core/conversions.h"
#include "osquery/core/windows/wmi.h"
#include "osquery/filesystem/fileops.h"

namespace osquery {
int getUidFromSid(PSID sid);
int getGidFromSid(PSID sid);
namespace tables {

const std::map<unsigned long, std::string> kMemoryConstants = {
    {PAGE_EXECUTE, "PAGE_EXECUTE"},
    {PAGE_EXECUTE_READ, "PAGE_EXECUTE_READ"},
    {PAGE_EXECUTE_READWRITE, "PAGE_EXECUTE_READWRITE"},
    {PAGE_EXECUTE_WRITECOPY, "PAGE_EXECUTE_WRITECOPY"},
    {PAGE_NOACCESS, "PAGE_NOACCESS"},
    {PAGE_READONLY, "PAGE_READONLY"},
    {PAGE_READWRITE, "PAGE_READWRITE"},
    {PAGE_WRITECOPY, "PAGE_WRITECOPY"},
    {PAGE_GUARD, "PAGE_GUARD"},
    {PAGE_NOCACHE, "PAGE_NOCACHE"},
    {PAGE_WRITECOMBINE, "PAGE_WRITECOMBINE"},
};

/// Given a pid, enumerates all loaded modules and memory pages for that process
Status genMemoryMap(unsigned long pid, QueryData& results) {
  auto proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
  if (proc == nullptr) {
    Row r;
    r["pid"] = INTEGER(pid);
    r["start"] = INTEGER(-1);
    r["end"] = INTEGER(-1);
    r["permissions"] = "";
    r["offset"] = INTEGER(-1);
    r["device"] = "-1";
    r["inode"] = INTEGER(-1);
    r["path"] = "";
    r["pseudo"] = INTEGER(-1);
    results.push_back(r);
    return Status(1, "Failed to open handle to process " + std::to_string(pid));
  }
  auto modSnap =
      CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid);
  if (modSnap == INVALID_HANDLE_VALUE) {
    CloseHandle(proc);
    return Status(1, "Failed to enumerate modules for " + std::to_string(pid));
  }

  auto formatMemPerms = [](unsigned long perm) {
    std::vector<std::string> perms;
    for (const auto& kv : kMemoryConstants) {
      if (kv.first & perm) {
        perms.push_back(kv.second);
      }
    }
    return osquery::join(perms, " | ");
  };

  MODULEENTRY32 me;
  MEMORY_BASIC_INFORMATION mInfo;
  me.dwSize = sizeof(MODULEENTRY32);
  auto ret = Module32First(modSnap, &me);
  while (ret != FALSE) {
    for (auto p = me.modBaseAddr;
         VirtualQueryEx(proc, p, &mInfo, sizeof(mInfo)) == sizeof(mInfo) &&
         p < (me.modBaseAddr + me.modBaseSize);
         p += mInfo.RegionSize) {
      Row r;
      r["pid"] = INTEGER(pid);
      std::stringstream ssStart;
      ssStart << std::hex << mInfo.BaseAddress;
      r["start"] = "0x" + ssStart.str();
      std::stringstream ssEnd;
      ssEnd << std::hex << std::setfill('0') << std::setw(16)
            << reinterpret_cast<unsigned long long>(mInfo.BaseAddress) +
                   mInfo.RegionSize;
      r["end"] = "0x" + ssEnd.str();
      r["permissions"] = formatMemPerms(mInfo.Protect);
      r["offset"] =
          BIGINT(reinterpret_cast<unsigned long long>(mInfo.AllocationBase));
      r["device"] = "-1";
      r["inode"] = INTEGER(-1);
      r["path"] = me.szExePath;
      r["pseudo"] = INTEGER(-1);
      results.push_back(r);
    }
    ret = Module32Next(modSnap, &me);
  }
  CloseHandle(proc);
  CloseHandle(modSnap);
  return Status(0, "Ok");
}

/// Helper function for enumerating all active processes on the system
Status getProcList(std::set<long>& pids) {
  auto procSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if (procSnap == INVALID_HANDLE_VALUE) {
    return Status(1, "Failed to open process snapshot");
  }

  PROCESSENTRY32 procEntry;
  procEntry.dwSize = sizeof(PROCESSENTRY32);
  auto ret = Process32First(procSnap, &procEntry);

  if (ret == FALSE) {
    CloseHandle(procSnap);
    return Status(1, "Failed to open first process");
  }

  while (ret != FALSE) {
    pids.insert(procEntry.th32ProcessID);
    ret = Process32Next(procSnap, &procEntry);
  }

  CloseHandle(procSnap);
  return Status(0, "Ok");
}

void genProcess(const WmiResultItem& result, QueryData& results_data) {
  Row r;
  Status s;
  long pid;
  long lPlaceHolder;
  std::string sPlaceHolder;

  /// Store current process pid for more efficient API use.
  auto currentPid = GetCurrentProcessId();

  s = result.GetLong("ProcessId", pid);
  r["pid"] = s.ok() ? BIGINT(pid) : BIGINT(-1);

  long uid = -1;
  long gid = -1;
  HANDLE hProcess = nullptr;
  if (pid == currentPid) {
    hProcess = GetCurrentProcess();
  } else {
    hProcess =
        OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid);
  }

  if (GetLastError() == ERROR_ACCESS_DENIED) {
    uid = 0;
    gid = 0;
  }

  result.GetString("Name", r["name"]);
  result.GetString("ExecutablePath", r["path"]);
  result.GetString("CommandLine", r["cmdline"]);
  result.GetString("ExecutionState", r["state"]);
  result.GetLong("ParentProcessId", lPlaceHolder);
  r["parent"] = BIGINT(lPlaceHolder);
  result.GetLong("Priority", lPlaceHolder);
  r["nice"] = INTEGER(lPlaceHolder);
  r["on_disk"] = osquery::pathExists(r["path"]).toString();
  result.GetLong("ThreadCount", lPlaceHolder);
  r["threads"] = INTEGER(lPlaceHolder);
  result.GetString("PrivatePageCount", sPlaceHolder);
  r["wired_size"] = BIGINT(sPlaceHolder);
  result.GetString("WorkingSetSize", sPlaceHolder);
  r["resident_size"] = sPlaceHolder;
  result.GetString("VirtualSize", sPlaceHolder);
  r["total_size"] = BIGINT(sPlaceHolder);

  std::vector<char> fileName(MAX_PATH + 1, 0x0);
  if (pid == currentPid) {
    GetModuleFileName(nullptr, fileName.data(), MAX_PATH);
  } else {
    GetModuleFileNameEx(hProcess, nullptr, fileName.data(), MAX_PATH);
  }

  r["cwd"] = SQL_TEXT(fileName.data());
  r["root"] = r["cwd"];

  r["pgroup"] = "-1";
  r["euid"] = "-1";
  r["suid"] = "-1";
  r["egid"] = "-1";
  r["sgid"] = "-1";

  FILETIME createTime;
  FILETIME exitTime;
  FILETIME kernelTime;
  FILETIME userTime;
  auto procRet =
      GetProcessTimes(hProcess, &createTime, &exitTime, &kernelTime, &userTime);
  if (procRet == FALSE) {
    r["user_time"] = BIGINT(-1);
    r["system_time"] = BIGINT(-1);
    r["start_time"] = BIGINT(-1);
  } else {
    // Windows stores proc times in 100 nanosecond ticks
    ULARGE_INTEGER utime;
    utime.HighPart = userTime.dwHighDateTime;
    utime.LowPart = userTime.dwLowDateTime;
    r["user_time"] = BIGINT(utime.QuadPart / 10000000);
    utime.HighPart = kernelTime.dwHighDateTime;
    utime.LowPart = kernelTime.dwLowDateTime;
    r["system_time"] = BIGINT(utime.QuadPart / 10000000);
    r["start_time"] = BIGINT(osquery::filetimeToUnixtime(createTime));
  }

  /// Get the process UID and GID from its SID
  HANDLE tok = nullptr;
  std::vector<char> tokUser(sizeof(TOKEN_USER), 0x0);
  auto ret = OpenProcessToken(hProcess, TOKEN_READ, &tok);
  if (ret != 0 && tok != nullptr) {
    unsigned long tokOwnerBuffLen;
    ret = GetTokenInformation(tok, TokenUser, nullptr, 0, &tokOwnerBuffLen);
    if (ret == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
      tokUser.resize(tokOwnerBuffLen);
      ret = GetTokenInformation(
          tok, TokenUser, tokUser.data(), tokOwnerBuffLen, &tokOwnerBuffLen);
    }

    // Check if the process is using an elevated token
    auto elevated = FALSE;
    TOKEN_ELEVATION Elevation;
    DWORD cbSize = sizeof(TOKEN_ELEVATION);
    if (GetTokenInformation(
            tok, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)) {
      elevated = Elevation.TokenIsElevated;
    }

    r["is_elevated_token"] = elevated ? INTEGER(1) : INTEGER(0);
  }
  if (uid != 0 && ret != 0 && !tokUser.empty()) {
    auto sid = PTOKEN_OWNER(tokUser.data())->Owner;
    r["uid"] = INTEGER(getUidFromSid(sid));
    r["gid"] = INTEGER(getGidFromSid(sid));
  } else {
    r["uid"] = INTEGER(uid);
    r["gid"] = INTEGER(gid);
  }

  if (hProcess != nullptr) {
    CloseHandle(hProcess);
  }
  if (tok != nullptr) {
    CloseHandle(tok);
    tok = nullptr;
  }
  results_data.push_back(r);
}

QueryData genProcesses(QueryContext& context) {
  QueryData results;

  std::string query = "SELECT * FROM Win32_Process";

  std::set<long> pidlist;
  if (context.constraints.count("pid") > 0 &&
      context.constraints.at("pid").exists(EQUALS)) {
    for (const auto& pid : context.constraints.at("pid").getAll<int>(EQUALS)) {
      if (pid > 0) {
        pidlist.insert(pid);
      }
    }
    // None of the constraints returned valid pids, bail out early
    if (pidlist.empty()) {
      return results;
    }
  }

  if (pidlist.size() > 0) {
    std::vector<std::string> constraints;
    for (const auto& pid : pidlist) {
      constraints.push_back("ProcessId=" + std::to_string(pid));
    }
    if (constraints.size() > 0) {
      query += " WHERE " + boost::algorithm::join(constraints, " OR ");
    }
  }

  WmiRequest request(query);
  if (request.getStatus().ok()) {
    for (const auto& item : request.results()) {
      long pid = 0;
      if (item.GetLong("ProcessId", pid).ok()) {
        genProcess(item, results);
      }
    }
  }

  return results;
}

QueryData genProcessMemoryMap(QueryContext& context) {
  QueryData results;

  std::set<long> pidlist;
  if (context.constraints.count("pid") > 0 &&
      context.constraints.at("pid").exists(EQUALS)) {
    for (const auto& pid : context.constraints.at("pid").getAll<int>(EQUALS)) {
      if (pid > 0) {
        pidlist.insert(pid);
      }
    }
  }
  if (pidlist.empty()) {
    getProcList(pidlist);
  }

  for (const auto& pid : pidlist) {
    auto s = genMemoryMap(pid, results);
    if (!s.ok()) {
      VLOG(1) << s.getMessage();
    }
  }

  return results;
}

} // namespace tables
} // namespace osquery
<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2013-2017 Inviwo Foundation
 * 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 <modules/opencl/syncclgl.h>
#include <modules/opencl/openclexception.h>

namespace inviwo {

#if defined(CL_VERSION_1_1)
std::map<cl_context, pfnclCreateEventFromSyncKHR> SyncCLGL::syncFunctionMap_;
#endif

SyncCLGL::SyncCLGL(const cl::Context& context, const cl::CommandQueue& queue)
    : context_(context)
    , queue_(queue)
#if defined(CL_VERSION_1_1)
    , glFenceSync_(nullptr)
#endif
{
#if defined(CL_VERSION_1_1)
    //  Check if function clCreateEventFromGLsyncKHR has been fetched previously,
    // add it if it has not
    if (syncFunctionMap_.find(context()) == syncFunctionMap_.end()) {
        // Get clCreateEventFromGLsyncKHR function from platform since
        // it is a vendor extension and cannot be statically linked
#if defined(CL_VERSION_1_2)  // version >= 1.2
        // Function was renamed in version 1.2
        auto device = queue.getInfo<CL_QUEUE_DEVICE>();
        auto platform = device.getInfo<CL_DEVICE_PLATFORM>();
        syncFunctionMap_[context()] =
            (pfnclCreateEventFromSyncKHR)clGetExtensionFunctionAddressForPlatform(
                platform, "clCreateEventFromGLsyncKHR");
#else  // Version 1.1
        // Requirescl_khr_gl_sharing extension must be supported since we are using sharing
        syncFunctionMap_[context()] = (pfnclCreateEventFromSyncKHR)clGetExtensionFunctionAddress(
            "clCreateEventFromGLsyncKHR");
#endif
    }
    pfnclCreateEventFromSyncKHR clCreateEventFromGLsync = syncFunctionMap_[context()];
    if (clCreateEventFromGLsync) {
        // Use more efficient synchronization
        // See section 9.9 in the OpenCL 1.1 spec for more information, also
        // https://www.cct.lsu.edu/~korobkin/tmp/SC10/tutorials/docs/M13/M13.pdf

        // Get sync point from OpenGL to be used when acquiring objects
        // Note that glFenceSync is supported since it exit in OpenGl 3.2 and higher
        glFenceSync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
    } else {
        // clCreateEventFromGLsync not supported.
        // We need to use a slower synchronization
        glFinish();
    }
#else
    glFinish();
#endif
}

SyncCLGL::~SyncCLGL() {
    releaseAllGLObjects();
#if defined(CL_VERSION_1_1)
    if (glFenceSync_) glDeleteSync(glFenceSync_);
#endif
}

void SyncCLGL::addToAquireGLObjectList(const BufferCLGL* object) {
    syncedObjects_.push_back(object->get());
}

void SyncCLGL::addToAquireGLObjectList(const LayerCLGL* object) {
    syncedObjects_.push_back(object->get());
}

void SyncCLGL::addToAquireGLObjectList(const ImageCLGL* object) {
    addToAquireGLObjectList(object->getLayerCL());
}

void SyncCLGL::addToAquireGLObjectList(const VolumeCLGL* object) {
    syncedObjects_.push_back(object->get());
}

void SyncCLGL::aquireAllObjects(const std::vector<cl::Event>* waitForEvents /*= nullptr*/,
                                cl::Event* event /*= nullptr*/) const {
#if defined(CL_VERSION_1_1)
    // Use fast synchronization if we can
    if (glFenceSync_) {
        pfnclCreateEventFromSyncKHR clCreateEventFromGLsync = syncFunctionMap_[context_()];
        // Sync with OpenGL
        cl_int err;
        std::vector<cl::Event> waitForSyncAndEvents(
            1, clCreateEventFromGLsync(context_(), glFenceSync_, &err));
        if (err != CL_SUCCESS) {
            throw OpenCLException("Failed to create sync event");
        }
        if (waitForEvents) {
            // Add events to wait for
            waitForSyncAndEvents.reserve(waitForEvents->size() + 1);
            waitForSyncAndEvents.insert(std::end(waitForSyncAndEvents), std::begin(*waitForEvents),
                                        std::end(*waitForEvents));
        }
        queue_.enqueueAcquireGLObjects(&syncedObjects_, &waitForSyncAndEvents, event);
    } else {
        // Fast sync not supported, glFinish has been called in constructor instead
        queue_.enqueueAcquireGLObjects(&syncedObjects_, waitForEvents, event);
    }
#else
    queue_.enqueueAcquireGLObjects(&syncedObjects_, waitForEvents, event);
#endif
}

void SyncCLGL::releaseAllGLObjects(const std::vector<cl::Event>* waitForEvents, cl::Event* event) {
    if (!syncedObjects_.empty()) {
#if defined(CL_VERSION_1_1)
        if (glFenceSync_) {
            cl::Event releaseEvent;
            // Use supplied event if existing
            cl::Event* releaseEventPtr = event != nullptr ? event : &releaseEvent;
            queue_.enqueueReleaseGLObjects(&syncedObjects_, waitForEvents, releaseEventPtr);
            // Synchronize OpenCL and OpenGL
            GLsync clSync = glCreateSyncFromCLeventARB(context_(), (*releaseEventPtr)(), 0);
            // without stalling CPU-thread:
            glWaitSync(clSync, 0, GL_TIMEOUT_IGNORED);
        } else {
            queue_.enqueueReleaseGLObjects(&syncedObjects_, waitForEvents, event);
            queue_.finish();
        }
#else
        queue_.enqueueReleaseGLObjects(&syncedObjects_, waitForEvents, event);
        queue_.finish();
#endif
        syncedObjects_.clear();
    }
}

}  // namespace inviwo
<commit_msg>OpenCL: SyncCLGL comment adjustment<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2013-2017 Inviwo Foundation
 * 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 <modules/opencl/syncclgl.h>
#include <modules/opencl/openclexception.h>

namespace inviwo {

#if defined(CL_VERSION_1_1)
std::map<cl_context, pfnclCreateEventFromSyncKHR> SyncCLGL::syncFunctionMap_;
#endif

SyncCLGL::SyncCLGL(const cl::Context& context, const cl::CommandQueue& queue)
    : context_(context)
    , queue_(queue)
#if defined(CL_VERSION_1_1)
    , glFenceSync_(nullptr)
#endif
{
#if defined(CL_VERSION_1_1)
    //  Check if function clCreateEventFromGLsyncKHR has been fetched previously,
    // add it if it has not
    if (syncFunctionMap_.find(context()) == syncFunctionMap_.end()) {
        // Get clCreateEventFromGLsyncKHR function from platform since
        // it is a vendor extension and cannot be statically linked
#if defined(CL_VERSION_1_2)  // version >= 1.2
        // Function was renamed in version 1.2
        auto device = queue.getInfo<CL_QUEUE_DEVICE>();
        auto platform = device.getInfo<CL_DEVICE_PLATFORM>();
        syncFunctionMap_[context()] =
            (pfnclCreateEventFromSyncKHR)clGetExtensionFunctionAddressForPlatform(
                platform, "clCreateEventFromGLsyncKHR");
#else  // Version 1.1
        // Requires cl_khr_gl_sharing extension. Extension is supported since we are using sharing
        syncFunctionMap_[context()] = (pfnclCreateEventFromSyncKHR)clGetExtensionFunctionAddress(
            "clCreateEventFromGLsyncKHR");
#endif
    }
    pfnclCreateEventFromSyncKHR clCreateEventFromGLsync = syncFunctionMap_[context()];
    if (clCreateEventFromGLsync) {
        // Use more efficient synchronization
        // See section 9.9 in the OpenCL 1.1 spec for more information, also
        // https://www.cct.lsu.edu/~korobkin/tmp/SC10/tutorials/docs/M13/M13.pdf

        // Get sync point from OpenGL to be used when acquiring objects
        // Note that glFenceSync is supported since it exit in OpenGl 3.2 and higher
        glFenceSync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
    } else {
        // clCreateEventFromGLsync not supported.
        // We need to use a slower synchronization
        glFinish();
    }
#else
    glFinish();
#endif
}

SyncCLGL::~SyncCLGL() {
    releaseAllGLObjects();
#if defined(CL_VERSION_1_1)
    if (glFenceSync_) glDeleteSync(glFenceSync_);
#endif
}

void SyncCLGL::addToAquireGLObjectList(const BufferCLGL* object) {
    syncedObjects_.push_back(object->get());
}

void SyncCLGL::addToAquireGLObjectList(const LayerCLGL* object) {
    syncedObjects_.push_back(object->get());
}

void SyncCLGL::addToAquireGLObjectList(const ImageCLGL* object) {
    addToAquireGLObjectList(object->getLayerCL());
}

void SyncCLGL::addToAquireGLObjectList(const VolumeCLGL* object) {
    syncedObjects_.push_back(object->get());
}

void SyncCLGL::aquireAllObjects(const std::vector<cl::Event>* waitForEvents /*= nullptr*/,
                                cl::Event* event /*= nullptr*/) const {
#if defined(CL_VERSION_1_1)
    // Use fast synchronization if we can
    if (glFenceSync_) {
        pfnclCreateEventFromSyncKHR clCreateEventFromGLsync = syncFunctionMap_[context_()];
        // Sync with OpenGL
        cl_int err;
        std::vector<cl::Event> waitForSyncAndEvents(
            1, clCreateEventFromGLsync(context_(), glFenceSync_, &err));
        if (err != CL_SUCCESS) {
            throw OpenCLException("Failed to create sync event");
        }
        if (waitForEvents) {
            // Add events to wait for
            waitForSyncAndEvents.reserve(waitForEvents->size() + 1);
            waitForSyncAndEvents.insert(std::end(waitForSyncAndEvents), std::begin(*waitForEvents),
                                        std::end(*waitForEvents));
        }
        queue_.enqueueAcquireGLObjects(&syncedObjects_, &waitForSyncAndEvents, event);
    } else {
        // Fast sync not supported, glFinish has been called in constructor instead
        queue_.enqueueAcquireGLObjects(&syncedObjects_, waitForEvents, event);
    }
#else
    queue_.enqueueAcquireGLObjects(&syncedObjects_, waitForEvents, event);
#endif
}

void SyncCLGL::releaseAllGLObjects(const std::vector<cl::Event>* waitForEvents, cl::Event* event) {
    if (!syncedObjects_.empty()) {
#if defined(CL_VERSION_1_1)
        if (glFenceSync_) {
            cl::Event releaseEvent;
            // Use supplied event if existing
            cl::Event* releaseEventPtr = event != nullptr ? event : &releaseEvent;
            queue_.enqueueReleaseGLObjects(&syncedObjects_, waitForEvents, releaseEventPtr);
            // Synchronize OpenCL and OpenGL
            GLsync clSync = glCreateSyncFromCLeventARB(context_(), (*releaseEventPtr)(), 0);
            // without stalling CPU-thread:
            glWaitSync(clSync, 0, GL_TIMEOUT_IGNORED);
        } else {
            queue_.enqueueReleaseGLObjects(&syncedObjects_, waitForEvents, event);
            queue_.finish();
        }
#else
        queue_.enqueueReleaseGLObjects(&syncedObjects_, waitForEvents, event);
        queue_.finish();
#endif
        syncedObjects_.clear();
    }
}

}  // namespace inviwo
<|endoftext|>


<commit_before>#include <cctype>
#include <fstream>
#include <stdio.h>
#include "utils/logoutput.h"

#include "settings.h"

#define STRINGIFY(_s) #_s
#define SETTING(name, default) do { _index.push_back(_ConfigSettingIndex(STRINGIFY(name), &name)); name = (default); } while(0)
#define SETTING2(name, altname, default) do { _index.push_back(_ConfigSettingIndex(STRINGIFY(name), &name)); _index.push_back(_ConfigSettingIndex(STRINGIFY(altname), &name)); name = (default); } while(0)

ConfigSettings::ConfigSettings()
{
    SETTING(layerThickness, 100);
    SETTING(initialLayerThickness, 300);
    SETTING(filamentDiameter, 2890);
    SETTING(filamentFlow, 100);
    SETTING(extrusionWidth, 400);
    SETTING(insetCount, 2);
    SETTING(downSkinCount, 6);
    SETTING(upSkinCount, 6);
    SETTING(sparseInfillLineDistance, 100 * extrusionWidth / 20);
    SETTING(infillOverlap, 15);
    SETTING(skirtDistance, 6000);
    SETTING(skirtLineCount, 1);
    SETTING(skirtMinLength, 0);

    SETTING(initialSpeedupLayers, 4);
    SETTING(initialLayerSpeed, 20);
    SETTING(printSpeed, 50);
    SETTING(infillSpeed, 50);
    SETTING(inset0Speed, 50);
    SETTING(insetXSpeed, 50);
    SETTING(moveSpeed, 150);
    SETTING(fanFullOnLayerNr, 2);

    SETTING(supportAngle, -1);
    SETTING(supportEverywhere, 0);
    SETTING(supportLineDistance, sparseInfillLineDistance);
    SETTING(supportXYDistance, 700);
    SETTING(supportZDistance, 150);
    SETTING(supportExtruder, -1);

    SETTING(retractionAmount, 4500);
    SETTING(retractionSpeed, 45);
    SETTING(retractionAmountExtruderSwitch, 14500);
    SETTING(retractionMinimalDistance, 1500);
    SETTING(minimalExtrusionBeforeRetraction, 100);
    SETTING(retractionZHop, 0);

    SETTING(enableCombing, 1);
    SETTING(enableOozeShield, 0);
    SETTING(wipeTowerSize, 0);
    SETTING(multiVolumeOverlap, 0);
    SETTING2(objectPosition.X, posx, 102500);
    SETTING2(objectPosition.Y, posy, 102500);
    SETTING(objectSink, 0);

    SETTING(raftMargin, 5000);
    SETTING(raftLineSpacing, 1000);
    SETTING(raftBaseThickness, 0);
    SETTING(raftBaseLinewidth, 0);
    SETTING(raftInterfaceThickness, 0);
    SETTING(raftInterfaceLinewidth, 0);

    SETTING(minimalLayerTime, 5);
    SETTING(minimalFeedrate, 10);
    SETTING(coolHeadLift, 0);
    SETTING(fanSpeedMin, 100);
    SETTING(fanSpeedMax, 100);

    SETTING(fixHorrible, 0);
    SETTING(spiralizeMode, 0);
    SETTING(gcodeFlavor, GCODE_FLAVOR_REPRAP);

    SETTING(extruderOffset[1].X, 0);
    SETTING(extruderOffset[1].Y, 0);
    SETTING(extruderOffset[2].X, 0);
    SETTING(extruderOffset[2].Y, 0);
    SETTING(extruderOffset[3].X, 0);
    SETTING(extruderOffset[3].Y, 0);

    startCode =
        "M109 S210     ;Heatup to 210C\n"
        "G21           ;metric values\n"
        "G90           ;absolute positioning\n"
        "G28           ;Home\n"
        "G1 Z15.0 F300 ;move the platform down 15mm\n"
        "G92 E0        ;zero the extruded length\n"
        "G1 F200 E5    ;extrude 5mm of feed stock\n"
        "G92 E0        ;zero the extruded length again\n";
    endCode =
        "M104 S0                     ;extruder heater off\n"
        "M140 S0                     ;heated bed heater off (if you have it)\n"
        "G91                            ;relative positioning\n"
        "G1 E-1 F300                    ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n"
        "G1 Z+0.5 E-5 X-20 Y-20 F9000   ;move Z up a bit and retract filament even more\n"
        "G28 X0 Y0                      ;move X/Y to min endstops, so the head is out of the way\n"
        "M84                         ;steppers off\n"
        "G90                         ;absolute positioning\n";
}

#undef STRINGIFY
#undef SETTING

bool ConfigSettings::setSetting(const char* key, const char* value)
{
    for(unsigned int n=0; n < _index.size(); n++)
    {
        if (strcasecmp(key, _index[n].key) == 0)
        {
            *_index[n].ptr = atoi(value);
            return true;
        }
    }
    if (strcasecmp(key, "startCode") == 0)
    {
        this->startCode = value;
        return true;
    }
    if (strcasecmp(key, "endCode") == 0)
    {
        this->endCode = value;
        return true;
    }
    return false;
}

void _trim_string(std::string &s) {
    // ltrim
    while((s.length() > 0) && isspace(s[0])) {
        s.erase(0, 1);
    }
    // rtrim
    while((s.length() > 0) && isspace(s[s.length() - 1])) {
        s.erase(s.length() - 1);
    }
}

bool ConfigSettings::readSettings(const char* path) {
    std::ifstream config(path);
    std::string line;
    size_t line_number = 0;

    while(config.good()) {
        size_t pos = std::string::npos;
        std::getline(config, line);
        line_number += 1;

        // De-comment and trim, skipping anything that shows up empty
        pos = line.find_first_of('#');
        if(pos != std::string::npos) line.erase(pos);
        _trim_string(line);
        if(line.length() == 0) continue;

        // Split into key = val
        std::string key(""), val("");
        pos = line.find_first_of('=');
        if(pos != std::string::npos && line.length() > (pos + 1)) {
            key = line.substr(0, pos);
            val = line.substr(pos + 1);
            _trim_string(key);
            _trim_string(val);
        }

        // Fail if we don't get a key and val
        if(key.length() == 0 || val.length() == 0) {
            logError("Config(%s): Line %zd: No key value pair found\n", path, line_number);
            return false;
        }

        // Set a config setting for the current K=V
        if(!setSetting(key.c_str(), val.c_str())) {
            logError("Config(%s):L%zd: Failed to set '%s' to '%s'\n", path, line_number, key.c_str(), val.c_str());
        }
    }

    return true;
}
<commit_msg>_trim_string() is now TRIM_STRING() the macro<commit_after>#include <cctype>
#include <fstream>
#include <stdio.h>
#include "utils/logoutput.h"

#include "settings.h"

#define TRIM_STRING(s) do { while(((s).length() > 0) && isspace((s)[0])) { (s).erase(0, 1); } while(((s).length() > 0) && isspace((s)[(s).length() - 1])) { (s).erase((s).length() - 1); } } while(0)
#define STRINGIFY(_s) #_s
#define SETTING(name, default) do { _index.push_back(_ConfigSettingIndex(STRINGIFY(name), &name)); name = (default); } while(0)
#define SETTING2(name, altname, default) do { _index.push_back(_ConfigSettingIndex(STRINGIFY(name), &name)); _index.push_back(_ConfigSettingIndex(STRINGIFY(altname), &name)); name = (default); } while(0)

ConfigSettings::ConfigSettings()
{
    SETTING(layerThickness, 100);
    SETTING(initialLayerThickness, 300);
    SETTING(filamentDiameter, 2890);
    SETTING(filamentFlow, 100);
    SETTING(extrusionWidth, 400);
    SETTING(insetCount, 2);
    SETTING(downSkinCount, 6);
    SETTING(upSkinCount, 6);
    SETTING(sparseInfillLineDistance, 100 * extrusionWidth / 20);
    SETTING(infillOverlap, 15);
    SETTING(skirtDistance, 6000);
    SETTING(skirtLineCount, 1);
    SETTING(skirtMinLength, 0);

    SETTING(initialSpeedupLayers, 4);
    SETTING(initialLayerSpeed, 20);
    SETTING(printSpeed, 50);
    SETTING(infillSpeed, 50);
    SETTING(inset0Speed, 50);
    SETTING(insetXSpeed, 50);
    SETTING(moveSpeed, 150);
    SETTING(fanFullOnLayerNr, 2);

    SETTING(supportAngle, -1);
    SETTING(supportEverywhere, 0);
    SETTING(supportLineDistance, sparseInfillLineDistance);
    SETTING(supportXYDistance, 700);
    SETTING(supportZDistance, 150);
    SETTING(supportExtruder, -1);

    SETTING(retractionAmount, 4500);
    SETTING(retractionSpeed, 45);
    SETTING(retractionAmountExtruderSwitch, 14500);
    SETTING(retractionMinimalDistance, 1500);
    SETTING(minimalExtrusionBeforeRetraction, 100);
    SETTING(retractionZHop, 0);

    SETTING(enableCombing, 1);
    SETTING(enableOozeShield, 0);
    SETTING(wipeTowerSize, 0);
    SETTING(multiVolumeOverlap, 0);
    SETTING2(objectPosition.X, posx, 102500);
    SETTING2(objectPosition.Y, posy, 102500);
    SETTING(objectSink, 0);

    SETTING(raftMargin, 5000);
    SETTING(raftLineSpacing, 1000);
    SETTING(raftBaseThickness, 0);
    SETTING(raftBaseLinewidth, 0);
    SETTING(raftInterfaceThickness, 0);
    SETTING(raftInterfaceLinewidth, 0);

    SETTING(minimalLayerTime, 5);
    SETTING(minimalFeedrate, 10);
    SETTING(coolHeadLift, 0);
    SETTING(fanSpeedMin, 100);
    SETTING(fanSpeedMax, 100);

    SETTING(fixHorrible, 0);
    SETTING(spiralizeMode, 0);
    SETTING(gcodeFlavor, GCODE_FLAVOR_REPRAP);

    SETTING(extruderOffset[1].X, 0);
    SETTING(extruderOffset[1].Y, 0);
    SETTING(extruderOffset[2].X, 0);
    SETTING(extruderOffset[2].Y, 0);
    SETTING(extruderOffset[3].X, 0);
    SETTING(extruderOffset[3].Y, 0);

    startCode =
        "M109 S210     ;Heatup to 210C\n"
        "G21           ;metric values\n"
        "G90           ;absolute positioning\n"
        "G28           ;Home\n"
        "G1 Z15.0 F300 ;move the platform down 15mm\n"
        "G92 E0        ;zero the extruded length\n"
        "G1 F200 E5    ;extrude 5mm of feed stock\n"
        "G92 E0        ;zero the extruded length again\n";
    endCode =
        "M104 S0                     ;extruder heater off\n"
        "M140 S0                     ;heated bed heater off (if you have it)\n"
        "G91                            ;relative positioning\n"
        "G1 E-1 F300                    ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n"
        "G1 Z+0.5 E-5 X-20 Y-20 F9000   ;move Z up a bit and retract filament even more\n"
        "G28 X0 Y0                      ;move X/Y to min endstops, so the head is out of the way\n"
        "M84                         ;steppers off\n"
        "G90                         ;absolute positioning\n";
}

#undef STRINGIFY
#undef SETTING

bool ConfigSettings::setSetting(const char* key, const char* value)
{
    for(unsigned int n=0; n < _index.size(); n++)
    {
        if (strcasecmp(key, _index[n].key) == 0)
        {
            *_index[n].ptr = atoi(value);
            return true;
        }
    }
    if (strcasecmp(key, "startCode") == 0)
    {
        this->startCode = value;
        return true;
    }
    if (strcasecmp(key, "endCode") == 0)
    {
        this->endCode = value;
        return true;
    }
    return false;
}

bool ConfigSettings::readSettings(const char* path) {
    std::ifstream config(path);
    std::string line;
    size_t line_number = 0;

    while(config.good()) {
        size_t pos = std::string::npos;
        std::getline(config, line);
        line_number += 1;

        // De-comment and trim, skipping anything that shows up empty
        pos = line.find_first_of('#');
        if(pos != std::string::npos) line.erase(pos);
        TRIM_STRING(line);
        if(line.length() == 0) continue;

        // Split into key = val
        std::string key(""), val("");
        pos = line.find_first_of('=');
        if(pos != std::string::npos && line.length() > (pos + 1)) {
            key = line.substr(0, pos);
            val = line.substr(pos + 1);
            TRIM_STRING(key);
            TRIM_STRING(val);
        }

        // Fail if we don't get a key and val
        if(key.length() == 0 || val.length() == 0) {
            logError("Config(%s): Line %zd: No key value pair found\n", path, line_number);
            return false;
        }

        // Set a config setting for the current K=V
        if(!setSetting(key.c_str(), val.c_str())) {
            logError("Config(%s):L%zd: Failed to set '%s' to '%s'\n", path, line_number, key.c_str(), val.c_str());
        }
    }

    return true;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: ManifestDefines.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: mtg $ $Date: 2001-10-02 22:29:42 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _MANIFEST_DEFINES_HXX
#define _MANIFEST_DEFINES_HXX

#define ELEMENT_MANIFEST "manifest:manifest"
#define ATTRIBUTE_XMLNS "xmlns:manifest"
#define MANIFEST_NAMESPACE "http://openoffice.org/2001/manifest"
#define MANIFEST_DOCTYPE "<!DOCTYPE manifest:manifest PUBLIC \"-//OpenOffice.org//DTD Manifest 1.0//EN\" \"Manifest.dtd\">"
#define ATTRIBUTE_CDATA "CDATA"

#define ELEMENT_FILE_ENTRY "manifest:file-entry"
#define ATTRIBUTE_FULL_PATH "manifest:full-path"
#define ATTRIBUTE_MEDIA_TYPE "manifest:media-type"
#define ATTRIBUTE_SIZE "manifest:size"

#define ELEMENT_ENCRYPTION_DATA "manifest:encryption-data"
#define ATTRIBUTE_CHECKSUM_TYPE "manifest:checksum-type"
#define ATTRIBUTE_CHECKSUM "manifest:checksum"

#define ELEMENT_ALGORITHM "manifest:algorithm"
#define ATTRIBUTE_ALGORITHM_NAME "manifest:algorithm-name"
#define ATTRIBUTE_INITIALISATION_VECTOR "manifest:initialisation-vector"

#define ELEMENT_KEY_DERIVATION "manifest:key-derivation"
#define ATTRIBUTE_KEY_DERIVATION_NAME "manifest:key-derivation-name"
#define ATTRIBUTE_SALT "manifest:salt"
#define ATTRIBUTE_ITERATION_COUNT "manifest:iteration-count"
#define CHECKSUM_TYPE "SHA1/1K"

#endif
<commit_msg>INTEGRATION: CWS oasisbf4 (1.5.186); FILE MERGED 2005/01/11 12:22:00 mav 1.5.186.1: #i38186# provide correct namespace information<commit_after>/*************************************************************************
 *
 *  $RCSfile: ManifestDefines.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-01-27 11:17:26 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _MANIFEST_DEFINES_HXX
#define _MANIFEST_DEFINES_HXX

#define ELEMENT_MANIFEST "manifest:manifest"
#define ATTRIBUTE_XMLNS "xmlns:manifest"
#define MANIFEST_NAMESPACE "http://openoffice.org/2001/manifest"
#define MANIFEST_OASIS_NAMESPACE "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"
#define MANIFEST_DOCTYPE "<!DOCTYPE manifest:manifest PUBLIC \"-//OpenOffice.org//DTD Manifest 1.0//EN\" \"Manifest.dtd\">"
#define ATTRIBUTE_CDATA "CDATA"

#define ELEMENT_FILE_ENTRY "manifest:file-entry"
#define ATTRIBUTE_FULL_PATH "manifest:full-path"
#define ATTRIBUTE_MEDIA_TYPE "manifest:media-type"
#define ATTRIBUTE_SIZE "manifest:size"

#define ELEMENT_ENCRYPTION_DATA "manifest:encryption-data"
#define ATTRIBUTE_CHECKSUM_TYPE "manifest:checksum-type"
#define ATTRIBUTE_CHECKSUM "manifest:checksum"

#define ELEMENT_ALGORITHM "manifest:algorithm"
#define ATTRIBUTE_ALGORITHM_NAME "manifest:algorithm-name"
#define ATTRIBUTE_INITIALISATION_VECTOR "manifest:initialisation-vector"

#define ELEMENT_KEY_DERIVATION "manifest:key-derivation"
#define ATTRIBUTE_KEY_DERIVATION_NAME "manifest:key-derivation-name"
#define ATTRIBUTE_SALT "manifest:salt"
#define ATTRIBUTE_ITERATION_COUNT "manifest:iteration-count"
#define CHECKSUM_TYPE "SHA1/1K"

#endif
<|endoftext|>


<commit_before>/**
 * Appcelerator Titanium - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2009 Appcelerator, Inc. All Rights Reserved.
 */

#include "pipe.h"
#include "native_pipe.h"
#include <vector>
#include <cstring>

#if defined(OS_WIN32)
# include "win32/win32_pipe.h"
#else
# include "posix/posix_pipe.h"
#endif

namespace ti
{
	Pipe::Pipe(const char *type) :
		KEventObject(type),
		active(true),
		eventsThreadAdapter(0)
	{
		//TODO doc me
		SetMethod("close", &Pipe::_Close);
		SetMethod("write", &Pipe::_Write);
		SetMethod("flush", &Pipe::_Flush);
		SetMethod("attach", &Pipe::_Attach);
		SetMethod("detach", &Pipe::_Detach);
		SetMethod("isAttached", &Pipe::_IsAttached);

		this->eventsThreadAdapter =
			new Poco::RunnableAdapter<Pipe>(*this, &Pipe::FireEvents);
		this->eventsThread.start(*this->eventsThreadAdapter);
	}

	Pipe::~Pipe()
	{
		active = false;
		eventsThread.join();
		delete eventsThreadAdapter;
	}

	void Pipe::Attach(SharedKObject object)
	{
		Poco::Mutex::ScopedLock lock(attachedMutex);
		attachedObjects.push_back(object);
	}

	void Pipe::Detach(SharedKObject object)
	{
		Poco::Mutex::ScopedLock lock(attachedMutex);
		std::vector<SharedKObject>::iterator i = attachedObjects.begin();
		while (i != attachedObjects.end())
		{
			SharedKObject obj = *i;
			if (obj->Equals(object))
			{
				i = attachedObjects.erase(i);
			}
			else
			{
				i++;
			}
		}
	}

	bool Pipe::IsAttached()
	{
		Poco::Mutex::ScopedLock lock(attachedMutex);
		return attachedObjects.size() > 0;
	}

	int Pipe::FindFirstLineFeed(char *data, int length, int *charsToErase)
	{
		int newline = -1;
		for (int i = 0; i < length; i++)
		{
			if (data[i] == '\n')
			{
				newline = i;
				*charsToErase = 1;
				break;
			}
			else if (data[i] == '\r')
			{
				if (i < length-1 && data[i+1] == '\n')
				{
					newline = i+1;
					*charsToErase = 2;
					break;
				}
			}
		}

		return newline;
	}

	AutoPipe Pipe::Clone()
	{
		AutoPipe pipe = new Pipe();
		return pipe;
	}

	void Pipe::_Attach(const ValueList& args, SharedValue result)
	{
		args.VerifyException("attach", "o");
		this->Attach(args.at(0)->ToObject());
	}

	void Pipe::_Detach(const ValueList& args, SharedValue result)
	{
		args.VerifyException("detach", "o");
		this->Detach(args.at(0)->ToObject());
	}

	void Pipe::_IsAttached(const ValueList& args, SharedValue result)
	{
		result->SetBool(this->IsAttached());
	}

	void Pipe::_Write(const ValueList& args, SharedValue result)
	{
		args.VerifyException("write", "o|s");

		AutoBlob blob = new Blob();
		if (args.at(0)->IsObject())
		{
			blob = args.at(0)->ToObject().cast<Blob>();
		}
		else if (args.at(0)->IsString())
		{
			blob = new Blob(args.at(0)->ToString());
		}

		if (blob.isNull())
		{
			throw ValueException::FromString("Pipe.write argument should be a Blob or string");
		}

		int written = this->Write(blob);
		result->SetInt(written);
	}

	void Pipe::_Flush(const ValueList& args, SharedValue result)
	{
		this->Flush();
	}

	void Pipe::_Close(const ValueList& args, SharedValue result)
	{
		this->Close();
	}

	int Pipe::Write(AutoBlob blob)
	{
		{ // Start the callbacks
			Poco::Mutex::ScopedLock lock(buffersMutex);
			buffers.push(blob);
		}

		// We want this to execute on the same thread and to make all
		// our writeable objects thread safe. This will allow data to
		// flow through pipes more quickly.
		{
			Poco::Mutex::ScopedLock lock(attachedMutex);
			for (size_t i = 0; i < attachedObjects.size(); i++)
			{
				this->CallWrite(attachedObjects.at(i), blob);
			}
		}

		return blob->Length();
	}

	void Pipe::CallWrite(SharedKObject target, AutoBlob blob)
	{
		SharedKMethod writeMethod = target->GetMethod("write");

		if (writeMethod.isNull())
		{
			logger->Error("Target object did not have a write method");
			return;
		}
		else
		{
			try
			{
				writeMethod->Call(ValueList(Value::NewObject(blob)));
			}
			catch (ValueException &e)
			{
				SharedString ss = e.DisplayString();
				logger->Error("Exception while trying to write to target: %s",
					ss->c_str());
			}
		}
	}

	void Pipe::Close()
	{
		{ // A Null Blob on the qeueue signals a close event
			Poco::Mutex::ScopedLock lock(buffersMutex);
			buffers.push(0);
		}

		// Call the close method on our attached objects
		{
			Poco::Mutex::ScopedLock lock(attachedMutex);
			for (size_t i = 0; i < attachedObjects.size(); i++)
			{
				this->CallClose(attachedObjects.at(i));
			}
		}
	}

	void Pipe::CallClose(SharedKObject target)
	{
		SharedKMethod closeMethod = target->GetMethod("close");

		if (closeMethod.isNull())
		{
			logger->Warn("Target object did not have a write method");
			return;
		}
		else
		{
			try
			{
				closeMethod->Call(ValueList());
			}
			catch (ValueException &e)
			{
				SharedString ss = e.DisplayString();
				logger->Error("Exception while trying to write to target: %s",
					ss->c_str());
			}
		}
	}

	void Pipe::Flush()
	{
	}

	void Pipe::FireReadBuffers()
	{
		AutoBlob blob = 0;
		for (size_t i = 0; i < buffers.size(); i++)
		{
			{
				Poco::Mutex::ScopedLock lock(buffersMutex);
				blob = buffers.front();
				buffers.pop();
			}

			if (!blob.isNull())
			{
				this->duplicate();
				AutoPtr<KEventObject> autothis = this;
				AutoPtr<Event> event = new ReadEvent(autothis, blob);
				this->FireEvent(event);
				blob = 0;
			}
			else
			{
				// A null blob signifies a close event
				this->FireEvent(Event::CLOSE);
				this->FireEvent(Event::CLOSED);
			}
		}
	}

	void Pipe::FireEvents()
	{
		while (active || buffers.size() > 0)
		{
			FireReadBuffers();
			Poco::Thread::sleep(50);
		}
	}
}
<commit_msg>Protect the FireEvents buffer a little more thoroughly.<commit_after>/**
 * Appcelerator Titanium - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2009 Appcelerator, Inc. All Rights Reserved.
 */

#include "pipe.h"
#include "native_pipe.h"
#include <vector>
#include <cstring>

#if defined(OS_WIN32)
# include "win32/win32_pipe.h"
#else
# include "posix/posix_pipe.h"
#endif

namespace ti
{
	Pipe::Pipe(const char *type) :
		KEventObject(type),
		active(true),
		eventsThreadAdapter(0)
	{
		//TODO doc me
		SetMethod("close", &Pipe::_Close);
		SetMethod("write", &Pipe::_Write);
		SetMethod("flush", &Pipe::_Flush);
		SetMethod("attach", &Pipe::_Attach);
		SetMethod("detach", &Pipe::_Detach);
		SetMethod("isAttached", &Pipe::_IsAttached);

		this->eventsThreadAdapter =
			new Poco::RunnableAdapter<Pipe>(*this, &Pipe::FireEvents);
		this->eventsThread.start(*this->eventsThreadAdapter);
	}

	Pipe::~Pipe()
	{
		active = false;
		eventsThread.join();
		delete eventsThreadAdapter;
	}

	void Pipe::Attach(SharedKObject object)
	{
		Poco::Mutex::ScopedLock lock(attachedMutex);
		attachedObjects.push_back(object);
	}

	void Pipe::Detach(SharedKObject object)
	{
		Poco::Mutex::ScopedLock lock(attachedMutex);
		std::vector<SharedKObject>::iterator i = attachedObjects.begin();
		while (i != attachedObjects.end())
		{
			SharedKObject obj = *i;
			if (obj->Equals(object))
			{
				i = attachedObjects.erase(i);
			}
			else
			{
				i++;
			}
		}
	}

	bool Pipe::IsAttached()
	{
		Poco::Mutex::ScopedLock lock(attachedMutex);
		return attachedObjects.size() > 0;
	}

	int Pipe::FindFirstLineFeed(char *data, int length, int *charsToErase)
	{
		int newline = -1;
		for (int i = 0; i < length; i++)
		{
			if (data[i] == '\n')
			{
				newline = i;
				*charsToErase = 1;
				break;
			}
			else if (data[i] == '\r')
			{
				if (i < length-1 && data[i+1] == '\n')
				{
					newline = i+1;
					*charsToErase = 2;
					break;
				}
			}
		}

		return newline;
	}

	AutoPipe Pipe::Clone()
	{
		AutoPipe pipe = new Pipe();
		return pipe;
	}

	void Pipe::_Attach(const ValueList& args, SharedValue result)
	{
		args.VerifyException("attach", "o");
		this->Attach(args.at(0)->ToObject());
	}

	void Pipe::_Detach(const ValueList& args, SharedValue result)
	{
		args.VerifyException("detach", "o");
		this->Detach(args.at(0)->ToObject());
	}

	void Pipe::_IsAttached(const ValueList& args, SharedValue result)
	{
		result->SetBool(this->IsAttached());
	}

	void Pipe::_Write(const ValueList& args, SharedValue result)
	{
		args.VerifyException("write", "o|s");

		AutoBlob blob = new Blob();
		if (args.at(0)->IsObject())
		{
			blob = args.at(0)->ToObject().cast<Blob>();
		}
		else if (args.at(0)->IsString())
		{
			blob = new Blob(args.at(0)->ToString());
		}

		if (blob.isNull())
		{
			throw ValueException::FromString("Pipe.write argument should be a Blob or string");
		}

		int written = this->Write(blob);
		result->SetInt(written);
	}

	void Pipe::_Flush(const ValueList& args, SharedValue result)
	{
		this->Flush();
	}

	void Pipe::_Close(const ValueList& args, SharedValue result)
	{
		this->Close();
	}

	int Pipe::Write(AutoBlob blob)
	{
		{ // Start the callbacks
			Poco::Mutex::ScopedLock lock(buffersMutex);
			buffers.push(blob);
		}

		// We want this to execute on the same thread and to make all
		// our writeable objects thread safe. This will allow data to
		// flow through pipes more quickly.
		{
			Poco::Mutex::ScopedLock lock(attachedMutex);
			for (size_t i = 0; i < attachedObjects.size(); i++)
			{
				this->CallWrite(attachedObjects.at(i), blob);
			}
		}

		return blob->Length();
	}

	void Pipe::CallWrite(SharedKObject target, AutoBlob blob)
	{
		SharedKMethod writeMethod = target->GetMethod("write");

		if (writeMethod.isNull())
		{
			logger->Error("Target object did not have a write method");
			return;
		}
		else
		{
			try
			{
				writeMethod->Call(ValueList(Value::NewObject(blob)));
			}
			catch (ValueException &e)
			{
				SharedString ss = e.DisplayString();
				logger->Error("Exception while trying to write to target: %s",
					ss->c_str());
			}
		}
	}

	void Pipe::Close()
	{
		{ // A Null Blob on the qeueue signals a close event
			Poco::Mutex::ScopedLock lock(buffersMutex);
			buffers.push(0);
		}

		// Call the close method on our attached objects
		{
			Poco::Mutex::ScopedLock lock(attachedMutex);
			for (size_t i = 0; i < attachedObjects.size(); i++)
			{
				this->CallClose(attachedObjects.at(i));
			}
		}
	}

	void Pipe::CallClose(SharedKObject target)
	{
		SharedKMethod closeMethod = target->GetMethod("close");

		if (closeMethod.isNull())
		{
			logger->Warn("Target object did not have a write method");
			return;
		}
		else
		{
			try
			{
				closeMethod->Call(ValueList());
			}
			catch (ValueException &e)
			{
				SharedString ss = e.DisplayString();
				logger->Error("Exception while trying to write to target: %s",
					ss->c_str());
			}
		}
	}

	void Pipe::Flush()
	{
	}

	void Pipe::FireReadBuffers()
	{
		AutoBlob blob = 0;
		int size = 0;
		{
			Poco::Mutex::ScopedLock lock(buffersMutex);
			size = buffers.size();
		}
		while (size > 0)
		{
			{
				Poco::Mutex::ScopedLock lock(buffersMutex);
				blob = buffers.front();
				buffers.pop();
			}

			if (!blob.isNull())
			{
				this->duplicate();
				AutoPtr<KEventObject> autothis = this;
				AutoPtr<Event> event = new ReadEvent(autothis, blob);
				this->FireEvent(event);
				blob = 0;
			}
			else
			{
				// A null blob signifies a close event
				this->FireEvent(Event::CLOSE);
				this->FireEvent(Event::CLOSED);
			}

			{
				Poco::Mutex::ScopedLock lock(buffersMutex);
				size = buffers.size();
			}
		}

	}

	void Pipe::FireEvents()
	{
		while (active || buffers.size() > 0)
		{
			FireReadBuffers();
			Poco::Thread::sleep(50);
		}
	}
}
<|endoftext|>


<commit_before>
#include "cmbNucPartsTreeItem.h"
#include "cmbNucAssembly.h"
#include "cmbNucCore.h"
#include <QFileInfo>
#include <QFont>
#include <QBrush>
#include <QStyle>
#include <QIcon>

//-----------------------------------------------------------------------------
cmbNucPartsTreeItem::cmbNucPartsTreeItem(
  QTreeWidgetItem* pNode, AssyPartObj* obj)
:  FileChanged(false), NeedGeneration(false),
   QTreeWidgetItem(pNode), PartObject(obj)
{
  this->connection = new cmbNucPartsTreeItemConnection();
  this->connection->v = this;
  std::string fname = this->PartObject->getFileName();
  if(fname.empty())
  {
    this->setText(3, "");
  }
  else
  {
    QFileInfo fi(fname.c_str());
    this->setText(3, fi.fileName());
  }
}

//-----------------------------------------------------------------------------
cmbNucPartsTreeItem::~cmbNucPartsTreeItem()
{
  delete this->connection;
}
//-----------------------------------------------------------------------------
void cmbNucPartsTreeItem::setText ( int column, const QString & text )
{
  this->QTreeWidgetItem::setText(column, text);
  if(column == 0)
    {
    this->PreviousText = text;
    }
}
//-----------------------------------------------------------------------------
void cmbNucPartsTreeItem::setData (
  int column, int role, const QVariant & value )
{
  if(column == 0 && role == Qt::EditRole) // keep the original text
    {
    this->PreviousText = this->text(column);
    }
  this->QTreeWidgetItem::setData(column, role, value);
}

void cmbNucPartsTreeItemConnection::checkSaveAndGenerate()
{
  v->checkSaveAndGenerate();
}

void cmbNucPartsTreeItem::checkSaveAndGenerate()
{
  enumNucPartsType selType = PartObject->GetType();
  bool need_to_save = false;
  bool need_to_generate = false;
  switch(selType)
    {
    case CMBNUC_CORE:
      {
      cmbNucCore * core = dynamic_cast<cmbNucCore*>(PartObject);
      need_to_save = core->changeSinceLastSave();
      need_to_generate = core->changeSinceLastGenerate();
      }
      break;
    case CMBNUC_ASSEMBLY:
      {
      cmbNucAssembly * assy = dynamic_cast<cmbNucAssembly*>(PartObject);
      need_to_save = assy->changeSinceLastSave();
      need_to_generate = assy->changeSinceLastGenerate();
      }
      break;
    default:
      return;
    }
  this->setHightlights(need_to_save, need_to_generate);
}

bool cmbNucPartsTreeItem::fileChanged() const
{
  return FileChanged;
}

bool cmbNucPartsTreeItem::needGeneration() const
{
  return NeedGeneration;
}

void cmbNucPartsTreeItem::setHightlights(bool fc, bool ng)
{
  FileChanged = fc;
  NeedGeneration = ng;
  if( FileChanged )
  {
    this->setText( 1, QChar(9999) );
  }
  else
  {
    QBrush b (Qt::green);
    setBackground( 1 , b );
    setForeground( 1 , b );
    this->setText( 1, " " );
  }

  std::string fname = this->PartObject->getFileName();
  if(fname.empty())
  {
    this->setText(3, "");
  }
  else
  {
    QFileInfo fi(fname.c_str());
    this->setText(3, fi.fileName());
  }

  if(NeedGeneration)
  {
    QBrush b;
    setForeground( 2 , b );
    this->setText( 2, QChar(9746) );
  }
  else
  {
    QBrush b (Qt::green);
    setBackground( 2 , b );
    setForeground( 2 , b );
    this->setText( 2, " " );
  }
}

QVariant cmbNucPartsTreeItem::data( int index, int role ) const
{
  if(role == Qt::ToolTipRole && index == 3)
  {
    std::string fname = this->PartObject->getFileName();
    if(!fname.empty())
    {
      return QVariant(fname.c_str());
    }
  }
  if(role == Qt::ToolTipRole && index == 1)
  {
    if(FileChanged)
    {
      return QVariant("Needs to be saved");
    }
    else
    {
      return QVariant("Saved");
    }
  }
  if(role == Qt::ToolTipRole && index == 2)
  {
    if(NeedGeneration)
    {
      return QVariant("MeshKit needs to be run");
    }
    else
    {
      return QVariant("MeshKit files up to date");
    }
  }
  return this->QTreeWidgetItem::data(index, role);
}
<commit_msg>fixed missing clear of color<commit_after>
#include "cmbNucPartsTreeItem.h"
#include "cmbNucAssembly.h"
#include "cmbNucCore.h"
#include <QFileInfo>
#include <QFont>
#include <QBrush>
#include <QStyle>
#include <QIcon>

//-----------------------------------------------------------------------------
cmbNucPartsTreeItem::cmbNucPartsTreeItem(
  QTreeWidgetItem* pNode, AssyPartObj* obj)
:  FileChanged(false), NeedGeneration(false),
   QTreeWidgetItem(pNode), PartObject(obj)
{
  this->connection = new cmbNucPartsTreeItemConnection();
  this->connection->v = this;
  std::string fname = this->PartObject->getFileName();
  if(fname.empty())
  {
    this->setText(3, "");
  }
  else
  {
    QFileInfo fi(fname.c_str());
    this->setText(3, fi.fileName());
  }
}

//-----------------------------------------------------------------------------
cmbNucPartsTreeItem::~cmbNucPartsTreeItem()
{
  delete this->connection;
}
//-----------------------------------------------------------------------------
void cmbNucPartsTreeItem::setText ( int column, const QString & text )
{
  this->QTreeWidgetItem::setText(column, text);
  if(column == 0)
    {
    this->PreviousText = text;
    }
}
//-----------------------------------------------------------------------------
void cmbNucPartsTreeItem::setData (
  int column, int role, const QVariant & value )
{
  if(column == 0 && role == Qt::EditRole) // keep the original text
    {
    this->PreviousText = this->text(column);
    }
  this->QTreeWidgetItem::setData(column, role, value);
}

void cmbNucPartsTreeItemConnection::checkSaveAndGenerate()
{
  v->checkSaveAndGenerate();
}

void cmbNucPartsTreeItem::checkSaveAndGenerate()
{
  enumNucPartsType selType = PartObject->GetType();
  bool need_to_save = false;
  bool need_to_generate = false;
  switch(selType)
    {
    case CMBNUC_CORE:
      {
      cmbNucCore * core = dynamic_cast<cmbNucCore*>(PartObject);
      need_to_save = core->changeSinceLastSave();
      need_to_generate = core->changeSinceLastGenerate();
      }
      break;
    case CMBNUC_ASSEMBLY:
      {
      cmbNucAssembly * assy = dynamic_cast<cmbNucAssembly*>(PartObject);
      need_to_save = assy->changeSinceLastSave();
      need_to_generate = assy->changeSinceLastGenerate();
      }
      break;
    default:
      return;
    }
  this->setHightlights(need_to_save, need_to_generate);
}

bool cmbNucPartsTreeItem::fileChanged() const
{
  return FileChanged;
}

bool cmbNucPartsTreeItem::needGeneration() const
{
  return NeedGeneration;
}

void cmbNucPartsTreeItem::setHightlights(bool fc, bool ng)
{
  FileChanged = fc;
  NeedGeneration = ng;
  if( FileChanged )
  {
    this->setText( 1, QChar(9999) );
    QBrush b;
    setBackground( 1 , b );
    setForeground( 1 , b );
  }
  else
  {
    QBrush b (Qt::green);
    setBackground( 1 , b );
    setForeground( 1 , b );
    this->setText( 1, " " );
  }

  std::string fname = this->PartObject->getFileName();
  if(fname.empty())
  {
    this->setText(3, "");
  }
  else
  {
    QFileInfo fi(fname.c_str());
    this->setText(3, fi.fileName());
  }

  if(NeedGeneration)
  {
    QBrush b;
    setBackground( 2 , b );
    setForeground( 2 , b );
    this->setText( 2, QChar(9746) );
  }
  else
  {
    QBrush b (Qt::green);
    setBackground( 2 , b );
    setForeground( 2 , b );
    this->setText( 2, " " );
  }
}

QVariant cmbNucPartsTreeItem::data( int index, int role ) const
{
  if(role == Qt::ToolTipRole && index == 3)
  {
    std::string fname = this->PartObject->getFileName();
    if(!fname.empty())
    {
      return QVariant(fname.c_str());
    }
  }
  if(role == Qt::ToolTipRole && index == 1)
  {
    if(FileChanged)
    {
      return QVariant("Needs to be saved");
    }
    else
    {
      return QVariant("Saved");
    }
  }
  if(role == Qt::ToolTipRole && index == 2)
  {
    if(NeedGeneration)
    {
      return QVariant("MeshKit needs to be run");
    }
    else
    {
      return QVariant("MeshKit files up to date");
    }
  }
  return this->QTreeWidgetItem::data(index, role);
}
<|endoftext|>


<commit_before>/******************************************************************************

  This source file is part of the Avogadro project.

  Copyright 2012 Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  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.

******************************************************************************/

#include "pluginmanager.h"

#include "transport/connectionlistenerfactory.h"

#include <QtCore/QCoreApplication>
#include <QtCore/QMutex>
#include <QtCore/QPluginLoader>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>

#include <QtCore/QDebug>

namespace MoleQueue
{

namespace
{
// Compiler initializes this static pointer to 0.
static PluginManager *pluginManagerInstance;
}

PluginManager::PluginManager(QObject *p) : QObject(p)
{
  m_relativeToApp = "/../lib/molequeue/plugins";
#ifdef __APPLE__
  QString buildRelative("/../../../..");
  qDebug() << QCoreApplication::applicationDirPath() + buildRelative
              + "/CMakeCache.txt";
  if (QFileInfo(QCoreApplication::applicationDirPath() + buildRelative
                + "/CMakeCache.txt").exists()) {
    qDebug() << QCoreApplication::applicationDirPath()
                + buildRelative
                + "/lib/molequeue/plugins";
    m_pluginDirs.append(QDir(QCoreApplication::applicationDirPath()
                             + buildRelative
                             + "/lib/molequeue/plugins").absolutePath());
    qDebug() << QDir(QCoreApplication::applicationDirPath()
                     + buildRelative
                     + "/lib/molequeue/plugins").absolutePath();
  }
#endif

// For multi configuration types add correct one to search path.
#ifdef MULTI_CONFIG_BUILD
  // First extract the build type ( the name of the application dir )
  QDir appDir(QCoreApplication::applicationDirPath());
  QString buildType = appDir.dirName();

  QDir dir(QCoreApplication::applicationDirPath()
           + "/../../lib/molequeue/plugins/"+ buildType);
  m_pluginDirs.append(dir.absolutePath());
#else
  QDir dir(QCoreApplication::applicationDirPath() + m_relativeToApp);
  m_pluginDirs.append(dir.absolutePath());
#endif
}

PluginManager::~PluginManager()
{
}

PluginManager * PluginManager::instance()
{
  static QMutex mutex;
  if (!pluginManagerInstance) {
    mutex.lock();
    if (!pluginManagerInstance)
      pluginManagerInstance = new PluginManager(QCoreApplication::instance());
    mutex.unlock();
  }
  return pluginManagerInstance;
}

void PluginManager::load()
{
  foreach(const QString &dir, m_pluginDirs)
    load(dir);
}

void PluginManager::load(const QString &path)
{
  QDir dir(path);
  qDebug() << dir.entryList(QDir::Files);
  foreach(const QString &pluginPath, dir.entryList(QDir::Files)) {
    QPluginLoader pluginLoader(dir.absolutePath() + QDir::separator() + pluginPath);

    if (pluginLoader.isLoaded()) {
      qDebug() << "Plugin already loaded: " << pluginLoader.fileName();
      continue;
    }

    QObject *pluginInstance = pluginLoader.instance();

    // Check if the plugin loaded correctly. Keep debug output for now, should
    // go away once we have verified this (or added to a logger).
    if (!pluginInstance) {
      qDebug() << "Failed to load" << pluginPath << "error"
               << pluginLoader.errorString();
    }
    else {
      qDebug() << "Loaded" << pluginPath << "->";
      pluginInstance->dumpObjectInfo();
    }

    // Now attempt to cast to known factory types, and make it available.
    ConnectionListenerFactory *connectionListenerFactory =
      qobject_cast<ConnectionListenerFactory *>(pluginInstance);
    if (connectionListenerFactory &&
        !m_connectionListenerFactories.contains(connectionListenerFactory))
      m_connectionListenerFactories.append(connectionListenerFactory);
  }
}

QList<ConnectionListenerFactory *> PluginManager::connectionListenerFactories() const
{
  return m_connectionListenerFactories;
}

} // End MoleQueue namespace
<commit_msg>Fix for installed MoleQueue relative plugin paths<commit_after>/******************************************************************************

  This source file is part of the Avogadro project.

  Copyright 2012 Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  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.

******************************************************************************/

#include "pluginmanager.h"

#include "transport/connectionlistenerfactory.h"

#include <QtCore/QCoreApplication>
#include <QtCore/QMutex>
#include <QtCore/QPluginLoader>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>

#include <QtCore/QDebug>

namespace MoleQueue
{

namespace
{
// Compiler initializes this static pointer to 0.
static PluginManager *pluginManagerInstance;
}

PluginManager::PluginManager(QObject *p) : QObject(p)
{
  m_relativeToApp = "/../lib/molequeue/plugins";
#ifdef __APPLE__
  QString buildRelative("/../../../..");
  m_relativeToApp = buildRelative + m_relativeToApp;
  qDebug() << QCoreApplication::applicationDirPath() + buildRelative
              + "/CMakeCache.txt";
  if (QFileInfo(QCoreApplication::applicationDirPath() + buildRelative
                + "/CMakeCache.txt").exists()) {
    qDebug() << QCoreApplication::applicationDirPath()
                + buildRelative
                + "/lib/molequeue/plugins";
    m_pluginDirs.append(QDir(QCoreApplication::applicationDirPath()
                             + buildRelative
                             + "/lib/molequeue/plugins").absolutePath());
    qDebug() << QDir(QCoreApplication::applicationDirPath()
                     + buildRelative
                     + "/lib/molequeue/plugins").absolutePath();
  }
#endif

// For multi configuration types add correct one to search path.
#ifdef MULTI_CONFIG_BUILD
  // First extract the build type ( the name of the application dir )
  QDir appDir(QCoreApplication::applicationDirPath());
  QString buildType = appDir.dirName();

  QDir dir(QCoreApplication::applicationDirPath()
           + "/../../lib/molequeue/plugins/"+ buildType);
  m_pluginDirs.append(dir.absolutePath());
#else
  QDir dir(QCoreApplication::applicationDirPath() + m_relativeToApp);
  m_pluginDirs.append(dir.absolutePath());
#endif
}

PluginManager::~PluginManager()
{
}

PluginManager * PluginManager::instance()
{
  static QMutex mutex;
  if (!pluginManagerInstance) {
    mutex.lock();
    if (!pluginManagerInstance)
      pluginManagerInstance = new PluginManager(QCoreApplication::instance());
    mutex.unlock();
  }
  return pluginManagerInstance;
}

void PluginManager::load()
{
  foreach(const QString &dir, m_pluginDirs)
    load(dir);
}

void PluginManager::load(const QString &path)
{
  QDir dir(path);
  qDebug() << dir.entryList(QDir::Files);
  foreach(const QString &pluginPath, dir.entryList(QDir::Files)) {
    QPluginLoader pluginLoader(dir.absolutePath() + QDir::separator() + pluginPath);

    if (pluginLoader.isLoaded()) {
      qDebug() << "Plugin already loaded: " << pluginLoader.fileName();
      continue;
    }

    QObject *pluginInstance = pluginLoader.instance();

    // Check if the plugin loaded correctly. Keep debug output for now, should
    // go away once we have verified this (or added to a logger).
    if (!pluginInstance) {
      qDebug() << "Failed to load" << pluginPath << "error"
               << pluginLoader.errorString();
    }
    else {
      qDebug() << "Loaded" << pluginPath << "->";
      pluginInstance->dumpObjectInfo();
    }

    // Now attempt to cast to known factory types, and make it available.
    ConnectionListenerFactory *connectionListenerFactory =
      qobject_cast<ConnectionListenerFactory *>(pluginInstance);
    if (connectionListenerFactory &&
        !m_connectionListenerFactories.contains(connectionListenerFactory))
      m_connectionListenerFactories.append(connectionListenerFactory);
  }
}

QList<ConnectionListenerFactory *> PluginManager::connectionListenerFactories() const
{
  return m_connectionListenerFactories;
}

} // End MoleQueue namespace
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: stringtransfer.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 16:22: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
 *
 ************************************************************************/

#ifndef _SVTOOLS_STRINGTRANSFER_HXX_
#include "stringtransfer.hxx"
#endif

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

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::datatransfer;

    //====================================================================
    //= OStringTransferable
    //====================================================================
    //--------------------------------------------------------------------
    OStringTransferable::OStringTransferable(const ::rtl::OUString& _rContent)
        :TransferableHelper()
        ,m_sContent( _rContent )
    {
    }

    //--------------------------------------------------------------------
    void OStringTransferable::AddSupportedFormats()
    {
        AddFormat(SOT_FORMAT_STRING);
    }

    //--------------------------------------------------------------------
    sal_Bool OStringTransferable::GetData( const DataFlavor& _rFlavor )
    {
        sal_uInt32 nFormat = SotExchange::GetFormat( _rFlavor );
        if (SOT_FORMAT_STRING == nFormat)
            return SetString( m_sContent, _rFlavor );

        return sal_False;
    }

    //====================================================================
    //= OStringTransfer
    //====================================================================
    //--------------------------------------------------------------------
    void OStringTransfer::CopyString( const ::rtl::OUString& _rContent, Window* _pWindow )
    {
        OStringTransferable* pTransferable = new OStringTransferable( _rContent );
        Reference< XTransferable > xTransfer = pTransferable;
        pTransferable->CopyToClipboard( _pWindow );
    }

    //--------------------------------------------------------------------
    sal_Bool OStringTransfer::PasteString( ::rtl::OUString& _rContent, Window* _pWindow )
    {
        TransferableDataHelper aClipboardData = TransferableDataHelper::CreateFromSystemClipboard( _pWindow );

        // check for a string format
        const DataFlavorExVector& rFormats = aClipboardData.GetDataFlavorExVector();
        for (   DataFlavorExVector::const_iterator aSearch = rFormats.begin();
                aSearch != rFormats.end();
                ++aSearch
            )
        {
            if (SOT_FORMAT_STRING == aSearch->mnSotId)
            {
                String sContent;
                sal_Bool bSuccess = aClipboardData.GetString( SOT_FORMAT_STRING, sContent );
                _rContent = sContent;
                return bSuccess;
            }
        }

        return sal_False;
    }

    //--------------------------------------------------------------------
    void OStringTransfer::StartStringDrag( const ::rtl::OUString& _rContent, Window* _pWindow, sal_Int8 _nDragSourceActions )
    {
        OStringTransferable* pTransferable = new OStringTransferable( _rContent );
        Reference< XTransferable > xTransfer = pTransferable;
        pTransferable->StartDrag(_pWindow, _nDragSourceActions);
    }

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

/*************************************************************************
 * history:
 *  $Log: not supported by cvs2svn $
 *  Revision 1.3.1096.1  2005/09/05 14:53:40  rt
 *  #i54170# Change license header: remove SISSL
 *
 *  Revision 1.3  2001/05/21 09:19:00  obr
 *  #81916# copy and paste only with window
 *
 *  Revision 1.2  2001/03/28 08:18:15  fs
 *  +StartStringDrag
 *
 *  Revision 1.1  2001/03/27 14:35:35  fs
 *  initial checkin - helper classes for clipboard handling of strings
 *
 *
 *  Revision 1.0 27.03.01 14:43:33  fs
 ************************************************************************/

<commit_msg>INTEGRATION: CWS rt15 (1.4.256); FILE MERGED 2006/06/27 10:18:40 rt 1.4.256.1: #i54459# CVS history removed from file.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: stringtransfer.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2006-07-25 09:48: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
 *
 ************************************************************************/

#ifndef _SVTOOLS_STRINGTRANSFER_HXX_
#include "stringtransfer.hxx"
#endif

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

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::datatransfer;

    //====================================================================
    //= OStringTransferable
    //====================================================================
    //--------------------------------------------------------------------
    OStringTransferable::OStringTransferable(const ::rtl::OUString& _rContent)
        :TransferableHelper()
        ,m_sContent( _rContent )
    {
    }

    //--------------------------------------------------------------------
    void OStringTransferable::AddSupportedFormats()
    {
        AddFormat(SOT_FORMAT_STRING);
    }

    //--------------------------------------------------------------------
    sal_Bool OStringTransferable::GetData( const DataFlavor& _rFlavor )
    {
        sal_uInt32 nFormat = SotExchange::GetFormat( _rFlavor );
        if (SOT_FORMAT_STRING == nFormat)
            return SetString( m_sContent, _rFlavor );

        return sal_False;
    }

    //====================================================================
    //= OStringTransfer
    //====================================================================
    //--------------------------------------------------------------------
    void OStringTransfer::CopyString( const ::rtl::OUString& _rContent, Window* _pWindow )
    {
        OStringTransferable* pTransferable = new OStringTransferable( _rContent );
        Reference< XTransferable > xTransfer = pTransferable;
        pTransferable->CopyToClipboard( _pWindow );
    }

    //--------------------------------------------------------------------
    sal_Bool OStringTransfer::PasteString( ::rtl::OUString& _rContent, Window* _pWindow )
    {
        TransferableDataHelper aClipboardData = TransferableDataHelper::CreateFromSystemClipboard( _pWindow );

        // check for a string format
        const DataFlavorExVector& rFormats = aClipboardData.GetDataFlavorExVector();
        for (   DataFlavorExVector::const_iterator aSearch = rFormats.begin();
                aSearch != rFormats.end();
                ++aSearch
            )
        {
            if (SOT_FORMAT_STRING == aSearch->mnSotId)
            {
                String sContent;
                sal_Bool bSuccess = aClipboardData.GetString( SOT_FORMAT_STRING, sContent );
                _rContent = sContent;
                return bSuccess;
            }
        }

        return sal_False;
    }

    //--------------------------------------------------------------------
    void OStringTransfer::StartStringDrag( const ::rtl::OUString& _rContent, Window* _pWindow, sal_Int8 _nDragSourceActions )
    {
        OStringTransferable* pTransferable = new OStringTransferable( _rContent );
        Reference< XTransferable > xTransfer = pTransferable;
        pTransferable->StartDrag(_pWindow, _nDragSourceActions);
    }

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

<|endoftext|>