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

  Program:   KWSys - Kitware System Library
  Module:    DynamicLoader.cxx

  Copyright (c) Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "kwsysPrivate.h"
#include KWSYS_HEADER(DynamicLoader.hxx)

#include KWSYS_HEADER(Configure.hxx)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
# include "DynamicLoader.hxx.in"
# include "Configure.hxx.in"
#endif

// This file is actually 3 different implementations.
// 1. HP machines which uses shl_load
// 2. Power PC MAC which uses GetSharedLibrary
// 3. Windows which uses LoadLibrary
// 4. Most unix systems which use dlopen (default )
// Each part of the ifdef contains a complete implementation for
// the static methods of DynamicLoader.

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
DynamicLoader::DynamicLoader()
{
}

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

}

// ---------------------------------------------------------------
// 1. Implementation for HPUX  machines
#ifdef __hpux
#include <dl.h>
#define DYNAMICLOADER_DEFINED 1

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
LibHandle DynamicLoader::OpenLibrary(const char* libname )
{
  return shl_load(libname, BIND_DEFERRED | DYNAMIC_PATH, 0L);
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary(LibHandle lib)
{
  return !shl_unload(lib);
}

//----------------------------------------------------------------------------
DynamicLoaderFunction
DynamicLoader::GetSymbolAddress(LibHandle lib, const char* sym)
{
  void* addr;
  int status;

  status = shl_findsym (&lib, sym, TYPE_PROCEDURE, &addr);
  void* result = (status < 0) ? (void*)0 : addr;

  // Hack to cast pointer-to-data to pointer-to-function.
  return *reinterpret_cast<DynamicLoaderFunction*>(&result);
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
  return "lib";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
  return ".sl";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  // TODO: Need implementation with errno/strerror
  /* If successful, shl_findsym returns an integer (int) value zero. If
   * shl_findsym cannot find sym, it returns -1 and sets errno to zero.
   * If any other errors occur, shl_findsym returns -1 and sets errno to one
   * of these values (defined in <errno.h>):
   * ENOEXEC
   * A format error was detected in the specified library.
   * ENOSYM
   * A symbol on which sym depends could not be found.
   * EINVAL
   * The specified handle is invalid.
   */

  return 0;
}

} // namespace KWSYS_NAMESPACE

#endif //__hpux

// ---------------------------------------------------------------
// 2. Implementation for Mac OS X 10.2.x and earlier
#ifdef __APPLE__
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1030
#include <mach-o/dyld.h>
#define DYNAMICLOADER_DEFINED 1

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
LibHandle DynamicLoader::OpenLibrary(const char* libname )
{
  NSObjectFileImageReturnCode rc;
  NSObjectFileImage image = 0;

  rc = NSCreateObjectFileImageFromFile(libname, &image);
  if(!image)
    {
    return 0;
    }
  return NSLinkModule(image, libname, NSLINKMODULE_OPTION_BINDNOW);
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary( LibHandle lib)
{
  DYLD_BOOL success = NSUnLinkModule(lib, NSUNLINKMODULE_OPTION_NONE);
  return success;
}

//----------------------------------------------------------------------------
DynamicLoaderFunction DynamicLoader::GetSymbolAddress(LibHandle /* lib */, const char* sym)
{
  void *result=0;
  if(NSIsSymbolNameDefined(sym))
    {
    NSSymbol symbol= NSLookupAndBindSymbol(sym);
    if(symbol)
      {
      result = NSAddressOfSymbol(symbol);
      }
    }
  // Hack to cast pointer-to-data to pointer-to-function.
  return *reinterpret_cast<DynamicLoaderFunction*>(&result);
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
  return "";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
  return ".dylib";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  return 0;
}

} // namespace KWSYS_NAMESPACE

#endif //MAC_OS_X_VERSION_MIN_REQUIRED < 1030
#endif // __APPLE__

// ---------------------------------------------------------------
// 3. Implementation for Windows win32 code
#ifdef _WIN32
#include <windows.h>
#define DYNAMICLOADER_DEFINED 1

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
LibHandle DynamicLoader::OpenLibrary(const char* libname)
{
  LibHandle lh;
#ifdef UNICODE
  wchar_t libn[MB_CUR_MAX];
  mbstowcs(libn, libname, MB_CUR_MAX);
  lh = LoadLibrary(libn);
#else
  lh = LoadLibrary(libname);
#endif
  return lh;
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary(LibHandle lib)
{
  return (int)FreeLibrary(lib);
}

//----------------------------------------------------------------------------
DynamicLoaderFunction DynamicLoader::GetSymbolAddress(LibHandle lib, const char* sym)
{
  void *result;
#ifdef UNICODE
  wchar_t wsym[MB_CUR_MAX];
  mbstowcs(wsym, sym, MB_CUR_MAX);
  result = GetProcAddress(lib, wsym);
#else
  result = (void*)GetProcAddress(lib, sym);
#endif
  // Hack to cast pointer-to-data to pointer-to-function.
  return *reinterpret_cast<DynamicLoaderFunction*>(&result);
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
  return "";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
  return ".dll";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  LPVOID lpMsgBuf;

  FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    NULL,
    GetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    (LPTSTR) &lpMsgBuf,
    0,
    NULL
    );

  static char* str = 0;
  delete [] str;
  str = strcpy(new char[strlen((char*)lpMsgBuf)+1], (char*)lpMsgBuf);
  // Free the buffer.
  LocalFree( lpMsgBuf );
  return str;
}

} // namespace KWSYS_NAMESPACE

#endif //_WIN32

// ---------------------------------------------------------------
// 4. Implementation for default UNIX machines.
// if nothing has been defined then use this
#ifndef DYNAMICLOADER_DEFINED
#define DYNAMICLOADER_DEFINED 1
// Setup for most unix machines
#include <dlfcn.h>

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
LibHandle DynamicLoader::OpenLibrary(const char* libname )
{
  return dlopen(libname, RTLD_LAZY);
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary(LibHandle lib)
{
  if (lib)
    {
    // The function dlclose() returns 0 on success, and non-zero on error.
    return !(int)dlclose(lib);
    }
  // else
  return 0;
}

//----------------------------------------------------------------------------
DynamicLoaderFunction DynamicLoader::GetSymbolAddress(LibHandle lib, const char* sym)
{
  void* result = dlsym(lib, sym);

  // Hack to cast pointer-to-data to pointer-to-function.
  return *reinterpret_cast<DynamicLoaderFunction*>(&result);
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
  return "lib";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
  return ".so";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  return dlerror();
}

} // namespace KWSYS_NAMESPACE

#endif
<commit_msg>COMP: Fix compilation on MacOSX<commit_after>/*=========================================================================

  Program:   KWSys - Kitware System Library
  Module:    DynamicLoader.cxx

  Copyright (c) Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "kwsysPrivate.h"
#include KWSYS_HEADER(DynamicLoader.hxx)

#include KWSYS_HEADER(Configure.hxx)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
# include "DynamicLoader.hxx.in"
# include "Configure.hxx.in"
#endif

// This file is actually 3 different implementations.
// 1. HP machines which uses shl_load
// 2. Power PC MAC which uses GetSharedLibrary
// 3. Windows which uses LoadLibrary
// 4. Most unix systems which use dlopen (default )
// Each part of the ifdef contains a complete implementation for
// the static methods of DynamicLoader.

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
DynamicLoader::DynamicLoader()
{
}

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

}

// ---------------------------------------------------------------
// 1. Implementation for HPUX  machines
#ifdef __hpux
#include <dl.h>
#define DYNAMICLOADER_DEFINED 1

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
LibHandle DynamicLoader::OpenLibrary(const char* libname )
{
  return shl_load(libname, BIND_DEFERRED | DYNAMIC_PATH, 0L);
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary(LibHandle lib)
{
  return !shl_unload(lib);
}

//----------------------------------------------------------------------------
DynamicLoaderFunction
DynamicLoader::GetSymbolAddress(LibHandle lib, const char* sym)
{
  void* addr;
  int status;

  status = shl_findsym (&lib, sym, TYPE_PROCEDURE, &addr);
  void* result = (status < 0) ? (void*)0 : addr;

  // Hack to cast pointer-to-data to pointer-to-function.
  return *reinterpret_cast<DynamicLoaderFunction*>(&result);
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
  return "lib";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
  return ".sl";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  // TODO: Need implementation with errno/strerror
  /* If successful, shl_findsym returns an integer (int) value zero. If
   * shl_findsym cannot find sym, it returns -1 and sets errno to zero.
   * If any other errors occur, shl_findsym returns -1 and sets errno to one
   * of these values (defined in <errno.h>):
   * ENOEXEC
   * A format error was detected in the specified library.
   * ENOSYM
   * A symbol on which sym depends could not be found.
   * EINVAL
   * The specified handle is invalid.
   */

  return 0;
}

} // namespace KWSYS_NAMESPACE

#endif //__hpux

// ---------------------------------------------------------------
// 2. Implementation for Mac OS X 10.2.x and earlier
#ifdef __APPLE__
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1030
#include <mach-o/dyld.h>
#define DYNAMICLOADER_DEFINED 1

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
LibHandle DynamicLoader::OpenLibrary(const char* libname )
{
  NSObjectFileImageReturnCode rc;
  NSObjectFileImage image = 0;

  rc = NSCreateObjectFileImageFromFile(libname, &image);
  if(!image)
    {
    return 0;
    }
  return NSLinkModule(image, libname, NSLINKMODULE_OPTION_BINDNOW);
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary( LibHandle lib)
{
  bool success = NSUnLinkModule(lib, NSUNLINKMODULE_OPTION_NONE);
  return success;
}

//----------------------------------------------------------------------------
DynamicLoaderFunction DynamicLoader::GetSymbolAddress(LibHandle /* lib */, const char* sym)
{
  void *result=0;
  if(NSIsSymbolNameDefined(sym))
    {
    NSSymbol symbol= NSLookupAndBindSymbol(sym);
    if(symbol)
      {
      result = NSAddressOfSymbol(symbol);
      }
    }
  // Hack to cast pointer-to-data to pointer-to-function.
  return *reinterpret_cast<DynamicLoaderFunction*>(&result);
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
  return "";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
  return ".dylib";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  return 0;
}

} // namespace KWSYS_NAMESPACE

#endif //MAC_OS_X_VERSION_MIN_REQUIRED < 1030
#endif // __APPLE__

// ---------------------------------------------------------------
// 3. Implementation for Windows win32 code
#ifdef _WIN32
#include <windows.h>
#define DYNAMICLOADER_DEFINED 1

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
LibHandle DynamicLoader::OpenLibrary(const char* libname)
{
  LibHandle lh;
#ifdef UNICODE
  wchar_t libn[MB_CUR_MAX];
  mbstowcs(libn, libname, MB_CUR_MAX);
  lh = LoadLibrary(libn);
#else
  lh = LoadLibrary(libname);
#endif
  return lh;
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary(LibHandle lib)
{
  return (int)FreeLibrary(lib);
}

//----------------------------------------------------------------------------
DynamicLoaderFunction DynamicLoader::GetSymbolAddress(LibHandle lib, const char* sym)
{
  void *result;
#ifdef UNICODE
  wchar_t wsym[MB_CUR_MAX];
  mbstowcs(wsym, sym, MB_CUR_MAX);
  result = GetProcAddress(lib, wsym);
#else
  result = (void*)GetProcAddress(lib, sym);
#endif
  // Hack to cast pointer-to-data to pointer-to-function.
  return *reinterpret_cast<DynamicLoaderFunction*>(&result);
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
  return "";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
  return ".dll";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  LPVOID lpMsgBuf;

  FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    NULL,
    GetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    (LPTSTR) &lpMsgBuf,
    0,
    NULL
    );

  static char* str = 0;
  delete [] str;
  str = strcpy(new char[strlen((char*)lpMsgBuf)+1], (char*)lpMsgBuf);
  // Free the buffer.
  LocalFree( lpMsgBuf );
  return str;
}

} // namespace KWSYS_NAMESPACE

#endif //_WIN32

