<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "cling/Interpreter/DynamicLibraryManager.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/InvocationOptions.h"

#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

#ifdef LLVM_ON_WIN32
#include <Windows.h>
#include <shlobj.h>
#else
#include <limits.h> /* PATH_MAX */
#include <dlfcn.h>
#endif

namespace {
#if defined(LLVM_ON_UNIX)
  static void GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) {
    char* env_var = getenv("LD_LIBRARY_PATH");
#if __APPLE__
    if (!env_var)
      env_var = getenv("DYLD_LIBRARY_PATH");
    if (!env_var)
      env_var = getenv("DYLD_FALLBACK_LIBRARY_PATH");
#endif
    if (env_var != 0) {
      static const char PathSeparator = ':';
      const char* at = env_var;
      const char* delim = strchr(at, PathSeparator);
      while (delim != 0) {
        std::string tmp(at, size_t(delim-at));
        if (llvm::sys::fs::is_directory(tmp.c_str()))
          Paths.push_back(tmp);
        at = delim + 1;
        delim = strchr(at, PathSeparator);
      }

      if (*at != 0)
        if (llvm::sys::fs::is_directory(llvm::StringRef(at)))
          Paths.push_back(at);
    }
#if defined(__APPLE__) || defined(__CYGWIN__)
    Paths.push_back("/usr/local/lib/");
    Paths.push_back("/usr/X11R6/lib/");
    Paths.push_back("/usr/lib/");
    Paths.push_back("/lib/");

    Paths.push_back("/lib/x86_64-linux-gnu/");
    Paths.push_back("/usr/local/lib64/");
    Paths.push_back("/usr/lib64/");
    Paths.push_back("/lib64/");
#else
    static bool initialized = false;
    static std::vector<std::string> SysPaths;
    if (!initialized) {
      // trick to get the system search path
      std::string cmd("LD_DEBUG=libs LD_PRELOAD=DOESNOTEXIST ls 2>&1");
      FILE *pf = popen(cmd.c_str (), "r");
      std::string result = "";
      std::string sys_path = "";
      char buffer[128];
      while (!feof(pf)) {
        if (fgets(buffer, 128, pf) != NULL)
          result += buffer;
      }
      pclose(pf);
      std::size_t from
        = result.find("search path=", result.find("(LD_LIBRARY_PATH)"));
      std::size_t to = result.find("(system search path)");
      if (from != std::string::npos && to != std::string::npos) {
        from += 12;
        sys_path = result.substr(from, to-from);
        sys_path.erase(std::remove_if(sys_path.begin(), sys_path.end(), isspace),
                       sys_path.end());
        sys_path += ':';
      }
      static const char PathSeparator = ':';
      const char* at = sys_path.c_str();
      const char* delim = strchr(at, PathSeparator);
      while (delim != 0) {
        std::string tmp(at, size_t(delim-at));
        if (llvm::sys::fs::is_directory(tmp.c_str()))
          SysPaths.push_back(tmp);
        at = delim + 1;
        delim = strchr(at, PathSeparator);
      }
      initialized = true;
    }

    for (std::vector<std::string>::const_iterator I = SysPaths.begin(),
           E = SysPaths.end(); I != E; ++I)
      Paths.push_back((*I).c_str());
#endif
  }
#elif defined(LLVM_ON_WIN32)
  static void GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) {
    char buff[MAX_PATH];
    // Generic form of C:\Windows\System32
    HRESULT res =  SHGetFolderPathA(NULL,
                                    CSIDL_FLAG_CREATE | CSIDL_SYSTEM,
                                    NULL,
                                    SHGFP_TYPE_CURRENT,
                                    buff);
    if (res != S_OK) {
      assert(0 && "Failed to get system directory");
      return;
    }
    Paths.push_back(buff);

    // Reset buff.
    buff[0] = 0;
    // Generic form of C:\Windows
    res =  SHGetFolderPathA(NULL,
                            CSIDL_FLAG_CREATE | CSIDL_WINDOWS,
                            NULL,
                            SHGFP_TYPE_CURRENT,
                            buff);
    if (res != S_OK) {
      assert(0 && "Failed to get windows directory");
      return;
    }
    Paths.push_back(buff);
  }

  static bool is_dll(const char *filename) {
    bool is_dll = false;
    HANDLE hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    if (hFileMapping == INVALID_HANDLE_VALUE) {
      CloseHandle(hFile);
      return false;
    }
    LPVOID lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
    if (lpFileBase == NULL) {
      CloseHandle(hFileMapping);
      CloseHandle(hFile);
      return false;
    }
    PIMAGE_DOS_HEADER pDOSHeader = static_cast<PIMAGE_DOS_HEADER>(lpFileBase);
    if (pDOSHeader->e_magic == IMAGE_DOS_SIGNATURE) {
      PIMAGE_NT_HEADERS pNTHeader = reinterpret_cast<PIMAGE_NT_HEADERS>((PBYTE)lpFileBase + pDOSHeader->e_lfanew);
      if ((pNTHeader->Signature == IMAGE_NT_SIGNATURE) &&
          ((pNTHeader->FileHeader.Characteristics & IMAGE_FILE_DLL)))
        is_dll = true;
    }
    UnmapViewOfFile(lpFileBase);
    CloseHandle(hFileMapping);
    CloseHandle(hFile);
    return is_dll;
  }
#else
# error "Unsupported platform."
#endif

}

namespace cling {
  DynamicLibraryManager::DynamicLibraryManager(const InvocationOptions& Opts)
    : m_Opts(Opts), m_Callbacks(0) {
    GetSystemLibraryPaths(m_SystemSearchPaths);
    m_SystemSearchPaths.push_back(".");
  }

  DynamicLibraryManager::~DynamicLibraryManager() {}

  static bool isSharedLib(llvm::StringRef LibName, bool* exists = 0) {
    using namespace llvm::sys::fs;
    file_magic Magic;
    std::error_code Error = identify_magic(LibName, Magic);
    bool onDisk = (Error != std::errc::no_such_file_or_directory);
    if (exists)
      *exists = onDisk;

    return onDisk &&
#ifdef __APPLE__
      (Magic == file_magic::macho_fixed_virtual_memory_shared_lib
       || Magic == file_magic::macho_dynamically_linked_shared_lib
       || Magic == file_magic::macho_dynamically_linked_shared_lib_stub
       || Magic == file_magic::macho_universal_binary)
#elif defined(LLVM_ON_UNIX)
#ifdef __CYGWIN__
      (Magic == file_magic::pecoff_executable)
#else
      (Magic == file_magic::elf_shared_object)
#endif
#elif defined(LLVM_ON_WIN32)
      (Magic == file_magic::pecoff_executable || is_dll(LibName.str().c_str()))
#else
# error "Unsupported platform."
#endif
      ;
  }

  std::string
  DynamicLibraryManager::lookupLibInPaths(llvm::StringRef libStem) const {
    llvm::SmallVector<std::string, 128>
      Paths(m_Opts.LibSearchPath.begin(), m_Opts.LibSearchPath.end());
    Paths.append(m_SystemSearchPaths.begin(), m_SystemSearchPaths.end());

    for (llvm::SmallVectorImpl<std::string>::const_iterator
           IPath = Paths.begin(), E = Paths.end();IPath != E; ++IPath) {
      llvm::SmallString<512> ThisPath(*IPath); // FIXME: move alloc outside loop
      llvm::sys::path::append(ThisPath, libStem);
      bool exists;
      if (isSharedLib(ThisPath.str(), &exists))
        return ThisPath.str();
      if (exists)
        return "";
    }
    return "";
  }

  std::string
  DynamicLibraryManager::lookupLibMaybeAddExt(llvm::StringRef libStem) const {
    using namespace llvm::sys;

    std::string foundDyLib = lookupLibInPaths(libStem);

    if (foundDyLib.empty()) {
      // Add DyLib extension:
      llvm::SmallString<512> filenameWithExt(libStem);
#if defined(LLVM_ON_UNIX)
#ifdef __APPLE__
      llvm::SmallString<512>::iterator IStemEnd = filenameWithExt.end() - 1;
#endif
      static const char* DyLibExt = ".so";
#elif defined(LLVM_ON_WIN32)
      static const char* DyLibExt = ".dll";
#else
# error "Unsupported platform."
#endif
      filenameWithExt += DyLibExt;
      foundDyLib = lookupLibInPaths(filenameWithExt);
#ifdef __APPLE__
      if (foundDyLib.empty()) {
        filenameWithExt.erase(IStemEnd + 1, filenameWithExt.end());
        filenameWithExt += ".dylib";
        foundDyLib = lookupLibInPaths(filenameWithExt);
      }
#endif
    }

    if (foundDyLib.empty())
      return "";

    // get canonical path name and check if already loaded
#if defined(LLVM_ON_WIN32)
    llvm::SmallString<_MAX_PATH> FullPath("");
    char *res = _fullpath((char *)FullPath.data(), foundDyLib.c_str(), _MAX_PATH);
#else
    llvm::SmallString<PATH_MAX+1> FullPath("");
    char *res = realpath(foundDyLib.c_str(), (char *)FullPath.data());
#endif
    if (res == 0) {
      llvm::errs() << "cling::DynamicLibraryManager::lookupLibMaybeAddExt(): "
        "error getting real (canonical) path of library " << foundDyLib << '\n';
      return foundDyLib;
    }
    FullPath.set_size(strlen(res));
    return FullPath.str();
  }

  std::string DynamicLibraryManager::normalizePath(llvm::StringRef path) {
    // Make the path canonical if the file exists.
    struct stat buffer;
    if (stat(path.data(), &buffer) != 0)
      return "";
#if defined(LLVM_ON_WIN32)
    char buf[_MAX_PATH];
    char *res = _fullpath(buf, path.data(), _MAX_PATH);
#else
    char buf[PATH_MAX+1];
    char *res = realpath(path.data(), buf);
#endif
    if (res == 0) {
      assert(0 && "Cannot normalize!?");
      return "";
    }
    return res;
  }

  std::string
  DynamicLibraryManager::lookupLibrary(llvm::StringRef libStem) const {
    llvm::SmallString<128> Absolute(libStem);
    llvm::sys::fs::make_absolute(Absolute);
    bool isAbsolute = libStem == Absolute;

    // If it is an absolute path, don't try iterate over the paths.
    if (isAbsolute) {
      if (isSharedLib(libStem))
        return normalizePath(libStem);
      else
        return "";
    }

    std::string foundName = lookupLibMaybeAddExt(libStem);
    if (foundName.empty() && !libStem.startswith("lib")) {
      // try with "lib" prefix:
      foundName = lookupLibMaybeAddExt("lib" + libStem.str());
    }

    if (isSharedLib(foundName))
      return normalizePath(foundName);
    return "";
  }

  DynamicLibraryManager::LoadLibResult
  DynamicLibraryManager::loadLibrary(const std::string& libStem,
                                     bool permanent) {
    std::string canonicalLoadedLib = lookupLibrary(libStem);
    if (canonicalLoadedLib.empty())
      return kLoadLibNotFound;

    if (m_LoadedLibraries.find(canonicalLoadedLib) != m_LoadedLibraries.end())
      return kLoadLibAlreadyLoaded;

    std::string errMsg;
    // TODO: !permanent case
#if defined(LLVM_ON_WIN32)
    HMODULE dyLibHandle = LoadLibraryEx(canonicalLoadedLib.c_str(), NULL,
                                        DONT_RESOLVE_DLL_REFERENCES);
    errMsg = "LoadLibraryEx: GetLastError() returned ";
    errMsg += GetLastError();
#else
    const void* dyLibHandle = dlopen(canonicalLoadedLib.c_str(),
                                     RTLD_LAZY|RTLD_GLOBAL);
    if (const char* DyLibError = dlerror()) {
      errMsg = DyLibError;
    }
#endif
    if (!dyLibHandle) {
      llvm::errs() << "cling::DynamicLibraryManager::loadLibrary(): " << errMsg
                   << '\n';
      return kLoadLibLoadError;
    }
    else if (InterpreterCallbacks* C = getCallbacks())
      C->LibraryLoaded(dyLibHandle, canonicalLoadedLib);

    std::pair<DyLibs::iterator, bool> insRes
      = m_DyLibs.insert(std::pair<DyLibHandle, std::string>(dyLibHandle,
                                                            canonicalLoadedLib));
    if (!insRes.second)
      return kLoadLibAlreadyLoaded;
    m_LoadedLibraries.insert(canonicalLoadedLib);
    return kLoadLibSuccess;
  }

