<commit_before>#ifndef _CSDBG_CONFIG
#define _CSDBG_CONFIG 1

/**
	@file include/config.hpp

	@brief Library configuration, type, macro and global variable definition
*/

#include <iostream>
#include <typeinfo>

#include <climits>
#include <cstdarg>
#include <cstring>

#ifdef __cplusplus
extern "C" {
#endif

#include <cxxabi.h>
#include <bfd.h>
#include <link.h>
#include <pthread.h>
#include <regex.h>
#include <sys/stat.h>

#ifdef CSDBG_WITH_HIGHLIGHT
#include <fcntl.h>
#include <sys/mman.h>
#endif

#ifdef CSDBG_WITH_STREAM
#include <sys/file.h>
#include <sys/time.h>

#ifdef CSDBG_WITH_STREAM_STTY
#include <termios.h>
#endif

#ifdef CSDBG_WITH_STREAM_TCP
#include <arpa/inet.h>
#include <sys/socket.h>
#endif
#endif

#ifdef __cplusplus
}
#endif

/**
	@brief Complete library namespace

	This namespace consists of the libcsdbg classes/templates and global variables
	(csdbg::g_*) that provide the default library configuration

	@todo Implement syscall wrappers for proper retval handling (replays)
	@todo Restructure config.hpp
*/
namespace csdbg {

/**
	@brief 8-bit signed integer
*/
typedef char								i8;

/**
	@brief 16-bit signed integer
*/
typedef short								i16;

/**
	@brief 32-bit signed integer
*/
typedef int									i32;

/**
	@brief 64-bit signed integer
*/
typedef long long						i64;

/**
	@brief 8-bit unsigned integer
*/
typedef unsigned char				u8;

/**
	@brief 16-bit unsigned integer
*/
typedef unsigned short			u16;

/**
	@brief 32-bit unsigned integer
*/
typedef unsigned int				u32;

/**
	@brief 64-bit unsigned integer
*/
typedef unsigned long long	u64;

/**
	@brief Locale codepage
*/
typedef const i8*						codepage_t;

/**
	@brief Console message header tag
*/
typedef const i8*						console_tag_t;

/**
	@brief Thread running status
*/
typedef u8									thread_status_t;

/*
	Address bus size type definition
*/
#if defined __x86_64__ || defined __ppc64__

/**
	@brief 64-bit memory address
*/
typedef unsigned long long	mem_addr_t;

#else

/**
	@brief 32-bit memory address
*/
typedef unsigned int				mem_addr_t;

#endif

/*
	Syntax highlighter type definitions
*/
#ifdef CSDBG_WITH_HIGHLIGHT

/**
	@brief VT100 attribute bitmask

	This type could be defined as a u8, it is defined as u16 to reserve space. The
	sizeof(csdbg::style) remains 8 bytes due to 4 byte alignment
*/
typedef u16									attrset_t;

/**
	@brief VT100 terminal color
*/
typedef u8									color_t;

/**
	@brief File metadata
*/
typedef struct stat					fileinfo_t;

#endif

/*
	Plugin system type definitions
*/
#ifdef CSDBG_WITH_PLUGIN

/**
	@brief DSO handle
*/
typedef void*								dso_t;

/**
	@brief Plugin callback
*/
typedef void (*							modsym_t)(void*, void*);

#endif

/*
	TCP streaming type definitions
*/
#ifdef CSDBG_WITH_STREAM_TCP

/**
	@brief TCP IPv4 address
*/
typedef struct sockaddr_in	tcp_addr_t;

/**
	@brief IP address
*/
typedef struct sockaddr			ip_addr_t;

#endif

}

/*
	Static library globals
*/
namespace csdbg {

/**
	@brief Supported csdbg::string codepages

	@see string::m_locale
*/
static const codepage_t g_codepages[] = {

	"iso-8859-1",

	"iso-8859-7"

};

/**
	@brief DSO filtering shell variable

	@see tracer::on_dso_load
*/
static const i8 g_libs_env[] = "CSDBG_LIBS";

/**
	@brief Library version major
*/
static const u16 g_major = 2;

/**
	@brief Block size (allocation alignment)

	@see string::memalign
*/
static const u16 g_memblock_sz = 64;

/**
	@brief Library version minor
*/
static const u16 g_minor = 0;

/**
	@brief Preallocation block size

	@see list::memalign
*/
static const u16 g_prealloc_sz = 128;

/**
	@brief Library installation prefix
*/
static const i8 g_prefix[] = "/usr/local";

#ifdef CSDBG_WITH_HIGHLIGHT

/**
	@brief C++ stack trace syntax

	@see csdbg::parser
*/
static const i8 g_trace_syntax[] = "[ \t\n\r\\{\\}\\(\\)\\*&,:<>]+";

#endif

#ifdef CSDBG_WITH_STREAM_TCP

/**
	@brief LDP service port
*/
static const i32 g_ldp_port = 4242;

#endif

}

/*
	Library output message tags and macros
*/
namespace csdbg {

/**
	@brief Tag for error console messages
*/
#define	ERROR_TAG						"[e]"

/**
	@brief Tag for exception console messages
*/
#define	EXCEPTION_TAG				"[x]"

/**
	@brief Tag for informational console messages
*/
#define	INFO_TAG						"[i]"

/**
	@brief Tag for warning console messages
*/
#define	WARNING_TAG					"[w]"

/**
	@brief Check if a tag is for an error console message
*/
#define is_error(x)					(strcmp(x, ERROR_TAG) == 0)

/**
	@brief Check if a tag is for an exception console message
*/
#define is_exception(x)			(strcmp(x, EXCEPTION_TAG) == 0)

/**
	@brief Check if a tag is for an informational console message
*/
#define is_info(x)					(strcmp(x, INFO_TAG) == 0)

/**
	@brief Check if a tag is for a warning console message
*/
#define is_warning(x)				(strcmp(x, WARNING_TAG) == 0)

}

/*
	Debug levels and assertions
*/
#ifdef CSDBG_WITH_DEBUG

/**
	@brief Error debug level
*/
#define CSDBG_DBGL_ERROR		0x01

/**
	@brief Warning debug level
*/
#define CSDBG_DBGL_WARNING	0x02

/**
	@brief Generic debug level
*/
#define CSDBG_DBGL_INFO			0x04

/**
	@brief Low debug level (only errors)
*/
#define CSDBG_DBGL_LOW			(CSDBG_DBGL_ERROR)

/**
	@brief Medium debug level (errors and warnings)
*/
#define CSDBG_DBGL_MEDIUM		(CSDBG_DBGL_LOW | CSDBG_DBGL_WARNING)

/**
	@brief High debug level (all messages)
*/
#define CSDBG_DBGL_HIGH			(CSDBG_DBGL_MEDIUM | CSDBG_DBGL_INFO)

/**
	@brief Selected debug level
*/
#define CSDBG_DBG_LEVEL			CSDBG_DBGL_HIGH

/**
	@brief Assertion macro
*/
#define __ASSERT(x)																						\
if (!(x)) {																										\
	std::cerr << "\r\nassertion '" << #x << "' failed";				\
	std::cerr << "\r\non line " << std::dec << __LINE__;				\
	std::cerr << "\r\nin file '" << __FILE__ << "'";						\
	std::cerr << "\r\nin function " << __PRETTY_FUNCTION__;		\
	std::cerr << "\r\n\r\n";																		\
}

#else

#define __ASSERT(x)

#endif

/*
	Use of color in terminals (RXVT, XTerm e.t.c) to color-code message tags and
	assertions
*/
#ifdef CSDBG_WITH_COLOR_TERM

/**
	@brief Tag color for error and exception messages
*/
#define ERROR_TAG_FG				9

/**
	@brief Tag color for error and exception messages
*/
#define EXCEPTION_TAG_FG		196

/**
	@brief Tag color for informational messages
*/
#define INFO_TAG_FG					61

/**
	@brief Tag color for warning messages
*/
#define WARNING_TAG_FG			202

#endif

#ifdef CSDBG_WITH_COLOR_ASSERTIONS

/**
	@brief Color coded assertion macro
*/
#define __D_ASSERT(x)																					\
	std::cerr << "\e[1m\e[38;5;9m";															\
	__ASSERT(x);																								\
	std::cerr << "\e[0m"

#else

#define __D_ASSERT(x)				__ASSERT(x)

#endif

/*
	Syntax highlighter definitions
*/
#ifdef CSDBG_WITH_HIGHLIGHT

/**
	@brief Highlighter color for numbers (any base)
*/
#define HLT_NUMBER_FG				208

/**
	@brief Highlighter color for C++ keywords
*/
#define HLT_KEYWORD_FG			61

/**
	@brief Highlighter color for C++ intrinsic types
*/
#define HLT_TYPE_FG					105

/**
	@brief Highlighter color for C++ files
*/
#define HLT_FILE_FG					250

/**
	@brief Highlighter color for C++ ABI scopes
*/
#define HLT_SCOPE_FG				250

/**
	@brief Highlighter color for C++ function names
*/
#define HLT_FUNCTION_FG			214

#endif

/*
	Use of gcc built-ins for branch prediction and cache optimization
*/
#ifdef __GNUC__

/**
	@brief Offer a hint (positive) to the pipeline branch predictor
*/
#define likely(expr)				__builtin_expect((expr), true)

/**
	@brief Offer a hint (negative) to the pipeline branch predictor
*/
#define unlikely(expr)			__builtin_expect((expr), false)

/**
	@brief Prefetch a block from memory to the cache (for read)
*/
#define precache_r(addr)		__builtin_prefetch((addr), 0, 3)

/**
	@brief Prefetch a block from memory to the cache (for write)
*/
#define precache_w(addr)		__builtin_prefetch((addr), 1, 3)

#else

#define likely(expr)				(expr)

#define unlikely(expr)			(expr)

#define precache_r(addr)

#define precache_w(addr)

#endif

#endif
<commit_msg>Update config.hpp<commit_after>#ifndef _CSDBG_CONFIG
#define _CSDBG_CONFIG 1

/**
	@file include/config.hpp

	@brief Library configuration, type, macro and global variable definition
*/

#include <iostream>
#include <typeinfo>

#include <climits>
#include <cstdarg>
#include <cstring>

#ifdef __cplusplus
extern "C" {
#endif

#include <cxxabi.h>
#include <bfd.h>
#include <link.h>
#include <pthread.h>
#include <regex.h>
#include <sys/stat.h>

#ifdef CSDBG_WITH_HIGHLIGHT
#include <fcntl.h>
#include <sys/mman.h>
#endif

#ifdef CSDBG_WITH_STREAM
#include <sys/file.h>
#include <sys/time.h>

#ifdef CSDBG_WITH_STREAM_STTY
#include <termios.h>
#endif

#ifdef CSDBG_WITH_STREAM_TCP
#include <arpa/inet.h>
#include <sys/socket.h>
#endif
#endif

#ifdef __cplusplus
}
#endif