// ---------------------------------------------------------------
// 4. Implementation for default UNIX machines.
// if nothing has been defined then use this
#ifndef DYNAMICLOADER_DEFINED
#define DYNAMICLOADER_DEFINED 1
// Setup for most unix machines
#include <dlfcn.h>

namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
LibHandle DynamicLoader::OpenLibrary(const char* libname )
{
  return dlopen(libname, RTLD_LAZY);
}

//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary(LibHandle lib)
{
  if (lib)
    {
    // The function dlclose() returns 0 on success, and non-zero on error.
    return !(int)dlclose(lib);
    }
  // else
  return 0;
}

//----------------------------------------------------------------------------
DynamicLoaderFunction DynamicLoader::GetSymbolAddress(LibHandle lib, const char* sym)
{
  void* result = dlsym(lib, sym);

  // Hack to cast pointer-to-data to pointer-to-function.
  return *reinterpret_cast<DynamicLoaderFunction*>(&result);
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibPrefix()
{
  return "lib";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LibExtension()
{
  return ".so";
}

//----------------------------------------------------------------------------
const char* DynamicLoader::LastError()
{
  return dlerror();
}

} // namespace KWSYS_NAMESPACE

#endif
<|endoftext|>


<commit_before>// Terminal.cpp -- source file
/*
 *
 * Author: septimomend (Ivan Chapkailo)
 *
 * 30.06.2017
 *
 */

#include "stdafx.h"
#include "Terminal.h"

Terminal::Terminal() // cstr
{
}

void Terminal::emergencyDestruction(const char* str)
{
  write(STDOUT_FILENO, "\x1b[2J", 4); // write clr code to file
  write(STDOUT_FILENO, "\x1b[H", 3);

  perror(str);
  exit(1);  // exit with error
}

void Terminal::rowModeOff()
{
  // the change will occur after all output written to STDIN_FILENO is transmitted,
  // and all input so far received but not read will be discarded before the change is made
  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &configObj.baseTermiosObj) == -1)
    emergencyDestruction("tcsetattr");
}

void Terminal::rowModeOn()
{
  if (tcgetattr(STDIN_FILENO, &configObj.baseTermiosObj) == -1)
    emergencyDestruction("tcgetattr");
  atexit(rowModeOff);

  struct termios raw = configObj.baseTermiosObj;
  // setting flags
  //
  raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
  raw.c_oflag &= ~(OPOST); // Post-process output
  raw.c_cflag |= (CS8); // Character size 8 bits
  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
  raw.c_cc[VMIN] = 0;
  raw.c_cc[VTIME] = 1;
}

int Terminal::whatKey() // defines key pressing
{
  // TODO
}

int Terminal::getCursorPosition(int *row, int *column) // returns cursor position
{
  // TODO
}

int Terminal::getWindowSize(int *row, int *column) // returns size of window
{
  // TODO
}
<commit_msg>fixed inheritance errors<commit_after>// Terminal.cpp -- source file
/*
 *
 * Author: septimomend (Ivan Chapkailo)
 *
 * 30.06.2017
 *
 */

#include "stdafx.h"
#include "Terminal.h"

Terminal::Terminal() // cstr
{
}

void Terminal::emergencyDestruction(const char* str)
{
  write(STDOUT_FILENO, "\x1b[2J", 4); // write clr code to file
  write(STDOUT_FILENO, "\x1b[H", 3);

  perror(str);
  exit(1);  // exit with error
}

void Terminal::rowModeOff()
{
  AllControllers all;
  ConfigurationController* configObj = all.getConfigObj();
  struct termios* termObj = configObj->getTermios();

  // the change will occur after all output written to STDIN_FILENO is transmitted,
  // and all input so far received but not read will be discarded before the change is made
  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, termObj) == -1)
    emergencyDestruction("tcsetattr");
}

void Terminal::rowModeOn()
{
  AllControllers all;
  ConfigurationController* configObj = all.getConfigObj();
  struct termios* termObj = configObj->getTermios();

  if (tcgetattr(STDIN_FILENO, termObj) == -1)
    emergencyDestruction("tcgetattr");
  atexit(rowModeOff);

  struct termios raw = *termObj;
  // setting flags
  //
  raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
  raw.c_oflag &= ~(OPOST); // Post-process output
  raw.c_cflag |= (CS8); // Character size 8 bits
  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
  raw.c_cc[VMIN] = 0;
  raw.c_cc[VTIME] = 1;
}

int Terminal::whatKey() // defines key pressing
{
  // TODO
}

int Terminal::getCursorPosition(int *row, int *column) // returns cursor position
{
  // TODO
}

int Terminal::getWindowSize(int *row, int *column) // returns size of window
{
  // TODO
}
<|endoftext|>


<commit_before><commit_msg>SIMD componentProduct<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 Cloudius Systems, Ltd.
 */

#pragma once

#include "exceptions/exceptions.hh"

enum class compressor {
    none,
    lz4,
    snappy,
    deflate,
};

class compression_parameters {
public:
    static constexpr int32_t DEFAULT_CHUNK_LENGTH = 64 * 1024;
    static constexpr double DEFAULT_CRC_CHECK_CHANCE = 1.0;

    static constexpr auto SSTABLE_COMPRESSION = "sstable_compression";
    static constexpr auto CHUNK_LENGTH_KB = "chunk_length_kb";
    static constexpr auto CRC_CHECK_CHANCE = "crc_check_chance";
private:
    compressor _compressor = compressor::none;
    int _chunk_length = DEFAULT_CHUNK_LENGTH;
    double _crc_check_chance = DEFAULT_CRC_CHECK_CHANCE;
public:
    compression_parameters() = default;
    compression_parameters(compressor c) : _compressor(c) { }
    compression_parameters(const std::map<sstring, sstring>& options) {
        validate_options(options);

        const auto& compressor_class = options.at(SSTABLE_COMPRESSION);
        if (compressor_class == "LZ4Compressor") {
            _compressor = compressor::lz4;
        } else if (compressor_class == "SnappyCompressor") {
            _compressor = compressor::snappy;
        } else if (compressor_class == "DeflateCompressor") {
            _compressor = compressor::deflate;
        } else {
            throw exceptions::configuration_exception(sstring("Unsupported compression class '") + compressor_class + "'.");
        }
        auto chunk_length = options.find(CHUNK_LENGTH_KB);
        if (chunk_length != options.end()) {
            try {
                _chunk_length = std::stoi(chunk_length->second) * 1024;
            } catch (const std::exception& e) {
                throw exceptions::syntax_exception(sstring("Invalid integer value ") + chunk_length->second + " for " + CHUNK_LENGTH_KB);
            }
        }
        auto crc_chance = options.find(CRC_CHECK_CHANCE);
        if (crc_chance != options.end()) {
            try {
                _crc_check_chance = std::stod(crc_chance->second);
            } catch (const std::exception& e) {
                throw exceptions::syntax_exception(sstring("Invalid double value ") + crc_chance->second + "for " + CRC_CHECK_CHANCE);
            }
        }
    }

    compressor get_compressor() const { return _compressor; }
    int32_t chunk_length() const { return _chunk_length; }
    double crc_check_chance() const { return _crc_check_chance; }

    void validate() {
        if (_chunk_length <= 0) {
            throw exceptions::configuration_exception(sstring("Invalid negative or null ") + CHUNK_LENGTH_KB);
        }
        // _chunk_length must be a power of two
        if (_chunk_length & (_chunk_length - 1)) {
            throw exceptions::configuration_exception(sstring(CHUNK_LENGTH_KB) + " must be a power of 2.");
        }
        if (_crc_check_chance < 0.0 || _crc_check_chance > 1.0) {
            throw exceptions::configuration_exception(sstring(CRC_CHECK_CHANCE) + " must be between 0.0 and 1.0.");
        }
    }
private:
    void validate_options(const std::map<sstring, sstring>& options) {
        // currently, there are no options specific to a particular compressor
        static std::set<sstring> keywords({
            sstring(SSTABLE_COMPRESSION),
            sstring(CHUNK_LENGTH_KB),
            sstring(CRC_CHECK_CHANCE),
        });
        for (auto&& opt : options) {
            if (!keywords.count(opt.first)) {
                throw exceptions::configuration_exception(sprint("Unknown compression option '%s'.", opt.first));
            }
        }
    }
};
<commit_msg>compress: accept both qualified and unqualified class names<commit_after>/*
 * Copyright (C) 2015 Cloudius Systems, Ltd.
 */

#pragma once

#include "exceptions/exceptions.hh"

enum class compressor {
    none,
    lz4,
    snappy,
    deflate,
};

class compression_parameters {
public:
    static constexpr int32_t DEFAULT_CHUNK_LENGTH = 64 * 1024;
    static constexpr double DEFAULT_CRC_CHECK_CHANCE = 1.0;

    static constexpr auto SSTABLE_COMPRESSION = "sstable_compression";
    static constexpr auto CHUNK_LENGTH_KB = "chunk_length_kb";
    static constexpr auto CRC_CHECK_CHANCE = "crc_check_chance";
private:
    compressor _compressor = compressor::none;
    int _chunk_length = DEFAULT_CHUNK_LENGTH;
    double _crc_check_chance = DEFAULT_CRC_CHECK_CHANCE;
public:
    compression_parameters() = default;
    compression_parameters(compressor c) : _compressor(c) { }
    compression_parameters(const std::map<sstring, sstring>& options) {
        validate_options(options);

        const auto& compressor_class = options.at(SSTABLE_COMPRESSION);
        if (is_compressor_class(compressor_class, "LZ4Compressor")) {
            _compressor = compressor::lz4;
        } else if (is_compressor_class(compressor_class, "SnappyCompressor")) {
            _compressor = compressor::snappy;
        } else if (is_compressor_class(compressor_class, "DeflateCompressor")) {
            _compressor = compressor::deflate;
        } else {
            throw exceptions::configuration_exception(sstring("Unsupported compression class '") + compressor_class + "'.");
        }
        auto chunk_length = options.find(CHUNK_LENGTH_KB);
        if (chunk_length != options.end()) {
            try {
                _chunk_length = std::stoi(chunk_length->second) * 1024;
            } catch (const std::exception& e) {
                throw exceptions::syntax_exception(sstring("Invalid integer value ") + chunk_length->second + " for " + CHUNK_LENGTH_KB);
            }
        }
        auto crc_chance = options.find(CRC_CHECK_CHANCE);
        if (crc_chance != options.end()) {
            try {
                _crc_check_chance = std::stod(crc_chance->second);
            } catch (const std::exception& e) {
                throw exceptions::syntax_exception(sstring("Invalid double value ") + crc_chance->second + "for " + CRC_CHECK_CHANCE);
            }
        }
    }

    compressor get_compressor() const { return _compressor; }
    int32_t chunk_length() const { return _chunk_length; }
    double crc_check_chance() const { return _crc_check_chance; }

    void validate() {
        if (_chunk_length <= 0) {
            throw exceptions::configuration_exception(sstring("Invalid negative or null ") + CHUNK_LENGTH_KB);
        }
        // _chunk_length must be a power of two
        if (_chunk_length & (_chunk_length - 1)) {
            throw exceptions::configuration_exception(sstring(CHUNK_LENGTH_KB) + " must be a power of 2.");
        }
        if (_crc_check_chance < 0.0 || _crc_check_chance > 1.0) {
            throw exceptions::configuration_exception(sstring(CRC_CHECK_CHANCE) + " must be between 0.0 and 1.0.");
        }
    }
private:
    void validate_options(const std::map<sstring, sstring>& options) {
        // currently, there are no options specific to a particular compressor
        static std::set<sstring> keywords({
            sstring(SSTABLE_COMPRESSION),
            sstring(CHUNK_LENGTH_KB),
            sstring(CRC_CHECK_CHANCE),
        });
        for (auto&& opt : options) {
            if (!keywords.count(opt.first)) {
                throw exceptions::configuration_exception(sprint("Unknown compression option '%s'.", opt.first));
            }
        }
    }
    bool is_compressor_class(const sstring& value, const sstring& class_name) {
        static const sstring namespace_prefix = "org.apache.cassandra.io.compress.";
        return value == class_name || value == namespace_prefix + class_name;
    }
};
<|endoftext|>