  void DynamicLibraryManager::unloadLibrary(llvm::StringRef libStem) {
    std::string canonicalLoadedLib = lookupLibrary(libStem);
    if (!isLibraryLoaded(canonicalLoadedLib))
      return;

    DyLibHandle dyLibHandle = 0;
    for (DyLibs::const_iterator I = m_DyLibs.begin(), E = m_DyLibs.end();
         I != E; ++I) {
      if (I->second == canonicalLoadedLib)
        dyLibHandle = I->first;
    }

    std::string errMsg;
    // TODO: !permanent case
#if defined(LLVM_ON_WIN32)
    FreeLibrary((HMODULE)dyLibHandle);
    errMsg = "UnoadLibraryEx: GetLastError() returned ";
    errMsg += GetLastError();
#else
    dlclose(const_cast<void*>(dyLibHandle));
    if (const char* DyLibError = dlerror()) {
      errMsg = DyLibError;
    }
#endif
    if (InterpreterCallbacks* C = getCallbacks())
      C->LibraryUnloaded(dyLibHandle, canonicalLoadedLib);

    m_DyLibs.erase(dyLibHandle);
    m_LoadedLibraries.erase(canonicalLoadedLib);
  }

  bool DynamicLibraryManager::isLibraryLoaded(llvm::StringRef fullPath) const {
    std::string canonPath = normalizePath(fullPath);
    if (m_LoadedLibraries.find(canonPath) != m_LoadedLibraries.end())
      return true;
    return false;
  }

  void DynamicLibraryManager::ExposeHiddenSharedLibrarySymbols(void* handle) {
    llvm::sys::DynamicLibrary::addPermanentLibrary(const_cast<void*>(handle));
  }
} // end namespace cling
<commit_msg>Exit early once the dylib is found.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "cling/Interpreter/DynamicLibraryManager.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/InvocationOptions.h"

#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

#ifdef LLVM_ON_WIN32
#include <Windows.h>
#include <shlobj.h>
#else
#include <limits.h> /* PATH_MAX */
#include <dlfcn.h>
#endif

namespace {
#if defined(LLVM_ON_UNIX)
  static void GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) {
    char* env_var = getenv("LD_LIBRARY_PATH");
#if __APPLE__
    if (!env_var)
      env_var = getenv("DYLD_LIBRARY_PATH");
    if (!env_var)
      env_var = getenv("DYLD_FALLBACK_LIBRARY_PATH");
#endif
    if (env_var != 0) {
      static const char PathSeparator = ':';
      const char* at = env_var;
      const char* delim = strchr(at, PathSeparator);
      while (delim != 0) {
        std::string tmp(at, size_t(delim-at));
        if (llvm::sys::fs::is_directory(tmp.c_str()))
          Paths.push_back(tmp);
        at = delim + 1;
        delim = strchr(at, PathSeparator);
      }

      if (*at != 0)
        if (llvm::sys::fs::is_directory(llvm::StringRef(at)))
          Paths.push_back(at);
    }
#if defined(__APPLE__) || defined(__CYGWIN__)
    Paths.push_back("/usr/local/lib/");
    Paths.push_back("/usr/X11R6/lib/");
    Paths.push_back("/usr/lib/");
    Paths.push_back("/lib/");

    Paths.push_back("/lib/x86_64-linux-gnu/");
    Paths.push_back("/usr/local/lib64/");
    Paths.push_back("/usr/lib64/");
    Paths.push_back("/lib64/");
#else
    static bool initialized = false;
    static std::vector<std::string> SysPaths;
    if (!initialized) {
      // trick to get the system search path
      std::string cmd("LD_DEBUG=libs LD_PRELOAD=DOESNOTEXIST ls 2>&1");
      FILE *pf = popen(cmd.c_str (), "r");
      std::string result = "";
      std::string sys_path = "";
      char buffer[128];
      while (!feof(pf)) {
        if (fgets(buffer, 128, pf) != NULL)
          result += buffer;
      }
      pclose(pf);
      std::size_t from
        = result.find("search path=", result.find("(LD_LIBRARY_PATH)"));
      std::size_t to = result.find("(system search path)");
      if (from != std::string::npos && to != std::string::npos) {
        from += 12;
        sys_path = result.substr(from, to-from);
        sys_path.erase(std::remove_if(sys_path.begin(), sys_path.end(), isspace),
                       sys_path.end());
        sys_path += ':';
      }
      static const char PathSeparator = ':';
      const char* at = sys_path.c_str();
      const char* delim = strchr(at, PathSeparator);
      while (delim != 0) {
        std::string tmp(at, size_t(delim-at));
        if (llvm::sys::fs::is_directory(tmp.c_str()))
          SysPaths.push_back(tmp);
        at = delim + 1;
        delim = strchr(at, PathSeparator);
      }
      initialized = true;
    }

    for (std::vector<std::string>::const_iterator I = SysPaths.begin(),
           E = SysPaths.end(); I != E; ++I)
      Paths.push_back((*I).c_str());
#endif
  }
#elif defined(LLVM_ON_WIN32)
  static void GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) {
    char buff[MAX_PATH];
    // Generic form of C:\Windows\System32
    HRESULT res =  SHGetFolderPathA(NULL,
                                    CSIDL_FLAG_CREATE | CSIDL_SYSTEM,
                                    NULL,
                                    SHGFP_TYPE_CURRENT,
                                    buff);
    if (res != S_OK) {
      assert(0 && "Failed to get system directory");
      return;
    }
    Paths.push_back(buff);

    // Reset buff.
    buff[0] = 0;
    // Generic form of C:\Windows
    res =  SHGetFolderPathA(NULL,
                            CSIDL_FLAG_CREATE | CSIDL_WINDOWS,
                            NULL,
                            SHGFP_TYPE_CURRENT,
                            buff);
    if (res != S_OK) {
      assert(0 && "Failed to get windows directory");
      return;
    }
    Paths.push_back(buff);
  }

  static bool is_dll(const char *filename) {
    bool is_dll = false;
    HANDLE hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    if (hFileMapping == INVALID_HANDLE_VALUE) {
      CloseHandle(hFile);
      return false;
    }
    LPVOID lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
    if (lpFileBase == NULL) {
      CloseHandle(hFileMapping);
      CloseHandle(hFile);
      return false;
    }
    PIMAGE_DOS_HEADER pDOSHeader = static_cast<PIMAGE_DOS_HEADER>(lpFileBase);
    if (pDOSHeader->e_magic == IMAGE_DOS_SIGNATURE) {
      PIMAGE_NT_HEADERS pNTHeader = reinterpret_cast<PIMAGE_NT_HEADERS>((PBYTE)lpFileBase + pDOSHeader->e_lfanew);
      if ((pNTHeader->Signature == IMAGE_NT_SIGNATURE) &&
          ((pNTHeader->FileHeader.Characteristics & IMAGE_FILE_DLL)))
        is_dll = true;
    }
    UnmapViewOfFile(lpFileBase);
    CloseHandle(hFileMapping);
    CloseHandle(hFile);
    return is_dll;
  }
#else
# error "Unsupported platform."
#endif

}

namespace cling {
  DynamicLibraryManager::DynamicLibraryManager(const InvocationOptions& Opts)
    : m_Opts(Opts), m_Callbacks(0) {
    GetSystemLibraryPaths(m_SystemSearchPaths);
    m_SystemSearchPaths.push_back(".");
  }

  DynamicLibraryManager::~DynamicLibraryManager() {}

  static bool isSharedLib(llvm::StringRef LibName, bool* exists = 0) {
    using namespace llvm::sys::fs;
    file_magic Magic;
    std::error_code Error = identify_magic(LibName, Magic);
    bool onDisk = (Error != std::errc::no_such_file_or_directory);
    if (exists)
      *exists = onDisk;

    return onDisk &&
#ifdef __APPLE__
      (Magic == file_magic::macho_fixed_virtual_memory_shared_lib
       || Magic == file_magic::macho_dynamically_linked_shared_lib
       || Magic == file_magic::macho_dynamically_linked_shared_lib_stub
       || Magic == file_magic::macho_universal_binary)
#elif defined(LLVM_ON_UNIX)
#ifdef __CYGWIN__
      (Magic == file_magic::pecoff_executable)
#else
      (Magic == file_magic::elf_shared_object)
#endif
#elif defined(LLVM_ON_WIN32)
      (Magic == file_magic::pecoff_executable || is_dll(LibName.str().c_str()))
#else
# error "Unsupported platform."
#endif
      ;
  }

  std::string
  DynamicLibraryManager::lookupLibInPaths(llvm::StringRef libStem) const {
    llvm::SmallVector<std::string, 128>
      Paths(m_Opts.LibSearchPath.begin(), m_Opts.LibSearchPath.end());
    Paths.append(m_SystemSearchPaths.begin(), m_SystemSearchPaths.end());

    for (llvm::SmallVectorImpl<std::string>::const_iterator
           IPath = Paths.begin(), E = Paths.end();IPath != E; ++IPath) {
      llvm::SmallString<512> ThisPath(*IPath); // FIXME: move alloc outside loop
      llvm::sys::path::append(ThisPath, libStem);
      bool exists;
      if (isSharedLib(ThisPath.str(), &exists))
        return ThisPath.str();
      if (exists)
        return "";
    }
    return "";
  }

  std::string
  DynamicLibraryManager::lookupLibMaybeAddExt(llvm::StringRef libStem) const {
    using namespace llvm::sys;

    std::string foundDyLib = lookupLibInPaths(libStem);

    if (foundDyLib.empty()) {
      // Add DyLib extension:
      llvm::SmallString<512> filenameWithExt(libStem);
#if defined(LLVM_ON_UNIX)
#ifdef __APPLE__
      llvm::SmallString<512>::iterator IStemEnd = filenameWithExt.end() - 1;
#endif
      static const char* DyLibExt = ".so";
#elif defined(LLVM_ON_WIN32)
      static const char* DyLibExt = ".dll";
#else
# error "Unsupported platform."
#endif
      filenameWithExt += DyLibExt;
      foundDyLib = lookupLibInPaths(filenameWithExt);
#ifdef __APPLE__
      if (foundDyLib.empty()) {
        filenameWithExt.erase(IStemEnd + 1, filenameWithExt.end());
        filenameWithExt += ".dylib";
        foundDyLib = lookupLibInPaths(filenameWithExt);
      }
#endif
    }

    if (foundDyLib.empty())
      return "";

    // get canonical path name and check if already loaded
#if defined(LLVM_ON_WIN32)
    llvm::SmallString<_MAX_PATH> FullPath("");
    char *res = _fullpath((char *)FullPath.data(), foundDyLib.c_str(), _MAX_PATH);
#else
    llvm::SmallString<PATH_MAX+1> FullPath("");
    char *res = realpath(foundDyLib.c_str(), (char *)FullPath.data());
#endif
    if (res == 0) {
      llvm::errs() << "cling::DynamicLibraryManager::lookupLibMaybeAddExt(): "
        "error getting real (canonical) path of library " << foundDyLib << '\n';
      return foundDyLib;
    }
    FullPath.set_size(strlen(res));
    return FullPath.str();
  }

  std::string DynamicLibraryManager::normalizePath(llvm::StringRef path) {
    // Make the path canonical if the file exists.
    struct stat buffer;
    if (stat(path.data(), &buffer) != 0)
      return "";
#if defined(LLVM_ON_WIN32)
    char buf[_MAX_PATH];
    char *res = _fullpath(buf, path.data(), _MAX_PATH);
#else
    char buf[PATH_MAX+1];
    char *res = realpath(path.data(), buf);
#endif
    if (res == 0) {
      assert(0 && "Cannot normalize!?");
      return "";
    }
    return res;
  }

  std::string
  DynamicLibraryManager::lookupLibrary(llvm::StringRef libStem) const {
    llvm::SmallString<128> Absolute(libStem);
    llvm::sys::fs::make_absolute(Absolute);
    bool isAbsolute = libStem == Absolute;

    // If it is an absolute path, don't try iterate over the paths.
    if (isAbsolute) {
      if (isSharedLib(libStem))
        return normalizePath(libStem);
      else
        return "";
    }

    std::string foundName = lookupLibMaybeAddExt(libStem);
    if (foundName.empty() && !libStem.startswith("lib")) {
      // try with "lib" prefix:
      foundName = lookupLibMaybeAddExt("lib" + libStem.str());
    }

    if (isSharedLib(foundName))
      return normalizePath(foundName);
    return "";
  }