/**
	@brief Complete library namespace

	This namespace consists of the libcsdbg classes/templates and global variables
	(csdbg::g_*) that provide the default library configuration

	@todo Implement syscall wrappers for proper retval handling (replays)
	@todo Restructure config.hpp
	@todo Create (from scratch) cmake hooks in config.h and children
*/
namespace csdbg {

/**
	@brief 8-bit signed integer
*/
typedef char								i8;

/**
	@brief 16-bit signed integer
*/
typedef short								i16;

/**
	@brief 32-bit signed integer
*/
typedef int									i32;

/**
	@brief 64-bit signed integer
*/
typedef long long						i64;

/**
	@brief 8-bit unsigned integer
*/
typedef unsigned char				u8;

/**
	@brief 16-bit unsigned integer
*/
typedef unsigned short			u16;

/**
	@brief 32-bit unsigned integer
*/
typedef unsigned int				u32;

/**
	@brief 64-bit unsigned integer
*/
typedef unsigned long long	u64;

/**
	@brief Locale codepage
*/
typedef const i8*						codepage_t;

/**
	@brief Console message header tag
*/
typedef const i8*						console_tag_t;

/**
	@brief Thread running status
*/
typedef u8									thread_status_t;

/*
	Address bus size type definition
*/
#if defined __x86_64__ || defined __ppc64__

/**
	@brief 64-bit memory address
*/
typedef unsigned long long	mem_addr_t;

#else

/**
	@brief 32-bit memory address
*/
typedef unsigned int				mem_addr_t;

#endif

/*
	Syntax highlighter type definitions
*/
#ifdef CSDBG_WITH_HIGHLIGHT

/**
	@brief VT100 attribute bitmask

	This type could be defined as a u8, it is defined as u16 to reserve space. The
	sizeof(csdbg::style) remains 8 bytes due to 4 byte alignment
*/
typedef u16									attrset_t;

/**
	@brief VT100 terminal color
*/
typedef u8									color_t;

/**
	@brief File metadata
*/
typedef struct stat					fileinfo_t;

#endif

/*
	Plugin system type definitions
*/
#ifdef CSDBG_WITH_PLUGIN

/**
	@brief DSO handle
*/
typedef void*								dso_t;

/**
	@brief Plugin callback
*/
typedef void (*							modsym_t)(void*, void*);

#endif

/*
	TCP streaming type definitions
*/
#ifdef CSDBG_WITH_STREAM_TCP

/**
	@brief TCP IPv4 address
*/
typedef struct sockaddr_in	tcp_addr_t;

/**
	@brief IP address
*/
typedef struct sockaddr			ip_addr_t;

#endif

}

/*
	Static library globals
*/
namespace csdbg {

/**
	@brief Supported csdbg::string codepages

	@see string::m_locale
*/
static const codepage_t g_codepages[] = {

	"iso-8859-1",

	"iso-8859-7"

};

/**
	@brief DSO filtering shell variable

	@see tracer::on_dso_load
*/
static const i8 g_libs_env[] = "CSDBG_LIBS";

/**
	@brief Library version major
*/
static const u16 g_major = 2;

/**
	@brief Block size (allocation alignment)

	@see string::memalign
*/
static const u16 g_memblock_sz = 64;

/**
	@brief Library version minor
*/
static const u16 g_minor = 0;

/**
	@brief Preallocation block size

	@see list::memalign
*/
static const u16 g_prealloc_sz = 128;

/**
	@brief Library installation prefix
*/
static const i8 g_prefix[] = "/usr/local";

#ifdef CSDBG_WITH_HIGHLIGHT

/**
	@brief C++ stack trace syntax

	@see csdbg::parser
*/
static const i8 g_trace_syntax[] = "[ \t\n\r\\{\\}\\(\\)\\*&,:<>]+";

#endif

#ifdef CSDBG_WITH_STREAM_TCP

/**
	@brief LDP service port
*/
static const i32 g_ldp_port = 4242;

#endif

}

/*
	Library output message tags and macros
*/
namespace csdbg {

/**
	@brief Tag for error console messages
*/
#define	ERROR_TAG						"[e]"

/**
	@brief Tag for exception console messages
*/
#define	EXCEPTION_TAG				"[x]"

/**
	@brief Tag for informational console messages
*/
#define	INFO_TAG						"[i]"

/**
	@brief Tag for warning console messages
*/
#define	WARNING_TAG					"[w]"

/**
	@brief Check if a tag is for an error console message
*/
#define is_error(x)					(strcmp(x, ERROR_TAG) == 0)

/**
	@brief Check if a tag is for an exception console message
*/
#define is_exception(x)			(strcmp(x, EXCEPTION_TAG) == 0)

/**
	@brief Check if a tag is for an informational console message
*/
#define is_info(x)					(strcmp(x, INFO_TAG) == 0)

/**
	@brief Check if a tag is for a warning console message
*/
#define is_warning(x)				(strcmp(x, WARNING_TAG) == 0)

}

/*
	Debug levels and assertions
*/
#ifdef CSDBG_WITH_DEBUG

/**
	@brief Error debug level
*/
#define CSDBG_DBGL_ERROR		0x01

/**
	@brief Warning debug level
*/
#define CSDBG_DBGL_WARNING	0x02

/**
	@brief Generic debug level
*/
#define CSDBG_DBGL_INFO			0x04

/**
	@brief Low debug level (only errors)
*/
#define CSDBG_DBGL_LOW			(CSDBG_DBGL_ERROR)

/**
	@brief Medium debug level (errors and warnings)
*/
#define CSDBG_DBGL_MEDIUM		(CSDBG_DBGL_LOW | CSDBG_DBGL_WARNING)

/**
	@brief High debug level (all messages)
*/
#define CSDBG_DBGL_HIGH			(CSDBG_DBGL_MEDIUM | CSDBG_DBGL_INFO)

/**
	@brief Selected debug level
*/
#define CSDBG_DBG_LEVEL			CSDBG_DBGL_HIGH

/**
	@brief Assertion macro
*/
#define __ASSERT(x)																						\
if (!(x)) {																										\
	std::cerr << "\r\nassertion '" << #x << "' failed";				\
	std::cerr << "\r\non line " << std::dec << __LINE__;				\
	std::cerr << "\r\nin file '" << __FILE__ << "'";						\
	std::cerr << "\r\nin function " << __PRETTY_FUNCTION__;		\
	std::cerr << "\r\n\r\n";																		\
}

#else

#define __ASSERT(x)

#endif

/*
	Use of color in terminals (RXVT, XTerm e.t.c) to color-code message tags and
	assertions
*/
#ifdef CSDBG_WITH_COLOR_TERM

/**
	@brief Tag color for error and exception messages
*/
#define ERROR_TAG_FG				9

/**
	@brief Tag color for error and exception messages
*/
#define EXCEPTION_TAG_FG		196

/**
	@brief Tag color for informational messages
*/
#define INFO_TAG_FG					61

/**
	@brief Tag color for warning messages
*/
#define WARNING_TAG_FG			202

#endif

#ifdef CSDBG_WITH_COLOR_ASSERTIONS

/**
	@brief Color coded assertion macro
*/
#define __D_ASSERT(x)																					\
	std::cerr << "\e[1m\e[38;5;9m";															\
	__ASSERT(x);																								\
	std::cerr << "\e[0m"

#else

#define __D_ASSERT(x)				__ASSERT(x)

#endif

/*
	Syntax highlighter definitions
*/
#ifdef CSDBG_WITH_HIGHLIGHT

/**
	@brief Highlighter color for numbers (any base)
*/
#define HLT_NUMBER_FG				208

/**
	@brief Highlighter color for C++ keywords
*/
#define HLT_KEYWORD_FG			61

/**
	@brief Highlighter color for C++ intrinsic types
*/
#define HLT_TYPE_FG					105

/**
	@brief Highlighter color for C++ files
*/
#define HLT_FILE_FG					250

/**
	@brief Highlighter color for C++ ABI scopes
*/
#define HLT_SCOPE_FG				250

/**
	@brief Highlighter color for C++ function names
*/
#define HLT_FUNCTION_FG			214

#endif

/*
	Use of gcc built-ins for branch prediction and cache optimization
*/
#ifdef __GNUC__

/**
	@brief Offer a hint (positive) to the pipeline branch predictor
*/
#define likely(expr)				__builtin_expect((expr), true)

/**
	@brief Offer a hint (negative) to the pipeline branch predictor
*/
#define unlikely(expr)			__builtin_expect((expr), false)

/**
	@brief Prefetch a block from memory to the cache (for read)
*/
#define precache_r(addr)		__builtin_prefetch((addr), 0, 3)

/**
	@brief Prefetch a block from memory to the cache (for write)
*/
#define precache_w(addr)		__builtin_prefetch((addr), 1, 3)

#else

#define likely(expr)				(expr)

#define unlikely(expr)			(expr)

#define precache_r(addr)

#define precache_w(addr)

#endif

#endif
<|endoftext|>


<commit_before>#pragma once

#include <type_traits>
#include <utility>

using std::pair;
using std::make_pair;

template<int N>
class strbuf {
 public:
  char _buf[N];

  strbuf(const char *s) {
    strncpy(_buf, s, N);
  }

  bool operator==(const strbuf<N> &other) {
    return !strncmp(_buf, other._buf, N);
  }
};

class scoped_acquire {
 private:
  spinlock *_l;

 public:
  scoped_acquire(spinlock *l) : _l(0) { acquire(l); }
  ~scoped_acquire() { release(); }
  void release() { if (_l) { ::release(_l); _l = 0; } }
  void acquire(spinlock *l) { assert(!_l); ::acquire(l); _l = l; }
};

class retryable {};

namespace std {
  struct ostream { int next_width; };
  extern ostream cout;

  static inline
  ostream& operator<<(ostream &s, const char *str) {
    if (!str)
      str = "(null)";

    int len = strlen(str);
    cprintf("%s", str);
    while (len < s.next_width) {
      cprintf(" ");
      len++;
    }
    s.next_width = 0;
    return s;
  }

  static inline
  ostream& operator<<(ostream &s, u32 v) {
    char buf[32];
    snprintf(buf, sizeof(buf), "%d", v);
    return s << buf;
  }

  static inline
  ostream& operator<<(ostream &s, u64 v) {
    char buf[32];
    snprintf(buf, sizeof(buf), "%ld", v);
    return s << buf;
  }

  static inline
  ostream& operator<<(ostream &s, ostream& (*xform)(ostream&)) {
    return xform(s);
  }

  static inline ostream& endl(ostream &s) { s << "\n"; return s; }
  static inline ostream& left(ostream &s) { return s; }

  struct ssetw { int _n; };
  static inline ssetw setw(int n) { return { n }; }

  static inline
  ostream& operator<<(ostream &s, const ssetw &sw) {
    s.next_width = sw._n;
    return s;
  }

  class bad_alloc : public retryable {};
}

/* C++ runtime */
void *operator new(unsigned long nbytes);
void *operator new(unsigned long nbytes, void *buf);
void *operator new[](unsigned long nbytes);
void operator delete(void *p);
void operator delete[](void *p);

/* Ref: http://sourcery.mentor.com/public/cxx-abi/abi.html */
extern "C" void __cxa_pure_virtual(void);
extern "C" int  __cxa_guard_acquire(s64 *guard_object);
extern "C" void __cxa_guard_release(s64 *guard_object);
extern "C" void __cxa_guard_abort(s64 *guard_object);
extern "C" int  __cxa_atexit(void (*f)(void *), void *p, void *d);
extern void *__dso_handle;