<commit_before>// Copyright (c) 2014 Vicente Romero Calero
//
// Distributed under the MIT software license, see the file LICENSE
//
// Author: Vicente Romero <vteromero@gmail.com>

#include "compress.h"

#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <list>
#include <unordered_set>
#include <vector>
#include "bpe.h"
#include "endian.h"

using namespace std;

struct BytePairOccurs
{
    uint8_t byte1;
    uint8_t byte2;
    int occurs;
};

extern Config config;

static void replaceBytes(
    uint8_t byte,
    uint8_t bytepair1,
    uint8_t bytepair2,
    list<uint8_t> &byte_block,
    vector<vector<int> > &byte_pairs,
    BytePairOccurs &best_byte_pair)
{
    list<uint8_t>::iterator it1 = byte_block.begin();
    list<uint8_t>::iterator it2 = next(it1);
    list<uint8_t>::iterator prev_it, next_it;

    best_byte_pair.occurs = 0;

    while(it2 != byte_block.end())
    {
        if((*it1 == bytepair1) && (*it2 == bytepair2))
        {
            // Update byte pairs
            prev_it = prev(it1);
            next_it = next(it2);

            --byte_pairs[bytepair1][bytepair2];

            if(prev_it != byte_block.end())
            {
                --byte_pairs[*prev_it][bytepair1];
                int occurs = ++byte_pairs[*prev_it][byte];
                if(occurs > best_byte_pair.occurs)
                {
                    best_byte_pair.byte1 = *prev_it;
                    best_byte_pair.byte2 = byte;
                    best_byte_pair.occurs = occurs;
                }
            }

            if(next_it != byte_block.end())
            {
                --byte_pairs[bytepair2][*next_it];
                int occurs = ++byte_pairs[byte][*next_it];
                if(occurs > best_byte_pair.occurs)
                {
                    best_byte_pair.byte1 = byte;
                    best_byte_pair.byte2 = *next_it;
                    best_byte_pair.occurs = occurs;
                }
            }

            // Perform the replacement
            it1 = byte_block.erase(it1, next_it);
            byte_block.insert(it1, byte);

            it2 = next(it1);
        }
        else
        {
            ++it1;
            ++it2;
        }
    }
}

static void compressBlock(
    uint8_t *buffer,
    int len,
    list<uint8_t> &byte_block,
    vector<pair<uint8_t, uint16_t> > &dictionary)
{
    unordered_set<uint8_t> unused_bytes;
    unordered_set<uint8_t>::iterator it_set;
    vector<vector<int> > byte_pairs(256, vector<int>(256, 0));
    BytePairOccurs best_byte_pair;
    uint8_t byte;

    best_byte_pair.byte1 = 0;
    best_byte_pair.byte2 = 0;
    best_byte_pair.occurs = 0;

    for(int i=0; i<256; ++i)
        unused_bytes.emplace(i);

    for(int i=0; i<len; ++i)
    {
        byte_block.push_back(buffer[i]);

        it_set = unused_bytes.find(buffer[i]);
        if(it_set != unused_bytes.end())
            unused_bytes.erase(it_set);

        if((i + 1) < len)
        {
            int occurs = ++byte_pairs[buffer[i]][buffer[i + 1]];
            if(occurs > best_byte_pair.occurs)
            {
                best_byte_pair.byte1 = buffer[i];
                best_byte_pair.byte2 = buffer[i + 1];
                best_byte_pair.occurs = occurs;
            }
        }
    }

    while(!unused_bytes.empty())
    {
        if(best_byte_pair.occurs < 4)
            break;

        it_set = unused_bytes.begin();
        byte = *it_set;

        dictionary.push_back(make_pair(byte, (best_byte_pair.byte1 << 8) | best_byte_pair.byte2));

        replaceBytes(
            byte,
            best_byte_pair.byte1,
            best_byte_pair.byte2,
            byte_block,
            byte_pairs,
            best_byte_pair);

        unused_bytes.erase(it_set);
    }
}

static int writeBlock(
    FILE *outfile,
    const list<uint8_t> &byte_block,
    const vector<pair<uint8_t, uint16_t> > &dictionary)
{
    uint8_t dict_size = dictionary.size();
    uint16_t data_size = byte_block.size();
    uint8_t buffer[data_size];
    int block_size = 3 + 3 * dict_size + data_size;

    fwrite(&dict_size, 1, 1, outfile);

    for(int i=dict_size-1; i>=0; --i)
    {
        fwrite(&(dictionary[i].first), 1, 1, outfile);
        fwrite16(dictionary[i].second, outfile);
    }

    fwrite16(data_size, outfile);

    copy(byte_block.begin(), byte_block.end(), buffer);
    fwrite(buffer, 1, data_size, outfile);

    return block_size;
}

void compress()
{
    int num_blocks = 0;
    uint8_t buffer[config.block_size];
    size_t read_size;
    long long total_size=0, total_compressed_size=0;

    FILE *infile = fopen(config.infile, "rb");
    if(infile == NULL)
    {
        perror(config.infile);
        exit(1);
    }

    FILE *outfile = NULL;
    if(config.stdout_opt)
    {
        outfile = stdout;
    }
    else
    {
        outfile = fopen(config.outfile, "wb");
        if(outfile == NULL)
        {
           perror(config.outfile);
           exit(1);
        }
    }

    do
    {
        read_size = fread(buffer, sizeof(uint8_t), config.block_size, infile);
        total_size += read_size;

        list<uint8_t> byte_block;
        vector<pair<uint8_t, uint16_t> > dictionary;
        compressBlock(buffer, read_size, byte_block, dictionary);

        total_compressed_size += writeBlock(outfile, byte_block, dictionary);

        num_blocks++;

    } while(!feof(infile));

    if(config.verbose_opt)
    {
        double reduction = (total_size - total_compressed_size) / (double)total_size;
        fprintf(stderr, "Reduction: %.2f%%\n", reduction * 100.0);
    }

    fclose(infile);

    if(!config.stdout_opt)
    {
        fclose(outfile);

        remove(config.infile);
    }
}
<commit_msg>deleted unused variable<commit_after>// Copyright (c) 2014 Vicente Romero Calero
//
// Distributed under the MIT software license, see the file LICENSE
//
// Author: Vicente Romero <vteromero@gmail.com>

#include "compress.h"

#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <list>
#include <unordered_set>
#include <vector>
#include "bpe.h"
#include "endian.h"

using namespace std;

struct BytePairOccurs
{
    uint8_t byte1;
    uint8_t byte2;
    int occurs;
};

extern Config config;

static void replaceBytes(
    uint8_t byte,
    uint8_t bytepair1,
    uint8_t bytepair2,
    list<uint8_t> &byte_block,
    vector<vector<int> > &byte_pairs,
    BytePairOccurs &best_byte_pair)
{
    list<uint8_t>::iterator it1 = byte_block.begin();
    list<uint8_t>::iterator it2 = next(it1);
    list<uint8_t>::iterator prev_it, next_it;

    best_byte_pair.occurs = 0;

    while(it2 != byte_block.end())
    {
        if((*it1 == bytepair1) && (*it2 == bytepair2))
        {
            // Update byte pairs
            prev_it = prev(it1);
            next_it = next(it2);

            --byte_pairs[bytepair1][bytepair2];

            if(prev_it != byte_block.end())
            {
                --byte_pairs[*prev_it][bytepair1];
                int occurs = ++byte_pairs[*prev_it][byte];
                if(occurs > best_byte_pair.occurs)
                {
                    best_byte_pair.byte1 = *prev_it;
                    best_byte_pair.byte2 = byte;
                    best_byte_pair.occurs = occurs;
                }
            }

            if(next_it != byte_block.end())
            {
                --byte_pairs[bytepair2][*next_it];
                int occurs = ++byte_pairs[byte][*next_it];
                if(occurs > best_byte_pair.occurs)
                {
                    best_byte_pair.byte1 = byte;
                    best_byte_pair.byte2 = *next_it;
                    best_byte_pair.occurs = occurs;
                }
            }

            // Perform the replacement
            it1 = byte_block.erase(it1, next_it);
            byte_block.insert(it1, byte);

            it2 = next(it1);
        }
        else
        {
            ++it1;
            ++it2;
        }
    }
}

static void compressBlock(
    uint8_t *buffer,
    int len,
    list<uint8_t> &byte_block,
    vector<pair<uint8_t, uint16_t> > &dictionary)
{
    unordered_set<uint8_t> unused_bytes;
    unordered_set<uint8_t>::iterator it_set;
    vector<vector<int> > byte_pairs(256, vector<int>(256, 0));
    BytePairOccurs best_byte_pair;
    uint8_t byte;

    best_byte_pair.byte1 = 0;
    best_byte_pair.byte2 = 0;
    best_byte_pair.occurs = 0;

    for(int i=0; i<256; ++i)
        unused_bytes.emplace(i);

    for(int i=0; i<len; ++i)
    {
        byte_block.push_back(buffer[i]);

        it_set = unused_bytes.find(buffer[i]);
        if(it_set != unused_bytes.end())
            unused_bytes.erase(it_set);

        if((i + 1) < len)
        {
            int occurs = ++byte_pairs[buffer[i]][buffer[i + 1]];
            if(occurs > best_byte_pair.occurs)
            {
                best_byte_pair.byte1 = buffer[i];
                best_byte_pair.byte2 = buffer[i + 1];
                best_byte_pair.occurs = occurs;
            }
        }
    }

    while(!unused_bytes.empty())
    {
        if(best_byte_pair.occurs < 4)
            break;

        it_set = unused_bytes.begin();
        byte = *it_set;

        dictionary.push_back(make_pair(byte, (best_byte_pair.byte1 << 8) | best_byte_pair.byte2));

        replaceBytes(
            byte,
            best_byte_pair.byte1,
            best_byte_pair.byte2,
            byte_block,
            byte_pairs,
            best_byte_pair);

        unused_bytes.erase(it_set);
    }
}

static int writeBlock(
    FILE *outfile,
    const list<uint8_t> &byte_block,
    const vector<pair<uint8_t, uint16_t> > &dictionary)
{
    uint8_t dict_size = dictionary.size();
    uint16_t data_size = byte_block.size();
    uint8_t buffer[data_size];
    int block_size = 3 + 3 * dict_size + data_size;

    fwrite(&dict_size, 1, 1, outfile);

    for(int i=dict_size-1; i>=0; --i)
    {
        fwrite(&(dictionary[i].first), 1, 1, outfile);
        fwrite16(dictionary[i].second, outfile);
    }

    fwrite16(data_size, outfile);

    copy(byte_block.begin(), byte_block.end(), buffer);
    fwrite(buffer, 1, data_size, outfile);

    return block_size;
}

void compress()
{
    uint8_t buffer[config.block_size];
    size_t read_size;
    long long total_size=0, total_compressed_size=0;

    FILE *infile = fopen(config.infile, "rb");
    if(infile == NULL)
    {
        perror(config.infile);
        exit(1);
    }

    FILE *outfile = NULL;
    if(config.stdout_opt)
    {
        outfile = stdout;
    }
    else
    {
        outfile = fopen(config.outfile, "wb");
        if(outfile == NULL)
        {
           perror(config.outfile);
           exit(1);
        }
    }

    do
    {
        read_size = fread(buffer, sizeof(uint8_t), config.block_size, infile);
        total_size += read_size;

        list<uint8_t> byte_block;
        vector<pair<uint8_t, uint16_t> > dictionary;
        compressBlock(buffer, read_size, byte_block, dictionary);

        total_compressed_size += writeBlock(outfile, byte_block, dictionary);

    } while(!feof(infile));

    if(config.verbose_opt)
    {
        double reduction = (total_size - total_compressed_size) / (double)total_size;
        fprintf(stderr, "Reduction: %.2f%%\n", reduction * 100.0);
    }

    fclose(infile);

    if(!config.stdout_opt)
    {
        fclose(outfile);

        remove(config.infile);
    }
}
<|endoftext|>