  DynamicLibraryManager::LoadLibResult
  DynamicLibraryManager::loadLibrary(const std::string& libStem,
                                     bool permanent) {
    std::string canonicalLoadedLib = lookupLibrary(libStem);
    if (canonicalLoadedLib.empty())
      return kLoadLibNotFound;

    if (m_LoadedLibraries.find(canonicalLoadedLib) != m_LoadedLibraries.end())
      return kLoadLibAlreadyLoaded;

    std::string errMsg;
    // TODO: !permanent case
#if defined(LLVM_ON_WIN32)
    HMODULE dyLibHandle = LoadLibraryEx(canonicalLoadedLib.c_str(), NULL,
                                        DONT_RESOLVE_DLL_REFERENCES);
    errMsg = "LoadLibraryEx: GetLastError() returned ";
    errMsg += GetLastError();
#else
    const void* dyLibHandle = dlopen(canonicalLoadedLib.c_str(),
                                     RTLD_LAZY|RTLD_GLOBAL);
    if (const char* DyLibError = dlerror()) {
      errMsg = DyLibError;
    }
#endif
    if (!dyLibHandle) {
      llvm::errs() << "cling::DynamicLibraryManager::loadLibrary(): " << errMsg
                   << '\n';
      return kLoadLibLoadError;
    }
    else if (InterpreterCallbacks* C = getCallbacks())
      C->LibraryLoaded(dyLibHandle, canonicalLoadedLib);

    std::pair<DyLibs::iterator, bool> insRes
      = m_DyLibs.insert(std::pair<DyLibHandle, std::string>(dyLibHandle,
                                                            canonicalLoadedLib));
    if (!insRes.second)
      return kLoadLibAlreadyLoaded;
    m_LoadedLibraries.insert(canonicalLoadedLib);
    return kLoadLibSuccess;
  }

  void DynamicLibraryManager::unloadLibrary(llvm::StringRef libStem) {
    std::string canonicalLoadedLib = lookupLibrary(libStem);
    if (!isLibraryLoaded(canonicalLoadedLib))
      return;

    DyLibHandle dyLibHandle = 0;
    for (DyLibs::const_iterator I = m_DyLibs.begin(), E = m_DyLibs.end();
         I != E; ++I) {
      if (I->second == canonicalLoadedLib) {
        dyLibHandle = I->first;
        break;
      }
    }

    std::string errMsg;
    // TODO: !permanent case
#if defined(LLVM_ON_WIN32)
    FreeLibrary((HMODULE)dyLibHandle);
    errMsg = "UnoadLibraryEx: GetLastError() returned ";
    errMsg += GetLastError();
#else
    dlclose(const_cast<void*>(dyLibHandle));
    if (const char* DyLibError = dlerror()) {
      errMsg = DyLibError;
    }
#endif
    if (InterpreterCallbacks* C = getCallbacks())
      C->LibraryUnloaded(dyLibHandle, canonicalLoadedLib);

    m_DyLibs.erase(dyLibHandle);
    m_LoadedLibraries.erase(canonicalLoadedLib);
  }

  bool DynamicLibraryManager::isLibraryLoaded(llvm::StringRef fullPath) const {
    std::string canonPath = normalizePath(fullPath);
    if (m_LoadedLibraries.find(canonPath) != m_LoadedLibraries.end())
      return true;
    return false;
  }

  void DynamicLibraryManager::ExposeHiddenSharedLibrarySymbols(void* handle) {
    llvm::sys::DynamicLibrary::addPermanentLibrary(const_cast<void*>(handle));
  }
} // end namespace cling
<|endoftext|>


<commit_before>#ifndef COMPRESS__H__
#define COMPRESS__H__

#include "iterbase.hpp"

#include <utility>
#include <initializer_list>

namespace iter {

    //Forward declarations of Compressed and compress
    template <typename Container, typename Selector>
    class Compressed;

    template <typename Container, typename Selector>
    Compressed<Container, Selector> compress(Container&&, Selector&&);

    template <typename T, typename Selector>
    Compressed<std::initializer_list<T>, Selector> compress(
            std::initializer_list<T>&&, Selector&&);

    template <typename Container, typename T>
    Compressed<Container, std::initializer_list<T>> compress(
            Container&&, std::initializer_list<T>&&);

    template <typename T, typename U>
    Compressed<std::initializer_list<T>, std::initializer_list<U>> compress(
            std::initializer_list<T>&&, std::initializer_list<U>&&);

    template <typename Container, typename Selector>
    class Compressed  {
        private:
            Container& container;
            Selector & selectors;

            // The only thing allowed to directly instantiate an Compressed is
            // the compress function
            friend Compressed compress<Container, Selector>(
                    Container&&, Selector&&);

            template <typename T, typename Sel>
            friend Compressed<std::initializer_list<T>, Sel> compress(
                    std::initializer_list<T>&&, Sel&&);

            template <typename Con, typename T>
            friend Compressed<Con, std::initializer_list<T>> compress(
                    Con&&, std::initializer_list<T>&&);

            template <typename T, typename U>
            friend Compressed<std::initializer_list<T>, std::initializer_list<U>> compress(
                    std::initializer_list<T>&&, std::initializer_list<U>&&);

            // Selector::Iterator type
            using selector_iter_type = decltype(std::begin(selectors));

            // Value constructor for use only in the compress function
            Compressed(Container&& container, Selector&& selectors)
                : container{container},
                selectors{selectors}
            { }
            Compressed() = delete;
            Compressed& operator=(const Compressed&) = delete;

        public:
            Compressed(const Compressed&) = default;

            class Iterator {
                private:
                    iterator_type<Container> sub_iter;
                    const iterator_type<Container> sub_end;

                    selector_iter_type selector_iter;
                    const selector_iter_type selector_end;

                    void increment_iterators() {
                        ++this->sub_iter;
                        ++this->selector_iter;
                    }

                    void skip_failures() {
                        while (this->sub_iter != this->sub_end &&
                               this->selector_iter != this->selector_end &&
                                !*this->selector_iter) {
                            this->increment_iterators();
                        }
                    }

                public:
                    Iterator (iterator_type<Container> cont_iter,
                              iterator_type<Container> cont_end,
                              selector_iter_type sel_iter,
                              selector_iter_type sel_end)
                        : sub_iter{cont_iter},
                        sub_end{cont_end},
                        selector_iter{sel_iter},
                        selector_end{sel_end}
                    {
                        this->skip_failures();
                    }

                    iterator_deref<Container> operator*() const {
                        return *this->sub_iter;
                    }

                    Iterator & operator++() {
                        this->increment_iterators();
                        this->skip_failures();
                        return *this;
                    }

                    bool operator!=(const Iterator & other) const {
                        return this->sub_iter != other.sub_iter &&
                            this->selector_iter != other.selector_iter;
                    }
            };

            Iterator begin() const {
                return {std::begin(this->container), std::end(this->container),
                    std::begin(this->selectors), std::end(this->selectors)};
            }

            Iterator end() const {
                return {std::end(this->container), std::end(this->container),
                        std::end(this->selectors), std::end(this->selectors)};
            }

    };

    // Helper function to instantiate an Compressed
    template <typename Container, typename Selector>
    Compressed<Container, Selector> compress(
            Container&& container, Selector&& selectors) {
        return {std::forward<Container>(container),
                std::forward<Selector>(selectors)};
    }

    template <typename T, typename Selector>
    Compressed<std::initializer_list<T>, Selector> compress(
            std::initializer_list<T>&& data, Selector&& selectors) {
        return {std::move(data),
                std::forward<Selector>(selectors)};
    }

    template <typename Container, typename T>
    Compressed<Container, std::initializer_list<T>> compress(
            Container&& container, std::initializer_list<T>&& selectors) {
        return {std::forward<Container>(container),
                std::move(selectors)};
    }

    template <typename T, typename U>
    Compressed<std::initializer_list<T>, std::initializer_list<U>> compress(
            std::initializer_list<T>&& data,
            std::initializer_list<U>&& selectors) {
        return {std::move(data),
                std::move(selectors)};
    }
}

#endif //ifndef COMPRESS__H__
<commit_msg>formats compress.hpp<commit_after>#ifndef COMPRESS__H__
#define COMPRESS__H__

#include "iterbase.hpp"

#include <utility>
#include <initializer_list>

namespace iter {

    //Forward declarations of Compressed and compress
    template <typename Container, typename Selector>
    class Compressed;

    template <typename Container, typename Selector>
    Compressed<Container, Selector> compress(Container&&, Selector&&);

    template <typename T, typename Selector>
    Compressed<std::initializer_list<T>, Selector> compress(
            std::initializer_list<T>&&, Selector&&);

    template <typename Container, typename T>
    Compressed<Container, std::initializer_list<T>> compress(
            Container&&, std::initializer_list<T>&&);

    template <typename T, typename U>
    Compressed<std::initializer_list<T>, std::initializer_list<U>> compress(
            std::initializer_list<T>&&, std::initializer_list<U>&&);

    template <typename Container, typename Selector>
    class Compressed  {
        private:
            Container& container;
            Selector & selectors;

            // The only thing allowed to directly instantiate an Compressed is
            // the compress function
            friend Compressed compress<Container, Selector>(
                    Container&&, Selector&&);

            template <typename T, typename Sel>
            friend Compressed<std::initializer_list<T>, Sel> compress(
                    std::initializer_list<T>&&, Sel&&);

            template <typename Con, typename T>
            friend Compressed<Con, std::initializer_list<T>> compress(
                    Con&&, std::initializer_list<T>&&);

            template <typename T, typename U>
            friend Compressed<std::initializer_list<T>, std::initializer_list<U>> compress(
                    std::initializer_list<T>&&, std::initializer_list<U>&&);

            // Selector::Iterator type
            using selector_iter_type = decltype(std::begin(selectors));

            // Value constructor for use only in the compress function
            Compressed(Container&& container, Selector&& selectors)
                : container{container},
                selectors{selectors}
            { }
            Compressed() = delete;
            Compressed& operator=(const Compressed&) = delete;

        public:
            Compressed(const Compressed&) = default;

            class Iterator {
                private:
                    iterator_type<Container> sub_iter;
                    const iterator_type<Container> sub_end;

                    selector_iter_type selector_iter;
                    const selector_iter_type selector_end;

                    void increment_iterators() {
                        ++this->sub_iter;
                        ++this->selector_iter;
                    }

                    void skip_failures() {
                        while (this->sub_iter != this->sub_end &&
                               this->selector_iter != this->selector_end &&
                                !*this->selector_iter) {
                            this->increment_iterators();
                        }
                    }

                public:
                    Iterator (iterator_type<Container> cont_iter,
                              iterator_type<Container> cont_end,
                              selector_iter_type sel_iter,
                              selector_iter_type sel_end)
                        : sub_iter{cont_iter},
                        sub_end{cont_end},
                        selector_iter{sel_iter},
                        selector_end{sel_end}
                    {
                        this->skip_failures();
                    }

                    iterator_deref<Container> operator*() const {
                        return *this->sub_iter;
                    }

                    Iterator& operator++() {
                        this->increment_iterators();
                        this->skip_failures();
                        return *this;
                    }

                    bool operator!=(const Iterator& other) const {
                        return this->sub_iter != other.sub_iter &&
                            this->selector_iter != other.selector_iter;
                    }
            };

            Iterator begin() const {
                return {std::begin(this->container), std::end(this->container),
                    std::begin(this->selectors), std::end(this->selectors)};
            }

            Iterator end() const {
                return {std::end(this->container), std::end(this->container),
                        std::end(this->selectors), std::end(this->selectors)};
            }

    };

    // Helper function to instantiate an Compressed
    template <typename Container, typename Selector>
    Compressed<Container, Selector> compress(
            Container&& container, Selector&& selectors) {
        return {std::forward<Container>(container),
                std::forward<Selector>(selectors)};
    }