#define NEW_DELETE_OPS(classname)                                   \
  static void* operator new(unsigned long nbytes) {                 \
    assert(nbytes == sizeof(classname));                            \
    void* p = kmalloc(sizeof(classname), #classname);               \
    if (p == nullptr)                                               \
      throw_bad_alloc();                                            \
    return p;                                                       \
  }                                                                 \
                                                                    \
  static void* operator new(unsigned long nbytes, classname *buf) { \
    assert(nbytes == sizeof(classname));                            \
    return buf;                                                     \
  }                                                                 \
                                                                    \
  static void operator delete(void *p) {                            \
    kmfree(p, sizeof(classname));                                   \
  }

template<class T>
class scoped_cleanup_obj {
 private:
  T handler_;
  bool active_;

 public:
  scoped_cleanup_obj(const T& h) : handler_(h), active_(true) {};
  ~scoped_cleanup_obj() { if (active_) handler_(); }
  void dismiss() { active_ = false; }

  void operator=(const scoped_cleanup_obj&) = delete;
  scoped_cleanup_obj(const scoped_cleanup_obj&) = delete;
  scoped_cleanup_obj(scoped_cleanup_obj&& other) :
    handler_(other.handler_), active_(other.active_) { other.dismiss(); }
};

template<class T>
scoped_cleanup_obj<T>
scoped_cleanup(const T& h)
{
  return scoped_cleanup_obj<T>(h);
}

static void inline
throw_bad_alloc()
{
#if EXCEPTIONS
  throw std::bad_alloc();
#else
  panic("bad alloc");
#endif
}
<commit_msg>Include kernel.hh in cpputil for kmalloc etc<commit_after>#pragma once

#include "kernel.hh"

#include <type_traits>
#include <utility>

using std::pair;
using std::make_pair;

template<int N>
class strbuf {
 public:
  char _buf[N];

  strbuf(const char *s) {
    strncpy(_buf, s, N);
  }

  bool operator==(const strbuf<N> &other) {
    return !strncmp(_buf, other._buf, N);
  }
};

class scoped_acquire {
 private:
  spinlock *_l;

 public:
  scoped_acquire(spinlock *l) : _l(0) { acquire(l); }
  ~scoped_acquire() { release(); }
  void release() { if (_l) { ::release(_l); _l = 0; } }
  void acquire(spinlock *l) { assert(!_l); ::acquire(l); _l = l; }
};

class retryable {};

namespace std {
  struct ostream { int next_width; };
  extern ostream cout;

  static inline
  ostream& operator<<(ostream &s, const char *str) {
    if (!str)
      str = "(null)";

    int len = strlen(str);
    cprintf("%s", str);
    while (len < s.next_width) {
      cprintf(" ");
      len++;
    }
    s.next_width = 0;
    return s;
  }

  static inline
  ostream& operator<<(ostream &s, u32 v) {
    char buf[32];
    snprintf(buf, sizeof(buf), "%d", v);
    return s << buf;
  }

  static inline
  ostream& operator<<(ostream &s, u64 v) {
    char buf[32];
    snprintf(buf, sizeof(buf), "%ld", v);
    return s << buf;
  }

  static inline
  ostream& operator<<(ostream &s, ostream& (*xform)(ostream&)) {
    return xform(s);
  }

  static inline ostream& endl(ostream &s) { s << "\n"; return s; }
  static inline ostream& left(ostream &s) { return s; }

  struct ssetw { int _n; };
  static inline ssetw setw(int n) { return { n }; }

  static inline
  ostream& operator<<(ostream &s, const ssetw &sw) {
    s.next_width = sw._n;
    return s;
  }

  class bad_alloc : public retryable {};
}

/* C++ runtime */
void *operator new(unsigned long nbytes);
void *operator new(unsigned long nbytes, void *buf);
void *operator new[](unsigned long nbytes);
void operator delete(void *p);
void operator delete[](void *p);

/* Ref: http://sourcery.mentor.com/public/cxx-abi/abi.html */
extern "C" void __cxa_pure_virtual(void);
extern "C" int  __cxa_guard_acquire(s64 *guard_object);
extern "C" void __cxa_guard_release(s64 *guard_object);
extern "C" void __cxa_guard_abort(s64 *guard_object);
extern "C" int  __cxa_atexit(void (*f)(void *), void *p, void *d);
extern void *__dso_handle;

#define NEW_DELETE_OPS(classname)                                   \
  static void* operator new(unsigned long nbytes) {                 \
    assert(nbytes == sizeof(classname));                            \
    void* p = kmalloc(sizeof(classname), #classname);               \
    if (p == nullptr)                                               \
      throw_bad_alloc();                                            \
    return p;                                                       \
  }                                                                 \
                                                                    \
  static void* operator new(unsigned long nbytes, classname *buf) { \
    assert(nbytes == sizeof(classname));                            \
    return buf;                                                     \
  }                                                                 \
                                                                    \
  static void operator delete(void *p) {                            \
    kmfree(p, sizeof(classname));                                   \
  }

template<class T>
class scoped_cleanup_obj {
 private:
  T handler_;
  bool active_;

 public:
  scoped_cleanup_obj(const T& h) : handler_(h), active_(true) {};
  ~scoped_cleanup_obj() { if (active_) handler_(); }
  void dismiss() { active_ = false; }

  void operator=(const scoped_cleanup_obj&) = delete;
  scoped_cleanup_obj(const scoped_cleanup_obj&) = delete;
  scoped_cleanup_obj(scoped_cleanup_obj&& other) :
    handler_(other.handler_), active_(other.active_) { other.dismiss(); }
};

template<class T>
scoped_cleanup_obj<T>
scoped_cleanup(const T& h)
{
  return scoped_cleanup_obj<T>(h);
}

static void inline
throw_bad_alloc()
{
#if EXCEPTIONS
  throw std::bad_alloc();
#else
  panic("bad alloc");
#endif
}
<|endoftext|>


<commit_before>/* ************************************************************************
 * Copyright 2015 Vratis, Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ************************************************************************ */

#include <mlopen/kernel_cache.hpp>

#include <iostream>
#include <iterator>

namespace mlopen {

OCLKernel KernelCache::GetKernel(const std::string& algorithm,
										const std::string& network_config) {

	std::pair<std::string, std::string> key = std::make_pair(algorithm, network_config);
#ifndef NDEBUG
	std::cout << "key: " << key.first <<" "<< key.second<< std::endl;
#endif

	auto kernel_iterator = kernel_map.find(key);
	if (kernel_iterator != kernel_map.end())
	{
#ifndef NDEBUG
		printf("kernel found\n");
#endif
		return kernel_iterator->second;
	}
	// TODO: Where should the default kernel be?
	else // return default kernel
	{
		printf("looking for default kernel (does not exist)\n");
		exit(0);
	}
}

OCLKernel KernelCache::GetKernel(cl_command_queue &queue,
										const std::string& algorithm,
										const std::string& network_config,
                                        const std::string& program_name,
                                        const std::string& kernel_name,
										const std::vector<size_t>& vld,
										const std::vector<size_t>& vgd,
                                        std::string params)
{

    if (params.length() > 0)
    {
        // Ensure only one space after the -cl-std.
        // >1 space can cause an Apple compiler bug. See clSPARSE issue #141.
        if (params.at(0) != ' ') params = " " + params;
    }

	std::pair<std::string, std::string> key = std::make_pair(algorithm, network_config);
#ifndef NDEBUG
    std::cout << "key: " << key.first << ',' << key.second << std::endl;
#endif

    auto kernel_iterator = kernel_map.find(key);
    if (kernel_iterator != kernel_map.end())
    {
#ifndef NDEBUG
		printf("kernel found\n");
#endif
        return kernel_iterator->second;
    }
    else //build program and compile the kernel;
    {
#ifndef NDEBUG
		printf("kernel not found\n");
#endif

        auto program = LoadProgram(GetContext(queue), GetDevice(queue), program_name, params);
		OCLKernel kernel(CreateKernel(program, kernel_name), vld, vgd);
        if (!network_config.empty() && !algorithm.empty()) kernel_map[key] = kernel;
        return kernel;
    }
}

KernelCache::KernelCache()
{}

}
<commit_msg>Throw exception when kernel is not found<commit_after>/* ************************************************************************
 * Copyright 2015 Vratis, Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ************************************************************************ */

#include <mlopen/kernel_cache.hpp>

#include <iostream>
#include <iterator>

namespace mlopen {

OCLKernel KernelCache::GetKernel(const std::string& algorithm,
										const std::string& network_config) {

	std::pair<std::string, std::string> key = std::make_pair(algorithm, network_config);
#ifndef NDEBUG
	std::cout << "key: " << key.first <<" "<< key.second<< std::endl;
#endif

	auto kernel_iterator = kernel_map.find(key);
	if (kernel_iterator != kernel_map.end())
	{
#ifndef NDEBUG
		printf("kernel found\n");
#endif
		return kernel_iterator->second;
	}
	else
	{
        MLOPEN_THROW("looking for default kernel (does not exist): " + algorithm + ", " + network_config);
	}
}

OCLKernel KernelCache::GetKernel(cl_command_queue &queue,
										const std::string& algorithm,
										const std::string& network_config,
                                        const std::string& program_name,
                                        const std::string& kernel_name,
										const std::vector<size_t>& vld,
										const std::vector<size_t>& vgd,
                                        std::string params)
{

    if (params.length() > 0)
    {
        // Ensure only one space after the -cl-std.
        // >1 space can cause an Apple compiler bug. See clSPARSE issue #141.
        if (params.at(0) != ' ') params = " " + params;
    }

	std::pair<std::string, std::string> key = std::make_pair(algorithm, network_config);
#ifndef NDEBUG
    std::cout << "key: " << key.first << ',' << key.second << std::endl;
#endif

    auto kernel_iterator = kernel_map.find(key);
    if (kernel_iterator != kernel_map.end())
    {
#ifndef NDEBUG
		printf("kernel found\n");
#endif
        return kernel_iterator->second;
    }
    else //build program and compile the kernel;
    {
#ifndef NDEBUG
		printf("kernel not found\n");
#endif

        auto program = LoadProgram(GetContext(queue), GetDevice(queue), program_name, params);
		OCLKernel kernel(CreateKernel(program, kernel_name), vld, vgd);
        if (!network_config.empty() && !algorithm.empty()) kernel_map[key] = kernel;
        return kernel;
    }
}

KernelCache::KernelCache()
{}

}
<|endoftext|>


<commit_before>#include "shoppinglist.h"

ShoppingList::ShoppingList(QObject *parent) : QAbstractTableModel(parent)
{
}

void ShoppingList::newItem(QString itemName, double price, int amount)
{
	if (!items.contains(itemName)) { //item is new, will insert new row
		itemRows.push_back(itemName);
		int row = rowCount();

		beginInsertRows(QModelIndex(), row, row);
		setItemPrice(itemName, price);
		setItemAmount(itemName, amount);
		endInsertRows();
	} else if (items[itemName].price == price) { //item exists, will add to the existing amount
		int row = itemRows.lastIndexOf(itemName);

		setItemAmount(itemName, items[itemName].amount + amount);
		emit dataChanged(index(row, 0), index(row, NUM_SHOPPINGLIST_PROPERTIES));
	} else { //ignore new item, price was not the same
		return;
	}
}

void ShoppingList::setItemPrice(QString itemName, double price)
{
	if (price > 0) {
		items[itemName].price = price;
	}
}

void ShoppingList::setItemAmount(QString itemName, int amount)
{
	if (amount > 0) {
		items[itemName].amount = amount;
	}
}

void ShoppingList::deleteItem(QString itemName)
{
	if (items.contains(itemName)) {
		int row = itemRows.lastIndexOf(itemName);
		beginRemoveRows(QModelIndex(), row, row);

		items.erase(items.find(itemName));
		itemRows.erase(itemRows.begin() + row);

		endRemoveRows();
	}
}

void ShoppingList::wipeList()
{
	if (items.size() > 0) {
		beginRemoveRows(QModelIndex(), 0, rowCount()-1);

		items.clear();
		itemRows.clear();

		endRemoveRows();
	}
}

void ShoppingList::deleteLastAddedItem()
{
	deleteItem(getItemName(rowCount()-1));
}

double ShoppingList::getTotalPrice()
{
	double totalAmount = 0;
	for (int i=0; i < rowCount(); i++) {
		ShoppingListItem item = items[getItemName(i)];
		totalAmount += item.amount*item.price;
	}
	return totalAmount;
}

QString ShoppingList::getItemName(int row) const
{
	if ((row >= 0) && (row < rowCount()) && (rowCount() > 0)) {
		return itemRows[row];
	} else {
		return QString();
	}
}

/**
 * QAbstractTableModel subclassing convenience functions.
 **/

void ShoppingList::setItemAmount(const QModelIndex &parent, int amount)
{
	setItemAmount(getItemName(parent.row()), amount);
}

void ShoppingList::deleteItem(const QModelIndex &parent)
{
	deleteItem(getItemName(parent.row()));
}

int ShoppingList::numItems() const
{
	return items.size();
}

/**
 * Neccessary functions for QAbstractTableModel subclassing.
 **/

int ShoppingList::rowCount(const QModelIndex &parent) const
{
	if (!parent.isValid()) {
		return numItems();
	}

	return 0;
}

int ShoppingList::columnCount(const QModelIndex &parent) const
{
	return NUM_SHOPPINGLIST_PROPERTIES;
}

QVariant ShoppingList::data(const QModelIndex &index, int role) const
{
	QString itemName = getItemName(index.row());
	if ((role == Qt::DisplayRole) && (itemName != QString())) {
		ShoppingListItem item = items[itemName];
		int column = index.column();

		switch (column) {
			case ITEM_NAME_COL:
				return itemName;
			case ITEM_PRICE_COL:
				return item.price;
			case ITEM_AMOUNT_COL:
				return item.amount;
		}
	}

	return QVariant(QVariant::Invalid);
}

Qt::ItemFlags ShoppingList::flags(const QModelIndex &index) const
{
	if (index.column() == ITEM_AMOUNT_COL) {
		return Qt::ItemIsEnabled | Qt::ItemIsEditable;
	} else {
		return Qt::NoItemFlags;
	}
}

QVariant ShoppingList::headerData(int section, Qt::Orientation orientation, int role) const
{
	if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole)) {
		switch (section) {
			case ITEM_NAME_COL:
				return QVariant(tr("Name"));
			case ITEM_PRICE_COL:
				return QVariant(tr("Price"));
			case ITEM_AMOUNT_COL:
				return QVariant(tr("Amount"));
		}
	}

	return QAbstractTableModel::headerData(section, orientation, role);
}