<commit_before>/* This file is part of Mapnik (c++ mapping toolkit)
 * Copyright (C) 2005 Artem Pavlenko
 *
 * Mapnik is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

//$Id$

#ifndef GEOMETRY_HH
#define GEOMETRY_HH

#include "vertex_vector.hh"
#include "vertex_transform.hh"
#include "ctrans.hh"
#include "ptr.hh"

namespace mapnik
{
    enum {
    	Point = 1,
    	LineString = 2,
    	Polygon = 3,
    };

    template <typename T,template <typename> class Container=vertex_vector>
    class geometry
    {
    public:
	typedef T vertex_type;
	typedef typename vertex_type::type value_type;
	typedef Container<vertex_type> container_type;
    private:
	int srid_;
	mutable unsigned itr_;
    protected:
	container_type cont_;
    public:
	geometry (int srid=-1)
	    : srid_(srid),
	      itr_(0),
	      cont_() {}

	virtual int type() const=0;

	virtual bool hit_test(value_type x,value_type y) const=0;

	int srid() const
	{
	    return srid_;
	}

	void move_to(value_type x,value_type y)
	{
	    cont_.push_back(x,y,SEG_MOVETO);
	}

	void line_to(value_type x,value_type y)
	{
	    cont_.push_back(x,y,SEG_LINETO);
	}

	//unsigned vertex(double* x, double* y)
	//	{
	//    return cont_.get_vertex(itr_++,x,y);
	//	}

	//void rewind(unsigned )
	//	{
	//    itr_=0;
	//	}
	template <typename Transform>
	class path_iterator
	{
	    typedef vertex<typename Transform::return_type,2> vertex_type;
	    const container_type* cont_;
	    unsigned pos_;
	    unsigned cmd_;
	    vertex_type vertex_;

	private:

	    void advance ()
	    {
		if (pos_ < cont_->size())
		{
		    value_type x,y;
		    vertex_.cmd=cont_->get_vertex(pos_,&x,&y);
		    vertex_.x=Transform::apply(x);
		    vertex_.y=Transform::apply(y);
		}
		else
		{
		    vertex_.cmd=SEG_END;
		    vertex_.x=0;
		    vertex_.y=0;
		}
		++pos_;
	    }

	public:

	    path_iterator()
		: cont_(0),
		  pos_(0),
		  cmd_(SEG_END),
		  vertex_(0,0,cmd_) {}

	    explicit path_iterator(const container_type& cont)
		: cont_(&cont),
		  pos_(0),
		  cmd_(SEG_MOVETO),
		  vertex_(0,0,cmd_)
	    {
		advance();
	    }

	    path_iterator& operator++()
	    {
		advance();
		return *this;
	    }

	    const vertex_type& operator*() const
	    {
		return vertex_;
	    }

	    const vertex_type* operator->() const
	    {
		return &vertex_;
	    }

	    bool operator !=(const path_iterator& itr)
	    {
		return vertex_.cmd !=itr.vertex_.cmd;
	    }
	};

	template <typename Transform>
	path_iterator<Transform> begin() const
	{
	    return path_iterator<Transform>(cont_);
	}

	template <typename Transform>
	path_iterator<Transform> end() const
	{
	    return path_iterator<Transform>();
	}

	void transform(const mapnik::CoordTransform& t)
	{
	    for (unsigned pos=0;pos<cont_.size();++pos)
	    {
		cont_.transform_at(pos,t);
	    }
	}

	unsigned num_points() const
	{
	    return cont_.size();
	}

	virtual ~geometry() {}
    private:
	geometry(const geometry&);
	geometry& operator=(const geometry&);
    };

    template <typename T, template <typename> class Container=vertex_vector>
    class point : public geometry<T,Container>
    {
	typedef typename   geometry<T,Container>::value_type value_type;
	using geometry<T,Container>::cont_;
    public:
	point(int srid)
	    : geometry<T,Container>(srid)
	{}

	int type() const
	{
	    return Point;
	}
	bool hit_test(value_type x,value_type y) const
	{
	    return point_on_points(x,y,*this);
	}
    };

    template <typename T, template <typename> class Container=vertex_vector>
    class polygon : public geometry<T,Container>
    {
	typedef geometry<T,Container> geometry_base;
	typedef typename geometry_base::value_type value_type;
	typedef typename geometry_base::template path_iterator<NO_SHIFT> path_iterator;
    public:
	polygon(int srid)
	    : geometry_base(srid)
	{}

	int type() const
	{
	    return Polygon;
	}

	bool hit_test(value_type x,value_type y) const
	{
	    path_iterator start = geometry_base::template begin<NO_SHIFT>();
	    path_iterator end = geometry_base::template end<NO_SHIFT>();
	    return point_inside_path(start,end,x,y);
	}
    };

    template <typename T, template <typename> class Container=vertex_vector>
    class line_string : public geometry<T,Container>
    {
	typedef typename   geometry<T,Container>::value_type value_type;
    public:
	line_string(int srid)
	    : geometry<T,Container>(srid)
	{}

	int type() const
	{
	    return LineString;
	}

	bool hit_test(value_type x,value_type y) const
	{
	    return point_on_path(x,y,*this);
	}
    };

    typedef point<vertex2d> point_impl;
    typedef line_string<vertex2d> line_string_impl;
    typedef polygon<vertex2d> polygon_impl;

    typedef geometry<vertex2d> geometry_type;
    typedef ref_ptr<geometry_type> geometry_ptr;
}

#endif //GEOMETRY_HH
<commit_msg>moved typedef typename geometry_base::template path_iterator<NO_SHIFT> path_iterator<commit_after>/* This file is part of Mapnik (c++ mapping toolkit)
 * Copyright (C) 2005 Artem Pavlenko
 *
 * Mapnik is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

//$Id$

#ifndef GEOMETRY_HH
#define GEOMETRY_HH

#include "vertex_vector.hh"
#include "vertex_transform.hh"
#include "ctrans.hh"
#include "ptr.hh"

namespace mapnik
{
    enum {
    	Point = 1,
    	LineString = 2,
    	Polygon = 3,
    };

    template <typename T,template <typename> class Container=vertex_vector>
    class geometry
    {
    public:
	typedef T vertex_type;
	typedef typename vertex_type::type value_type;
	typedef Container<vertex_type> container_type;
    private:
	int srid_;
	mutable unsigned itr_;
    protected:
	container_type cont_;
    public:
	geometry (int srid=-1)
	    : srid_(srid),
	      itr_(0),
	      cont_() {}

	virtual int type() const=0;

	virtual bool hit_test(value_type x,value_type y) const=0;

	int srid() const
	{
	    return srid_;
	}

	void move_to(value_type x,value_type y)
	{
	    cont_.push_back(x,y,SEG_MOVETO);
	}

	void line_to(value_type x,value_type y)
	{
	    cont_.push_back(x,y,SEG_LINETO);
	}

	//unsigned vertex(double* x, double* y)
	//	{
	//    return cont_.get_vertex(itr_++,x,y);
	//	}

	//void rewind(unsigned )
	//	{
	//    itr_=0;
	//	}
	template <typename Transform>
	class path_iterator
	{
	    typedef vertex<typename Transform::return_type,2> vertex_type;
	    const container_type* cont_;
	    unsigned pos_;
	    unsigned cmd_;
	    vertex_type vertex_;

	private:

	    void advance ()
	    {
		if (pos_ < cont_->size())
		{
		    value_type x,y;
		    vertex_.cmd=cont_->get_vertex(pos_,&x,&y);
		    vertex_.x=Transform::apply(x);
		    vertex_.y=Transform::apply(y);
		}
		else
		{
		    vertex_.cmd=SEG_END;
		    vertex_.x=0;
		    vertex_.y=0;
		}
		++pos_;
	    }

	public:

	    path_iterator()
		: cont_(0),
		  pos_(0),
		  cmd_(SEG_END),
		  vertex_(0,0,cmd_) {}

	    explicit path_iterator(const container_type& cont)
		: cont_(&cont),
		  pos_(0),
		  cmd_(SEG_MOVETO),
		  vertex_(0,0,cmd_)
	    {
		advance();
	    }

	    path_iterator& operator++()
	    {
		advance();
		return *this;
	    }

	    const vertex_type& operator*() const
	    {
		return vertex_;
	    }

	    const vertex_type* operator->() const
	    {
		return &vertex_;
	    }

	    bool operator !=(const path_iterator& itr)
	    {
		return vertex_.cmd !=itr.vertex_.cmd;
	    }
	};

	template <typename Transform>
	path_iterator<Transform> begin() const
	{
	    return path_iterator<Transform>(cont_);
	}

	template <typename Transform>
	path_iterator<Transform> end() const
	{
	    return path_iterator<Transform>();
	}

	void transform(const mapnik::CoordTransform& t)
	{
	    for (unsigned pos=0;pos<cont_.size();++pos)
	    {
		cont_.transform_at(pos,t);
	    }
	}

	unsigned num_points() const
	{
	    return cont_.size();
	}

	virtual ~geometry() {}
    private:
	geometry(const geometry&);
	geometry& operator=(const geometry&);
    };

    template <typename T, template <typename> class Container=vertex_vector>
    class point : public geometry<T,Container>
    {
	typedef typename   geometry<T,Container>::value_type value_type;
	using geometry<T,Container>::cont_;
    public:
	point(int srid)
	    : geometry<T,Container>(srid)
	{}

	int type() const
	{
	    return Point;
	}
	bool hit_test(value_type x,value_type y) const
	{
	    return point_on_points(x,y,*this);
	}
    };

    template <typename T, template <typename> class Container=vertex_vector>
    class polygon : public geometry<T,Container>
    {
	typedef geometry<T,Container> geometry_base;
	typedef typename geometry_base::value_type value_type;

    public:
	polygon(int srid)
	    : geometry_base(srid)
	{}

	int type() const
	{
	    return Polygon;
	}

	bool hit_test(value_type x,value_type y) const
	{
	    typedef typename geometry_base::template path_iterator<NO_SHIFT> path_iterator;
	    path_iterator start = geometry_base::template begin<NO_SHIFT>();
	    path_iterator end = geometry_base::template end<NO_SHIFT>();
	    return point_inside_path(start,end,x,y);
	}
    };

    template <typename T, template <typename> class Container=vertex_vector>
    class line_string : public geometry<T,Container>
    {
	typedef typename   geometry<T,Container>::value_type value_type;
    public:
	line_string(int srid)
	    : geometry<T,Container>(srid)
	{}

	int type() const
	{
	    return LineString;
	}

	bool hit_test(value_type x,value_type y) const
	{
	    return point_on_path(x,y,*this);
	}
    };

    typedef point<vertex2d> point_impl;
    typedef line_string<vertex2d> line_string_impl;
    typedef polygon<vertex2d> polygon_impl;

    typedef geometry<vertex2d> geometry_type;
    typedef ref_ptr<geometry_type> geometry_ptr;
}

#endif //GEOMETRY_HH
<|endoftext|>


<commit_before>#include <fstream>
#include <iostream>

#include <glob.h>   // TODO

#include <pdal/StageFactory.hpp>

#include <entwine/drivers/arbiter.hpp>
#include <entwine/types/bbox.hpp>
#include <entwine/types/schema.hpp>
#include <entwine/tree/clipper.hpp>
#include <entwine/tree/reader.hpp>

#include "read-queries/entwine.hpp"
#include "read-queries/unindexed.hpp"
#include "types/paths.hpp"
#include "util/buffer-pool.hpp"

#include "session.hpp"

namespace
{
    // TODO Put this somewhere else - platform dependent code.
    std::vector<std::string> resolve(
            const std::vector<std::string>& dirs,
            const std::string& name)
    {
        glob_t buffer;
        for (std::size_t i(0); i < dirs.size(); ++i)
        {
            auto flags(GLOB_NOSORT | GLOB_TILDE);
            if (i) flags |= GLOB_APPEND;

            glob((dirs[i] + "/" + name + "*").c_str(), flags, 0, &buffer);
        }

        std::vector<std::string> results;
        for (std::size_t i(0); i < buffer.gl_pathc; ++i)
        {
            results.push_back(buffer.gl_pathv[i]);
        }

        globfree(&buffer);

        return results;
    }
}

Session::Session(
        pdal::StageFactory& stageFactory,
        std::mutex& factoryMutex)
    : m_stageFactory(stageFactory)
    , m_factoryMutex(factoryMutex)
    , m_initOnce()
    , m_source()
    , m_entwine()
    , m_name()
    , m_paths()
    , m_arbiter()
{ }

Session::~Session()
{ }

bool Session::initialize(
        const std::string& name,
        const Paths& paths,
        std::shared_ptr<entwine::Arbiter> arbiter)
{
    m_initOnce.ensure([this, &name, &paths, arbiter]()
    {
        std::cout << "Discovering " << name << std::endl;

        m_name = name;
        m_paths.reset(new Paths(paths));
        m_arbiter = arbiter;

        resolveSource();
        resolveIndex();

        std::cout << "Source for " << name << ": " <<
            (sourced() ? "FOUND" : "NOT found") << std::endl;

        std::cout << "Index for " << name << ": " <<
            (indexed() ? "FOUND" : "NOT found") << std::endl;
    });

    return sourced() || indexed();
}

std::size_t Session::getNumPoints()
{
    if (indexed()) return m_entwine->numPoints();
    else return m_source->numPoints();
}

std::string Session::getStats()
{
    // TODO
    return "{ }";
}

std::string Session::getSrs()
{
    return "";
}

entwine::BBox Session::getBounds()
{
    if (resolveIndex())
    {
        return m_entwine->bbox();
    }
    else
    {
        throw std::runtime_error("No index found for " + m_name);
    }
}

std::shared_ptr<ReadQuery> Session::query(
        const entwine::Schema& schema,
        const bool compress)
{
    if (resolveSource())
    {
        return std::shared_ptr<ReadQuery>(
                new UnindexedReadQuery(
                    schema,
                    compress,
                    *m_source));
    }
    else
    {
        return std::shared_ptr<ReadQuery>();
    }
}

std::shared_ptr<ReadQuery> Session::query(
        const entwine::Schema& schema,
        bool compress,
        const entwine::BBox& bbox,
        std::size_t depthBegin,
        std::size_t depthEnd)
{
    if (resolveIndex())
    {
        std::vector<std::size_t> results(
                m_entwine->query(
                    bbox.exists() ? bbox : m_entwine->bbox(),
                    depthBegin,
                    depthEnd));

        return std::shared_ptr<ReadQuery>(
                new EntwineReadQuery(
                    schema,
                    compress,
                    false,
                    *m_entwine,
                    results));
    }
    else
    {
        return std::shared_ptr<ReadQuery>();
    }
}

std::shared_ptr<ReadQuery> Session::query(
        const entwine::Schema& schema,
        bool compress,
        const entwine::BBox& bbox,
        std::size_t rasterize,
        RasterMeta& rasterMeta)
{
    throw std::runtime_error("TODO - Session::query (rastered)");
    return std::shared_ptr<ReadQuery>();
}

const entwine::Schema& Session::schema()
{
    if (indexed()) return m_entwine->schema();
    else return m_source->schema();
}

bool Session::sourced()
{
    std::lock_guard<std::mutex> lock(m_sourceMutex);
    return m_source.get() != 0;
}

bool Session::indexed()
{
    std::lock_guard<std::mutex> lock(m_indexMutex);
    return m_entwine.get() != 0;
}

bool Session::resolveSource()
{
    // TODO For now only works for local paths.  Support any Source the Arbiter
    // contains.
    std::lock_guard<std::mutex> lock(m_sourceMutex);
    if (!m_source)
    {
        const auto sources(resolve(m_paths->inputs, m_name));

        if (sources.size() > 1)
        {
            std::cout << "Found competing sources for " << m_name << std::endl;
        }

        if (sources.size())
        {
            std::size_t i(0);

            while (!m_source && i < sources.size())
            {
                const std::string path(sources[i++]);

                std::unique_lock<std::mutex> lock(m_factoryMutex);
                const std::string driver(
                        m_stageFactory.inferReaderDriver(path));
                lock.unlock();

                if (driver.size())
                {
                    try
                    {
                        m_source.reset(
                                new SourceManager(
                                    m_stageFactory,
                                    m_factoryMutex,
                                    path,
                                    driver));
                    }
                    catch (...)
                    {
                        std::cout << "Bad source: " << path << std::endl;
                        m_source.reset(0);
                    }
                }
            }
        }
    }

    return m_source.get() != 0;
}

bool Session::resolveIndex()
{
    std::lock_guard<std::mutex> lock(m_indexMutex);
    if (!m_entwine)
    {
        std::vector<std::string> searchPaths(m_paths->inputs);
        searchPaths.push_back(m_paths->output);
        searchPaths.push_back("s3://");

        for (std::string path : searchPaths)
        {
            try
            {
                if (path.size() && path.back() != '/') path.push_back('/');

                entwine::Source source(m_arbiter->getSource(path + m_name));

                // TODO Specify via config.
                m_entwine.reset(new entwine::Reader(source, 128, 128));
            }
            catch (...)
            {
                m_entwine.reset(0);
            }

            if (m_entwine) break;
        }
    }

    return m_entwine.get() != 0;
}

<commit_msg>Add failure logging to indexed Reader creation loop.<commit_after>#include <fstream>
#include <iostream>

#include <glob.h>   // TODO

#include <pdal/StageFactory.hpp>

#include <entwine/drivers/arbiter.hpp>
#include <entwine/types/bbox.hpp>
#include <entwine/types/schema.hpp>
#include <entwine/tree/clipper.hpp>
#include <entwine/tree/reader.hpp>

#include "read-queries/entwine.hpp"
#include "read-queries/unindexed.hpp"
#include "types/paths.hpp"
#include "util/buffer-pool.hpp"

#include "session.hpp"

namespace
{
    // TODO Put this somewhere else - platform dependent code.
    std::vector<std::string> resolve(
            const std::vector<std::string>& dirs,
            const std::string& name)
    {
        glob_t buffer;
        for (std::size_t i(0); i < dirs.size(); ++i)
        {
            auto flags(GLOB_NOSORT | GLOB_TILDE);
            if (i) flags |= GLOB_APPEND;

            glob((dirs[i] + "/" + name + "*").c_str(), flags, 0, &buffer);
        }

        std::vector<std::string> results;
        for (std::size_t i(0); i < buffer.gl_pathc; ++i)
        {
            results.push_back(buffer.gl_pathv[i]);
        }

        globfree(&buffer);

        return results;
    }
}

Session::Session(
        pdal::StageFactory& stageFactory,
        std::mutex& factoryMutex)
    : m_stageFactory(stageFactory)
    , m_factoryMutex(factoryMutex)
    , m_initOnce()
    , m_source()
    , m_entwine()
    , m_name()
    , m_paths()
    , m_arbiter()
{ }

Session::~Session()
{ }

bool Session::initialize(
        const std::string& name,
        const Paths& paths,
        std::shared_ptr<entwine::Arbiter> arbiter)
{
    m_initOnce.ensure([this, &name, &paths, arbiter]()
    {
        std::cout << "Discovering " << name << std::endl;

        m_name = name;
        m_paths.reset(new Paths(paths));
        m_arbiter = arbiter;

        resolveSource();
        resolveIndex();

        std::cout << "Source for " << name << ": " <<
            (sourced() ? "FOUND" : "NOT found") << std::endl;

        std::cout << "Index for " << name << ": " <<
            (indexed() ? "FOUND" : "NOT found") << std::endl;
    });

    return sourced() || indexed();
}

std::size_t Session::getNumPoints()
{
    if (indexed()) return m_entwine->numPoints();
    else return m_source->numPoints();
}

std::string Session::getStats()
{
    // TODO
    return "{ }";
}

std::string Session::getSrs()
{
    return "";
}

entwine::BBox Session::getBounds()
{
    if (resolveIndex())
    {
        return m_entwine->bbox();
    }
    else
    {
        throw std::runtime_error("No index found for " + m_name);
    }
}

std::shared_ptr<ReadQuery> Session::query(
        const entwine::Schema& schema,
        const bool compress)
{
    if (resolveSource())
    {
        return std::shared_ptr<ReadQuery>(
                new UnindexedReadQuery(
                    schema,
                    compress,
                    *m_source));
    }
    else
    {
        return std::shared_ptr<ReadQuery>();
    }
}

std::shared_ptr<ReadQuery> Session::query(
        const entwine::Schema& schema,
        bool compress,
        const entwine::BBox& bbox,
        std::size_t depthBegin,
        std::size_t depthEnd)
{
    if (resolveIndex())
    {
        std::vector<std::size_t> results(
                m_entwine->query(
                    bbox.exists() ? bbox : m_entwine->bbox(),
                    depthBegin,
                    depthEnd));

        return std::shared_ptr<ReadQuery>(
                new EntwineReadQuery(
                    schema,
                    compress,
                    false,
                    *m_entwine,
                    results));
    }
    else
    {
        return std::shared_ptr<ReadQuery>();
    }
}

std::shared_ptr<ReadQuery> Session::query(
        const entwine::Schema& schema,
        bool compress,
        const entwine::BBox& bbox,
        std::size_t rasterize,
        RasterMeta& rasterMeta)
{
    throw std::runtime_error("TODO - Session::query (rastered)");
    return std::shared_ptr<ReadQuery>();
}

const entwine::Schema& Session::schema()
{
    if (indexed()) return m_entwine->schema();
    else return m_source->schema();
}

bool Session::sourced()
{
    std::lock_guard<std::mutex> lock(m_sourceMutex);
    return m_source.get() != 0;
}

bool Session::indexed()
{
    std::lock_guard<std::mutex> lock(m_indexMutex);
    return m_entwine.get() != 0;
}

bool Session::resolveSource()
{
    // TODO For now only works for local paths.  Support any Source the Arbiter
    // contains.
    std::lock_guard<std::mutex> lock(m_sourceMutex);
    if (!m_source)
    {
        const auto sources(resolve(m_paths->inputs, m_name));

        if (sources.size() > 1)
        {
            std::cout << "Found competing sources for " << m_name << std::endl;
        }

        if (sources.size())
        {
            std::size_t i(0);

            while (!m_source && i < sources.size())
            {
                const std::string path(sources[i++]);

                std::unique_lock<std::mutex> lock(m_factoryMutex);
                const std::string driver(
                        m_stageFactory.inferReaderDriver(path));
                lock.unlock();

                if (driver.size())
                {
                    try
                    {
                        m_source.reset(
                                new SourceManager(
                                    m_stageFactory,
                                    m_factoryMutex,
                                    path,
                                    driver));
                    }
                    catch (...)
                    {
                        std::cout << "Bad source: " << path << std::endl;
                        m_source.reset(0);
                    }
                }
            }
        }
    }

    return m_source.get() != 0;
}

bool Session::resolveIndex()
{
    std::lock_guard<std::mutex> lock(m_indexMutex);
    if (!m_entwine)
    {
        std::vector<std::string> searchPaths(m_paths->inputs);
        searchPaths.push_back(m_paths->output);
        searchPaths.push_back("s3://");

        for (std::string path : searchPaths)
        {
            try
            {
                if (path.size() && path.back() != '/') path.push_back('/');

                entwine::Source source(m_arbiter->getSource(path + m_name));

                // TODO Specify via config.
                m_entwine.reset(new entwine::Reader(source, 128, 128));
            }
            catch (std::runtime_error& e)
            {
                std::cout << "At " << path << ": " <<
                    e.what() << "\n" << std::endl;
            }
            catch (...)
            {
                m_entwine.reset(0);
            }

            if (m_entwine) break;
        }
    }

    return m_entwine.get() != 0;
}

<|endoftext|>


<commit_before>#include "BLITSaw_vst3.h"
#include "BLITSaw_vst3_guids.h"
#include "pluginterfaces/base/ibstream.h"
#include "pluginterfaces/vst/ivstparameterchanges.h"
#include "pluginterfaces/vst/ivstevents.h"
#include <algorithm>

namespace Steinberg { namespace Vst {

//-------------------------------------------------------------------------
// BLITSaw_vst3 Implementation
//-------------------------------------------------------------------------
BLITSaw_vst3::BLITSaw_vst3()
{
	setControllerClass(AGainControllerUID);
}

//-------------------------------------------------------------------------
FUnknown* BLITSaw_vst3::createInstance(void* context)
{
	return (IAudioProcessor*)new BLITSaw_vst3();
}

//-------------------------------------------------------------------------
tresult PLUGIN_API BLITSaw_vst3::initialize(FUnknown* context)
{
	/*親クラス初期化処理*/
	tresult result = AudioEffect::initialize(context);
	if(result != kResultOk)
	{
		return result;
	}

	/*バスの設定*/
	addAudioOutput(STR16("Stereo Out"), SpeakerArr::kStereo);
	addEventInput (STR16 ("Event Input"), 1);

	return kResultOk;
}