    template <typename T, typename Selector>
    Compressed<std::initializer_list<T>, Selector> compress(
            std::initializer_list<T>&& data, Selector&& selectors) {
        return {std::move(data),
                std::forward<Selector>(selectors)};
    }

    template <typename Container, typename T>
    Compressed<Container, std::initializer_list<T>> compress(
            Container&& container, std::initializer_list<T>&& selectors) {
        return {std::forward<Container>(container),
                std::move(selectors)};
    }

    template <typename T, typename U>
    Compressed<std::initializer_list<T>, std::initializer_list<U>> compress(
            std::initializer_list<T>&& data,
            std::initializer_list<U>&& selectors) {
        return {std::move(data),
                std::move(selectors)};
    }
}

#endif //ifndef COMPRESS__H__
<|endoftext|>


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

  Library:   CTK

  Copyright (c) Kitware Inc.

  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.txt

  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.

=========================================================================*/

// Qt includes
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlError>
#include <QVariant>
#include <QDate>
#include <QStringList>
#include <QSet>
#include <QFile>
#include <QDirIterator>
#include <QFileInfo>
#include <QDebug>
#include <QPixmap>

// ctkDICOM includes
#include "ctkDICOMIndexer.h"
#include "ctkDICOMIndexer_p.h"
#include "ctkDICOMDatabase.h"

// DCMTK includes
#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmdata/dcdeftag.h>
#include <dcmtk/dcmdata/dcdatset.h>
#include <dcmtk/ofstd/ofcond.h>
#include <dcmtk/ofstd/ofstring.h>
#include <dcmtk/ofstd/ofstd.h>        /* for class OFStandard */
#include <dcmtk/dcmdata/dcddirif.h>   /* for class DicomDirInterface */
#include <dcmtk/dcmimgle/dcmimage.h>  /* for class DicomImage */
#include <dcmtk/dcmimage/diregist.h>  /* include support for color images */

//------------------------------------------------------------------------------
// ctkDICOMIndexerPrivate methods

//------------------------------------------------------------------------------
ctkDICOMIndexerPrivate::ctkDICOMIndexerPrivate(ctkDICOMIndexer& o) : q_ptr(&o), Canceled(false)
{
}

//------------------------------------------------------------------------------
ctkDICOMIndexerPrivate::~ctkDICOMIndexerPrivate()
{
}

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

//------------------------------------------------------------------------------
// ctkDICOMIndexer methods

//------------------------------------------------------------------------------
ctkDICOMIndexer::ctkDICOMIndexer(QObject *parent):d_ptr(new ctkDICOMIndexerPrivate(*this))
{
  Q_UNUSED(parent);
}

//------------------------------------------------------------------------------
ctkDICOMIndexer::~ctkDICOMIndexer()
{
}

//------------------------------------------------------------------------------
void ctkDICOMIndexer::addFile(ctkDICOMDatabase& database,
                              const QString filePath,
                              const QString & sourceDirectoryName,
                              const QString& destinationDirectoryName)
{
  qDebug() << "Currently processing " << filePath;
  if ( !destinationDirectoryName.isEmpty() )
  {
    qDebug() << "Copying " << filePath << " into the destination directory: " << destinationDirectoryName;
  }

  emit indexingFilePath( filePath );

  database.insert( filePath, !destinationDirectoryName.isEmpty(), true, true, sourceDirectoryName, destinationDirectoryName );
}

//------------------------------------------------------------------------------
void ctkDICOMIndexer::addDirectory(ctkDICOMDatabase& ctkDICOMDatabase,
                                   const QString& directoryName,
                                   const QString& destinationDirectoryName)
{
  QStringList listOfFiles;
  QDir directory(directoryName);

  if(directory.exists("DICOMDIR"))
  {
    addDicomdir(ctkDICOMDatabase,directoryName,destinationDirectoryName);
  }
  else
  {
    QDirIterator it(directoryName,QDir::Files,QDirIterator::Subdirectories);
    qDebug() << "Iterating subdirs of \"" << directory << "\"";
    while(it.hasNext())
    {
      QString currentPath( it.next() );
      qDebug() << "Currently in subdir \"" << currentPath << "\"";
      listOfFiles << currentPath;
    }
    emit foundFilesToIndex(listOfFiles.count());
    addListOfFiles( ctkDICOMDatabase, listOfFiles, directoryName, destinationDirectoryName );
  }
}

//------------------------------------------------------------------------------
void ctkDICOMIndexer::addListOfFiles(ctkDICOMDatabase& ctkDICOMDatabase,
                                     const QStringList& listOfFiles,
                                     const QString & sourceDirectoryName,
                                     const QString& destinationDirectoryName)
{
  Q_D(ctkDICOMIndexer);
  d->Canceled = false;
  int CurrentFileIndex = 0;

  if ( !destinationDirectoryName.isEmpty() )
  {
    qDebug() << "destinationDirectory is set to " << destinationDirectoryName;
  }

  foreach(QString filePath, listOfFiles)
  {
    int percent = ( 100 * CurrentFileIndex ) / listOfFiles.size();
    emit this->progress(percent);
    this->addFile( ctkDICOMDatabase, filePath, sourceDirectoryName, destinationDirectoryName );
    CurrentFileIndex++;

    if( d->Canceled )
      {
      break;
      }
  }
  emit this->indexingComplete();
}

//------------------------------------------------------------------------------
void ctkDICOMIndexer::addDicomdir( ctkDICOMDatabase & ctkDICOMDatabase,
                                   const QString & directoryName,
                                   const QString & destinationDirectoryName )
{
  //Initialize dicomdir with directory path
  QString dcmFilePath = directoryName;
  dcmFilePath.append( "/DICOMDIR" );
  DcmDicomDir * dicomDir = new DcmDicomDir( dcmFilePath.toStdString().c_str() );

  //Values to store records data at the moment only uid needed
  OFString patientsName, studyInstanceUID, seriesInstanceUID, sopInstanceUID, referencedFileName ;

  //Variables for progress operations
  QString instanceFilePath;
  QStringList listOfInstances;

  DcmDirectoryRecord * rootRecord = &( dicomDir->getRootRecord() );
  DcmDirectoryRecord * patientRecord = NULL;
  DcmDirectoryRecord * studyRecord = NULL;
  DcmDirectoryRecord * seriesRecord = NULL;
  DcmDirectoryRecord * fileRecord = NULL;

  /*Iterate over all records in dicomdir and setup path to the dataset of the filerecord
  then insert. the filerecord into the database.
  If any UID is missing the record and all of it's subelements won't be added to the database*/
  bool success = true;
  if(rootRecord != NULL)
  {
    while ((patientRecord = rootRecord->nextSub(patientRecord)) != NULL)
    {
      logger.debug( "Reading new Patient:" );
      if (patientRecord->findAndGetOFString(DCM_PatientName, patientsName).bad())
      {
        logger.warn( "DICOMDIR file at "+directoryName+" is invalid: patient name not found. All records belonging to this patient will be ignored.");
        success = false;
        continue;
      }
      logger.debug( "Patient's Name: " + QString(patientsName.c_str()) );
      while ((studyRecord = patientRecord->nextSub(studyRecord)) != NULL)
      {
        logger.debug( "Reading new Study:" );
        if (studyRecord->findAndGetOFString(DCM_StudyInstanceUID, studyInstanceUID).bad())
        {
          logger.warn( "DICOMDIR file at "+directoryName+" is invalid: study instance UID not found for patient "+ QString(patientsName.c_str())+". All records belonging to this study will be ignored.");
          success = false;
          continue;
        }
        logger.debug( "Study instance UID: " + QString(studyInstanceUID.c_str()) );

        while ((seriesRecord = studyRecord->nextSub(seriesRecord)) != NULL)
        {
          logger.debug( "Reading new Series:" );
          if (seriesRecord->findAndGetOFString(DCM_SeriesInstanceUID, seriesInstanceUID).bad())
          {
            logger.warn( "DICOMDIR file at "+directoryName+" is invalid: series instance UID not found for patient "+ QString(patientsName.c_str())+", study "+ QString(studyInstanceUID.c_str())+". All records belonging to this series will be ignored.");
            success = false;
            continue;
          }
          logger.debug( "Series instance UID: " + QString(seriesInstanceUID.c_str()) );

          while ((fileRecord = seriesRecord->nextSub(fileRecord)) != NULL)
          {
            if (fileRecord->findAndGetOFStringArray(DCM_ReferencedSOPInstanceUIDInFile, sopInstanceUID).bad()
              || fileRecord->findAndGetOFStringArray(DCM_ReferencedFileID,referencedFileName).bad())
            {
              logger.warn( "DICOMDIR file at "+directoryName+" is invalid: referenced SOP instance UID or file name is invalid for patient "
                + QString(patientsName.c_str())+", study "+ QString(studyInstanceUID.c_str())+", series "+ QString(seriesInstanceUID.c_str())+
                ". This file will be ignored.");
              success = false;
              continue;
            }

            //Get the filepath of the instance and insert it into a list
            instanceFilePath = directoryName;
            instanceFilePath.append( "/" );
            instanceFilePath.append( QString( referencedFileName.c_str() ) );
            instanceFilePath.replace( "\\", "/" );
            listOfInstances << instanceFilePath;
          }
        }
      }
    }
    emit foundFilesToIndex( listOfInstances.count() );
    addListOfFiles( ctkDICOMDatabase, listOfInstances, directoryName, destinationDirectoryName );
  }
  return success;
}

//------------------------------------------------------------------------------
void ctkDICOMIndexer::refreshDatabase( ctkDICOMDatabase& dicomDatabase, const QString & directoryName )
{
  Q_UNUSED(dicomDatabase);
  Q_UNUSED(directoryName);
  /*
   * Probably this should go to the database class as well
   * Or we have to extend the interface to make possible what we do here
   * without using SQL directly

  /// get all filenames from the database
  QSqlQuery allFilesQuery(dicomDatabase.database());
  QStringList databaseFileNames;
  QStringList filesToRemove;
  this->loggedExec(allFilesQuery, "SELECT Filename from Images;");

  while (allFilesQuery.next())
    {
    QString fileName = allFilesQuery.value(0).toString();
    databaseFileNames.append(fileName);
    if (! QFile::exists(fileName) )
      {
      filesToRemove.append(fileName);
      }
    }

  QSet<QString> filesytemFiles;
  QDirIterator dirIt(directoryName);
  while (dirIt.hasNext())
    {
    filesytemFiles.insert(dirIt.next());
    }

  // TODO: it looks like this function was never finished...
  //
  // I guess the next step is to remove all filesToRemove from the database
  // and also to add filesystemFiles into the database tables
  */
  }

//------------------------------------------------------------------------------
void ctkDICOMIndexer::waitForImportFinished()
{
  // No-op - this had been used when the indexing was multi-threaded,
  // and has only been retained for API compatibility.
}

//----------------------------------------------------------------------------
void ctkDICOMIndexer::cancel()
{
  Q_D(ctkDICOMIndexer);
  d->Canceled = true;
}
<commit_msg>COMP: Fix due to the issues caused by merging with main CTK repo<commit_after>/*=========================================================================

  Library:   CTK

  Copyright (c) Kitware Inc.

  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.txt

  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.

=========================================================================*/

// Qt includes
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlError>
#include <QVariant>
#include <QDate>
#include <QStringList>
#include <QSet>
#include <QFile>
#include <QDirIterator>
#include <QFileInfo>
#include <QDebug>
#include <QPixmap>

// ctkDICOM includes
#include "ctkDICOMIndexer.h"
#include "ctkDICOMIndexer_p.h"
#include "ctkDICOMDatabase.h"

// DCMTK includes
#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmdata/dcdeftag.h>
#include <dcmtk/dcmdata/dcdatset.h>
#include <dcmtk/ofstd/ofcond.h>
#include <dcmtk/ofstd/ofstring.h>
#include <dcmtk/ofstd/ofstd.h>        /* for class OFStandard */
#include <dcmtk/dcmdata/dcddirif.h>   /* for class DicomDirInterface */
#include <dcmtk/dcmimgle/dcmimage.h>  /* for class DicomImage */
#include <dcmtk/dcmimage/diregist.h>  /* include support for color images */

//------------------------------------------------------------------------------
// ctkDICOMIndexerPrivate methods

//------------------------------------------------------------------------------
ctkDICOMIndexerPrivate::ctkDICOMIndexerPrivate(ctkDICOMIndexer& o) : q_ptr(&o), Canceled(false)
{
}