/**
 * QAbstractTableModel edit functions.
 **/

bool ShoppingList::setData(const QModelIndex &index, const QVariant &value, int role)
{
	if (index.column() == ITEM_AMOUNT_COL) {
		setItemAmount(getItemName(index.row()), value.toInt());
		emit dataChanged(index, index);
		return true;
	}

	return false;
}

#include <QGridLayout>
#include <QTableView>
#include <QLabel>
#include <QHeaderView>
#include <QPainter>

ShoppingListItemDelegate::ShoppingListItemDelegate(QObject *parent) : QStyledItemDelegate(parent)
{
}

void ShoppingListItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &inputOption, const QModelIndex &index) const Q_DECL_OVERRIDE
{
	QStyleOptionViewItem option = inputOption;
	option.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;
	if (index.column() == ITEM_AMOUNT_COL) {
		painter->drawText(option.rect, option.displayAlignment, index.data().toString() + " x ");
	} else if (index.column() == ITEM_PRICE_COL) {
		painter->drawText(option.rect, option.displayAlignment, index.data().toString() + " kr");
	} else {
		QStyledItemDelegate::paint(painter, inputOption, index);
	}
}

ShoppingListWidget::ShoppingListWidget(ShoppingList *list, QWidget *parent) : QWidget(parent)
{
	//view for displaying shopping list
	QTableView *listView = new QTableView;
	listView->verticalHeader()->hide();
	listView->setAlternatingRowColors(true);
	listView->setGridStyle(Qt::NoPen);
	listView->setModel(list);

	//use custom delegate for displaying each item
	listView->setItemDelegate(new ShoppingListItemDelegate);

	//layout
	QGridLayout *layout = new QGridLayout(this);
	layout->addWidget(new QLabel(tr("Sum: ")), 0, 0);
	QLabel *currSum = new QLabel("0");
	layout->addWidget(currSum, 0, 1);
	layout->addWidget(listView, 1, 0, 1, 2);
}
<commit_msg>Replace rowCount() by numItems() in shoppinglist.cpp.<commit_after>#include "shoppinglist.h"

ShoppingList::ShoppingList(QObject *parent) : QAbstractTableModel(parent)
{
}

void ShoppingList::newItem(QString itemName, double price, int amount)
{
	if (!items.contains(itemName)) { //item is new, will insert new row
		itemRows.push_back(itemName);
		int row = numItems();

		beginInsertRows(QModelIndex(), row, row);
		setItemPrice(itemName, price);
		setItemAmount(itemName, amount);
		endInsertRows();
	} else if (items[itemName].price == price) { //item exists, will add to the existing amount
		int row = itemRows.lastIndexOf(itemName);

		setItemAmount(itemName, items[itemName].amount + amount);
		emit dataChanged(index(row, 0), index(row, NUM_SHOPPINGLIST_PROPERTIES));
	} else { //ignore new item, price was not the same
		return;
	}
}

void ShoppingList::setItemPrice(QString itemName, double price)
{
	if (price > 0) {
		items[itemName].price = price;
	}
}

void ShoppingList::setItemAmount(QString itemName, int amount)
{
	if (amount > 0) {
		items[itemName].amount = amount;
	}
}

void ShoppingList::deleteItem(QString itemName)
{
	if (items.contains(itemName)) {
		int row = itemRows.lastIndexOf(itemName);
		beginRemoveRows(QModelIndex(), row, row);

		items.erase(items.find(itemName));
		itemRows.erase(itemRows.begin() + row);

		endRemoveRows();
	}
}

void ShoppingList::wipeList()
{
	if (items.size() > 0) {
		beginRemoveRows(QModelIndex(), 0, numItems()-1);

		items.clear();
		itemRows.clear();

		endRemoveRows();
	}
}

void ShoppingList::deleteLastAddedItem()
{
	deleteItem(getItemName(numItems()-1));
}

double ShoppingList::getTotalPrice()
{
	double totalAmount = 0;
	for (int i=0; i < numItems(); i++) {
		ShoppingListItem item = items[getItemName(i)];
		totalAmount += item.amount*item.price;
	}
	return totalAmount;
}

QString ShoppingList::getItemName(int row) const
{
	if ((row >= 0) && (row < numItems()) && (numItems() > 0)) {
		return itemRows[row];
	} else {
		return QString();
	}
}

/**
 * QAbstractTableModel subclassing convenience functions.
 **/

void ShoppingList::setItemAmount(const QModelIndex &parent, int amount)
{
	setItemAmount(getItemName(parent.row()), amount);
}

void ShoppingList::deleteItem(const QModelIndex &parent)
{
	deleteItem(getItemName(parent.row()));
}

int ShoppingList::numItems() const
{
	return items.size();
}

/**
 * Neccessary functions for QAbstractTableModel subclassing.
 **/

int ShoppingList::rowCount(const QModelIndex &parent) const
{
	if (!parent.isValid()) {
		return numItems();
	}

	return 0;
}

int ShoppingList::columnCount(const QModelIndex &parent) const
{
	return NUM_SHOPPINGLIST_PROPERTIES;
}

QVariant ShoppingList::data(const QModelIndex &index, int role) const
{
	QString itemName = getItemName(index.row());
	if ((role == Qt::DisplayRole) && (itemName != QString())) {
		ShoppingListItem item = items[itemName];
		int column = index.column();

		switch (column) {
			case ITEM_NAME_COL:
				return itemName;
			case ITEM_PRICE_COL:
				return item.price;
			case ITEM_AMOUNT_COL:
				return item.amount;
		}
	}

	return QVariant(QVariant::Invalid);
}

Qt::ItemFlags ShoppingList::flags(const QModelIndex &index) const
{
	if (index.column() == ITEM_AMOUNT_COL) {
		return Qt::ItemIsEnabled | Qt::ItemIsEditable;
	} else {
		return Qt::NoItemFlags;
	}
}

QVariant ShoppingList::headerData(int section, Qt::Orientation orientation, int role) const
{
	if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole)) {
		switch (section) {
			case ITEM_NAME_COL:
				return QVariant(tr("Name"));
			case ITEM_PRICE_COL:
				return QVariant(tr("Price"));
			case ITEM_AMOUNT_COL:
				return QVariant(tr("Amount"));
		}
	}

	return QAbstractTableModel::headerData(section, orientation, role);
}

/**
 * QAbstractTableModel edit functions.
 **/

bool ShoppingList::setData(const QModelIndex &index, const QVariant &value, int role)
{
	if (index.column() == ITEM_AMOUNT_COL) {
		setItemAmount(getItemName(index.row()), value.toInt());
		emit dataChanged(index, index);
		return true;
	}

	return false;
}

#include <QGridLayout>
#include <QTableView>
#include <QLabel>
#include <QHeaderView>
#include <QPainter>

ShoppingListItemDelegate::ShoppingListItemDelegate(QObject *parent) : QStyledItemDelegate(parent)
{
}

void ShoppingListItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &inputOption, const QModelIndex &index) const Q_DECL_OVERRIDE
{
	QStyleOptionViewItem option = inputOption;
	option.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;
	if (index.column() == ITEM_AMOUNT_COL) {
		painter->drawText(option.rect, option.displayAlignment, index.data().toString() + " x ");
	} else if (index.column() == ITEM_PRICE_COL) {
		painter->drawText(option.rect, option.displayAlignment, index.data().toString() + " kr");
	} else {
		QStyledItemDelegate::paint(painter, inputOption, index);
	}
}

ShoppingListWidget::ShoppingListWidget(ShoppingList *list, QWidget *parent) : QWidget(parent)
{
	//view for displaying shopping list
	QTableView *listView = new QTableView;
	listView->verticalHeader()->hide();
	listView->setAlternatingRowColors(true);
	listView->setGridStyle(Qt::NoPen);
	listView->setModel(list);

	//use custom delegate for displaying each item
	listView->setItemDelegate(new ShoppingListItemDelegate);

	//layout
	QGridLayout *layout = new QGridLayout(this);
	layout->addWidget(new QLabel(tr("Sum: ")), 0, 0);
	QLabel *currSum = new QLabel("0");
	layout->addWidget(currSum, 0, 1);
	layout->addWidget(listView, 1, 0, 1, 2);
}
<|endoftext|>


<commit_before>/////////////////////////////////////////
//
//             OpenLieroX
//
// code under LGPL, based on JasonBs work,
// enhanced by Dark Charlie and Albert Zeyer
//
//
/////////////////////////////////////////