//-------------------------------------------------------------------------
tresult PLUGIN_API BLITSaw_vst3::setBusArrangements(
	SpeakerArrangement* inputs,
	int32 numIns,
	SpeakerArrangement* outputs,
	int32 numOuts
){
	if (numIns == 0 && numOuts == 1 && outputs[0] == SpeakerArr::kStereo)
	{
		return AudioEffect::setBusArrangements (inputs, numIns, outputs, numOuts);
	}
	return kResultFalse;
}

tresult PLUGIN_API BLITSaw_vst3::setProcessing (TBool state)
{
	// state 起動1 終了0
	if( state == 1 )
	{
		for(auto note = _notes.begin(); note != _notes.end(); ++note)
		{
			note->setSampleRate( processSetup.sampleRate );
		}

		_filter.setSampleRate( processSetup.sampleRate );
	}

	return kResultOk;
}

//-------------------------------------------------------------------------
tresult PLUGIN_API BLITSaw_vst3::process(ProcessData& data)
{
	// update parameters
	if( data.inputParameterChanges )
	{
		int32 numParamsChanged = data.inputParameterChanges->getParameterCount();
		for( int32 ii = 0; ii < numParamsChanged; ii++ )
		{
			IParamValueQueue* paramQueue = data.inputParameterChanges->getParameterData(ii);
			if( paramQueue )
			{
				int32 offsetSamples;
				double value;
				// 末尾の値を取得
				if(paramQueue->getPoint(paramQueue->getPointCount() - 1, offsetSamples, value) == kResultTrue)
				{
					ParamID id = paramQueue->getParameterId();
					if( id == feedback )
					{
						// -> [0.99, 1.0]
						double feedback = 0.99 + 0.01 * value;
						blit.setFeedback(feedback);
					}
					else if( id == coarse )
					{
						double coarse_pitch = static_cast<int>( 48 * value + 0.5 ) - 24;

						for(auto note = _notes.begin(); note != _notes.end(); ++note)
						{
							note->setCorasePitch( coarse_pitch );
						}
					}
					else if( id == fine )
					{
						double finepitch = static_cast<int>( 200 * value + 0.5 ) - 100;
						for(auto note = _notes.begin(); note != _notes.end(); ++note)
						{
							note->setFinePitch( finepitch );
						}
					}
					else if( id == attack )
					{
						double attack_time = value * 0.2; // [0, 0.2]
						blit.setAttackTime( attack_time, processSetup.sampleRate );
					}
					else if( id == release )
					{
						double release_time = value * 0.2; // [0, 0.2]
						blit.setReleaseTime( release_time, processSetup.sampleRate );
					}
					else if( id == cutoff )
					{
						double cutoff_freq = 200.0 * pow(20.0, (double)value); // [200, 4000]
						_filter.setCutoff( cutoff_freq );

					}
					else if( id == resonance )
					{
						double q = 0.70710678118654757274 * (1.0 - value) + 20.0*value;
						_filter.setResonance( q );
					}
					else if( id == high )
					{
						_filter.setHigh( value );
					}
					else if( id == band )
					{
						_filter.setBand( value );
					}
					else if( id == low )
					{
						_filter.setLow( value );
					}
				}
			}
		}
	}

	// process events
	if( data.inputEvents )
	{
		int nEventCount = data.inputEvents->getEventCount();

		for( int ii = 0; ii < nEventCount; ii++ )
		{
			Event e;
			tresult result = data.inputEvents->getEvent(ii, e);
			if( result != kResultOk )continue;

			if( e.type == Event::kNoteOnEvent )
			{
				int16 note_no = e.noteOff.pitch;
				auto target_note = std::find_if(
					_notes.begin(),
					_notes.end(),
					[note_no](const bandlimited_sawtooth_oscillator_note_vst3& n){return n.id() == note_no;});

				if( target_note != _notes.end() )
				{
					// ノートOFF
					target_note->trigger(e.noteOn);
				}
				else
				{
					// 利用可能なノートを検索する
					auto available_note = std::find_if(
						_notes.begin(),
						_notes.end(),
						[](const bandlimited_sawtooth_oscillator_note_vst3& n){return n.adsr == bandlimited_sawtooth_oscillator_note::Silent;});

					if( available_note != _notes.end() )
					{
						// ノートON
						available_note->trigger( e.noteOn );
					}
				}
			}
			else if( e.type == Event::kNoteOffEvent )
			{
				//int32 note_id = e.noteOff.noteId;
				//auto target_note = std::find_if(
				//	_notes.begin(),
				//	_notes.end(),
				//	[note_id](const bandlimited_sawtooth_oscillator_note_vst3& n){return n.id() == note_id;});
				int16 note_no = e.noteOff.pitch;
				auto target_note = std::find_if(
					_notes.begin(),
					_notes.end(),
					[note_no](const bandlimited_sawtooth_oscillator_note_vst3& n){return n.id() == note_no;});

				if( target_note != _notes.end() )
				{
					// ノートOFF
					target_note->release();
				}
			}
			else if( e.type == Event::kDataEvent )
			{
				unsigned char status = e.data.bytes[0] & 0xf0;	// ignoring channel

				if( status == 0xE0 )
				{
					unsigned char data1 = e.data.bytes[1] & 0x7f;
					unsigned char data2 = e.data.bytes[2] & 0x7f;

					double pitch_bend = (( data1 + data2*128 ) - 8192 ) / 8192.0;

					for(auto note = _notes.begin(); note != _notes.end(); ++note)
					{
						note->setPitchBend( pitch_bend );
					}
				}
			}

		}
	}

	bool bAllSilent= std::all_of(
		_notes.begin(),
		_notes.end(),
		[](const bandlimited_sawtooth_oscillator_note_vst3& n){return n.adsr == bandlimited_sawtooth_oscillator_note::Silent;});

	if( bAllSilent )
	{
		return kResultOk;
	}

	_filter.updateFilter();

	/*--------*/
	/*音声処理*/
	/*--------*/
	if (data.numInputs == 0 && data.numOutputs == 1 )
	{
		for(auto note = _notes.begin(); note != _notes.end(); ++note)
		{
			// ピッチを更新
			note->updateFrequency();
		}

		if( data.outputs[0].numChannels == 2 )
		{
			//float** in  = data.inputs[0].channelBuffers32;
			float** out = data.outputs[0].channelBuffers32;

			const int32 sampleFrames = data.numSamples;
			for( int ii = 0; ii < sampleFrames; ii++ )
			{
				double value = 0.0;
				for(auto note = _notes.begin(); note != _notes.end(); ++note)
				{
					if( note->adsr == bandlimited_sawtooth_oscillator_note::Silent )continue;

					// ノート毎の音を足し合わせる
					value += note->saw * note->envelope * note->velocity();

					// オシレーター更新
					blit.updateOcsillater( *note );

					// エンベロープ更新
					blit.updateEnvelope( *note );
				}

				//
				// フィルタを掛けたければ掛ける
				//
				double filterd_value = _filter.process(value);

				// 出力バッファに設定する
				double pan = 0.0;
				out[0][ii] = static_cast<float>( filterd_value * (1.0 - pan) * 0.5 );
				out[1][ii] = static_cast<float>( filterd_value * (1.0 + pan) * 0.5 );
			}
		}
	}
	return kResultOk;
}

}}
<commit_msg>コメント訂正<commit_after>#include "BLITSaw_vst3.h"
#include "BLITSaw_vst3_guids.h"
#include "pluginterfaces/base/ibstream.h"
#include "pluginterfaces/vst/ivstparameterchanges.h"
#include "pluginterfaces/vst/ivstevents.h"
#include <algorithm>