//------------------------------------------------------------------------------
ctkDICOMIndexerPrivate::~ctkDICOMIndexerPrivate()
{
}

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

//------------------------------------------------------------------------------
// ctkDICOMIndexer methods

//------------------------------------------------------------------------------
ctkDICOMIndexer::ctkDICOMIndexer(QObject *parent):d_ptr(new ctkDICOMIndexerPrivate(*this))
{
  Q_UNUSED(parent);
}

//------------------------------------------------------------------------------
ctkDICOMIndexer::~ctkDICOMIndexer()
{
}

//------------------------------------------------------------------------------
void ctkDICOMIndexer::addFile(ctkDICOMDatabase& database,
                              const QString filePath,
                              const QString & sourceDirectoryName,
                              const QString& destinationDirectoryName)
{
  qDebug() << "Currently processing " << filePath;
  if ( !destinationDirectoryName.isEmpty() )
  {
    qDebug() << "Copying " << filePath << " into the destination directory: " << destinationDirectoryName;
  }

  emit indexingFilePath( filePath );

  database.insert( filePath, !destinationDirectoryName.isEmpty(), true, true, sourceDirectoryName, destinationDirectoryName );
}

//------------------------------------------------------------------------------
void ctkDICOMIndexer::addDirectory(ctkDICOMDatabase& ctkDICOMDatabase,
                                   const QString& directoryName,
                                   const QString& destinationDirectoryName)
{
  QStringList listOfFiles;
  QDir directory(directoryName);

  if(directory.exists("DICOMDIR"))
  {
    addDicomdir(ctkDICOMDatabase,directoryName,destinationDirectoryName);
  }
  else
  {
    QDirIterator it(directoryName,QDir::Files,QDirIterator::Subdirectories);
    qDebug() << "Iterating subdirs of \"" << directory << "\"";
    while(it.hasNext())
    {
      QString currentPath( it.next() );
      qDebug() << "Currently in subdir \"" << currentPath << "\"";
      listOfFiles << currentPath;
    }
    emit foundFilesToIndex(listOfFiles.count());
    addListOfFiles( ctkDICOMDatabase, listOfFiles, directoryName, destinationDirectoryName );
  }
}

//------------------------------------------------------------------------------
void ctkDICOMIndexer::addListOfFiles(ctkDICOMDatabase& ctkDICOMDatabase,
                                     const QStringList& listOfFiles,
                                     const QString & sourceDirectoryName,
                                     const QString& destinationDirectoryName)
{
  Q_D(ctkDICOMIndexer);
  d->Canceled = false;
  int CurrentFileIndex = 0;

  if ( !destinationDirectoryName.isEmpty() )
  {
    qDebug() << "destinationDirectory is set to " << destinationDirectoryName;
  }

  foreach(QString filePath, listOfFiles)
  {
    int percent = ( 100 * CurrentFileIndex ) / listOfFiles.size();
    emit this->progress(percent);
    this->addFile( ctkDICOMDatabase, filePath, sourceDirectoryName, destinationDirectoryName );
    CurrentFileIndex++;

    if( d->Canceled )
      {
      break;
      }
  }
  emit this->indexingComplete();
}

//------------------------------------------------------------------------------
bool ctkDICOMIndexer::addDicomdir( ctkDICOMDatabase & ctkDICOMDatabase,
                                   const QString & directoryName,
                                   const QString & destinationDirectoryName )
{
  //Initialize dicomdir with directory path
  QString dcmFilePath = directoryName;
  dcmFilePath.append( "/DICOMDIR" );
  DcmDicomDir * dicomDir = new DcmDicomDir( dcmFilePath.toStdString().c_str() );

  //Values to store records data at the moment only uid needed
  OFString patientsName, studyInstanceUID, seriesInstanceUID, sopInstanceUID, referencedFileName ;

  //Variables for progress operations
  QString instanceFilePath;
  QStringList listOfInstances;

  DcmDirectoryRecord * rootRecord = &( dicomDir->getRootRecord() );
  DcmDirectoryRecord * patientRecord = NULL;
  DcmDirectoryRecord * studyRecord = NULL;
  DcmDirectoryRecord * seriesRecord = NULL;
  DcmDirectoryRecord * fileRecord = NULL;

  /*Iterate over all records in dicomdir and setup path to the dataset of the filerecord
  then insert. the filerecord into the database.
  If any UID is missing the record and all of it's subelements won't be added to the database*/
  bool success = true;
  if(rootRecord != NULL)
  {
    while ((patientRecord = rootRecord->nextSub(patientRecord)) != NULL)
    {
      qDebug() << "Reading new Patient:";
      if (patientRecord->findAndGetOFString(DCM_PatientName, patientsName).bad())
      {
        qDebug() << "DICOMDIR file at " << directoryName << " is invalid: patient name not found. All records belonging to this patient will be ignored.";
        success = false;
        continue;
      }
      qDebug() << "Patient's Name: " << QString( patientsName.c_str() );
      while ((studyRecord = patientRecord->nextSub(studyRecord)) != NULL)
      {
        qDebug() << "Reading new Study:";
        if (studyRecord->findAndGetOFString(DCM_StudyInstanceUID, studyInstanceUID).bad())
        {
          qDebug() << "DICOMDIR file at " << directoryName << " is invalid: study instance UID not found for patient "
				           <<  QString(patientsName.c_str()) << ". All records belonging to this study will be ignored.";
          success = false;
          continue;
        }
        qDebug() << "Study instance UID: " << QString(studyInstanceUID.c_str());

        while ((seriesRecord = studyRecord->nextSub(seriesRecord)) != NULL)
        {
          qDebug() << "Reading new Series:";
          if (seriesRecord->findAndGetOFString(DCM_SeriesInstanceUID, seriesInstanceUID).bad())
          {
            qDebug() << "DICOMDIR file at " << directoryName << " is invalid: series instance UID not found for patient " << QString(patientsName.c_str())
					           << ", study " << QString(studyInstanceUID.c_str()) << ". All records belonging to this series will be ignored.";
            success = false;
            continue;
          }
          qDebug() << "Series instance UID: " << QString(seriesInstanceUID.c_str());

          while ((fileRecord = seriesRecord->nextSub(fileRecord)) != NULL)
          {
            if (fileRecord->findAndGetOFStringArray(DCM_ReferencedSOPInstanceUIDInFile, sopInstanceUID).bad()
              || fileRecord->findAndGetOFStringArray(DCM_ReferencedFileID,referencedFileName).bad())
            {
              qDebug() << "DICOMDIR file at " << directoryName << " is invalid: referenced SOP instance UID or file name is invalid for patient "
                	     << QString(patientsName.c_str()) << ", study " << QString(studyInstanceUID.c_str()) << ", series " << QString(seriesInstanceUID.c_str())
              		     << ". This file will be ignored.";
              success = false;
              continue;
            }

            //Get the filepath of the instance and insert it into a list
            instanceFilePath = directoryName;
            instanceFilePath.append( "/" );
            instanceFilePath.append( QString( referencedFileName.c_str() ) );
            instanceFilePath.replace( "\\", "/" );
            listOfInstances << instanceFilePath;
          }
        }
      }
    }
    emit foundFilesToIndex( listOfInstances.count() );
    addListOfFiles( ctkDICOMDatabase, listOfInstances, directoryName, destinationDirectoryName );
  }

  return success;
}

//------------------------------------------------------------------------------
void ctkDICOMIndexer::refreshDatabase( ctkDICOMDatabase& dicomDatabase, const QString & directoryName )
{
  Q_UNUSED(dicomDatabase);
  Q_UNUSED(directoryName);
  /*
   * Probably this should go to the database class as well
   * Or we have to extend the interface to make possible what we do here
   * without using SQL directly

  /// get all filenames from the database
  QSqlQuery allFilesQuery(dicomDatabase.database());
  QStringList databaseFileNames;
  QStringList filesToRemove;
  this->loggedExec(allFilesQuery, "SELECT Filename from Images;");

  while (allFilesQuery.next())
    {
    QString fileName = allFilesQuery.value(0).toString();
    databaseFileNames.append(fileName);
    if (! QFile::exists(fileName) )
      {
      filesToRemove.append(fileName);
      }
    }

  QSet<QString> filesytemFiles;
  QDirIterator dirIt(directoryName);
  while (dirIt.hasNext())
    {
    filesytemFiles.insert(dirIt.next());
    }

  // TODO: it looks like this function was never finished...
  //
  // I guess the next step is to remove all filesToRemove from the database
  // and also to add filesystemFiles into the database tables
  */
  }

//------------------------------------------------------------------------------
void ctkDICOMIndexer::waitForImportFinished()
{
  // No-op - this had been used when the indexing was multi-threaded,
  // and has only been retained for API compatibility.
}

//----------------------------------------------------------------------------
void ctkDICOMIndexer::cancel()
{
  Q_D(ctkDICOMIndexer);
  d->Canceled = true;
}
<|endoftext|>


<commit_before>#include "MT_XDFDialogs.h"

enum
{
    ID_X_CHOICE = wxID_HIGHEST + 1,
    ID_Y_CHOICE,
    ID_TIMESTEP
};

MT_LoadXDFDialog::MT_LoadXDFDialog(wxWindow* parent,
                                   MT_ExperimentDataFile* pXDF)
    : wxDialog(parent,
               wxID_ANY,
               wxT("XDF Settings"),
               wxDefaultPosition,
               wxDefaultSize,
               wxDEFAULT_DIALOG_STYLE),
      m_pXDF(pXDF)
{
    /* gather relevant information from XDF */
    std::vector<std::string> datanames;
    std::vector<std::string> datafiles;
    m_pXDF->getFilesFromXML(&datanames, &datafiles);

    unsigned int x_guess = 0;
    unsigned int y_guess = 0;
    unsigned int frame_period_guess = 32;
    for(unsigned int i = 0; i < datanames.size(); i++)
    {
        wxString cname(datanames[i].c_str());
        m_asXChoices.Add(cname);
        m_asYChoices.Add(cname);
        if(cname.Find(wxT("X")) != wxNOT_FOUND ||
           cname.Find(wxT("x")) != wxNOT_FOUND)
        {
            x_guess = i;
        }
        if(cname.Find(wxT("Y")) != wxNOT_FOUND ||
           cname.Find(wxT("y")) != wxNOT_FOUND)
        {
            y_guess = i;
        }
    }

    MT_XDFSettingsGroup* pDG = m_pXDF->getSettingsGroup();
    m_pDG = pDG;

    if(pDG && (pDG->GetGroupName() == MT_XDFSettingsGroup::SettingsName))
    {
        unsigned int i = pDG->GetIndexByName(MT_XDFSettingsGroup::XPlaybackName);
        if(i >= 0 && i < pDG->GetGroupSize())
        {
            wxString X_Found(pDG->GetStringValue(i).c_str());
            int j = m_asXChoices.Index(X_Found);
            if(j != wxNOT_FOUND)
            {
                x_guess = j;
            }
        }
        i = pDG->GetIndexByName(MT_XDFSettingsGroup::YPlaybackName);
        if(i >= 0 && i < pDG->GetGroupSize())
        {
            wxString Y_Found(pDG->GetStringValue(i).c_str());
            int j = m_asXChoices.Index(Y_Found);
            if(j != wxNOT_FOUND)
            {
                y_guess = j;
            }
        }
        i = pDG->GetIndexByName(MT_XDFSettingsGroup::PlaybackFramePeriodName);
        if(i >= 0 && i < pDG->GetGroupSize())
        {
            int v = (int) pDG->GetNumericValue(i);
            if(v > 0)
            {
                frame_period_guess = v;
            }
        }
    }
    if(x_guess == y_guess)
    {
        y_guess = x_guess + 1;
    }

    /* GUI setup */
    wxBoxSizer* vbox0 = new wxBoxSizer(wxVERTICAL);

    wxBoxSizer* hbox0 = new wxBoxSizer(wxHORIZONTAL);

    wxBoxSizer* vbox1 = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer* vbox2 = new wxBoxSizer(wxVERTICAL);

    vbox1->Add(new wxStaticText(this, wxID_ANY, wxT("X Data")),
               0, wxLEFT | wxRIGHT, 10);

    m_pXChoice = new wxChoice(this,
                              ID_X_CHOICE,
                              wxDefaultPosition,
                              wxSize(150, 20),
                              m_asXChoices);
    vbox1->Add(m_pXChoice, 0, wxLEFT | wxRIGHT, 10);

    vbox2->Add(new wxStaticText(this, wxID_ANY, wxT("Y Data")),
               0, wxLEFT | wxRIGHT, 10);

    m_pYChoice = new wxChoice(this,
                              ID_Y_CHOICE,
                              wxDefaultPosition,
                              wxSize(150, 20),
                              m_asYChoices);
    vbox2->Add(m_pYChoice, 0, wxLEFT | wxRIGHT, 10);

    hbox0->Add(vbox1);
    hbox0->Add(vbox2);
    vbox0->Add(hbox0, 0, wxTOP, 10);

    wxBoxSizer* hbox1 = new wxBoxSizer(wxHORIZONTAL);

    hbox1->Add(new wxStaticText(this, wxID_ANY, wxT("Time Step [msec]")),
               0, wxLEFT | wxRIGHT, 10);
    wxString sDt;
    sDt.Printf("%d", frame_period_guess);
    m_pTimeStepCtrl = new wxTextCtrl(this,
                                     ID_TIMESTEP,
                                     sDt,
                                     wxDefaultPosition,
                                     wxSize(100, 20));
    hbox1->Add(m_pTimeStepCtrl, 0, wxLEFT | wxRIGHT | wxALIGN_RIGHT, 10);

    vbox0->Add(hbox1, 0, wxLEFT | wxRIGHT | wxTOP | wxALIGN_RIGHT, 10);

    vbox0->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALL | wxALIGN_RIGHT, 10);

    SetSizerAndFit(vbox0);

    Connect(wxID_OK,
            wxEVT_COMMAND_BUTTON_CLICKED,
            wxCommandEventHandler(MT_LoadXDFDialog::onOKClicked));
    Connect(ID_TIMESTEP,
            wxEVT_COMMAND_TEXT_UPDATED,
            wxCommandEventHandler(MT_LoadXDFDialog::onTSChanged));

    m_pXChoice->SetSelection(x_guess);
    m_pYChoice->SetSelection(y_guess);
}