// Sounds header file
// Created 29/7/02
// Jason Boettcher

// Disable this pseudo-warning
#ifdef _MSC_VER
#pragma warning(disable: 4786)
#pragma warning(disable: 4996)
#endif

#include <SDL.h>
#include <stdlib.h>

#include "sound/SoundsBase.h"
#include "LieroX.h"
#include "Debug.h"
#include "AuxLib.h"
#include "Cache.h"
#include "StringUtils.h"
#include "MathLib.h"
#include "Timer.h"
#include "Options.h"
#include "FindFile.h"
#include "game/Sounds.h"

#include "sound/sfx.h"
#include "sound/sfxdriver.h"

///////////////////
// Load the sounds
bool LoadSounds()
{
	if(bDedicated) return false;

	//sfxGeneral.smpChat = LoadSample("data/sounds/chat.wav",2);
	sfxGeneral.smpClick = LoadSample("data/sounds/click.wav",2);
	sfxGeneral.smpNotify = LoadSample("data/sounds/notify.wav",2);
	if( sfxGeneral.smpNotify.get() == NULL ) {
		notes << "LoadSounds: cannot load notify.wav" << endl;
		sfxGeneral.smpNotify = LoadSample("data/sounds/dirt.wav",2);	// Very funny sound
	}

	LoadSounds_Game();

	return true;
}

sfxgen_t	sfxGeneral;

#ifdef DEDICATED_ONLY

///////////////////
// Load a sample
SmartPointer<SoundSample> LoadSample(const std::string& _filename, int maxplaying) { return NULL; }

bool InitSoundSystem(int rate, int channels, int buffers) { return false; }
bool StartSoundSystem() { return false; }
bool StopSoundSystem() { return false; }
bool SetSoundVolume(int vol) { return false; }
int GetSoundVolume() { return 0; }
bool QuitSoundSystem() { return false; }
SmartPointer<SoundSample> LoadSoundSample(const std::string& filename, int maxsimulplays) { return NULL; }
bool FreeSoundSample(SoundSample* sample) { return false; }
bool PlaySoundSample(SoundSample* sample) { return false; }
void StartSound(SoundSample* smp, CVec pos, int local, int volume, CWorm *me) {}

#else // not DEDICATED_ONLY

static bool SoundSystemAvailable = false;

///////////////////
// Load a sample and cache it

SmartPointer<SoundSample> LoadSample(const std::string& _filename, int maxplaying)
{
	if(bDedicated) return NULL;
	if(!SoundSystemAvailable) return NULL;

	if(_filename.size() == 0) return NULL;

	// Try cache first
	SmartPointer<SoundSample> SampleCached = cCache.GetSound(_filename);
	if (SampleCached.get())
		return SampleCached;

	SmartPointer<SoundSample> Sample = sfx.getDriver()->load(_filename);

	if(Sample.get() && Sample->avail()) {
		// Save to cache
		cCache.SaveSound(_filename, Sample);
		return Sample;
	}

	// dont print additional warnings here, we will print all warnings inside of load
	return NULL;
}

bool InitSoundSystem(int rate, int channels, int buffers) {
	if(SoundSystemAvailable) return true;
	SoundSystemAvailable = false;

	if(bDedicated) return false;

	if(!sfx.init()) {
		errors << "InitSoundSystem failed" << endl;
		return false;
	}

	SoundSystemAvailable = true;
	notes << "SoundSystem initialised" << endl;
	return true;
}

static bool SoundSystemStarted = false;

bool StartSoundSystem() {
	if(!SoundSystemAvailable) return false;

	// TODO: this is only a workaround
	SoundSystemStarted = true;
	SetSoundVolume( tLXOptions->iSoundVolume );
	return true;
}

bool StopSoundSystem() {
	if(!SoundSystemAvailable) return false;

	// TODO: this is only a workaround
	SoundSystemStarted = false;
	if(SoundSystemAvailable)
		sfx.getDriver()->setVolume(0);
	return true;
}

bool SetSoundVolume(int vol) {
	tLXOptions->iSoundVolume = vol;
	if(!SoundSystemAvailable) return false;

	if(SoundSystemStarted) {
		sfx.getDriver()->setVolume(float(vol) / 100.0f);
		return true;
	}

	return false;
}

int GetSoundVolume()  {
	if(!SoundSystemAvailable) return 0;

	return Round(sfx.getDriver()->volume() * 100);
}

bool QuitSoundSystem() {
	if(!SoundSystemAvailable) return false;
	SoundSystemAvailable = false;

	sfx.shutDown();
	return true;
}

bool FreeSoundSample(SoundSample* sample) {
	// HINT: this gets called in the SmartPointer<> destructor, at the very end of the program
	// It is safe to call Mix_FreeChunk here though

	// no sample, so we are ready
	if(!sample) return true;

	// the destructor will free the internal sfxdriver dependend buffer
	delete sample;
	return true;
}

bool PlaySoundSample(SoundSample* sample) {
	if(!SoundSystemAvailable || !SoundSystemStarted) return false;

	if(sample == NULL)
		return false;

	sample->play(1.0f, 1.0f);
	return true;
}

///////////////////
// Play a sound in the viewport
void StartSound(SoundSample* smp, CVec pos, int local, int volume, CWorm *me)
{
	if(!SoundSystemAvailable || !SoundSystemStarted) return;

	if(smp == NULL)
		return;

//	int pan = 0;
//	int maxhearing = 750;	// Maximum distance for hearing

	// If this wasn't a sound by me, setup the volume & pan based on position
	if(!local) {
		/*float side = pos.x - me->getPos().x;
		float distance = CalculateDistance(pos,me->getPos());

		// To far
		if(distance > maxhearing)
			return;

		volume = (int)(100.0f*(1.0f-distance/maxhearing));
		pan = (int)(100*(side/maxhearing));*/

		// Check if it's in the viewport
		/*CViewport *v = me->getViewport();
		int wx = v->GetWorldX();
		int wy = v->GetWorldY();
		int l = v->GetLeft();
		int t = v->GetTop();

		// Are we inside the viewport?
		int x = (int)pos.x - wx;
		int y = (int)pos.y - wy;
		x*=2;
		y*=2;

		if(x+l+10 < l || x-10 > v->GetVirtW())
			return;
		if(y+t+10 < t || y-10 > v->GetVirtH())
			return;*/
	}

	smp->play2D(Vec(pos), 100, 1);

	// this was the old call (using BASS_SamplePlayEx):
	//PlayExSampleSoundEx(smp,0,-1,volume,pan,-1);
}

#endif

id3v1_t GetMP3Info(const std::string& file)
{
	id3v1_t info;
	// Clear the info
	memset(&info,0,sizeof(id3v1_t));

	if (file == "")
		return info;

	FILE *fp = fopen(Utf8ToSystemNative(file).c_str(),"rb");
	if (!fp)
		return info;

	// The tag begins 128 bytes before the end of the MP3 file
	if (fseek(fp,-128,SEEK_END))  {
		fclose(fp);
		return info;
	}

	// Check the header
	char header[4];
	if (!fread(&header[0],3,1,fp))  {
		fclose(fp);
		return info;
	}
	header[3] = '\0';
	if (strcmp(header,"TAG"))  {
		fclose(fp);
		return info;
	}

	// Read the ID3 tag
	if (!fread(&info,sizeof(id3v1_t),1,fp))  {
		memset(&info,0,sizeof(id3v1_t));
		fclose(fp);
		return info;
	}

	fclose(fp);

	return info;
}

template <> void SmartPointer_ObjectDeinit<SoundSample> ( SoundSample * obj )
{
	FreeSoundSample(obj);
};
<commit_msg>small fix<commit_after>/////////////////////////////////////////
//
//             OpenLieroX
//
// code under LGPL, based on JasonBs work,
// enhanced by Dark Charlie and Albert Zeyer
//
//
/////////////////////////////////////////

// Sounds header file
// Created 29/7/02
// Jason Boettcher

// Disable this pseudo-warning
#ifdef _MSC_VER
#pragma warning(disable: 4786)
#pragma warning(disable: 4996)
#endif

#include <SDL.h>
#include <cstdlib>

#include "sound/SoundsBase.h"
#include "LieroX.h"
#include "Debug.h"
#include "AuxLib.h"
#include "Cache.h"
#include "StringUtils.h"
#include "MathLib.h"
#include "Timer.h"
#include "Options.h"
#include "FindFile.h"
#include "game/Sounds.h"

#include "sound/sfx.h"
#include "sound/sfxdriver.h"

///////////////////
// Load the sounds
bool LoadSounds()
{
	if(bDedicated) return false;

	//sfxGeneral.smpChat = LoadSample("data/sounds/chat.wav",2);
	sfxGeneral.smpClick = LoadSample("data/sounds/click.wav",2);
	sfxGeneral.smpNotify = LoadSample("data/sounds/notify.wav",2);
	if( sfxGeneral.smpNotify.get() == NULL ) {
		notes << "LoadSounds: cannot load notify.wav" << endl;
		sfxGeneral.smpNotify = LoadSample("data/sounds/dirt.wav",2);	// Very funny sound
	}

	LoadSounds_Game();

	return true;
}

sfxgen_t	sfxGeneral;

#ifdef DEDICATED_ONLY

///////////////////
// Load a sample
SmartPointer<SoundSample> LoadSample(const std::string& _filename, int maxplaying) { return NULL; }

bool InitSoundSystem(int rate, int channels, int buffers) { return false; }
bool StartSoundSystem() { return false; }
bool StopSoundSystem() { return false; }
bool SetSoundVolume(int vol) { return false; }
int GetSoundVolume() { return 0; }
bool QuitSoundSystem() { return false; }
SmartPointer<SoundSample> LoadSoundSample(const std::string& filename, int maxsimulplays) { return NULL; }
bool FreeSoundSample(SoundSample* sample) { return false; }
bool PlaySoundSample(SoundSample* sample) { return false; }
void StartSound(SoundSample* smp, CVec pos, int local, int volume, CWorm *me) {}

#else // not DEDICATED_ONLY

static bool SoundSystemAvailable = false;

///////////////////
// Load a sample and cache it

SmartPointer<SoundSample> LoadSample(const std::string& _filename, int maxplaying)
{
	if(bDedicated) return NULL;
	if(!SoundSystemAvailable) return NULL;

	if(_filename.size() == 0) return NULL;

	// Try cache first
	SmartPointer<SoundSample> SampleCached = cCache.GetSound(_filename);
	if (SampleCached.get())
		return SampleCached;

	SmartPointer<SoundSample> Sample = sfx.getDriver()->load(_filename);

	if(Sample.get() && Sample->avail()) {
		// Save to cache
		cCache.SaveSound(_filename, Sample);
		return Sample;
	}

	// dont print additional warnings here, we will print all warnings inside of load
	return NULL;
}

bool InitSoundSystem(int rate, int channels, int buffers) {
	if(SoundSystemAvailable) return true;
	SoundSystemAvailable = false;

	if(bDedicated) return false;

	if(!sfx.init()) {
		errors << "InitSoundSystem failed" << endl;
		return false;
	}

	SoundSystemAvailable = true;
	notes << "SoundSystem initialised" << endl;
	return true;
}

static bool SoundSystemStarted = false;

bool StartSoundSystem() {
	if(!SoundSystemAvailable) return false;

	// TODO: this is only a workaround
	SoundSystemStarted = true;
	SetSoundVolume( tLXOptions->iSoundVolume );
	return true;
}