namespace Steinberg { namespace Vst {

//-------------------------------------------------------------------------
// BLITSaw_vst3 Implementation
//-------------------------------------------------------------------------
BLITSaw_vst3::BLITSaw_vst3()
{
	setControllerClass(AGainControllerUID);
}

//-------------------------------------------------------------------------
FUnknown* BLITSaw_vst3::createInstance(void* context)
{
	return (IAudioProcessor*)new BLITSaw_vst3();
}

//-------------------------------------------------------------------------
tresult PLUGIN_API BLITSaw_vst3::initialize(FUnknown* context)
{
	/*親クラス初期化処理*/
	tresult result = AudioEffect::initialize(context);
	if(result != kResultOk)
	{
		return result;
	}

	/*バスの設定*/
	addAudioOutput(STR16("Stereo Out"), SpeakerArr::kStereo);
	addEventInput (STR16 ("Event Input"), 1);

	return kResultOk;
}

//-------------------------------------------------------------------------
tresult PLUGIN_API BLITSaw_vst3::setBusArrangements(
	SpeakerArrangement* inputs,
	int32 numIns,
	SpeakerArrangement* outputs,
	int32 numOuts
){
	if (numIns == 0 && numOuts == 1 && outputs[0] == SpeakerArr::kStereo)
	{
		return AudioEffect::setBusArrangements (inputs, numIns, outputs, numOuts);
	}
	return kResultFalse;
}

tresult PLUGIN_API BLITSaw_vst3::setProcessing (TBool state)
{
	// state 起動1 終了0
	if( state == 1 )
	{
		for(auto note = _notes.begin(); note != _notes.end(); ++note)
		{
			note->setSampleRate( processSetup.sampleRate );
		}

		_filter.setSampleRate( processSetup.sampleRate );
	}

	return kResultOk;
}

//-------------------------------------------------------------------------
tresult PLUGIN_API BLITSaw_vst3::process(ProcessData& data)
{
	// update parameters
	if( data.inputParameterChanges )
	{
		int32 numParamsChanged = data.inputParameterChanges->getParameterCount();
		for( int32 ii = 0; ii < numParamsChanged; ii++ )
		{
			IParamValueQueue* paramQueue = data.inputParameterChanges->getParameterData(ii);
			if( paramQueue )
			{
				int32 offsetSamples;
				double value;
				// 末尾の値を取得
				if(paramQueue->getPoint(paramQueue->getPointCount() - 1, offsetSamples, value) == kResultTrue)
				{
					ParamID id = paramQueue->getParameterId();
					if( id == feedback )
					{
						// -> [0.99, 1.0]
						double feedback = 0.99 + 0.01 * value;
						blit.setFeedback(feedback);
					}
					else if( id == coarse )
					{
						double coarse_pitch = static_cast<int>( 48 * value + 0.5 ) - 24;

						for(auto note = _notes.begin(); note != _notes.end(); ++note)
						{
							note->setCorasePitch( coarse_pitch );
						}
					}
					else if( id == fine )
					{
						double finepitch = static_cast<int>( 200 * value + 0.5 ) - 100;
						for(auto note = _notes.begin(); note != _notes.end(); ++note)
						{
							note->setFinePitch( finepitch );
						}
					}
					else if( id == attack )
					{
						double attack_time = value * 0.2; // [0, 0.2]
						blit.setAttackTime( attack_time, processSetup.sampleRate );
					}
					else if( id == release )
					{
						double release_time = value * 0.2; // [0, 0.2]
						blit.setReleaseTime( release_time, processSetup.sampleRate );
					}
					else if( id == cutoff )
					{
						double cutoff_freq = 200.0 * pow(20.0, (double)value); // [200, 4000]
						_filter.setCutoff( cutoff_freq );

					}
					else if( id == resonance )
					{
						double q = 0.70710678118654757274 * (1.0 - value) + 20.0*value;
						_filter.setResonance( q );
					}
					else if( id == high )
					{
						_filter.setHigh( value );
					}
					else if( id == band )
					{
						_filter.setBand( value );
					}
					else if( id == low )
					{
						_filter.setLow( value );
					}
				}
			}
		}
	}

	// process events
	if( data.inputEvents )
	{
		int nEventCount = data.inputEvents->getEventCount();

		for( int ii = 0; ii < nEventCount; ii++ )
		{
			Event e;
			tresult result = data.inputEvents->getEvent(ii, e);
			if( result != kResultOk )continue;

			if( e.type == Event::kNoteOnEvent )
			{
				int16 note_no = e.noteOff.pitch;
				auto target_note = std::find_if(
					_notes.begin(),
					_notes.end(),
					[note_no](const bandlimited_sawtooth_oscillator_note_vst3& n){return n.id() == note_no;});

				if( target_note != _notes.end() )
				{
					// 再度ノートON
					target_note->trigger(e.noteOn);
				}
				else
				{
					// 利用可能なノートを検索する
					auto available_note = std::find_if(
						_notes.begin(),
						_notes.end(),
						[](const bandlimited_sawtooth_oscillator_note_vst3& n){return n.adsr == bandlimited_sawtooth_oscillator_note::Silent;});

					if( available_note != _notes.end() )
					{
						// ノートON
						available_note->trigger( e.noteOn );
					}
				}
			}
			else if( e.type == Event::kNoteOffEvent )
			{
				//int32 note_id = e.noteOff.noteId;
				//auto target_note = std::find_if(
				//	_notes.begin(),
				//	_notes.end(),
				//	[note_id](const bandlimited_sawtooth_oscillator_note_vst3& n){return n.id() == note_id;});
				int16 note_no = e.noteOff.pitch;
				auto target_note = std::find_if(
					_notes.begin(),
					_notes.end(),
					[note_no](const bandlimited_sawtooth_oscillator_note_vst3& n){return n.id() == note_no;});

				if( target_note != _notes.end() )
				{
					// ノートOFF
					target_note->release();
				}
			}
			else if( e.type == Event::kDataEvent )
			{
				unsigned char status = e.data.bytes[0] & 0xf0;	// ignoring channel

				if( status == 0xE0 )
				{
					unsigned char data1 = e.data.bytes[1] & 0x7f;
					unsigned char data2 = e.data.bytes[2] & 0x7f;

					double pitch_bend = (( data1 + data2*128 ) - 8192 ) / 8192.0;

					for(auto note = _notes.begin(); note != _notes.end(); ++note)
					{
						note->setPitchBend( pitch_bend );
					}
				}
			}

		}
	}

	bool bAllSilent= std::all_of(
		_notes.begin(),
		_notes.end(),
		[](const bandlimited_sawtooth_oscillator_note_vst3& n){return n.adsr == bandlimited_sawtooth_oscillator_note::Silent;});

	if( bAllSilent )
	{
		return kResultOk;
	}

	_filter.updateFilter();

	/*--------*/
	/*音声処理*/
	/*--------*/
	if (data.numInputs == 0 && data.numOutputs == 1 )
	{
		for(auto note = _notes.begin(); note != _notes.end(); ++note)
		{
			// ピッチを更新
			note->updateFrequency();
		}

		if( data.outputs[0].numChannels == 2 )
		{
			float** out = data.outputs[0].channelBuffers32;

			const int32 sampleFrames = data.numSamples;
			for( int ii = 0; ii < sampleFrames; ii++ )
			{
				double value = 0.0;
				for(auto note = _notes.begin(); note != _notes.end(); ++note)
				{
					if( note->adsr == bandlimited_sawtooth_oscillator_note::Silent )continue;

					// ノート毎の音を足し合わせる
					value += note->saw * note->envelope * note->velocity();

					// オシレーター更新
					blit.updateOcsillater( *note );

					// エンベロープ更新
					blit.updateEnvelope( *note );
				}

				//
				// フィルタを掛けたければ掛ける
				//
				double filterd_value = _filter.process(value);

				// 出力バッファに設定する
				double pan = 0.0;
				out[0][ii] = static_cast<float>( filterd_value * (1.0 - pan) * 0.5 );
				out[1][ii] = static_cast<float>( filterd_value * (1.0 + pan) * 0.5 );
			}
		}
	}
	return kResultOk;
}

}}
<|endoftext|>