void MT_LoadXDFDialog::onTSChanged(wxCommandEvent& event)
{
    if(!(m_pTimeStepCtrl->IsModified()))
    {
        return;
    }
    MT_ValidateTextCtrlInteger(m_pTimeStepCtrl);
}

void MT_LoadXDFDialog::onOKClicked(wxCommandEvent& event)
{

    std::string X_sel(m_pXChoice->GetStringSelection().mb_str());
    std::string Y_sel(m_pYChoice->GetStringSelection().mb_str());
    std::string FR(m_pTimeStepCtrl->GetValue().mb_str());

    m_pDG->SetStringValueByName(MT_XDFSettingsGroup::XPlaybackName,
                                X_sel);
    m_pDG->SetStringValueByName(MT_XDFSettingsGroup::YPlaybackName,
                                Y_sel);
    m_pDG->SetStringValueByName(MT_XDFSettingsGroup::PlaybackFramePeriodName,
                                FR);

    if(IsModal())
    {
        EndModal(wxID_OK);
    }
    else
    {
        Close();
    }
}

void MT_LoadXDFDialog::getInfo(std::string* x_name,
                               std::string* y_name,
                               unsigned int* frame_period_msec)
{
    *x_name = std::string(m_pXChoice->GetStringSelection().mb_str());
    *y_name = std::string(m_pYChoice->GetStringSelection().mb_str());
    *frame_period_msec = MT_ClampTextCtrlInt(m_pTimeStepCtrl,
                                             0,
                                             MT_max_int);

}
<commit_msg>[MT_GUI, Unicode] Fixed problems with MT_LoadXDFDialog converting std::string to wxString.<commit_after>#include "MT_XDFDialogs.h"

enum
{
    ID_X_CHOICE = wxID_HIGHEST + 1,
    ID_Y_CHOICE,
    ID_TIMESTEP
};

MT_LoadXDFDialog::MT_LoadXDFDialog(wxWindow* parent,
                                   MT_ExperimentDataFile* pXDF)
    : wxDialog(parent,
               wxID_ANY,
               wxT("XDF Settings"),
               wxDefaultPosition,
               wxDefaultSize,
               wxDEFAULT_DIALOG_STYLE),
      m_pXDF(pXDF)
{
    /* gather relevant information from XDF */
    std::vector<std::string> datanames;
    std::vector<std::string> datafiles;
    m_pXDF->getFilesFromXML(&datanames, &datafiles);

    unsigned int x_guess = 0;
    unsigned int y_guess = 0;
    unsigned int frame_period_guess = 32;
    for(unsigned int i = 0; i < datanames.size(); i++)
    {
        wxString cname(MT_StringToWxString(datanames[i].c_str()));
        m_asXChoices.Add(cname);
        m_asYChoices.Add(cname);
        if(cname.Find(wxT("X")) != wxNOT_FOUND ||
           cname.Find(wxT("x")) != wxNOT_FOUND)
        {
            x_guess = i;
        }
        if(cname.Find(wxT("Y")) != wxNOT_FOUND ||
           cname.Find(wxT("y")) != wxNOT_FOUND)
        {
            y_guess = i;
        }
    }

    MT_XDFSettingsGroup* pDG = m_pXDF->getSettingsGroup();
    m_pDG = pDG;

    if(pDG && (pDG->GetGroupName() == MT_XDFSettingsGroup::SettingsName))
    {
        unsigned int i = pDG->GetIndexByName(MT_XDFSettingsGroup::XPlaybackName);
        if(i >= 0 && i < pDG->GetGroupSize())
        {
            wxString X_Found(MT_StringToWxString(pDG->GetStringValue(i).c_str()));
            int j = m_asXChoices.Index(X_Found);
            if(j != wxNOT_FOUND)
            {
                x_guess = j;
            }
        }
        i = pDG->GetIndexByName(MT_XDFSettingsGroup::YPlaybackName);
        if(i >= 0 && i < pDG->GetGroupSize())
        {
            wxString Y_Found(MT_StringToWxString(pDG->GetStringValue(i).c_str()));
            int j = m_asXChoices.Index(Y_Found);
            if(j != wxNOT_FOUND)
            {
                y_guess = j;
            }
        }
        i = pDG->GetIndexByName(MT_XDFSettingsGroup::PlaybackFramePeriodName);
        if(i >= 0 && i < pDG->GetGroupSize())
        {
            int v = (int) pDG->GetNumericValue(i);
            if(v > 0)
            {
                frame_period_guess = v;
            }
        }
    }
    if(x_guess == y_guess)
    {
        y_guess = x_guess + 1;
    }

    /* GUI setup */
    wxBoxSizer* vbox0 = new wxBoxSizer(wxVERTICAL);

    wxBoxSizer* hbox0 = new wxBoxSizer(wxHORIZONTAL);

    wxBoxSizer* vbox1 = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer* vbox2 = new wxBoxSizer(wxVERTICAL);

    vbox1->Add(new wxStaticText(this, wxID_ANY, wxT("X Data")),
               0, wxLEFT | wxRIGHT, 10);

    m_pXChoice = new wxChoice(this,
                              ID_X_CHOICE,
                              wxDefaultPosition,
                              wxSize(150, 20),
                              m_asXChoices);
    vbox1->Add(m_pXChoice, 0, wxLEFT | wxRIGHT, 10);

    vbox2->Add(new wxStaticText(this, wxID_ANY, wxT("Y Data")),
               0, wxLEFT | wxRIGHT, 10);

    m_pYChoice = new wxChoice(this,
                              ID_Y_CHOICE,
                              wxDefaultPosition,
                              wxSize(150, 20),
                              m_asYChoices);
    vbox2->Add(m_pYChoice, 0, wxLEFT | wxRIGHT, 10);

    hbox0->Add(vbox1);
    hbox0->Add(vbox2);
    vbox0->Add(hbox0, 0, wxTOP, 10);

    wxBoxSizer* hbox1 = new wxBoxSizer(wxHORIZONTAL);

    hbox1->Add(new wxStaticText(this, wxID_ANY, wxT("Time Step [msec]")),
               0, wxLEFT | wxRIGHT, 10);
    wxString sDt;
    sDt.Printf(wxT("%d"), frame_period_guess);
    m_pTimeStepCtrl = new wxTextCtrl(this,
                                     ID_TIMESTEP,
                                     sDt,
                                     wxDefaultPosition,
                                     wxSize(100, 20));
    hbox1->Add(m_pTimeStepCtrl, 0, wxLEFT | wxRIGHT | wxALIGN_RIGHT, 10);

    vbox0->Add(hbox1, 0, wxLEFT | wxRIGHT | wxTOP | wxALIGN_RIGHT, 10);

    vbox0->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALL | wxALIGN_RIGHT, 10);

    SetSizerAndFit(vbox0);

    Connect(wxID_OK,
            wxEVT_COMMAND_BUTTON_CLICKED,
            wxCommandEventHandler(MT_LoadXDFDialog::onOKClicked));
    Connect(ID_TIMESTEP,
            wxEVT_COMMAND_TEXT_UPDATED,
            wxCommandEventHandler(MT_LoadXDFDialog::onTSChanged));

    m_pXChoice->SetSelection(x_guess);
    m_pYChoice->SetSelection(y_guess);
}

void MT_LoadXDFDialog::onTSChanged(wxCommandEvent& event)
{
    if(!(m_pTimeStepCtrl->IsModified()))
    {
        return;
    }
    MT_ValidateTextCtrlInteger(m_pTimeStepCtrl);
}

void MT_LoadXDFDialog::onOKClicked(wxCommandEvent& event)
{

    std::string X_sel(m_pXChoice->GetStringSelection().mb_str());
    std::string Y_sel(m_pYChoice->GetStringSelection().mb_str());
    std::string FR(m_pTimeStepCtrl->GetValue().mb_str());

    m_pDG->SetStringValueByName(MT_XDFSettingsGroup::XPlaybackName,
                                X_sel);
    m_pDG->SetStringValueByName(MT_XDFSettingsGroup::YPlaybackName,
                                Y_sel);
    m_pDG->SetStringValueByName(MT_XDFSettingsGroup::PlaybackFramePeriodName,
                                FR);

    if(IsModal())
    {
        EndModal(wxID_OK);
    }
    else
    {
        Close();
    }
}

void MT_LoadXDFDialog::getInfo(std::string* x_name,
                               std::string* y_name,
                               unsigned int* frame_period_msec)
{
    *x_name = std::string(m_pXChoice->GetStringSelection().mb_str());
    *y_name = std::string(m_pYChoice->GetStringSelection().mb_str());
    *frame_period_msec = MT_ClampTextCtrlInt(m_pTimeStepCtrl,
                                             0,
                                             MT_max_int);

}
<|endoftext|>