bool StopSoundSystem() {
	if(!SoundSystemAvailable) return false;

	// TODO: this is only a workaround
	SoundSystemStarted = false;
	if(SoundSystemAvailable)
		sfx.getDriver()->setVolume(0);
	return true;
}

bool SetSoundVolume(int vol) {
	tLXOptions->iSoundVolume = vol;
	if(!SoundSystemAvailable) return false;

	if(SoundSystemStarted) {
		sfx.getDriver()->setVolume(float(vol) / 100.0f);
		return true;
	}

	return false;
}

int GetSoundVolume()  {
	if(!SoundSystemAvailable) return 0;

	return Round(sfx.getDriver()->volume() * 100);
}

bool QuitSoundSystem() {
	if(!SoundSystemAvailable) return false;
	SoundSystemAvailable = false;

	sfx.shutDown();
	return true;
}

bool FreeSoundSample(SoundSample* sample) {
	// HINT: this gets called in the SmartPointer<> destructor, at the very end of the program
	// It is safe to call Mix_FreeChunk here though

	// no sample, so we are ready
	if(!sample) return true;

	// the destructor will free the internal sfxdriver dependend buffer
	delete sample;
	return true;
}

bool PlaySoundSample(SoundSample* sample) {
	if(!SoundSystemAvailable || !SoundSystemStarted) return false;

	if(sample == NULL)
		return false;

	sample->play(1.0f, 1.0f);
	return true;
}

///////////////////
// Play a sound in the viewport
void StartSound(SoundSample* smp, CVec pos, int local, int volume, CWorm *me)
{
	if(!SoundSystemAvailable || !SoundSystemStarted) return;

	if(smp == NULL)
		return;

//	int pan = 0;
//	int maxhearing = 750;	// Maximum distance for hearing

	// If this wasn't a sound by me, setup the volume & pan based on position
	if(!local) {
		/*float side = pos.x - me->getPos().x;
		float distance = CalculateDistance(pos,me->getPos());

		// To far
		if(distance > maxhearing)
			return;

		volume = (int)(100.0f*(1.0f-distance/maxhearing));
		pan = (int)(100*(side/maxhearing));*/

		// Check if it's in the viewport
		/*CViewport *v = me->getViewport();
		int wx = v->GetWorldX();
		int wy = v->GetWorldY();
		int l = v->GetLeft();
		int t = v->GetTop();

		// Are we inside the viewport?
		int x = (int)pos.x - wx;
		int y = (int)pos.y - wy;
		x*=2;
		y*=2;

		if(x+l+10 < l || x-10 > v->GetVirtW())
			return;
		if(y+t+10 < t || y-10 > v->GetVirtH())
			return;*/
	}

	smp->play2D(Vec(pos), 100, 1);

	// this was the old call (using BASS_SamplePlayEx):
	//PlayExSampleSoundEx(smp,0,-1,volume,pan,-1);
}

#endif

id3v1_t GetMP3Info(const std::string& file)
{
	id3v1_t info;
	// Clear the info
	memset(&info,0,sizeof(id3v1_t));

	if (file == "")
		return info;

	FILE *fp = fopen(Utf8ToSystemNative(file).c_str(),"rb");
	if (!fp)
		return info;

	// The tag begins 128 bytes before the end of the MP3 file
	if (fseek(fp,-128,SEEK_END))  {
		fclose(fp);
		return info;
	}

	// Check the header
	char header[4];
	if (!fread(&header[0],3,1,fp))  {
		fclose(fp);
		return info;
	}
	header[3] = '\0';
	if (strcmp(header,"TAG"))  {
		fclose(fp);
		return info;
	}

	// Read the ID3 tag
	if (!fread(&info,sizeof(id3v1_t),1,fp))  {
		memset(&info,0,sizeof(id3v1_t));
		fclose(fp);
		return info;
	}

	fclose(fp);

	return info;
}

template <> void SmartPointer_ObjectDeinit<SoundSample> ( SoundSample * obj )
{
	FreeSoundSample(obj);
};
<|endoftext|>


<commit_before>#pragma once

#include <cmath>
#include <vector>

namespace kdbush {

template <uint8_t I, typename T>
struct nth {
    inline static typename std::tuple_element<I, T>::type get(const T &t) {
        return std::get<I>(t);
    }
};

template <typename TPoint, typename TIndex = std::size_t>
class KDBush {

public:
    using TNumber = decltype(nth<0, TPoint>::get(std::declval<TPoint>()));

    static const uint8_t defaultNodeSize = 64;

    KDBush(const std::vector<TPoint> &points_, const uint8_t nodeSize_ = defaultNodeSize)
        : KDBush(std::begin(points_), std::end(points_), nodeSize_) {
    }

    template <typename TPointIter>
    KDBush(TPointIter points_begin,
           TPointIter points_end,
           const uint8_t nodeSize_ = defaultNodeSize)
        : nodeSize(nodeSize_) {

        const TIndex size = std::distance(points_begin, points_end);

        points.reserve(size);
        ids.reserve(size);

        for (TIndex i = 0; i < size; i++) {
            const auto p = *(points_begin + i);
            points.emplace_back(nth<0, TPoint>::get(p), nth<1, TPoint>::get(p));
            ids.push_back(i);
        }

        sortKD(0, size - 1, 0);
    }

    template <typename TOutputIter>
    void range(const TNumber minX,
               const TNumber minY,
               const TNumber maxX,
               const TNumber maxY,
               TOutputIter out) {
        range(minX, minY, maxX, maxY, out, 0, ids.size() - 1, 0);
    }

    template <typename TOutputIter>
    void within(const TNumber qx, const TNumber qy, const TNumber r, TOutputIter out) {
        within(qx, qy, r, out, 0, ids.size() - 1, 0);
    }

private:
    std::vector<TIndex> ids;
    std::vector<std::pair<TNumber, TNumber>> points;
    uint8_t nodeSize;

    template <typename TOutputIter>
    void range(const TNumber minX,
               const TNumber minY,
               const TNumber maxX,
               const TNumber maxY,
               TOutputIter out,
               const TIndex left,
               const TIndex right,
               const uint8_t axis) {

        if (right - left <= nodeSize) {
            for (auto i = left; i <= right; i++) {
                const TNumber x = std::get<0>(points[i]);
                const TNumber y = std::get<1>(points[i]);
                if (x >= minX && x <= maxX && y >= minY && y <= maxY) *out++ = ids[i];
            }
            return;
        }

        const TIndex m = (left + right) >> 1;
        const TNumber x = std::get<0>(points[m]);
        const TNumber y = std::get<1>(points[m]);

        if (x >= minX && x <= maxX && y >= minY && y <= maxY) *out++ = ids[m];

        if (axis == 0 ? minX <= x : minY <= y)
            range(minX, minY, maxX, maxY, out, left, m - 1, (axis + 1) % 2);

        if (axis == 0 ? maxX >= x : maxY >= y)
            range(minX, minY, maxX, maxY, out, m + 1, right, (axis + 1) % 2);
    }

    template <typename TOutputIter>
    void within(const TNumber qx,
                const TNumber qy,
                const TNumber r,
                TOutputIter out,
                const TIndex left,
                const TIndex right,
                const uint8_t axis) {

        const TNumber r2 = r * r;

        if (right - left <= nodeSize) {
            for (auto i = left; i <= right; i++) {
                const TNumber x = std::get<0>(points[i]);
                const TNumber y = std::get<1>(points[i]);
                if (sqDist(x, y, qx, qy) <= r2) *out++ = ids[i];
            }
            return;
        }

        const TIndex m = (left + right) >> 1;
        const TNumber x = std::get<0>(points[m]);
        const TNumber y = std::get<1>(points[m]);

        if (sqDist(x, y, qx, qy) <= r2) *out++ = ids[m];

        if (axis == 0 ? qx - r <= x : qy - r <= y)
            within(qx, qy, r, out, left, m - 1, (axis + 1) % 2);

        if (axis == 0 ? qx + r >= x : qy + r >= y)
            within(qx, qy, r, out, m + 1, right, (axis + 1) % 2);
    }

    void sortKD(const TIndex left, const TIndex right, const uint8_t axis) {
        if (right - left <= nodeSize) return;
        const TIndex m = (left + right) >> 1;
        if (axis == 0) {
            select<0>(m, left, right);
        } else {
            select<1>(m, left, right);
        }
        sortKD(left, m - 1, (axis + 1) % 2);
        sortKD(m + 1, right, (axis + 1) % 2);
    }

    template <uint8_t axis>
    void select(const TIndex k, TIndex left, TIndex right) {

        while (right > left) {
            if (right - left > 600) {
                const TIndex n = right - left + 1;
                const TIndex m = k - left + 1;
                const double z = log(n);
                const double s = 0.5 * exp(2 * z / 3);
                const double sd = 0.5 * sqrt(z * s * (n - s) / n) * (2 * m < n ? -1 : 1);
                const TIndex newLeft = std::max(left, TIndex(k - m * s / n + sd));
                const TIndex newRight = std::min(right, TIndex(k + (n - m) * s / n + sd));
                select<axis>(k, newLeft, newRight);
            }

            const TNumber t = std::get<axis>(points[k]);
            TIndex i = left;
            TIndex j = right;

            swapItem(left, k);
            if (std::get<axis>(points[right]) > t) swapItem(left, right);

            while (i < j) {
                swapItem(i, j);
                i++;
                j--;
                while (std::get<axis>(points[i]) < t) i++;
                while (std::get<axis>(points[j]) > t) j--;
            }

            if (std::get<axis>(points[left]) == t)
                swapItem(left, j);
            else {
                j++;
                swapItem(j, right);
            }

            if (j <= k) left = j + 1;
            if (k <= j) right = j - 1;
        }
    }

    void swapItem(const TIndex i, const TIndex j) {
        std::iter_swap(ids.begin() + i, ids.begin() + j);
        std::iter_swap(points.begin() + i, points.begin() + j);
    }

    TNumber sqDist(const TNumber ax, const TNumber ay, const TNumber bx, const TNumber by) {
        const TNumber dx = ax - bx;
        const TNumber dy = ay - by;
        return dx * dx + dy * dy;
    }
};

} // namespace kdbush
<commit_msg>add more headers<commit_after>#pragma once

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <tuple>
#include <vector>

namespace kdbush {

template <std::uint8_t I, typename T>
struct nth {
    inline static typename std::tuple_element<I, T>::type get(const T &t) {
        return std::get<I>(t);
    }
};

template <typename TPoint, typename TIndex = std::size_t>
class KDBush {

public:
    using TNumber = decltype(nth<0, TPoint>::get(std::declval<TPoint>()));

    static const std::uint8_t defaultNodeSize = 64;

    KDBush(const std::vector<TPoint> &points_, const std::uint8_t nodeSize_ = defaultNodeSize)
        : KDBush(std::begin(points_), std::end(points_), nodeSize_) {
    }

    template <typename TPointIter>
    KDBush(TPointIter points_begin,
           TPointIter points_end,
           const std::uint8_t nodeSize_ = defaultNodeSize)
        : nodeSize(nodeSize_) {

        const TIndex size = std::distance(points_begin, points_end);

        points.reserve(size);
        ids.reserve(size);

        for (TIndex i = 0; i < size; i++) {
            const auto p = *(points_begin + i);
            points.emplace_back(nth<0, TPoint>::get(p), nth<1, TPoint>::get(p));
            ids.push_back(i);
        }

        sortKD(0, size - 1, 0);
    }