<commit_before>/*
* Simple ASN.1 String Types
* (C) 1999-2007,2020 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/asn1_obj.h>
#include <botan/der_enc.h>
#include <botan/ber_dec.h>
#include <botan/internal/charset.h>
#include <botan/internal/ct_utils.h>

namespace Botan {

namespace {

/*
* Choose an encoding for the string
*/
ASN1_Type choose_encoding(const std::string& str)
   {
   auto all_printable = CT::Mask<uint8_t>::set();

   for(size_t i = 0; i != str.size(); ++i)
      {
      const uint8_t c = static_cast<uint8_t>(str[i]);

      auto is_alpha_lower = CT::Mask<uint8_t>::is_within_range(c, 'a', 'z');
      auto is_alpha_upper = CT::Mask<uint8_t>::is_within_range(c, 'A', 'Z');
      auto is_decimal = CT::Mask<uint8_t>::is_within_range(c, '0', '9');

      auto is_print_punc = CT::Mask<uint8_t>::is_any_of(c, {
            ' ', '(', ')', '+', ',', '=', ',', '-', '.', '/',
            ':', '=', '?'});

      auto is_printable = is_alpha_lower | is_alpha_upper | is_decimal | is_print_punc;

      all_printable &= is_printable;
      }

   if(all_printable.is_set())
      return ASN1_Type::PrintableString;
   else
      return ASN1_Type::Utf8String;
   }

bool is_utf8_subset_string_type(ASN1_Type tag)
   {
   return (tag == ASN1_Type::NumericString ||
           tag == ASN1_Type::PrintableString ||
           tag == ASN1_Type::VisibleString ||
           tag == ASN1_Type::Ia5String ||
           tag == ASN1_Type::Utf8String);
   }

bool is_asn1_string_type(ASN1_Type tag)
   {
   return (is_utf8_subset_string_type(tag) ||
           tag == ASN1_Type::TeletexString ||
           tag == ASN1_Type::BmpString ||
           tag == ASN1_Type::UniversalString);
   }

}

//static
bool ASN1_String::is_string_type(ASN1_Type tag)
   {
   return is_asn1_string_type(tag);
   }

ASN1_String::ASN1_String(const std::string& str, ASN1_Type t) : m_utf8_str(str), m_tag(t)
   {
   if(!is_utf8_subset_string_type(m_tag))
      {
      throw Invalid_Argument("ASN1_String only supports encoding to UTF-8 or a UTF-8 subset");
      }
   }

ASN1_String::ASN1_String(const std::string& str) :
   ASN1_String(str, choose_encoding(str))
   {}

/*
* DER encode an ASN1_String
*/
void ASN1_String::encode_into(DER_Encoder& encoder) const
   {
   if(m_data.empty())
      {
      BOTAN_ASSERT_NOMSG(is_utf8_subset_string_type(tagging()));
      encoder.add_object(tagging(), ASN1_Class::Universal, m_utf8_str);
      }
   else
      {
      // If this string was decoded, reserialize using original encoding
      encoder.add_object(tagging(), ASN1_Class::Universal, m_data.data(), m_data.size());
      }
   }

/*
* Decode a BER encoded ASN1_String
*/
void ASN1_String::decode_from(BER_Decoder& source)
   {
   BER_Object obj = source.get_next_object();

   if(!is_asn1_string_type(obj.type()))
      {
      throw Decoding_Error("ASN1_String: Unknown string type " +
                           std::to_string(static_cast<uint32_t>(obj.type())));
      }

   m_tag = obj.type();
   m_data.assign(obj.bits(), obj.bits() + obj.length());

   if(m_tag == ASN1_Type::BmpString)
      {
      m_utf8_str = ucs2_to_utf8(m_data.data(), m_data.size());
      }
   else if(m_tag == ASN1_Type::UniversalString)
      {
      m_utf8_str = ucs4_to_utf8(m_data.data(), m_data.size());
      }
   else if(m_tag == ASN1_Type::TeletexString)
      {
      /*
      TeletexString is nominally ITU T.61 not ISO-8859-1 but it seems
      the majority of implementations actually used that charset here.
      */
      m_utf8_str = latin1_to_utf8(m_data.data(), m_data.size());
      }
   else
      {
      // All other supported string types are UTF-8 or some subset thereof
      m_utf8_str = ASN1::to_string(obj);
      }
   }

}
<commit_msg>Remove duplicated chars from allowed chars in ASN1_Type::PrintableString<commit_after>/*
* Simple ASN.1 String Types
* (C) 1999-2007,2020 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/asn1_obj.h>
#include <botan/der_enc.h>
#include <botan/ber_dec.h>
#include <botan/internal/charset.h>
#include <botan/internal/ct_utils.h>

namespace Botan {

namespace {

/*
* Choose an encoding for the string
*/
ASN1_Type choose_encoding(const std::string& str)
   {
   auto all_printable = CT::Mask<uint8_t>::set();

   for(size_t i = 0; i != str.size(); ++i)
      {
      const uint8_t c = static_cast<uint8_t>(str[i]);

      auto is_alpha_lower = CT::Mask<uint8_t>::is_within_range(c, 'a', 'z');
      auto is_alpha_upper = CT::Mask<uint8_t>::is_within_range(c, 'A', 'Z');
      auto is_decimal = CT::Mask<uint8_t>::is_within_range(c, '0', '9');

      auto is_print_punc = CT::Mask<uint8_t>::is_any_of(c, {
            ' ', '(', ')', '+', ',', '-', '.', '/',
            ':', '=', '?'});

      auto is_printable = is_alpha_lower | is_alpha_upper | is_decimal | is_print_punc;

      all_printable &= is_printable;
      }

   if(all_printable.is_set())
      return ASN1_Type::PrintableString;
   else
      return ASN1_Type::Utf8String;
   }

bool is_utf8_subset_string_type(ASN1_Type tag)
   {
   return (tag == ASN1_Type::NumericString ||
           tag == ASN1_Type::PrintableString ||
           tag == ASN1_Type::VisibleString ||
           tag == ASN1_Type::Ia5String ||
           tag == ASN1_Type::Utf8String);
   }

bool is_asn1_string_type(ASN1_Type tag)
   {
   return (is_utf8_subset_string_type(tag) ||
           tag == ASN1_Type::TeletexString ||
           tag == ASN1_Type::BmpString ||
           tag == ASN1_Type::UniversalString);
   }

}

//static
bool ASN1_String::is_string_type(ASN1_Type tag)
   {
   return is_asn1_string_type(tag);
   }

ASN1_String::ASN1_String(const std::string& str, ASN1_Type t) : m_utf8_str(str), m_tag(t)
   {
   if(!is_utf8_subset_string_type(m_tag))
      {
      throw Invalid_Argument("ASN1_String only supports encoding to UTF-8 or a UTF-8 subset");
      }
   }

ASN1_String::ASN1_String(const std::string& str) :
   ASN1_String(str, choose_encoding(str))
   {}

/*
* DER encode an ASN1_String
*/
void ASN1_String::encode_into(DER_Encoder& encoder) const
   {
   if(m_data.empty())
      {
      BOTAN_ASSERT_NOMSG(is_utf8_subset_string_type(tagging()));
      encoder.add_object(tagging(), ASN1_Class::Universal, m_utf8_str);
      }
   else
      {
      // If this string was decoded, reserialize using original encoding
      encoder.add_object(tagging(), ASN1_Class::Universal, m_data.data(), m_data.size());
      }
   }