<commit_before>/**************************************************************************
* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

// $Id$

#include "AliMUONTrackerPreprocessor.h"

#include "AliMUONPedestalSubprocessor.h"
#include "AliMUONHVSubprocessor.h"
#include "AliMUONGMSSubprocessor.h"

#include "AliLog.h"
#include "AliShuttleInterface.h"
#include "Riostream.h"
#include "TObjArray.h"

/// \class AliMUONTrackerPreprocessor
///
/// Shuttle preprocessor for MUON tracker
///
/// It's simply a manager class that deals with a list of sub-tasks
/// (of type AliMUONVSubprocessor).
///
/// \author Laurent Aphecetche

/// \cond CLASSIMP
ClassImp(AliMUONTrackerPreprocessor)
/// \endcond

//_____________________________________________________________________________
AliMUONTrackerPreprocessor::AliMUONTrackerPreprocessor(AliShuttleInterface* shuttle)
: AliMUONPreprocessor("MCH",shuttle),
  fPedestalSubprocessor(new AliMUONPedestalSubprocessor(this)),
  fGMSSubprocessor(new AliMUONGMSSubprocessor(this)),
  fHVSubprocessor(new AliMUONHVSubprocessor(this))
{
  /// ctor.
}

//_____________________________________________________________________________
AliMUONTrackerPreprocessor::~AliMUONTrackerPreprocessor()
{
  /// dtor

  delete fPedestalSubprocessor;
  delete fGMSSubprocessor;
  delete fHVSubprocessor;
}

//_____________________________________________________________________________
void
AliMUONTrackerPreprocessor::Initialize(Int_t run, UInt_t startTime, UInt_t endTime)
{
  ClearSubprocessors();

  TString runType = GetRunType();

  if ( runType == "PEDESTAL_RUN" ) // FIXME : check the name
  {
    Add(fPedestalSubprocessor); // to be called only for pedestal runs
    Log("INFO-Will run Pedestal subprocessor");
  }
  else if ( runType == "ELECTRONICS_CALIBRATION_RUN" ) // FIXME : check the name
  {
    Log("WARNING-Subprocessor for gains not yet implemented");
    //fSubprocessors->Add(new AliMUONGainSubprocessor(this)); // to be called only for gain runs
  }
  else if ( runType == "GMS" ) // FIXME : check the name
  {
    Add(fGMSSubprocessor);
    Log("INFO-Will run GMS subprocessor");
  }
  else if ( runType == "PHYSICS" ) // FIXME : check the name
  {
    Add(fHVSubprocessor); // to be called only for physics runs
    Log("INFO-Will run HV subprocessor");
  }
  else
  {
    Log(Form("ERROR-Unknown RunType=%",runType.Data()));
  }

  AliMUONPreprocessor::Initialize(run,startTime,endTime);

}
<commit_msg>Adding comment<commit_after>/**************************************************************************
* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

// $Id$

#include "AliMUONTrackerPreprocessor.h"

#include "AliMUONPedestalSubprocessor.h"
#include "AliMUONHVSubprocessor.h"
#include "AliMUONGMSSubprocessor.h"

#include "AliLog.h"
#include "AliShuttleInterface.h"
#include "Riostream.h"
#include "TObjArray.h"

/// \class AliMUONTrackerPreprocessor
///
/// Shuttle preprocessor for MUON tracker
///
/// It's simply a manager class that deals with a list of sub-tasks
/// (of type AliMUONVSubprocessor).
///
/// \author Laurent Aphecetche

/// \cond CLASSIMP
ClassImp(AliMUONTrackerPreprocessor)
/// \endcond

//_____________________________________________________________________________
AliMUONTrackerPreprocessor::AliMUONTrackerPreprocessor(AliShuttleInterface* shuttle)
: AliMUONPreprocessor("MCH",shuttle),
  fPedestalSubprocessor(new AliMUONPedestalSubprocessor(this)),
  fGMSSubprocessor(new AliMUONGMSSubprocessor(this)),
  fHVSubprocessor(new AliMUONHVSubprocessor(this))
{
  /// ctor.
}

//_____________________________________________________________________________
AliMUONTrackerPreprocessor::~AliMUONTrackerPreprocessor()
{
  /// dtor

  delete fPedestalSubprocessor;
  delete fGMSSubprocessor;
  delete fHVSubprocessor;
}

//_____________________________________________________________________________
void
AliMUONTrackerPreprocessor::Initialize(Int_t run, UInt_t startTime, UInt_t endTime)
{
  /// Re-register the subprocessor(s) depnding on the actual runTYpe

  ClearSubprocessors();

  TString runType = GetRunType();

  if ( runType == "PEDESTAL_RUN" ) // FIXME : check the name
  {
    Add(fPedestalSubprocessor); // to be called only for pedestal runs
    Log("INFO-Will run Pedestal subprocessor");
  }
  else if ( runType == "ELECTRONICS_CALIBRATION_RUN" ) // FIXME : check the name
  {
    Log("WARNING-Subprocessor for gains not yet implemented");
    //fSubprocessors->Add(new AliMUONGainSubprocessor(this)); // to be called only for gain runs
  }
  else if ( runType == "GMS" ) // FIXME : check the name
  {
    Add(fGMSSubprocessor);
    Log("INFO-Will run GMS subprocessor");
  }
  else if ( runType == "PHYSICS" ) // FIXME : check the name
  {
    Add(fHVSubprocessor); // to be called only for physics runs
    Log("INFO-Will run HV subprocessor");
  }
  else
  {
    Log(Form("ERROR-Unknown RunType=%",runType.Data()));
  }

  AliMUONPreprocessor::Initialize(run,startTime,endTime);

}
<|endoftext|>


<commit_before>// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#include "sfidl-generator.hh"
#include "sfidl-options.hh"
#include "sfidl-parser.hh"

using namespace Sfidl;

int main (int argc, char **argv)
{
  Options options;
  Parser parser;

  if (!options.parse (&argc, &argv, parser))
    {
      /* invalid options */
      return 1;
    }

  if (options.doExit)
    {
      return 0;
    }

  if (options.doHelp)
    {
      options.printUsage ();
      return 0;
    }

  if (argc != 2)
    {
      options.printUsage ();
      return 1;
    }

  if (!options.codeGenerator)
    {
      options.printUsage();
      return 1;
    }

  if (!parser.parse(argv[1]))
    {
      /* parse error */
      return 1;
    }

  if (!options.codeGenerator->run ())
    {
      delete options.codeGenerator;
      return 1;
    }

  delete options.codeGenerator;
  return 0;
}

#include "sfidl-generator.cc"
#include "sfidl-namespace.cc"
#include "sfidl-options.cc"
#include "sfidl-parser.cc"
#include "sfidl-factory.cc"
#include "sfidl-typelist.cc"
#include "sfidl-cbase.cc"
#include "sfidl-clientc.cc"
#include "sfidl-clientcxx.cc"
#include "sfidl-corec.cc"
#include "sfidl-corecxx.cc"
#include "sfidl-cxxbase.cc"
#include "sfidl-hostc.cc"
#include "sfidl-utils.cc"

/* vim:set ts=8 sts=2 sw=2: */
<commit_msg>SFI: sfidl.cc: main: abort if an assertion is triggered<commit_after>// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#include "sfidl-generator.hh"
#include "sfidl-options.hh"
#include "sfidl-parser.hh"

using namespace Sfidl;

int main (int argc, char **argv)
{
  Bse::assertion_failed_hook ([&] () { Bse::breakpoint(); });

  Options options;
  Parser parser;

  if (!options.parse (&argc, &argv, parser))
    {
      /* invalid options */
      return 1;
    }

  if (options.doExit)
    {
      return 0;
    }

  if (options.doHelp)
    {
      options.printUsage ();
      return 0;
    }

  if (argc != 2)
    {
      options.printUsage ();
      return 1;
    }

  if (!options.codeGenerator)
    {
      options.printUsage();
      return 1;
    }

  if (!parser.parse(argv[1]))
    {
      /* parse error */
      return 1;
    }

  if (!options.codeGenerator->run ())
    {
      delete options.codeGenerator;
      return 1;
    }

  delete options.codeGenerator;
  return 0;
}

#include "sfidl-generator.cc"
#include "sfidl-namespace.cc"
#include "sfidl-options.cc"
#include "sfidl-parser.cc"
#include "sfidl-factory.cc"
#include "sfidl-typelist.cc"
#include "sfidl-cbase.cc"
#include "sfidl-clientc.cc"
#include "sfidl-clientcxx.cc"
#include "sfidl-corec.cc"
#include "sfidl-corecxx.cc"
#include "sfidl-cxxbase.cc"
#include "sfidl-hostc.cc"
#include "sfidl-utils.cc"

/* vim:set ts=8 sts=2 sw=2: */
<|endoftext|>


<commit_before>// MapView.cpp :  Դϴ.
//

#include "stdafx.h"
#include "MapTool.h"
#include "MapView.h"
#include "../../etc/Utility.h"
#include "MainPanel.h"

CMapView *g_mapView = NULL;
vector<graphic::cCube*> g_cubes;

using namespace graphic;

const int WINSIZE_X = 1024;		//ʱ   ũ
const int WINSIZE_Y = 768;	//ʱ   ũ

// CMapView
CMapView::CMapView() :
	m_dxInit(false)
,	m_RButtonDown(false)
{
	g_mapView = this;
}

CMapView::~CMapView()
{
}

BEGIN_MESSAGE_MAP(CMapView, CView)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_RBUTTONDOWN()
	ON_WM_RBUTTONUP()
	ON_WM_KEYDOWN()
END_MESSAGE_MAP()

// CMapView ׸Դϴ.

void CMapView::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: ⿡ ׸ ڵ带 ߰մϴ.
}

// CMapView Դϴ.

#ifdef _DEBUG
void CMapView::AssertValid() const
{
	CView::AssertValid();
}

#ifndef _WIN32_WCE
void CMapView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}
#endif
#endif //_DEBUG

// CMapView ޽ óԴϴ.
LPDIRECT3DDEVICE9 g_pDevice;
LPDIRECT3DDEVICE9 graphic::GetDevice()
{
	return g_pDevice;
}

bool CMapView::Init()
{
	if (!graphic::InitDirectX(m_hWnd, WINSIZE_X, WINSIZE_Y, g_pDevice))
	{
		return 0;
	}

	m_camPos = Vector3(100,100,-500);
	m_lookAtPos = Vector3(0,0,0);
	UpdateCamera();

	m_matProj.SetProjection(D3DX_PI / 4.f, (float)WINSIZE_X / (float) WINSIZE_Y, 1.f, 10000.0f) ;
	graphic::GetDevice()->SetTransform(D3DTS_PROJECTION, (D3DXMATRIX*)&m_matProj) ;

	graphic::GetDevice()->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE);

	graphic::GetDevice()->LightEnable (
		0, // Ȱȭ/ Ȱȭ Ϸ  Ʈ
		true); // true = Ȱȭ  false = Ȱȭ

	m_grid.Create(64,64,50.f);
	m_cube.SetCube(Vector3(-10,-10,-10), Vector3(10,10,10));
	m_cube.SetColor( 0xFF0000FF );
	m_dxInit = true;
	return true;
}

void CMapView::Render()
{
	if (!m_dxInit)
		return;

	//ȭ û
	if (SUCCEEDED(g_pDevice->Clear(
		0,			//û  D3DRECT 迭 		( ü Ŭ 0 )
		NULL,		//û  D3DRECT 迭 		( ü Ŭ NULL )
		D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL,	//ûҵ  ÷ ( D3DCLEAR_TARGET ÷, D3DCLEAR_ZBUFFER ̹, D3DCLEAR_STENCIL ٽǹ
		D3DCOLOR_XRGB(150, 150, 150),			//÷۸ ûϰ ä ( 0xAARRGGBB )
		1.0f,				//̹۸ ûҰ ( 0 ~ 1 0  ī޶󿡼 ϰ 1  ī޶󿡼   )
		0					//ٽ ۸ äﰪ
		)))
	{
		//ȭ ûҰ  ̷ ٸ...
		g_pDevice->BeginScene();

		//RenderFPS(timeDelta);
		GetDevice()->SetRenderState( D3DRS_LIGHTING, FALSE);

		Matrix44 matIdentity;
		GetDevice()->SetTransform( D3DTS_WORLD, (D3DMATRIX*)&matIdentity);
		m_grid.Render();
		RenderAxis();

		m_cube.Render(matIdentity);
		for (int i=0; i < (int)g_cubes.size(); ++i)
			g_cubes[ i]->Render(matIdentity);

		//
		g_pDevice->EndScene();
		//    ȭ
		g_pDevice->Present( NULL, NULL, NULL, NULL );
	}

}

void CMapView::Update(float elapseT)
{

}

void CMapView::OnMouseMove(UINT nFlags, CPoint point)
{
	if (m_RButtonDown)
	{
		CPoint pos = point  - m_curPos;
		m_curPos = point;

		{ // rotate Y-Axis
			Quaternion q(Vector3(0,1,0), pos.x * 0.005f);
			Matrix44 m = q.GetMatrix();
			m_camPos *= m;
		}

		{ // rotate X-Axis
			Quaternion q(Vector3(1,0,0), pos.y * 0.005f);
			Matrix44 m = q.GetMatrix();
			m_camPos *= m;
		}

		UpdateCamera();
	}
	else
	{
		Vector3 orig, dir, pickPos;
		GetRay(point.x, point.y, orig, dir);
		if (m_grid.Pick(point.x, point.y, orig, dir, pickPos))
		{
			Matrix44 mT;
			mT.SetTranslate(pickPos);
			m_cube.SetTransform(mT);
		}
	}

	CView::OnMouseMove(nFlags, point);
}