    template <typename TOutputIter>
    void range(const TNumber minX,
               const TNumber minY,
               const TNumber maxX,
               const TNumber maxY,
               TOutputIter out) {
        range(minX, minY, maxX, maxY, out, 0, ids.size() - 1, 0);
    }

    template <typename TOutputIter>
    void within(const TNumber qx, const TNumber qy, const TNumber r, TOutputIter out) {
        within(qx, qy, r, out, 0, ids.size() - 1, 0);
    }

private:
    std::vector<TIndex> ids;
    std::vector<std::pair<TNumber, TNumber>> points;
    std::uint8_t nodeSize;

    template <typename TOutputIter>
    void range(const TNumber minX,
               const TNumber minY,
               const TNumber maxX,
               const TNumber maxY,
               TOutputIter out,
               const TIndex left,
               const TIndex right,
               const std::uint8_t axis) {

        if (right - left <= nodeSize) {
            for (auto i = left; i <= right; i++) {
                const TNumber x = std::get<0>(points[i]);
                const TNumber y = std::get<1>(points[i]);
                if (x >= minX && x <= maxX && y >= minY && y <= maxY) *out++ = ids[i];
            }
            return;
        }

        const TIndex m = (left + right) >> 1;
        const TNumber x = std::get<0>(points[m]);
        const TNumber y = std::get<1>(points[m]);

        if (x >= minX && x <= maxX && y >= minY && y <= maxY) *out++ = ids[m];

        if (axis == 0 ? minX <= x : minY <= y)
            range(minX, minY, maxX, maxY, out, left, m - 1, (axis + 1) % 2);

        if (axis == 0 ? maxX >= x : maxY >= y)
            range(minX, minY, maxX, maxY, out, m + 1, right, (axis + 1) % 2);
    }

    template <typename TOutputIter>
    void within(const TNumber qx,
                const TNumber qy,
                const TNumber r,
                TOutputIter out,
                const TIndex left,
                const TIndex right,
                const std::uint8_t axis) {

        const TNumber r2 = r * r;

        if (right - left <= nodeSize) {
            for (auto i = left; i <= right; i++) {
                const TNumber x = std::get<0>(points[i]);
                const TNumber y = std::get<1>(points[i]);
                if (sqDist(x, y, qx, qy) <= r2) *out++ = ids[i];
            }
            return;
        }

        const TIndex m = (left + right) >> 1;
        const TNumber x = std::get<0>(points[m]);
        const TNumber y = std::get<1>(points[m]);

        if (sqDist(x, y, qx, qy) <= r2) *out++ = ids[m];

        if (axis == 0 ? qx - r <= x : qy - r <= y)
            within(qx, qy, r, out, left, m - 1, (axis + 1) % 2);

        if (axis == 0 ? qx + r >= x : qy + r >= y)
            within(qx, qy, r, out, m + 1, right, (axis + 1) % 2);
    }

    void sortKD(const TIndex left, const TIndex right, const std::uint8_t axis) {
        if (right - left <= nodeSize) return;
        const TIndex m = (left + right) >> 1;
        if (axis == 0) {
            select<0>(m, left, right);
        } else {
            select<1>(m, left, right);
        }
        sortKD(left, m - 1, (axis + 1) % 2);
        sortKD(m + 1, right, (axis + 1) % 2);
    }

    template <std::uint8_t axis>
    void select(const TIndex k, TIndex left, TIndex right) {

        while (right > left) {
            if (right - left > 600) {
                const TIndex n = right - left + 1;
                const TIndex m = k - left + 1;
                const double z = log(n);
                const double s = 0.5 * exp(2 * z / 3);
                const double sd = 0.5 * sqrt(z * s * (n - s) / n) * (2 * m < n ? -1 : 1);
                const TIndex newLeft = std::max(left, TIndex(k - m * s / n + sd));
                const TIndex newRight = std::min(right, TIndex(k + (n - m) * s / n + sd));
                select<axis>(k, newLeft, newRight);
            }

            const TNumber t = std::get<axis>(points[k]);
            TIndex i = left;
            TIndex j = right;

            swapItem(left, k);
            if (std::get<axis>(points[right]) > t) swapItem(left, right);

            while (i < j) {
                swapItem(i, j);
                i++;
                j--;
                while (std::get<axis>(points[i]) < t) i++;
                while (std::get<axis>(points[j]) > t) j--;
            }

            if (std::get<axis>(points[left]) == t)
                swapItem(left, j);
            else {
                j++;
                swapItem(j, right);
            }

            if (j <= k) left = j + 1;
            if (k <= j) right = j - 1;
        }
    }

    void swapItem(const TIndex i, const TIndex j) {
        std::iter_swap(ids.begin() + i, ids.begin() + j);
        std::iter_swap(points.begin() + i, points.begin() + j);
    }

    TNumber sqDist(const TNumber ax, const TNumber ay, const TNumber bx, const TNumber by) {
        const TNumber dx = ax - bx;
        const TNumber dy = ay - by;
        return dx * dx + dy * dy;
    }
};

} // namespace kdbush
<|endoftext|>


<commit_before>/* sqlite.cpp */

//Abstracts the db functions, for future postgrsql/mysql/etc support

/*
       Licensed to the DALnet project.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you under the Apache License, Version 2.0 (the
       "License"); you may not use this file except in compliance
       with the License.  You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing,
       software distributed under the License is distributed on an
       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       KIND, either express or implied.  See the License for the
       specific language governing permissions and limitations
       under the License.
*/

#include <sqlite3>

sqlite *db;

short db_connect(char svr[64]){
	int rtn;
	rtn = sqlite3_open(svr,&db)
	if (rtn){
		return -1;
		sqlite3_close(db);
	};
};
short db_exec(int rtn,char exec[1024],int err){
	rtn = sqlite_exec(db,exec,callback,0,err);
	if (rtn!=SQLITTE_OK)return -1;
};

void db_close(){
	sqlite_close(db);
};
<commit_msg>Fixed some sqlite errors<commit_after>/* sqlite.cpp */

//Abstracts the db functions, for future postgrsql/mysql/etc support

/*
       Licensed to the DALnet project.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you under the Apache License, Version 2.0 (the
       "License"); you may not use this file except in compliance
       with the License.  You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing,
       software distributed under the License is distributed on an
       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       KIND, either express or implied.  See the License for the
       specific language governing permissions and limitations
       under the License.
*/

#include <sqlite3.h>

sqlite3 *db;

int callback(void *NotUsed, int argc, char **argv, char **azColName); //placeholder

short db_connect(char svr[64]){
	int rtn;
	rtn = sqlite3_open(svr,&db);
	if (rtn){
		return -1;
		sqlite3_close(db);
	};
};
short db_exec(int rtn,char exec[1024],char **err){
	rtn = sqlite3_exec(db,exec,callback,0,err);
	if (!rtn)return -1;
};

void db_close(){
	sqlite3_close(db);
};
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Modified by Cloudius Systems.
 * Copyright 2015 Cloudius Systems.
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "gms/version_generator.hh"
#include "types.hh"
#include "utils/serialization.hh"
#include <ostream>
#include <limits>

namespace gms {
/**
 * HeartBeat State associated with any given endpoint.
 */
class heart_beat_state {
private:
    int32_t _generation;
    int32_t _version;
public:
    bool operator==(const heart_beat_state& other) const {
        return _generation == other._generation && _version == other._version;
    }

    heart_beat_state(int32_t gen)
        : _generation(gen)
        , _version(0) {
    }

    heart_beat_state(int32_t gen, int32_t ver)
        : _generation(gen)
        , _version(ver) {
    }

    int32_t get_generation() const {
        return _generation;
    }

    void update_heart_beat() {
        _version = version_generator::get_next_version();
    }

    int32_t get_heart_beat_version() const {
        return _version;
    }

    void force_newer_generation_unsafe() {
        _generation += 1;
    }

    void force_highest_possible_version_unsafe() {
        _version = std::numeric_limits<int32_t>::max();
    }

    friend inline std::ostream& operator<<(std::ostream& os, const heart_beat_state& h) {
        return os << "{ generation = " << h._generation << ", version = " << h._version << " }";
    }

    // The following replaces HeartBeatStateSerializer from the Java code
    void serialize(bytes::iterator& out) const {
        serialize_int32(out, _generation);
        serialize_int32(out, _version);
    }

    static heart_beat_state deserialize(bytes_view& v) {
        auto generation = read_simple<int32_t>(v);
        auto version = read_simple<int32_t>(v);
        return heart_beat_state(generation, version);
    }

    size_t serialized_size() const {
        return serialize_int32_size + serialize_int32_size;
    }
};

} // gms
<commit_msg>gossip: Drop unused serialization code<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Modified by Cloudius Systems.
 * Copyright 2015 Cloudius Systems.
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "gms/version_generator.hh"
#include "types.hh"
#include "utils/serialization.hh"
#include <ostream>
#include <limits>

namespace gms {
/**
 * HeartBeat State associated with any given endpoint.
 */
class heart_beat_state {
private:
    int32_t _generation;
    int32_t _version;
public:
    bool operator==(const heart_beat_state& other) const {
        return _generation == other._generation && _version == other._version;
    }

    heart_beat_state(int32_t gen)
        : _generation(gen)
        , _version(0) {
    }

    heart_beat_state(int32_t gen, int32_t ver)
        : _generation(gen)
        , _version(ver) {
    }

    int32_t get_generation() const {
        return _generation;
    }

    void update_heart_beat() {
        _version = version_generator::get_next_version();
    }

    int32_t get_heart_beat_version() const {
        return _version;
    }

    void force_newer_generation_unsafe() {
        _generation += 1;
    }

    void force_highest_possible_version_unsafe() {
        _version = std::numeric_limits<int32_t>::max();
    }

    friend inline std::ostream& operator<<(std::ostream& os, const heart_beat_state& h) {
        return os << "{ generation = " << h._generation << ", version = " << h._version << " }";
    }
};

} // gms
<|endoftext|>


<commit_before>#include <cryptopp/osrng.h>
#include <cryptopp/secblock.h>
#include <cryptopp/elgamal.h>
#include <cryptopp/cryptlib.h>
#include <cryptopp/files.h>
#include <memory.h>
#include <string.h>
#include <gtest/gtest.h>
#include <agora-airgap/sha256.h>
#include <agora-airgap/ElGamal.h>
#include <gmpxx.h>

using namespace std;
using namespace AgoraAirgap::sha256;
using namespace CryptoPP;

TEST(Sha256Test, StringOne) {
	BYTE text1[] = {"abc"};
	BYTE hash1[SHA256_BLOCK_SIZE] = {
		0xba,0x78,0x16,0xbf,0x8f,0x01,0xcf,0xea,0x41,0x41,0x40,0xde,0x5d,0xae,0x22,0x23,
		0xb0,0x03,0x61,0xa3,0x96,0x17,0x7a,0x9c,0xb4,0x10,0xff,0x61,0xf2,0x00,0x15,0xad
	};
	BYTE buf[SHA256_BLOCK_SIZE];
	SHA256_CTX ctx;
	sha256_init(&ctx);
	sha256_update(&ctx, text1, sizeof(text1)-1);
	sha256_final(&ctx, buf);
	EXPECT_EQ(0, memcmp(hash1, buf, SHA256_BLOCK_SIZE));
}