/*
* Decode a BER encoded ASN1_String
*/
void ASN1_String::decode_from(BER_Decoder& source)
   {
   BER_Object obj = source.get_next_object();

   if(!is_asn1_string_type(obj.type()))
      {
      throw Decoding_Error("ASN1_String: Unknown string type " +
                           std::to_string(static_cast<uint32_t>(obj.type())));
      }

   m_tag = obj.type();
   m_data.assign(obj.bits(), obj.bits() + obj.length());

   if(m_tag == ASN1_Type::BmpString)
      {
      m_utf8_str = ucs2_to_utf8(m_data.data(), m_data.size());
      }
   else if(m_tag == ASN1_Type::UniversalString)
      {
      m_utf8_str = ucs4_to_utf8(m_data.data(), m_data.size());
      }
   else if(m_tag == ASN1_Type::TeletexString)
      {
      /*
      TeletexString is nominally ITU T.61 not ISO-8859-1 but it seems
      the majority of implementations actually used that charset here.
      */
      m_utf8_str = latin1_to_utf8(m_data.data(), m_data.size());
      }
   else
      {
      // All other supported string types are UTF-8 or some subset thereof
      m_utf8_str = ASN1::to_string(obj);
      }
   }

}
<|endoftext|>


<commit_before><commit_msg>useless aStr string<commit_after><|endoftext|>


<commit_before>//*******************************************************************
//glfont2.cpp -- glFont Version 2.0 implementation
//Copyright (c) 1998-2002 Brad Fish
//See glfont.html for terms of use
//May 14, 2002
//*******************************************************************

//STL headers
#include <string>
#include <utility>
#include <iostream>
#include <fstream>
using namespace std;

//OpenGL headers
#ifdef _WINDOWS
#include <windows.h>
#endif
#include <GL/gl.h>

//glFont header
#include "glfont2.h"
using namespace glfont;

//*******************************************************************
//GLFont Class Implementation
//*******************************************************************
GLFont::GLFont ()
{
	//Initialize header to safe state
	header.tex = -1;
	header.tex_width = 0;
	header.tex_height = 0;
	header.start_char = 0;
	header.end_char = 0;
	header.chars = NULL;
}
//*******************************************************************
GLFont::~GLFont ()
{
	//Destroy the font
	Destroy();
}
//*******************************************************************
bool GLFont::Create (const char *file_name, int tex)
{
	ifstream input;
	int num_chars, num_tex_bytes;
	char *tex_bytes;

	//Destroy the old font if there was one, just to be safe
	Destroy();

	//Open input file
	input.open(file_name, ios::in | ios::binary);
	if (!input)
		return false;

	//Read the header from file
	input.read((char *)&header, sizeof(header));
	header.tex = tex;

	//Allocate space for character array
	num_chars = header.end_char - header.start_char + 1;
	if ((header.chars = new GLFontChar[num_chars]) == NULL)
		return false;

	//Read character array
	for(int i=0; i < num_chars; i++)
		input.read((char *)&header.chars[i], sizeof(GLFontChar) - (sizeof(void*) - 4));

	//Read texture pixel data
	num_tex_bytes = header.tex_width * header.tex_height * 2;
	tex_bytes = new char[num_tex_bytes];
	input.read(tex_bytes, num_tex_bytes);

	//Create OpenGL texture
	glBindTexture(GL_TEXTURE_2D, tex);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glTexImage2D(GL_TEXTURE_2D, 0, 2, header.tex_width,
		header.tex_height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
		(void *)tex_bytes);

	//Free texture pixels memory
	delete[] tex_bytes;

	//Close input file
	input.close();

	//Return successfully

	cout << "Start: " << header.start_char << ", End: " << header.end_char << ", Chars: " << header.chars << endl;
	cout << "Height: " << header.tex_height << ", Width: " << header.tex_width << endl;
	//Read character array
	for(int i=header.start_char; i < header.end_char; i++)
	{
		GLFontChar c = header.chars[i - header.start_char];
		cout << "Char: " << i << ", dx: " << c.dx << ", dy: " << c.dy << endl;
		cout << "ty1: " << c.ty1 << ", ty2: " << c.ty2 << ", tx1: " << c.tx1 << ", tx2: " << c.tx2 << endl;
	}

	return true;
}
//*******************************************************************
bool GLFont::Create (const std::string &file_name, int tex)
{
	return Create(file_name.c_str(), tex);
}
//*******************************************************************
void GLFont::Destroy (void)
{
	//Delete the character array if necessary
	if (header.chars)
	{
		delete[] header.chars;
		header.chars = NULL;
	}
}
//*******************************************************************
void GLFont::GetTexSize (std::pair<int, int> *size)
{
	//Retrieve texture size
	size->first = header.tex_width;
	size->second = header.tex_height;
}
//*******************************************************************
int GLFont::GetTexWidth (void)
{
	//Return texture width
	return header.tex_width;
}
//*******************************************************************
int GLFont::GetTexHeight (void)
{
	//Return texture height
	return header.tex_height;
}
//*******************************************************************
void GLFont::GetCharInterval (std::pair<int, int> *interval)
{
	//Retrieve character interval
	interval->first = header.start_char;
	interval->second = header.end_char;
}
//*******************************************************************
int GLFont::GetStartChar (void)
{
	//Return start character
	return header.start_char;
}
//*******************************************************************
int GLFont::GetEndChar (void)
{
	//Return end character
	return header.end_char;
}
//*******************************************************************
void GLFont::GetCharSize (int c, std::pair<int, int> *size)
{
	//Make sure character is in range
	if (c < header.start_char || c > header.end_char)
	{
		//Not a valid character, so it obviously has no size
		size->first = 0;
		size->second = 0;
	}
	else
	{
		GLFontChar *glfont_char;

		//Retrieve character size
		glfont_char = &header.chars[c - header.start_char];
		size->first = (int)(glfont_char->dx * header.tex_width);
		size->second = (int)(glfont_char->dy *
			header.tex_height);
	}
}
//*******************************************************************
int GLFont::GetCharWidth (int c)
{
	//Make sure in range
	if (c < header.start_char || c > header.end_char)
		return 0;
	else
	{
		GLFontChar *glfont_char;

		//Retrieve character width
		glfont_char = &header.chars[c - header.start_char];
		return (int)(glfont_char->dx * header.tex_width);
	}
}
//*******************************************************************
int GLFont::GetCharHeight (int c)
{
	//Make sure in range
	if (c < header.start_char || c > header.end_char)
		return 0;
	else
	{
		GLFontChar *glfont_char;

		//Retrieve character height
		glfont_char = &header.chars[c - header.start_char];
		return (int)(glfont_char->dy * header.tex_height);
	}
}
//*******************************************************************
void GLFont::Begin (void)
{
	//Bind to font texture
	glBindTexture(GL_TEXTURE_2D, header.tex);
}
//*******************************************************************

//End of file

<commit_msg>fix for 64-bit. i mean it really<commit_after>//*******************************************************************
//glfont2.cpp -- glFont Version 2.0 implementation
//Copyright (c) 1998-2002 Brad Fish
//See glfont.html for terms of use
//May 14, 2002
//*******************************************************************

//STL headers
#include <string>
#include <utility>
#include <iostream>
#include <fstream>
using namespace std;

//OpenGL headers
#ifdef _WINDOWS
#include <windows.h>
#endif
#include <GL/gl.h>

//glFont header
#include "glfont2.h"
using namespace glfont;

//*******************************************************************
//GLFont Class Implementation
//*******************************************************************
GLFont::GLFont ()
{
	//Initialize header to safe state
	header.tex = -1;
	header.tex_width = 0;
	header.tex_height = 0;
	header.start_char = 0;
	header.end_char = 0;
	header.chars = NULL;
}
//*******************************************************************
GLFont::~GLFont ()
{
	//Destroy the font
	Destroy();
}
//*******************************************************************
bool GLFont::Create (const char *file_name, int tex)
{
	ifstream input;
	int num_chars, num_tex_bytes;
	char *tex_bytes;

	//Destroy the old font if there was one, just to be safe
	Destroy();

	//Open input file
	input.open(file_name, ios::in | ios::binary);
	if (!input)
		return false;

	//Read the header from file
	input.read((char *)&header, sizeof(header) - (sizeof(void*) - 4));
	header.tex = tex;

	//Allocate space for character array
	num_chars = header.end_char - header.start_char + 1;
	if ((header.chars = new GLFontChar[num_chars]) == NULL)
		return false;

	//Read character array
	for(int i=0; i < num_chars; i++)
		input.read((char *)&header.chars[i], sizeof(GLFontChar));

	//Read texture pixel data
	num_tex_bytes = header.tex_width * header.tex_height * 2;
	tex_bytes = new char[num_tex_bytes];
	input.read(tex_bytes, num_tex_bytes);

	//Create OpenGL texture
	glBindTexture(GL_TEXTURE_2D, tex);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glTexImage2D(GL_TEXTURE_2D, 0, 2, header.tex_width,
		header.tex_height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
		(void *)tex_bytes);

	//Free texture pixels memory
	delete[] tex_bytes;

	//Close input file
	input.close();

	//Return successfully

	cout << "Start: " << header.start_char << ", End: " << header.end_char << ", Chars: " << header.chars << endl;
	cout << "Height: " << header.tex_height << ", Width: " << header.tex_width << endl;
	//Read character array
	for(int i=header.start_char; i < header.end_char; i++)
	{
		GLFontChar c = header.chars[i - header.start_char];
		cout << "Char: " << i << ", dx: " << c.dx << ", dy: " << c.dy << endl;
		cout << "ty1: " << c.ty1 << ", ty2: " << c.ty2 << ", tx1: " << c.tx1 << ", tx2: " << c.tx2 << endl;
	}

	return true;
}
//*******************************************************************
bool GLFont::Create (const std::string &file_name, int tex)
{
	return Create(file_name.c_str(), tex);
}
//*******************************************************************
void GLFont::Destroy (void)
{
	//Delete the character array if necessary
	if (header.chars)
	{
		delete[] header.chars;
		header.chars = NULL;
	}
}
//*******************************************************************
void GLFont::GetTexSize (std::pair<int, int> *size)
{
	//Retrieve texture size
	size->first = header.tex_width;
	size->second = header.tex_height;
}
//*******************************************************************
int GLFont::GetTexWidth (void)
{
	//Return texture width
	return header.tex_width;
}
//*******************************************************************
int GLFont::GetTexHeight (void)
{
	//Return texture height
	return header.tex_height;
}
//*******************************************************************
void GLFont::GetCharInterval (std::pair<int, int> *interval)
{
	//Retrieve character interval
	interval->first = header.start_char;
	interval->second = header.end_char;
}
//*******************************************************************
int GLFont::GetStartChar (void)
{
	//Return start character
	return header.start_char;
}
//*******************************************************************
int GLFont::GetEndChar (void)
{
	//Return end character
	return header.end_char;
}
//*******************************************************************
void GLFont::GetCharSize (int c, std::pair<int, int> *size)
{
	//Make sure character is in range
	if (c < header.start_char || c > header.end_char)
	{
		//Not a valid character, so it obviously has no size
		size->first = 0;
		size->second = 0;
	}
	else
	{
		GLFontChar *glfont_char;

		//Retrieve character size
		glfont_char = &header.chars[c - header.start_char];
		size->first = (int)(glfont_char->dx * header.tex_width);
		size->second = (int)(glfont_char->dy *
			header.tex_height);
	}
}
//*******************************************************************
int GLFont::GetCharWidth (int c)
{
	//Make sure in range
	if (c < header.start_char || c > header.end_char)
		return 0;
	else
	{
		GLFontChar *glfont_char;

		//Retrieve character width
		glfont_char = &header.chars[c - header.start_char];
		return (int)(glfont_char->dx * header.tex_width);
	}
}
//*******************************************************************
int GLFont::GetCharHeight (int c)
{
	//Make sure in range
	if (c < header.start_char || c > header.end_char)
		return 0;
	else
	{
		GLFontChar *glfont_char;

		//Retrieve character height
		glfont_char = &header.chars[c - header.start_char];
		return (int)(glfont_char->dy * header.tex_height);
	}
}
//*******************************************************************
void GLFont::Begin (void)
{
	//Bind to font texture
	glBindTexture(GL_TEXTURE_2D, header.tex);
}
//*******************************************************************

//End of file

<|endoftext|>