void CMapView::OnLButtonDown(UINT nFlags, CPoint point)
{
	Vector3 orig, dir, pickPos;
	GetRay(point.x, point.y, orig, dir);
	if (m_grid.Pick(point.x, point.y, orig, dir, pickPos))
	{
		graphic::cCube *newCube = new graphic::cCube();
		newCube->SetCube(Vector3(-10,-10,-10), Vector3(10,10,10));
		newCube->SetTransform( m_cube.GetTransform() );
		newCube->SetColor(0xFF0000);
		g_cubes.push_back( newCube );

		g_mainPanel->InsertCube( *newCube );
	}

	CView::OnLButtonDown(nFlags, point);
}

void CMapView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: ⿡ ޽ ó ڵ带 ߰ /Ǵ ⺻ ȣմϴ.

	CView::OnLButtonUp(nFlags, point);
}

void CMapView::OnRButtonDown(UINT nFlags, CPoint point)
{
	SetFocus();
	SetCapture();
	m_RButtonDown = true;
	m_curPos = point;
	CView::OnRButtonDown(nFlags, point);
}

void CMapView::OnRButtonUp(UINT nFlags, CPoint point)
{
	ReleaseCapture();
	m_RButtonDown = false;
	CView::OnRButtonUp(nFlags, point);
}

void CMapView::UpdateCamera()
{
	Vector3 dir = m_lookAtPos - m_camPos;
	dir.Normalize();
	m_matView.SetView(m_camPos, dir, Vector3(0,1,0));
	graphic::GetDevice()->SetTransform(D3DTS_VIEW, (D3DXMATRIX*)&m_matView);
}

void CMapView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	if (nChar == VK_TAB)
	{
		static bool flag = false;
		GetDevice()->SetRenderState(D3DRS_CULLMODE, flag);
		GetDevice()->SetRenderState(D3DRS_FILLMODE, flag? D3DFILL_SOLID : D3DFILL_WIREFRAME);
		flag = !flag;
	}

	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CMapView::GetRay(int sx, int sy, Vector3 &orig, Vector3 &dir)
{
	const float x =  ((sx * 2.0F / WINSIZE_X) - 1.0F );
	const float y = -((sy * 2.0F / WINSIZE_Y) - 1.0F );

	Vector3 v;
	v.x = x / m_matProj._11;
	v.y = y / m_matProj._22;
	v.z =  1.0F;

	Matrix44 m = m_matView.Inverse();

	dir.x = v.x * m._11 + v.y * m._21 + v.z * m._31;
	dir.y = v.x * m._12 + v.y * m._22 + v.z * m._32;
	dir.z = v.x * m._13 + v.y * m._23 + v.z * m._33;
	dir.Normalize();

	orig.x = m._41;
	orig.y = m._42;
	orig.z = m._43;
}

void CMapView::SelectCube( int index )
{
	for (int i=0; i < (int)g_cubes.size(); ++i)
		g_cubes[ i]->SetColor( 0xFF0000 );
	g_cubes[ index]->SetColor( 0x00FF00 );
}
<commit_msg>update maptool bug<commit_after>// MapView.cpp :  Դϴ.
//

#include "stdafx.h"
#include "MapTool.h"
#include "MapView.h"
#include "../../etc/Utility.h"
#include "MainPanel.h"

CMapView *g_mapView = NULL;
vector<graphic::cCube*> g_cubes;

using namespace graphic;

const int WINSIZE_X = 1024;		//ʱ   ũ
const int WINSIZE_Y = 768;	//ʱ   ũ

// CMapView
CMapView::CMapView() :
	m_dxInit(false)
,	m_RButtonDown(false)
{
	g_mapView = this;
}

CMapView::~CMapView()
{
}

BEGIN_MESSAGE_MAP(CMapView, CView)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_RBUTTONDOWN()
	ON_WM_RBUTTONUP()
	ON_WM_KEYDOWN()
END_MESSAGE_MAP()

// CMapView ׸Դϴ.

void CMapView::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: ⿡ ׸ ڵ带 ߰մϴ.
}

// CMapView Դϴ.

#ifdef _DEBUG
void CMapView::AssertValid() const
{
	CView::AssertValid();
}

#ifndef _WIN32_WCE
void CMapView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}
#endif
#endif //_DEBUG

// CMapView ޽ óԴϴ.
LPDIRECT3DDEVICE9 g_pDevice;
LPDIRECT3DDEVICE9 graphic::GetDevice()
{
	return g_pDevice;
}

bool CMapView::Init()
{
	if (!graphic::InitDirectX(m_hWnd, WINSIZE_X, WINSIZE_Y, g_pDevice))
	{
		return 0;
	}

	m_camPos = Vector3(100,100,-500);
	m_lookAtPos = Vector3(0,0,0);
	UpdateCamera();

	m_matProj.SetProjection(D3DX_PI / 4.f, (float)WINSIZE_X / (float) WINSIZE_Y, 1.f, 10000.0f) ;
	graphic::GetDevice()->SetTransform(D3DTS_PROJECTION, (D3DXMATRIX*)&m_matProj) ;

	graphic::GetDevice()->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE);

	graphic::GetDevice()->LightEnable (
		0, // Ȱȭ/ Ȱȭ Ϸ  Ʈ
		true); // true = Ȱȭ  false = Ȱȭ

	m_grid.Create(64,64,50.f);
	m_cube.SetCube(Vector3(-10,-10,-10), Vector3(10,10,10));
	m_cube.SetColor( 0xFF0000FF );
	m_dxInit = true;
	return true;
}

void CMapView::Render()
{
	if (!m_dxInit)
		return;

	//ȭ û
	if (SUCCEEDED(g_pDevice->Clear(
		0,			//û  D3DRECT 迭 		( ü Ŭ 0 )
		NULL,		//û  D3DRECT 迭 		( ü Ŭ NULL )
		D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL,	//ûҵ  ÷ ( D3DCLEAR_TARGET ÷, D3DCLEAR_ZBUFFER ̹, D3DCLEAR_STENCIL ٽǹ
		D3DCOLOR_XRGB(150, 150, 150),			//÷۸ ûϰ ä ( 0xAARRGGBB )
		1.0f,				//̹۸ ûҰ ( 0 ~ 1 0  ī޶󿡼 ϰ 1  ī޶󿡼   )
		0					//ٽ ۸ äﰪ
		)))
	{
		//ȭ ûҰ  ̷ ٸ...
		g_pDevice->BeginScene();

		//RenderFPS(timeDelta);
		GetDevice()->SetRenderState( D3DRS_LIGHTING, FALSE);

		Matrix44 matIdentity;
		GetDevice()->SetTransform( D3DTS_WORLD, (D3DMATRIX*)&matIdentity);
		m_grid.Render();
		RenderAxis();

		m_cube.Render(matIdentity);
		for (int i=0; i < (int)g_cubes.size(); ++i)
			g_cubes[ i]->Render(matIdentity);

		//
		g_pDevice->EndScene();
		//    ȭ
		g_pDevice->Present( NULL, NULL, NULL, NULL );
	}

}

void CMapView::Update(float elapseT)
{

}

void CMapView::OnMouseMove(UINT nFlags, CPoint point)
{
	if (m_RButtonDown)
	{
		CPoint pos = point  - m_curPos;
		m_curPos = point;

		{ // rotate Y-Axis
			Quaternion q(Vector3(0,1,0), pos.x * 0.005f);
			Matrix44 m = q.GetMatrix();
			m_camPos *= m;
		}

		{ // rotate X-Axis
			Quaternion q(Vector3(1,0,0), pos.y * 0.005f);
			Matrix44 m = q.GetMatrix();
			m_camPos *= m;
		}

		UpdateCamera();
	}
	else
	{
		Vector3 orig, dir, pickPos;
		GetRay(point.x, point.y, orig, dir);
		if (m_grid.Pick(point.x, point.y, orig, dir, pickPos))
		{
			Matrix44 mT;
			mT.SetTranslate(pickPos);
			m_cube.SetTransform(mT);
		}
	}

	CView::OnMouseMove(nFlags, point);
}

void CMapView::OnLButtonDown(UINT nFlags, CPoint point)
{
	Vector3 orig, dir, pickPos;
	GetRay(point.x, point.y, orig, dir);
	if (m_grid.Pick(point.x, point.y, orig, dir, pickPos))
	{
		graphic::cCube *newCube = new graphic::cCube();
		newCube->SetCube(Vector3(-10,-10,-10), Vector3(10,10,10));
		newCube->SetTransform( m_cube.GetTransform() );
		newCube->SetColor(0xFF0000);
		g_cubes.push_back( newCube );

		g_mainPanel->InsertCube( *newCube );
	}

	CView::OnLButtonDown(nFlags, point);
}

void CMapView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: ⿡ ޽ ó ڵ带 ߰ /Ǵ ⺻ ȣմϴ.

	CView::OnLButtonUp(nFlags, point);
}

void CMapView::OnRButtonDown(UINT nFlags, CPoint point)
{
	SetFocus();
	SetCapture();
	m_RButtonDown = true;
	m_curPos = point;
	CView::OnRButtonDown(nFlags, point);
}

void CMapView::OnRButtonUp(UINT nFlags, CPoint point)
{
	ReleaseCapture();
	m_RButtonDown = false;
	CView::OnRButtonUp(nFlags, point);
}

void CMapView::UpdateCamera()
{
	Vector3 dir = m_lookAtPos - m_camPos;
	dir.Normalize();
	m_matView.SetView(m_camPos, dir, Vector3(0,1,0));
	graphic::GetDevice()->SetTransform(D3DTS_VIEW, (D3DXMATRIX*)&m_matView);
}

void CMapView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	if (nChar == VK_TAB)
	{
		static bool flag = false;
		GetDevice()->SetRenderState(D3DRS_CULLMODE, flag);
		GetDevice()->SetRenderState(D3DRS_FILLMODE, flag? D3DFILL_SOLID : D3DFILL_WIREFRAME);
		flag = !flag;
	}

	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CMapView::GetRay(int sx, int sy, Vector3 &orig, Vector3 &dir)
{
	const float x =  ((sx * 2.0F / WINSIZE_X) - 1.0F );
	const float y = -((sy * 2.0F / WINSIZE_Y) - 1.0F );

	Vector3 v;
	v.x = x / m_matProj._11;
	v.y = y / m_matProj._22;
	v.z =  1.0F;

	Matrix44 m = m_matView.Inverse();

	dir.x = v.x * m._11 + v.y * m._21 + v.z * m._31;
	dir.y = v.x * m._12 + v.y * m._22 + v.z * m._32;
	dir.z = v.x * m._13 + v.y * m._23 + v.z * m._33;
	dir.Normalize();

	orig.x = m._41;
	orig.y = m._42;
	orig.z = m._43;
}

void CMapView::SelectCube( int index )
{
	if (index < 0)
		return;

	for (int i=0; i < (int)g_cubes.size(); ++i)
		g_cubes[ i]->SetColor( 0xFF0000 );
	g_cubes[ index]->SetColor( 0x00FF00 );
}
<|endoftext|>


<commit_before>#include <array>

using box = std::array<int, 4>;

auto prelude = x3::lit('[') ;
auto box = x3::lit('[') > x3::int_ > ',' x3::int_ > ',' x3::int_ > ',' x3::int_ > ']';
auto innerboxlist = *(box > ',') > box;
auto fullboxlist = x3::lit("array") > '(' > '[' > boxlist > ']' > ',' > "dtype" > '=' > "int64" > ')';

<commit_msg>A little bit more X3 stuff<commit_after>#include <array>
#include <boost/spirit/home/x3.hpp>

using namespace boost::spirit;

using box = std::array<int, 4>;

auto constexpr bracketize(auto what)
{
	return '[' > what > ']';
}

auto boxrule = bracketize(x3::int_ > ',' > x3::int_ > ',' > x3::int_ > ',' > x3::int_);
auto innerboxlist = *(boxrule > ',') > boxrule;
auto fullboxlist = x3::lit("array") > '(' > bracketize(innerboxlist ) > ',' > "dtype" > '=' > "int64" > ')';

auto boxes = bracketize(*(fullboxlist));

auto scorelist = x3::lit("array") > '(' > bracketize(*(x3::double_)) > ')';
auto scores = bracketize(*(scorelist));

int main()
{
	scores.has_action;
}

<|endoftext|>