TEST(Sha256Test, StringTwo) {
	BYTE text2[] = {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"};
	BYTE hash2[SHA256_BLOCK_SIZE] = {
		0x24,0x8d,0x6a,0x61,0xd2,0x06,0x38,0xb8,0xe5,0xc0,0x26,0x93,0x0c,0x3e,0x60,0x39,
	    0xa3,0x3c,0xe4,0x59,0x64,0xff,0x21,0x67,0xf6,0xec,0xed,0xd4,0x19,0xdb,0x06,0xc1
	};
	BYTE buf[SHA256_BLOCK_SIZE];
	SHA256_CTX ctx;
	sha256_init(&ctx);
	sha256_update(&ctx, text2, sizeof(text2)-1);
	sha256_final(&ctx, buf);
	EXPECT_EQ(0, memcmp(hash2, buf, SHA256_BLOCK_SIZE));
}

TEST(Sha256Test, StringLoopTest) {
	BYTE text3[] = {"aaaaaaaaaa"};
	BYTE hash3[SHA256_BLOCK_SIZE] = {
		0xcd,0xc7,0x6e,0x5c,0x99,0x14,0xfb,0x92,0x81,0xa1,0xc7,0xe2,0x84,0xd7,0x3e,0x67,
	    0xf1,0x80,0x9a,0x48,0xa4,0x97,0x20,0x0e,0x04,0x6d,0x39,0xcc,0xc7,0x11,0x2c,0xd0
	};
	BYTE buf[SHA256_BLOCK_SIZE];
	SHA256_CTX ctx;
	sha256_init(&ctx);
	for (int idx = 0; idx < 100000; ++idx) {
	   sha256_update(&ctx, text3, sizeof(text3)-1);
	}
	sha256_final(&ctx, buf);
	EXPECT_EQ(0, memcmp(hash3, buf, SHA256_BLOCK_SIZE));
}

/*
TEST(ElGamalUnitTest, SmallMessageDecryption) {
	mpz_t p, q, g, y, x, m,  alpha, beta;
	string sm;

	mpz_init_set_str(p, "1019", 10);
	mpz_init_set_str(m, "0", 10);
	mpz_init_set_str(q, "359", 10); //q = (p-1)/2 = 359
	mpz_init_set_str(g, "3", 10);
	mpz_init_set_str(y, "770", 10); //y = (g^x) mod p
	mpz_init_set_str(alpha, "81", 10);
	mpz_init_set_str(beta, "818", 10);
	mpz_init_set_str(x, "66", 10);

	mpz_class
		p_c(p),
		q_c(q),
		g_c(g),
		x_c(x),
		y_c(y),
		alpha_c(alpha),
		beta_c(beta);

	AgoraAirgap::ElGamal::PublicKey pk(
		p_c,
		q_c,
		g_c,
		y_c
	);

	AgoraAirgap::ElGamal::Ciphertext ctext(alpha_c, beta_c, pk);
	ElGamal::SecretKey sk(x_c, pk);
	//AgoraAirgap::ElGamal::Plaintext ptext = AgoraAirgap::ElGamal::decrypt(sk, ctext);
	//ptext.getM(m);
	//sm = string(mpz_get_str(NULL, 10, m));
	//EXPECT_EQ(0, sm.compare("134"));

	//U = r^x mod p = (81^66) mod 1019 = 508
	//U^-1  <----------> (U^-1) U  = 1 mod p -> (U^-1) U = 1 + p*n              so U^-1 = 339
	//M = (U^-1) t  mod p = (339 * 818) mod 1019 = 134
}
*/

TEST(AgoraUnitTest, SmallMessageEncryption) {

	mpz_t p, q, g, y, x, m, rand;
	string alpha, beta;

	mpz_init_set_str(p, "1019", 10);
	mpz_init_set_str(q, "509", 10); //q = (p-1)/2 = 509
	mpz_init_set_str(g, "3", 10);
	mpz_init_set_str(y, "770", 10); //y = (g^x) mod p
	mpz_init_set_str(x, "66", 10);
	mpz_init_set_str(m, "133", 10);
	mpz_init_set_str(rand, "4", 10);

	mpz_class
		p_c(p),
		q_c(q),
		g_c(g),
		x_c(x),
		y_c(y),
		rand_c(rand),
		m_c(m);

	AgoraAirgap::ElGamal::PublicKey pk(p_c,q_c, g_c, y_c);
	AgoraAirgap::ElGamal::Plaintext plaintext(m_c, pk, true);
  	AgoraAirgap::ElGamal::Ciphertext ciphertext =
	  	AgoraAirgap::ElGamal::encrypt(pk, plaintext, rand_c);
	//Random::getRandomInteger(rand, pk.q);
	//alpha = (g^random) mod p  = (3^4) mod 1019 = 81
	//U = (h^random) mod p = (770^4) mod 1019 = 508
	//M = m+1 = 134
	//beta = ( U M  ) mod p = ( 508 * 134) mod 1019 = 818

	EXPECT_EQ(0, ciphertext.alpha.get_str().compare("81"));
	EXPECT_EQ(0, ciphertext.beta.get_str().compare("818"));
}

/*
TEST(ElGamalIntegrationTest, SmallEncryptDecryptIntegration) {

	mpz_t p, q, g, y, x, m, rand;
	string alpha, beta;
	string sm;

	mpz_init_set_str(p, "1019", 10);
	mpz_init_set_str(q, "359", 10); //q = (p-1)/2 = 359
	mpz_init_set_str(g, "3", 10);
	mpz_init_set_str(y, "770", 10); //y = (g^x) mod p
	mpz_init_set_str(x, "66", 10);
	mpz_init_set_str(m, "133", 10);
		//ElGamal::Params params = ElGamal::Params(p, q, g);
		//ElGamal::SecretKey sk = params.generate();
		//ElGamal::PublicKey pk = sk.pk;
	ElGamal::PublicKey pk(p, q, g, y);
	ElGamal::SecretKey sk(x, pk);
	mpz_init(rand);
	Random::getRandomInteger(rand, pk.q);
	//alpha = (g^random) mod p  = (3^4) mod 1019 = 81    if random = rand = 4
	//U = (h^random) mod p = (770^4) mod 1019 = 508
	//M = m+1 = 134
	//beta = ( U M  ) mod p = ( 508 * 134) mod 1019 = 818
	Agora::Encrypted_answer coded_m = Agora::encryptAnswer(pk, m, rand);

	ElGamal::Plaintext ptext = Agora::decryptAnswer(sk, coded_m);
	ptext.getM(m);
	sm = string(mpz_get_str(NULL, 10, m));
	EXPECT_EQ(0, sm.compare("134"));
}*/

<commit_msg>remove commented unit tests because they refer to decryption, and we don't have any decryption code in agora-airgap<commit_after>#include <cryptopp/osrng.h>
#include <cryptopp/secblock.h>
#include <cryptopp/elgamal.h>
#include <cryptopp/cryptlib.h>
#include <cryptopp/files.h>
#include <memory.h>
#include <string.h>
#include <gtest/gtest.h>
#include <agora-airgap/sha256.h>
#include <agora-airgap/ElGamal.h>
#include <gmpxx.h>

using namespace std;
using namespace AgoraAirgap::sha256;
using namespace CryptoPP;

TEST(Sha256Test, StringOne) {
	BYTE text1[] = {"abc"};
	BYTE hash1[SHA256_BLOCK_SIZE] = {
		0xba,0x78,0x16,0xbf,0x8f,0x01,0xcf,0xea,0x41,0x41,0x40,0xde,0x5d,0xae,0x22,0x23,
		0xb0,0x03,0x61,0xa3,0x96,0x17,0x7a,0x9c,0xb4,0x10,0xff,0x61,0xf2,0x00,0x15,0xad
	};
	BYTE buf[SHA256_BLOCK_SIZE];
	SHA256_CTX ctx;
	sha256_init(&ctx);
	sha256_update(&ctx, text1, sizeof(text1)-1);
	sha256_final(&ctx, buf);
	EXPECT_EQ(0, memcmp(hash1, buf, SHA256_BLOCK_SIZE));
}

TEST(Sha256Test, StringTwo) {
	BYTE text2[] = {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"};
	BYTE hash2[SHA256_BLOCK_SIZE] = {
		0x24,0x8d,0x6a,0x61,0xd2,0x06,0x38,0xb8,0xe5,0xc0,0x26,0x93,0x0c,0x3e,0x60,0x39,
	    0xa3,0x3c,0xe4,0x59,0x64,0xff,0x21,0x67,0xf6,0xec,0xed,0xd4,0x19,0xdb,0x06,0xc1
	};
	BYTE buf[SHA256_BLOCK_SIZE];
	SHA256_CTX ctx;
	sha256_init(&ctx);
	sha256_update(&ctx, text2, sizeof(text2)-1);
	sha256_final(&ctx, buf);
	EXPECT_EQ(0, memcmp(hash2, buf, SHA256_BLOCK_SIZE));
}

TEST(Sha256Test, StringLoopTest) {
	BYTE text3[] = {"aaaaaaaaaa"};
	BYTE hash3[SHA256_BLOCK_SIZE] = {
		0xcd,0xc7,0x6e,0x5c,0x99,0x14,0xfb,0x92,0x81,0xa1,0xc7,0xe2,0x84,0xd7,0x3e,0x67,
	    0xf1,0x80,0x9a,0x48,0xa4,0x97,0x20,0x0e,0x04,0x6d,0x39,0xcc,0xc7,0x11,0x2c,0xd0
	};
	BYTE buf[SHA256_BLOCK_SIZE];
	SHA256_CTX ctx;
	sha256_init(&ctx);
	for (int idx = 0; idx < 100000; ++idx) {
	   sha256_update(&ctx, text3, sizeof(text3)-1);
	}
	sha256_final(&ctx, buf);
	EXPECT_EQ(0, memcmp(hash3, buf, SHA256_BLOCK_SIZE));
}

TEST(AgoraUnitTest, SmallMessageEncryption) {

	mpz_t p, q, g, y, x, m, rand;
	string alpha, beta;

	mpz_init_set_str(p, "1019", 10);
	mpz_init_set_str(q, "509", 10); //q = (p-1)/2 = 509
	mpz_init_set_str(g, "3", 10);
	mpz_init_set_str(y, "770", 10); //y = (g^x) mod p
	mpz_init_set_str(x, "66", 10);
	mpz_init_set_str(m, "133", 10);
	mpz_init_set_str(rand, "4", 10);

	mpz_class
		p_c(p),
		q_c(q),
		g_c(g),
		x_c(x),
		y_c(y),
		rand_c(rand),
		m_c(m);

	AgoraAirgap::ElGamal::PublicKey pk(p_c,q_c, g_c, y_c);
	AgoraAirgap::ElGamal::Plaintext plaintext(m_c, pk, true);
  	AgoraAirgap::ElGamal::Ciphertext ciphertext =
	  	AgoraAirgap::ElGamal::encrypt(pk, plaintext, rand_c);
	//alpha = (g^random) mod p  = (3^4) mod 1019 = 81
	//U = (y^random) mod p = (770^4) mod 1019 = 508
	//M = m+1 = 134
	//beta = ( U M  ) mod p = ( 508 * 134) mod 1019 = 818

	EXPECT_EQ(0, ciphertext.alpha.get_str().compare("81"));
	EXPECT_EQ(0, ciphertext.beta.get_str().compare("818"));
}
<|endoftext|>