<commit_before>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "PyBZDB.h"

namespace Python
{

static void      BZDB_dealloc       (BZDB *bzdb);
static PyObject *BZDB_getAttr       (BZDB *bzdb, char *name);
static int       BZDB_setAttr       (BZDB *bzdb, char *name, PyObject *v);
static PyObject *BZDB_repr          (BZDB *bzdb);
static int       BZDB_length        (BZDB *bzdb);
static PyObject *BZDB_subscript     (BZDB *bzdb, PyObject *key);
static int       BZDB_ass_subscript (BZDB *bzdb, PyObject *key, PyObject *value);

static PyMethodDef BZDB_methods[] = {
	{NULL, NULL, 0, NULL},
};

PyMappingMethods BZDB_mapping = {
	(inquiry) BZDB_length,			// mp_length
	(binaryfunc) BZDB_subscript,		// mp_subscript
	(objobjargproc) BZDB_ass_subscript,	// mp_ass_subscript
};

PyTypeObject BZDB_Type = {
	PyObject_HEAD_INIT(NULL)
	0,				// ob_size
	"BZDB",				// tp_name
	sizeof (BZDB),			// tp_basicsize
	0,				// tp_itemsize
	(destructor) BZDB_dealloc,	// tp_dealloc
	0,				// tp_print
	0,				// tp_getattr
	0,				// tp_setattr
	0,				// tp_compare
	(reprfunc) BZDB_repr,		// tp_repr
	0,				// tp_as_number
	0,				// tp_as_sequence
	&BZDB_mapping,			// tp_as_mapping
	0,				// tp_as_hash
	0,				// tp_call
	0,				// tp_str
	0,				// tp_getattro
	0,				// tp_setattro
	0,				// tp_flags
	0,				// tp_doc
};

static void
BZDB_dealloc (BZDB *bzdb)
{
}

static PyObject *
BZDB_getAttr (BZDB *bzdb, char *name)
{
}

static int
BZDB_setAttr (BZDB *bzdb, char *name, PyObject *v)
{
}

static PyObject *
BZDB_repr (BZDB *bzdb)
{
}

static int
BZDB_length (BZDB *bzdb)
{
}

static PyObject *
BZDB_subscript (BZDB *bzdb, PyObject *key)
{
}

static int
BZDB_ass_subscript (BZDB *bzdb, PyObject *key, PyObject *value)
{
}

}
<commit_msg>this might be how this is supposed to work...<commit_after>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "PyBZDB.h"

namespace Python
{

static void      BZDB_dealloc       (BZDB *bzdb);
static PyObject *BZDB_repr          (BZDB *bzdb);
static int       BZDB_length        (BZDB *bzdb);
static PyObject *BZDB_subscript     (BZDB *bzdb, PyObject *key);
static int       BZDB_ass_subscript (BZDB *bzdb, PyObject *key, PyObject *value);

static PyMethodDef BZDB_methods[] = {
	{NULL, NULL, 0, NULL},
};

PyMappingMethods BZDB_mapping = {
	(inquiry) BZDB_length,			// mp_length
	(binaryfunc) BZDB_subscript,		// mp_subscript
	(objobjargproc) BZDB_ass_subscript,	// mp_ass_subscript
};

PyTypeObject BZDB_Type = {
	PyObject_HEAD_INIT(NULL)
	0,				// ob_size
	"BZDB",				// tp_name
	sizeof (BZDB),			// tp_basicsize
	0,				// tp_itemsize
	(destructor) BZDB_dealloc,	// tp_dealloc
	0,				// tp_print
	0,				// tp_getattr
	0,				// tp_setattr
	0,				// tp_compare
	(reprfunc) BZDB_repr,		// tp_repr
	0,				// tp_as_number
	0,				// tp_as_sequence
	&BZDB_mapping,			// tp_as_mapping
	0,				// tp_as_hash
	0,				// tp_call
	0,				// tp_str
	0,				// tp_getattro
	0,				// tp_setattro
	0,				// tp_flags
	0,				// tp_doc
};

PyObject *
CreateBZDB ()
{
	BZDB *bzdb = (BZDB *) PyObject_NEW (BZDB, &BZDB_Type);
	return ((PyObject *) bzdb);
}

static void
BZDB_dealloc (BZDB *bzdb)
{
	PyObject_DEL (bzdb);
}

static PyObject *
BZDB_repr (BZDB *bzdb)
{
}

static int
BZDB_length (BZDB *bzdb)
{
}

static PyObject *
BZDB_subscript (BZDB *bzdb, PyObject *key)
{
	if (!PyString_Check (key)) {
		// FIXME - throw KeyError
		return NULL;
	}
	char *k = PyString_AsString (key);
	return PyString_FromString (bz_getBZDString (k).c_str ());
}

static int
BZDB_ass_subscript (BZDB *bzdb, PyObject *key, PyObject *value)
{
}

}
<|endoftext|>


<commit_before>//SteamPy

#include <steam/steam_api.h>
#include <steam/isteamfriends.h>
#include <steam/isteamugc.h>

extern "C"
{
	__declspec(dllexport) bool SteamInit();
	__declspec(dllexport) const char* GetPersonaName();
	__declspec(dllexport) int GetFriendCount();
	__declspec(dllexport) const char* GetFriendNameByIndex(int index, int flag);
	__declspec(dllexport) int GetFriendStateByIndex(int index, int flag);
	__declspec(dllexport) int GetPersonaState();
	__declspec(dllexport) uint32 GetFriendGame(int index, int flag);
	__declspec(dllexport) bool IsFriendInGame(int index, int flag);
	__declspec(dllexport) void SetPersonaName(const char* newname);
}
bool SteamInit()
{
	return SteamAPI_Init();
}

const char* GetPersonaName()
{
	return SteamFriends()->GetPersonaName();
}

int GetFriendCount(int flag)
{
	return SteamFriends()->GetFriendCount(flag);
}

const char* GetFriendNameByIndex(int index, int flag)
{
	const char* name = SteamFriends()->GetFriendPersonaName(SteamFriends()->GetFriendByIndex(index, flag));
	return name;
}

int GetFriendStateByIndex(int index, int flag)
{
	return SteamFriends()->GetFriendPersonaState(SteamFriends()->GetFriendByIndex(index, flag));
}

int GetPersonaState()
{
	return SteamFriends()->GetPersonaState();
}

uint32 GetFriendGame(int index, int flag)
{
	FriendGameInfo_t* friendgame = new FriendGameInfo_t();
	SteamFriends()->GetFriendGamePlayed(SteamFriends()->GetFriendByIndex(index, flag), friendgame);
	return friendgame->m_gameID.AppID();
}

bool IsFriendInGame(int index, int flag)
{
	return SteamFriends()->GetFriendGamePlayed(SteamFriends()->GetFriendByIndex(index, flag), new FriendGameInfo_t());
}

void SetPersonaName(const char* newname)
{
	SteamFriends()->SetPersonaName(newname);
}<commit_msg>linux<commit_after>//SteamPy

#include <steam/steam_api.h>
#include <steam/isteamfriends.h>
#include <steam/isteamugc.h>

#if defined _WIN32
	#define DLL_PUBLIC __declspec(dllexport)
#else
	#define DLL_PUBLIC __attribute__ ((visibility("default")))
#endif

extern "C"
{
	__declspec(dllexport) bool SteamInit();
	__declspec(dllexport) const char* GetPersonaName();
	__declspec(dllexport) int GetFriendCount();
	__declspec(dllexport) const char* GetFriendNameByIndex(int index, int flag);
	__declspec(dllexport) int GetFriendStateByIndex(int index, int flag);
	__declspec(dllexport) int GetPersonaState();
	__declspec(dllexport) uint32 GetFriendGame(int index, int flag);
	__declspec(dllexport) bool IsFriendInGame(int index, int flag);
	__declspec(dllexport) void SetPersonaName(const char* newname);
}

bool SteamInit()
{
	return SteamAPI_Init();
}

const char* GetPersonaName()
{
	return SteamFriends()->GetPersonaName();
}

int GetFriendCount(int flag)
{
	return SteamFriends()->GetFriendCount(flag);
}

const char* GetFriendNameByIndex(int index, int flag)
{
	const char* name = SteamFriends()->GetFriendPersonaName(SteamFriends()->GetFriendByIndex(index, flag));
	return name;
}

int GetFriendStateByIndex(int index, int flag)
{
	return SteamFriends()->GetFriendPersonaState(SteamFriends()->GetFriendByIndex(index, flag));
}

int GetPersonaState()
{
	return SteamFriends()->GetPersonaState();
}

uint32 GetFriendGame(int index, int flag)
{
	FriendGameInfo_t* friendgame = new FriendGameInfo_t();
	SteamFriends()->GetFriendGamePlayed(SteamFriends()->GetFriendByIndex(index, flag), friendgame);
	return friendgame->m_gameID.AppID();
}

bool IsFriendInGame(int index, int flag)
{
	return SteamFriends()->GetFriendGamePlayed(SteamFriends()->GetFriendByIndex(index, flag), new FriendGameInfo_t());
}

void SetPersonaName(const char* newname)
{
	SteamFriends()->SetPersonaName(newname);
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// @brief Utf8/Utf16 Helper class
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2004-2012 triagens GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Frank Celler
/// @author Achim Brandt
/// @author Copyright 2010-2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "Utf8Helper.h"

#ifdef TRI_HAVE_ICU
#include "unicode/normalizer2.h"
#include "unicode/ucasemap.h"
#else
#include "string.h"
#endif

#include "Logger/Logger.h"
#include "BasicsC/strings.h"

using namespace triagens::basics;
using namespace std;

Utf8Helper Utf8Helper::DefaultUtf8Helper;

// -----------------------------------------------------------------------------
// --SECTION--                                      constructors and destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup UTF8
/// @{
////////////////////////////////////////////////////////////////////////////////

Utf8Helper::Utf8Helper () : _coll(0) {
  setCollatorLanguage("");
}

Utf8Helper::Utf8Helper (const string& lang) : _coll(0) {
  setCollatorLanguage(lang);
}

Utf8Helper::~Utf8Helper () {
  if (_coll) {
    delete _coll;
  }
}

/*
int Utf8Helper::compareUtf8 (const char* left, size_t leftLength, const char* right, size_t rightLength) {
#ifdef TRI_HAVE_ICU
  if (!_coll) {
    LOGGER_ERROR << "no Collator in Utf8Helper::compareUtf8()!";
    return 0;
  }

  UErrorCode status = U_ZERO_ERROR;
  int result = _coll->compareUTF8(StringPiece(left, leftLength), StringPiece(right, rightLength), status);
  if(U_FAILURE(status)) {
    LOGGER_ERROR << "error in Collator::compareUTF8(...): " << u_errorName(status);
    return 0;
  }
  return result;
#else
  if (leftLength == rightLength) {
    return memcmp((const void*)left, (const void*)right, leftLength);
  }

  int result = memcmp((const void*)left, (const void*)right, leftLength < rightLength ? leftLength : rightLength);

  if (result == 0) {
    if (leftLength < rightLength) {
      return -1;
    }
    return 1;
  }
  return result;
#endif
}
*/

int Utf8Helper::compareUtf8 (const char* left, const char* right) {
#ifdef TRI_HAVE_ICU
  if (!_coll) {
    LOGGER_ERROR << "no Collator in Utf8Helper::compareUtf8()!";
    return (strcmp(left, right));
  }

  UErrorCode status = U_ZERO_ERROR;
  int result = _coll->compareUTF8(StringPiece(left), StringPiece(right), status);
  if(U_FAILURE(status)) {
    LOGGER_ERROR << "error in Collator::compareUTF8(...): " << u_errorName(status);
    return (strcmp(left, right));
  }

  return result;
#else
  return (strcmp(left, right));
#endif
}

int Utf8Helper::compareUtf16 (const uint16_t* left, size_t leftLength, const uint16_t* right, size_t rightLength) {
#ifdef TRI_HAVE_ICU
  if (!_coll) {
    LOGGER_ERROR << "no Collator in Utf8Helper::compareUtf16()!";
#endif

    if (leftLength == rightLength) {
      return memcmp((const void*)left, (const void*)right, leftLength * 2);
    }

    int result = memcmp((const void*)left, (const void*)right, leftLength < rightLength ? leftLength * 2 : rightLength * 2);

    if (result == 0) {
      if (leftLength < rightLength) {
        return -1;
      }
      return 1;
    }

    return result;
#ifdef TRI_HAVE_ICU
  }

  return _coll->compare((const UChar *)left, leftLength, (const UChar *)right, rightLength);
#endif
}

void Utf8Helper::setCollatorLanguage (const string& lang) {
#ifdef TRI_HAVE_ICU

  UErrorCode status = U_ZERO_ERROR;

  if (_coll) {
    ULocDataLocaleType type = ULOC_ACTUAL_LOCALE;
    const Locale& locale = _coll->getLocale(type, status);

    if(U_FAILURE(status)) {
      LOGGER_ERROR << "error in Collator::getLocale(...): " << u_errorName(status);
      return;
    }
    if (lang == locale.getName()) {
      return;
    }
  }

  Collator* coll;
  if (lang == "") {
    // get default collator for empty language
    coll = Collator::createInstance(status);
  }
  else {
    Locale locale(lang.c_str());
    coll = Collator::createInstance(locale, status);
  }

  if(U_FAILURE(status)) {
    LOGGER_ERROR << "error in Collator::createInstance(): " << u_errorName(status);
    if (coll) {
      delete coll;
    }
    return;
  }

  // set the default attributes for sorting:
  coll->setAttribute(UCOL_CASE_FIRST, UCOL_UPPER_FIRST, status);  // A < a
  coll->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status);  // no normalization
  coll->setAttribute(UCOL_STRENGTH, UCOL_IDENTICAL, status);      // UCOL_IDENTICAL, UCOL_PRIMARY, UCOL_SECONDARY, UCOL_TERTIARY

  if(U_FAILURE(status)) {
    LOGGER_ERROR << "error in Collator::setAttribute(...): " << u_errorName(status);
    delete coll;
    return;
  }

  if (_coll) {
    delete _coll;
  }

  _coll = coll;
#endif
}

string Utf8Helper::getCollatorLanguage () {
#ifdef TRI_HAVE_ICU
  if (_coll) {
    UErrorCode status = U_ZERO_ERROR;
    ULocDataLocaleType type = ULOC_VALID_LOCALE;
    const Locale& locale = _coll->getLocale(type, status);

    if(U_FAILURE(status)) {
      LOGGER_ERROR << "error in Collator::getLocale(...): " << u_errorName(status);
      return "";
    }
    return locale.getLanguage();
  }
#endif
  return "";
}

string Utf8Helper::getCollatorCountry () {
#ifdef TRI_HAVE_ICU
  if (_coll) {
    UErrorCode status = U_ZERO_ERROR;
    ULocDataLocaleType type = ULOC_VALID_LOCALE;
    const Locale& locale = _coll->getLocale(type, status);

    if(U_FAILURE(status)) {
      LOGGER_ERROR << "error in Collator::getLocale(...): " << u_errorName(status);
      return "";
    }
    return locale.getCountry();
  }
#endif
  return "";
}

////////////////////////////////////////////////////////////////////////////////
/// @brief Lowercase the characters in a UTF-8 string.
////////////////////////////////////////////////////////////////////////////////

string Utf8Helper::toLowerCase (const string& src) {
  int32_t utf8len = 0;
  char* utf8 = tolower(TRI_UNKNOWN_MEM_ZONE, src.c_str(), src.length(), utf8len);

  string result(utf8, utf8len);
  TRI_Free(TRI_UNKNOWN_MEM_ZONE, utf8);
  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief Lowercase the characters in a UTF-8 string.
////////////////////////////////////////////////////////////////////////////////

char* Utf8Helper::tolower (TRI_memory_zone_t* zone, const char *src, int32_t srcLength, int32_t& dstLength) {
  char* utf8_dest = 0;

  if (src == 0 || srcLength == 0) {
    utf8_dest = (char*) TRI_Allocate(zone, sizeof(char), false);
    utf8_dest[0] = '\0';
    dstLength = 0;
    return utf8_dest;
  }

#ifdef TRI_HAVE_ICU
  uint32_t options = U_FOLD_CASE_DEFAULT;
  UErrorCode status = U_ZERO_ERROR;

  string locale = getCollatorLanguage();
  LocalUCaseMapPointer csm(ucasemap_open(locale.c_str(), options, &status));

  if (U_FAILURE(status)) {
    LOGGER_ERROR << "error in ucasemap_open(...): " << u_errorName(status);
  }
  else {
    utf8_dest = (char*) TRI_Allocate(zone, (srcLength+1) * sizeof(char), false);

    dstLength = ucasemap_utf8ToLower(csm.getAlias(),
                    utf8_dest,
                    srcLength + 1,
                    src,
                    srcLength,
                    &status);

    if (status == U_BUFFER_OVERFLOW_ERROR) {
        TRI_Free(zone, utf8_dest);
        utf8_dest = (char*) TRI_Allocate(zone, (dstLength+1) * sizeof(char), false);

        dstLength = ucasemap_utf8ToLower(csm.getAlias(),
                    utf8_dest,
                    dstLength + 1,
                    src,
                    srcLength,
                    &status);
    }

    if (U_FAILURE(status)) {
      LOGGER_ERROR << "error in ucasemap_utf8ToLower(...): " << u_errorName(status);
      TRI_Free(zone, utf8_dest);
    }
    else {
      return utf8_dest;
    }
  }
#endif

  utf8_dest = TRI_LowerAsciiStringZ(zone, src);
  dstLength = strlen(utf8_dest);
  return utf8_dest;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief Uppercase the characters in a UTF-8 string.
////////////////////////////////////////////////////////////////////////////////

string Utf8Helper::toUpperCase (const string& src) {
  int32_t utf8len = 0;
  char* utf8 = toupper(TRI_UNKNOWN_MEM_ZONE, src.c_str(), src.length(), utf8len);

  string result(utf8, utf8len);
  TRI_Free(TRI_UNKNOWN_MEM_ZONE, utf8);
  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief Lowercase the characters in a UTF-8 string.
////////////////////////////////////////////////////////////////////////////////

char* Utf8Helper::toupper (TRI_memory_zone_t* zone, const char *src, int32_t srcLength, int32_t& dstLength) {
  char* utf8_dest = 0;

  if (src == 0 || srcLength == 0) {
    utf8_dest = (char*) TRI_Allocate(zone, sizeof(char), false);
    utf8_dest[0] = '\0';
    dstLength = 0;
    return utf8_dest;
  }

#ifdef TRI_HAVE_ICU
  uint32_t options = U_FOLD_CASE_DEFAULT;
  UErrorCode status = U_ZERO_ERROR;

  string locale = getCollatorLanguage();
  LocalUCaseMapPointer csm(ucasemap_open(locale.c_str(), options, &status));

  if (U_FAILURE(status)) {
    LOGGER_ERROR << "error in ucasemap_open(...): " << u_errorName(status);
  }
  else {
    utf8_dest = (char*) TRI_Allocate(zone, (srcLength+1) * sizeof(char), false);

    dstLength = ucasemap_utf8ToUpper(csm.getAlias(),
                    utf8_dest,
                    srcLength,
                    src,
                    srcLength,
                    &status);

    if (status == U_BUFFER_OVERFLOW_ERROR) {
        TRI_Free(zone, utf8_dest);
        dstLength = dstLength+1;
        utf8_dest = (char*) TRI_Allocate(zone, dstLength * sizeof(char), false);

        dstLength = ucasemap_utf8ToUpper(csm.getAlias(),
                    utf8_dest,
                    dstLength,
                    src,
                    srcLength,
                    &status);
    }

    if (U_FAILURE(status)) {
      LOGGER_ERROR << "error in ucasemap_utf8ToUpper(...): " << u_errorName(status);
      TRI_Free(zone, utf8_dest);
    }
    else {
      return utf8_dest;
    }
  }
#endif

  utf8_dest = TRI_LowerAsciiStringZ(zone, src);
  dstLength = strlen(utf8_dest);
  return utf8_dest;
}

#ifdef __cplusplus
extern "C" {
#endif

  ////////////////////////////////////////////////////////////////////////////////
/// @brief compare two utf16 strings
////////////////////////////////////////////////////////////////////////////////

int TR_compare_utf16 (const uint16_t* left, size_t leftLength, const uint16_t* right, size_t rightLength) {
  return Utf8Helper::DefaultUtf8Helper.compareUtf16(left, leftLength, right, rightLength);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief compare two utf8 strings
////////////////////////////////////////////////////////////////////////////////

int TR_compare_utf8 (const char* left, const char* right) {
  return Utf8Helper::DefaultUtf8Helper.compareUtf8(left, right);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief Lowercase the characters in a UTF-8 string (implemented in Basic/Utf8Helper.cpp)
////////////////////////////////////////////////////////////////////////////////

char* TR_tolower_utf8 (TRI_memory_zone_t* zone, const char *src, int32_t srcLength, int32_t* dstLength) {
  return Utf8Helper::DefaultUtf8Helper.tolower(zone, src, srcLength, *dstLength);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief Uppercase the characters in a UTF-8 string (implemented in Basic/Utf8Helper.cpp)
////////////////////////////////////////////////////////////////////////////////

char* TR_toupper_utf8 (TRI_memory_zone_t* zone, const char *src, int32_t srcLength, int32_t* dstLength) {
  return Utf8Helper::DefaultUtf8Helper.toupper(zone, src, srcLength, *dstLength);
}

#ifdef __cplusplus
}
#endif

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
// End:
<commit_msg>bugfix<commit_after>////////////////////////////////////////////////////////////////////////////////
/// @brief Utf8/Utf16 Helper class
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2004-2012 triagens GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Frank Celler
/// @author Achim Brandt
/// @author Copyright 2010-2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "Utf8Helper.h"

#ifdef TRI_HAVE_ICU
#include "unicode/normalizer2.h"
#include "unicode/ucasemap.h"
#else
#include "string.h"
#endif

#include "Logger/Logger.h"
#include "BasicsC/strings.h"

using namespace triagens::basics;
using namespace std;

Utf8Helper Utf8Helper::DefaultUtf8Helper;

// -----------------------------------------------------------------------------
// --SECTION--                                      constructors and destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup UTF8
/// @{
////////////////////////////////////////////////////////////////////////////////

Utf8Helper::Utf8Helper () : _coll(0) {
  setCollatorLanguage("");
}

Utf8Helper::Utf8Helper (const string& lang) : _coll(0) {
  setCollatorLanguage(lang);
}

Utf8Helper::~Utf8Helper () {
  if (_coll) {
    delete _coll;
  }
}

/*
int Utf8Helper::compareUtf8 (const char* left, size_t leftLength, const char* right, size_t rightLength) {
#ifdef TRI_HAVE_ICU
  if (!_coll) {
    LOGGER_ERROR << "no Collator in Utf8Helper::compareUtf8()!";
    return 0;
  }

  UErrorCode status = U_ZERO_ERROR;
  int result = _coll->compareUTF8(StringPiece(left, leftLength), StringPiece(right, rightLength), status);
  if(U_FAILURE(status)) {
    LOGGER_ERROR << "error in Collator::compareUTF8(...): " << u_errorName(status);
    return 0;
  }
  return result;
#else
  if (leftLength == rightLength) {
    return memcmp((const void*)left, (const void*)right, leftLength);
  }

  int result = memcmp((const void*)left, (const void*)right, leftLength < rightLength ? leftLength : rightLength);

  if (result == 0) {
    if (leftLength < rightLength) {
      return -1;
    }
    return 1;
  }
  return result;
#endif
}
*/

int Utf8Helper::compareUtf8 (const char* left, const char* right) {
#ifdef TRI_HAVE_ICU
  if (!_coll) {
    LOGGER_ERROR << "no Collator in Utf8Helper::compareUtf8()!";
    return (strcmp(left, right));
  }

  UErrorCode status = U_ZERO_ERROR;
  int result = _coll->compareUTF8(StringPiece(left), StringPiece(right), status);
  if(U_FAILURE(status)) {
    LOGGER_ERROR << "error in Collator::compareUTF8(...): " << u_errorName(status);
    return (strcmp(left, right));
  }

  return result;
#else
  return (strcmp(left, right));
#endif
}

int Utf8Helper::compareUtf16 (const uint16_t* left, size_t leftLength, const uint16_t* right, size_t rightLength) {
#ifdef TRI_HAVE_ICU
  if (!_coll) {
    LOGGER_ERROR << "no Collator in Utf8Helper::compareUtf16()!";
#endif

    if (leftLength == rightLength) {
      return memcmp((const void*)left, (const void*)right, leftLength * 2);
    }

    int result = memcmp((const void*)left, (const void*)right, leftLength < rightLength ? leftLength * 2 : rightLength * 2);

    if (result == 0) {
      if (leftLength < rightLength) {
        return -1;
      }
      return 1;
    }

    return result;
#ifdef TRI_HAVE_ICU
  }

  return _coll->compare((const UChar *)left, leftLength, (const UChar *)right, rightLength);
#endif
}

void Utf8Helper::setCollatorLanguage (const string& lang) {
#ifdef TRI_HAVE_ICU

  UErrorCode status = U_ZERO_ERROR;

  if (_coll) {
    ULocDataLocaleType type = ULOC_ACTUAL_LOCALE;
    const Locale& locale = _coll->getLocale(type, status);

    if(U_FAILURE(status)) {
      LOGGER_ERROR << "error in Collator::getLocale(...): " << u_errorName(status);
      return;
    }
    if (lang == locale.getName()) {
      return;
    }
  }

  Collator* coll;
  if (lang == "") {
    // get default collator for empty language
    coll = Collator::createInstance(status);
  }
  else {
    Locale locale(lang.c_str());
    coll = Collator::createInstance(locale, status);
  }

  if(U_FAILURE(status)) {
    LOGGER_ERROR << "error in Collator::createInstance(): " << u_errorName(status);
    if (coll) {
      delete coll;
    }
    return;
  }

  // set the default attributes for sorting:
  coll->setAttribute(UCOL_CASE_FIRST, UCOL_UPPER_FIRST, status);  // A < a
  coll->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status);  // no normalization
  coll->setAttribute(UCOL_STRENGTH, UCOL_IDENTICAL, status);      // UCOL_IDENTICAL, UCOL_PRIMARY, UCOL_SECONDARY, UCOL_TERTIARY

  if(U_FAILURE(status)) {
    LOGGER_ERROR << "error in Collator::setAttribute(...): " << u_errorName(status);
    delete coll;
    return;
  }

  if (_coll) {
    delete _coll;
  }

  _coll = coll;
#endif
}

string Utf8Helper::getCollatorLanguage () {
#ifdef TRI_HAVE_ICU
  if (_coll) {
    UErrorCode status = U_ZERO_ERROR;
    ULocDataLocaleType type = ULOC_VALID_LOCALE;
    const Locale& locale = _coll->getLocale(type, status);

    if(U_FAILURE(status)) {
      LOGGER_ERROR << "error in Collator::getLocale(...): " << u_errorName(status);
      return "";
    }
    return locale.getLanguage();
  }
#endif
  return "";
}

string Utf8Helper::getCollatorCountry () {
#ifdef TRI_HAVE_ICU
  if (_coll) {
    UErrorCode status = U_ZERO_ERROR;
    ULocDataLocaleType type = ULOC_VALID_LOCALE;
    const Locale& locale = _coll->getLocale(type, status);

    if(U_FAILURE(status)) {
      LOGGER_ERROR << "error in Collator::getLocale(...): " << u_errorName(status);
      return "";
    }
    return locale.getCountry();
  }
#endif
  return "";
}

////////////////////////////////////////////////////////////////////////////////
/// @brief Lowercase the characters in a UTF-8 string.
////////////////////////////////////////////////////////////////////////////////

string Utf8Helper::toLowerCase (const string& src) {
  int32_t utf8len = 0;
  char* utf8 = tolower(TRI_UNKNOWN_MEM_ZONE, src.c_str(), src.length(), utf8len);

  string result(utf8, utf8len);
  TRI_Free(TRI_UNKNOWN_MEM_ZONE, utf8);
  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief Lowercase the characters in a UTF-8 string.
////////////////////////////////////////////////////////////////////////////////

char* Utf8Helper::tolower (TRI_memory_zone_t* zone, const char *src, int32_t srcLength, int32_t& dstLength) {
  char* utf8_dest = 0;

  if (src == 0 || srcLength == 0) {
    utf8_dest = (char*) TRI_Allocate(zone, sizeof(char), false);
    utf8_dest[0] = '\0';
    dstLength = 0;
    return utf8_dest;
  }

#ifdef TRI_HAVE_ICU
  uint32_t options = U_FOLD_CASE_DEFAULT;
  UErrorCode status = U_ZERO_ERROR;

  string locale = getCollatorLanguage();
  LocalUCaseMapPointer csm(ucasemap_open(locale.c_str(), options, &status));

  if (U_FAILURE(status)) {
    LOGGER_ERROR << "error in ucasemap_open(...): " << u_errorName(status);
  }
  else {
    utf8_dest = (char*) TRI_Allocate(zone, (srcLength+1) * sizeof(char), false);

    dstLength = ucasemap_utf8ToLower(csm.getAlias(),
                    utf8_dest,
                    srcLength + 1,
                    src,
                    srcLength,
                    &status);

    if (status == U_BUFFER_OVERFLOW_ERROR) {
      status = U_ZERO_ERROR;
      TRI_Free(zone, utf8_dest);
      utf8_dest = (char*) TRI_Allocate(zone, (dstLength + 1) * sizeof(char), false);

      dstLength = ucasemap_utf8ToLower(csm.getAlias(),
                    utf8_dest,
                    dstLength + 1,
                    src,
                    srcLength,
                    &status);
    }

    if (U_FAILURE(status)) {
      LOGGER_ERROR << "error in ucasemap_utf8ToLower(...): " << u_errorName(status);
      TRI_Free(zone, utf8_dest);
    }
    else {
      return utf8_dest;
    }
  }
#endif

  utf8_dest = TRI_LowerAsciiStringZ(zone, src);
  dstLength = strlen(utf8_dest);
  return utf8_dest;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief Uppercase the characters in a UTF-8 string.
////////////////////////////////////////////////////////////////////////////////

string Utf8Helper::toUpperCase (const string& src) {
  int32_t utf8len = 0;
  char* utf8 = toupper(TRI_UNKNOWN_MEM_ZONE, src.c_str(), src.length(), utf8len);

  string result(utf8, utf8len);
  TRI_Free(TRI_UNKNOWN_MEM_ZONE, utf8);
  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief Lowercase the characters in a UTF-8 string.
////////////////////////////////////////////////////////////////////////////////

char* Utf8Helper::toupper (TRI_memory_zone_t* zone, const char *src, int32_t srcLength, int32_t& dstLength) {
  char* utf8_dest = 0;

  if (src == 0 || srcLength == 0) {
    utf8_dest = (char*) TRI_Allocate(zone, sizeof(char), false);
    utf8_dest[0] = '\0';
    dstLength = 0;
    return utf8_dest;
  }

#ifdef TRI_HAVE_ICU
  uint32_t options = U_FOLD_CASE_DEFAULT;
  UErrorCode status = U_ZERO_ERROR;

  string locale = getCollatorLanguage();
  LocalUCaseMapPointer csm(ucasemap_open(locale.c_str(), options, &status));

  if (U_FAILURE(status)) {
    LOGGER_ERROR << "error in ucasemap_open(...): " << u_errorName(status);
  }
  else {
    utf8_dest = (char*) TRI_Allocate(zone, (srcLength+1) * sizeof(char), false);

    dstLength = ucasemap_utf8ToUpper(csm.getAlias(),
                    utf8_dest,
                    srcLength,
                    src,
                    srcLength,
                    &status);

    if (status == U_BUFFER_OVERFLOW_ERROR) {
      status = U_ZERO_ERROR;
      TRI_Free(zone, utf8_dest);
      utf8_dest = (char*) TRI_Allocate(zone, (dstLength + 1) * sizeof(char), false);

      dstLength = ucasemap_utf8ToUpper(csm.getAlias(),
                    utf8_dest,
                    dstLength + 1,
                    src,
                    srcLength,
                    &status);
    }

    if (U_FAILURE(status)) {
      LOGGER_ERROR << "error in ucasemap_utf8ToUpper(...): " << u_errorName(status);
      TRI_Free(zone, utf8_dest);
    }
    else {
      return utf8_dest;
    }
  }
#endif

  utf8_dest = TRI_UpperAsciiStringZ(zone, src);
  dstLength = strlen(utf8_dest);
  return utf8_dest;
}

#ifdef __cplusplus
extern "C" {
#endif

  ////////////////////////////////////////////////////////////////////////////////
/// @brief compare two utf16 strings
////////////////////////////////////////////////////////////////////////////////

int TR_compare_utf16 (const uint16_t* left, size_t leftLength, const uint16_t* right, size_t rightLength) {
  return Utf8Helper::DefaultUtf8Helper.compareUtf16(left, leftLength, right, rightLength);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief compare two utf8 strings
////////////////////////////////////////////////////////////////////////////////

int TR_compare_utf8 (const char* left, const char* right) {
  return Utf8Helper::DefaultUtf8Helper.compareUtf8(left, right);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief Lowercase the characters in a UTF-8 string (implemented in Basic/Utf8Helper.cpp)
////////////////////////////////////////////////////////////////////////////////

char* TR_tolower_utf8 (TRI_memory_zone_t* zone, const char *src, int32_t srcLength, int32_t* dstLength) {
  return Utf8Helper::DefaultUtf8Helper.tolower(zone, src, srcLength, *dstLength);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief Uppercase the characters in a UTF-8 string (implemented in Basic/Utf8Helper.cpp)
////////////////////////////////////////////////////////////////////////////////

char* TR_toupper_utf8 (TRI_memory_zone_t* zone, const char *src, int32_t srcLength, int32_t* dstLength) {
  return Utf8Helper::DefaultUtf8Helper.toupper(zone, src, srcLength, *dstLength);
}

#ifdef __cplusplus
}
#endif

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
// End:
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012 Sacha Refshauge
 *
 */
// Qt 4.7+ / 5.0+ implementation of the framework.
// Currently supports: Android, Symbian, Blackberry, Maemo/Meego, Linux, Windows, Mac OSX

#include <QApplication>
#include <QUrl>
#include <QDir>
#include <QDesktopWidget>
#include <QDesktopServices>
#include <QLocale>
#include <QThread>

#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
#include <QStandardPaths>
#ifdef QT_HAS_SYSTEMINFO
#include <QScreenSaver>
#endif
#endif

#ifdef __SYMBIAN32__
#include <QSystemScreenSaver>
#include <QFeedbackHapticsEffect>
#include "SymbianMediaKeys.h"
#endif
#ifdef QT_HAS_SDL
#include "SDL/SDLJoystick.h"
#include "SDL_audio.h"
#endif
#include "QtMain.h"
#include "math/math_util.h"

#include <string.h>

InputState* input_state;

#ifdef QT_HAS_SDL
extern void mixaudio(void *userdata, Uint8 *stream, int len) {
	NativeMix((short *)stream, len / 4);
}
#endif

std::string System_GetProperty(SystemProperty prop) {
	switch (prop) {
	case SYSPROP_NAME:
#ifdef __SYMBIAN32__
		return "Qt:Symbian";
#elif defined(BLACKBERRY)
		return "Qt:Blackberry";
#elif defined(MAEMO)
		return "Qt:Maemo";
#elif defined(ANDROID)
		return "Qt:Android";
#elif defined(Q_OS_LINUX)
		return "Qt:Linux";
#elif defined(_WIN32)
		return "Qt:Windows";
#elif defined(Q_OS_MAC)
		return "Qt:Mac";
#else
		return "Qt";
#endif
	case SYSPROP_LANGREGION:
		return QLocale::system().name().toStdString();
	default:
		return "";
	}
}

int System_GetPropertyInt(SystemProperty prop) {return -1;}

void System_SendMessage(const char *command, const char *parameter) {
	if (!strcmp(command, "finish")) {
		qApp->exit(0);
	}
}

bool System_InputBoxGetString(const char *title, const char *defaultValue, char *outValue, size_t outLength)
{
	QString text = emugl->InputBoxGetQString(QString(title), QString(defaultValue));
	if (text.isEmpty())
		return false;
	strcpy(outValue, text.toStdString().c_str());
	return true;
}

void Vibrate(int length_ms) {
	if (length_ms == -1 || length_ms == -3)
		length_ms = 50;
	else if (length_ms == -2)
		length_ms = 25;
	// Symbian only for now
#if defined(__SYMBIAN32__)
	QFeedbackHapticsEffect effect;
	effect.setIntensity(0.8);
	effect.setDuration(length_ms);
	effect.start();
#endif
}

void LaunchBrowser(const char *url)
{
	QDesktopServices::openUrl(QUrl(url));
}

float CalculateDPIScale()
{
	// Sane default rather than check DPI
#ifdef __SYMBIAN32__
	return 1.4f;
#elif defined(USING_GLES2)
	return 1.2f;
#else
	return 1.0f;
#endif
}

static int mainInternal(QApplication &a)
{
#ifdef MOBILE_DEVICE
	emugl = new MainUI();
	emugl->resize(pixel_xres, pixel_yres);
	emugl->showFullScreen();
#endif
	EnableFZ();
	// Disable screensaver
#ifdef __SYMBIAN32__
	QSystemScreenSaver ssObject(emugl);
	ssObject.setScreenSaverInhibit();
	QScopedPointer<SymbianMediaKeys> mediakeys(new SymbianMediaKeys());
#elif defined(QT_HAS_SYSTEMINFO)
	QScreenSaver ssObject(emugl);
	ssObject.setScreenSaverEnabled(false);
#endif

#ifdef QT_HAS_SDL
	SDLJoystick joy(true);
	joy.startEventLoop();
	SDL_Init(SDL_INIT_AUDIO);
	SDL_AudioSpec fmt, ret_fmt;
	memset(&fmt, 0, sizeof(fmt));
	fmt.freq = 44100;
	fmt.format = AUDIO_S16;
	fmt.channels = 2;
	fmt.samples = 2048;
	fmt.callback = &mixaudio;
	fmt.userdata = (void *)0;

	if (SDL_OpenAudio(&fmt, &ret_fmt) < 0) {
		ELOG("Failed to open audio: %s", SDL_GetError());
	} else {
		if (ret_fmt.samples != fmt.samples) // Notify, but still use it
			ELOG("Output audio samples: %d (requested: %d)", ret_fmt.samples, fmt.samples);
		if (ret_fmt.freq != fmt.freq || ret_fmt.format != fmt.format || ret_fmt.channels != fmt.channels) {
			ELOG("Sound buffer format does not match requested format.");
			ELOG("Output audio freq: %d (requested: %d)", ret_fmt.freq, fmt.freq);
			ELOG("Output audio format: %d (requested: %d)", ret_fmt.format, fmt.format);
			ELOG("Output audio channels: %d (requested: %d)", ret_fmt.channels, fmt.channels);
			ELOG("Provided output format does not match requirement, turning audio off");
			SDL_CloseAudio();
		}
	}

	// Audio must be unpaused _after_ NativeInit()
	SDL_PauseAudio(0);
#else
	QScopedPointer<QThread> thread(new QThread);
	QScopedPointer<MainAudio> audio(new MainAudio());
	audio->moveToThread(thread.data());
	QObject::connect(thread.data(), SIGNAL(started()), audio.data(), SLOT(run()));
	thread->start();
#endif
	int ret = a.exec();
#ifndef QT_HAS_SDL
	thread->quit();
#endif
	return ret;
}

#ifndef QT_HAS_SDL
Q_DECL_EXPORT
#endif
int main(int argc, char *argv[])
{
#if defined(Q_OS_LINUX) && !defined(MAEMO)
	QApplication::setAttribute(Qt::AA_X11InitThreads, true);
#endif
	QApplication a(argc, argv);
	QSize res = QApplication::desktop()->screenGeometry().size();
	if (res.width() < res.height())
		res.transpose();
	pixel_xres = res.width();
	pixel_yres = res.height();
	g_dpi_scale = CalculateDPIScale();
	dp_xres = (int)(pixel_xres * g_dpi_scale); dp_yres = (int)(pixel_yres * g_dpi_scale);
	net::Init();
	std::string savegame_dir = ".";
	std::string assets_dir = ".";
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
	savegame_dir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation).toStdString();
	assets_dir = QStandardPaths::writableLocation(QStandardPaths::DataLocation).toStdString();
#elif defined(__SYMBIAN32__)
	savegame_dir = "E:/PPSSPP";
	assets_dir = "E:/PPSSPP";
#elif defined(BLACKBERRY)
	savegame_dir = "/accounts/1000/shared/misc";
	assets_dir = "app/native/assets";
#elif defined(MAEMO)
	savegame_dir = "/home/user/MyDocs/PPSSPP";
	assets_dir = "/opt/PPSSPP";
#endif
	savegame_dir += "/";
	assets_dir += "/";
	NativeInit(argc, (const char **)argv, savegame_dir.c_str(), assets_dir.c_str(), "BADCOFFEE");

	int ret = mainInternal(a);

#ifndef MOBILE_DEVICE
	exit(0);
#endif
	NativeShutdownGraphics();
#ifdef QT_HAS_SDL
	SDL_PauseAudio(1);
	SDL_CloseAudio();
#endif
	NativeShutdown();
	net::Shutdown();
	return ret;
}

<commit_msg>Qt: Terminate the thread instead of quitting. Stops an annoying popup on OSX and should speed up exit on systems that didn't like the thread still running.<commit_after>/*
 * Copyright (c) 2012 Sacha Refshauge
 *
 */
// Qt 4.7+ / 5.0+ implementation of the framework.
// Currently supports: Android, Symbian, Blackberry, Maemo/Meego, Linux, Windows, Mac OSX

#include <QApplication>
#include <QUrl>
#include <QDir>
#include <QDesktopWidget>
#include <QDesktopServices>
#include <QLocale>
#include <QThread>

#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
#include <QStandardPaths>
#ifdef QT_HAS_SYSTEMINFO
#include <QScreenSaver>
#endif
#endif

#ifdef __SYMBIAN32__
#include <QSystemScreenSaver>
#include <QFeedbackHapticsEffect>
#include "SymbianMediaKeys.h"
#endif
#ifdef QT_HAS_SDL
#include "SDL/SDLJoystick.h"
#include "SDL_audio.h"
#endif
#include "QtMain.h"
#include "math/math_util.h"

#include <string.h>

InputState* input_state;

#ifdef QT_HAS_SDL
extern void mixaudio(void *userdata, Uint8 *stream, int len) {
	NativeMix((short *)stream, len / 4);
}
#endif

std::string System_GetProperty(SystemProperty prop) {
	switch (prop) {
	case SYSPROP_NAME:
#ifdef __SYMBIAN32__
		return "Qt:Symbian";
#elif defined(BLACKBERRY)
		return "Qt:Blackberry";
#elif defined(MAEMO)
		return "Qt:Maemo";
#elif defined(ANDROID)
		return "Qt:Android";
#elif defined(Q_OS_LINUX)
		return "Qt:Linux";
#elif defined(_WIN32)
		return "Qt:Windows";
#elif defined(Q_OS_MAC)
		return "Qt:Mac";
#else
		return "Qt";
#endif
	case SYSPROP_LANGREGION:
		return QLocale::system().name().toStdString();
	default:
		return "";
	}
}

int System_GetPropertyInt(SystemProperty prop) {return -1;}

void System_SendMessage(const char *command, const char *parameter) {
	if (!strcmp(command, "finish")) {
		qApp->exit(0);
	}
}

bool System_InputBoxGetString(const char *title, const char *defaultValue, char *outValue, size_t outLength)
{
	QString text = emugl->InputBoxGetQString(QString(title), QString(defaultValue));
	if (text.isEmpty())
		return false;
	strcpy(outValue, text.toStdString().c_str());
	return true;
}

void Vibrate(int length_ms) {
	if (length_ms == -1 || length_ms == -3)
		length_ms = 50;
	else if (length_ms == -2)
		length_ms = 25;
	// Symbian only for now
#if defined(__SYMBIAN32__)
	QFeedbackHapticsEffect effect;
	effect.setIntensity(0.8);
	effect.setDuration(length_ms);
	effect.start();
#endif
}

void LaunchBrowser(const char *url)
{
	QDesktopServices::openUrl(QUrl(url));
}

float CalculateDPIScale()
{
	// Sane default rather than check DPI
#ifdef __SYMBIAN32__
	return 1.4f;
#elif defined(USING_GLES2)
	return 1.2f;
#else
	return 1.0f;
#endif
}

static int mainInternal(QApplication &a)
{
#ifdef MOBILE_DEVICE
	emugl = new MainUI();
	emugl->resize(pixel_xres, pixel_yres);
	emugl->showFullScreen();
#endif
	EnableFZ();
	// Disable screensaver
#ifdef __SYMBIAN32__
	QSystemScreenSaver ssObject(emugl);
	ssObject.setScreenSaverInhibit();
	QScopedPointer<SymbianMediaKeys> mediakeys(new SymbianMediaKeys());
#elif defined(QT_HAS_SYSTEMINFO)
	QScreenSaver ssObject(emugl);
	ssObject.setScreenSaverEnabled(false);
#endif

#ifdef QT_HAS_SDL
	SDLJoystick joy(true);
	joy.startEventLoop();
	SDL_Init(SDL_INIT_AUDIO);
	SDL_AudioSpec fmt, ret_fmt;
	memset(&fmt, 0, sizeof(fmt));
	fmt.freq = 44100;
	fmt.format = AUDIO_S16;
	fmt.channels = 2;
	fmt.samples = 2048;
	fmt.callback = &mixaudio;
	fmt.userdata = (void *)0;

	if (SDL_OpenAudio(&fmt, &ret_fmt) < 0) {
		ELOG("Failed to open audio: %s", SDL_GetError());
	} else {
		if (ret_fmt.samples != fmt.samples) // Notify, but still use it
			ELOG("Output audio samples: %d (requested: %d)", ret_fmt.samples, fmt.samples);
		if (ret_fmt.freq != fmt.freq || ret_fmt.format != fmt.format || ret_fmt.channels != fmt.channels) {
			ELOG("Sound buffer format does not match requested format.");
			ELOG("Output audio freq: %d (requested: %d)", ret_fmt.freq, fmt.freq);
			ELOG("Output audio format: %d (requested: %d)", ret_fmt.format, fmt.format);
			ELOG("Output audio channels: %d (requested: %d)", ret_fmt.channels, fmt.channels);
			ELOG("Provided output format does not match requirement, turning audio off");
			SDL_CloseAudio();
		}
	}

	// Audio must be unpaused _after_ NativeInit()
	SDL_PauseAudio(0);
#else
	QScopedPointer<QThread> thread(new QThread);
	QScopedPointer<MainAudio> audio(new MainAudio());
	audio->moveToThread(thread.data());
	QObject::connect(thread.data(), SIGNAL(started()), audio.data(), SLOT(run()));
	thread->start();
#endif
	int ret = a.exec();
#ifndef QT_HAS_SDL
	thread->terminate();
#endif
	return ret;
}

#ifndef QT_HAS_SDL
Q_DECL_EXPORT
#endif
int main(int argc, char *argv[])
{
#if defined(Q_OS_LINUX) && !defined(MAEMO)
	QApplication::setAttribute(Qt::AA_X11InitThreads, true);
#endif
	QApplication a(argc, argv);
	QSize res = QApplication::desktop()->screenGeometry().size();
	if (res.width() < res.height())
		res.transpose();
	pixel_xres = res.width();
	pixel_yres = res.height();
	g_dpi_scale = CalculateDPIScale();
	dp_xres = (int)(pixel_xres * g_dpi_scale); dp_yres = (int)(pixel_yres * g_dpi_scale);
	net::Init();
	std::string savegame_dir = ".";
	std::string assets_dir = ".";
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
	savegame_dir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation).toStdString();
	assets_dir = QStandardPaths::writableLocation(QStandardPaths::DataLocation).toStdString();
#elif defined(__SYMBIAN32__)
	savegame_dir = "E:/PPSSPP";
	assets_dir = "E:/PPSSPP";
#elif defined(BLACKBERRY)
	savegame_dir = "/accounts/1000/shared/misc";
	assets_dir = "app/native/assets";
#elif defined(MAEMO)
	savegame_dir = "/home/user/MyDocs/PPSSPP";
	assets_dir = "/opt/PPSSPP";
#endif
	savegame_dir += "/";
	assets_dir += "/";
	NativeInit(argc, (const char **)argv, savegame_dir.c_str(), assets_dir.c_str(), "BADCOFFEE");

	int ret = mainInternal(a);

#ifndef MOBILE_DEVICE
	exit(0);
#endif
	NativeShutdownGraphics();
#ifdef QT_HAS_SDL
	SDL_PauseAudio(1);
	SDL_CloseAudio();
#endif
	NativeShutdown();
	net::Shutdown();
	return ret;
}

<|endoftext|>


<commit_before>//===-- llvm/CodeGen/AsmStream.cpp - AsmStream Framework --------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains instantiations of "standard" AsmOStreams.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/AsmStream.h"

#include <unistd.h>

namespace llvm {
  raw_asm_fd_ostream asmouts(STDOUT_FILENO, false);
  raw_asm_fd_ostream asmerrs(STDERR_FILENO, false);
}
<commit_msg><commit_after>//===-- llvm/CodeGen/AsmStream.cpp - AsmStream Framework --------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains instantiations of "standard" AsmOStreams.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/AsmStream.h"

namespace llvm {
  raw_asm_fd_ostream asmouts(STDOUT_FILENO, false);
  raw_asm_fd_ostream asmerrs(STDERR_FILENO, false);
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012 Sacha Refshauge
 *
 */
// Qt 4.7+ / 5.0+ implementation of the framework.
// Currently supports: Symbian, Blackberry, Maemo/Meego, Linux, Windows, Mac OSX

#include <QApplication>
#include <QUrl>
#include <QDir>
#include <QDesktopWidget>
#include <QDesktopServices>
#include <QLocale>
#include <QThread>

#ifdef ANDROID
#include <QStandardPaths>
#endif

#ifdef __SYMBIAN32__
#include <e32std.h>
#include <QSystemScreenSaver>
#include <QFeedbackHapticsEffect>
#include "SymbianMediaKeys.h"
#endif
#ifdef QT_HAS_SDL
#include "SDL/SDLJoystick.h"
#endif
#include "QtMain.h"

#include <string.h>

InputState* input_state;

std::string System_GetProperty(SystemProperty prop) {
	switch (prop) {
	case SYSPROP_NAME:
#ifdef __SYMBIAN32__
		return "Qt:Symbian";
#elif defined(BLACKBERRY)
		return "Qt:Blackberry";
#elif defined(MAEMO)
		return "Qt:Maemo";
#elif defined(ANDROID)
		return "Qt:Android";
#elif defined(Q_OS_LINUX)
		return "Qt:Linux";
#elif defined(_WIN32)
		return "Qt:Windows";
#elif defined(Q_OS_MAC)
		return "Qt:Mac";
#else
		return "Qt";
#endif
	case SYSPROP_LANGREGION:
		return QLocale::system().name().toStdString();
	default:
		return "";
	}
}

void System_SendMessage(const char *command, const char *parameter) {
	if (!strcmp(command, "finish")) {
		qApp->exit(0);
	}
}

bool System_InputBoxGetString(const char *title, const char *defaultValue, char *outValue, size_t outLength)
{
	QString text = emugl->InputBoxGetQString(QString(title), QString(defaultValue));
	if (text.isEmpty())
		return false;
	strcpy(outValue, text.toStdString().c_str());
	return true;
}

void Vibrate(int length_ms) {
	if (length_ms == -1 || length_ms == -3)
		length_ms = 50;
	else if (length_ms == -2)
		length_ms = 25;
	// Symbian only for now
#if defined(__SYMBIAN32__)
	QFeedbackHapticsEffect effect;
	effect.setIntensity(0.8);
	effect.setDuration(length_ms);
	effect.start();
#endif
}

void LaunchBrowser(const char *url)
{
	QDesktopServices::openUrl(QUrl(url));
}

float CalculateDPIScale()
{
	// Sane default rather than check DPI
#ifdef __SYMBIAN32__
	return 1.4f;
#elif defined(USING_GLES2)
	return 1.2f;
#else
	return 1.0f;
#endif
}

static int mainInternal(QApplication &a)
{
#ifdef MOBILE_DEVICE
	emugl = new MainUI();
	emugl->resize(pixel_xres, pixel_yres);
	emugl->showFullScreen();
#endif
#ifdef __SYMBIAN32__
	// Set RunFast hardware mode for VFPv2.
	User::SetFloatingPointMode(EFpModeRunFast);
	// Disable screensaver
	QScopedPointer<QSystemScreenSaver> ssObject(new QSystemScreenSaver(emugl));
	ssObject->setScreenSaverInhibit();
	QScopedPointer<SymbianMediaKeys> mediakeys(new SymbianMediaKeys());
#endif

	QScopedPointer<QThread> thread(new QThread);
	QScopedPointer<MainAudio> audio(new MainAudio());
	audio->moveToThread(thread.data());
	QObject::connect(thread.data(), SIGNAL(started()), audio.data(), SLOT(run()));
	thread->start();

#ifdef QT_HAS_SDL
	SDLJoystick joy(true);
	joy.startEventLoop();
#endif
	int ret = a.exec();
	thread->quit();
	return ret;
}

#ifndef QT_HAS_SDL
Q_DECL_EXPORT
#endif
int main(int argc, char *argv[])
{
#if defined(Q_OS_LINUX) && !defined(MAEMO)
	QApplication::setAttribute(Qt::AA_X11InitThreads, true);
#endif
	QApplication a(argc, argv);
	QSize res = QApplication::desktop()->screenGeometry().size();
	if (res.width() < res.height())
		res.transpose();
	pixel_xres = res.width();
	pixel_yres = res.height();
	g_dpi_scale = CalculateDPIScale();
	dp_xres = (int)(pixel_xres * g_dpi_scale); dp_yres = (int)(pixel_yres * g_dpi_scale);
	net::Init();
#ifdef __SYMBIAN32__
	const char *savegame_dir = "E:/PPSSPP/";
	const char *assets_dir = "E:/PPSSPP/";
#elif defined(BLACKBERRY)
	const char *savegame_dir = "/accounts/1000/shared/misc/";
	const char *assets_dir = "app/native/assets/";
#elif defined(MAEMO)
	const char *savegame_dir = "/home/user/MyDocs/PPSSPP/";
	const char *assets_dir = "/opt/PPSSPP/";
#elif defined(ANDROID)
	const char *savegame_dir = QStandardPaths::standardLocations(QStandardPaths::HomeLocation).at(0).toStdString().c_str();
	const char *assets_dir = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation).at(0).toStdString().c_str();
	setenv("QT_USE_ANDROID_NATIVE_DIALOGS", "1", 1); // Which Qt version does this need?
#else
	const char *savegame_dir = "./";
	const char *assets_dir = "./";
#endif
	NativeInit(argc, (const char **)argv, savegame_dir, assets_dir, "BADCOFFEE");

	int ret = mainInternal(a);

	NativeShutdown();
	net::Shutdown();
	return ret;
}

<commit_msg>Qt: Use SDL Audio where available. Should give consistent audio amongst Linux platforms.<commit_after>/*
 * Copyright (c) 2012 Sacha Refshauge
 *
 */
// Qt 4.7+ / 5.0+ implementation of the framework.
// Currently supports: Symbian, Blackberry, Maemo/Meego, Linux, Windows, Mac OSX

#include <QApplication>
#include <QUrl>
#include <QDir>
#include <QDesktopWidget>
#include <QDesktopServices>
#include <QLocale>
#include <QThread>

#ifdef ANDROID
#include <QStandardPaths>
#endif

#ifdef __SYMBIAN32__
#include <e32std.h>
#include <QSystemScreenSaver>
#include <QFeedbackHapticsEffect>
#include "SymbianMediaKeys.h"
#endif
#ifdef QT_HAS_SDL
#include "SDL/SDLJoystick.h"
#include "SDL_audio.h"
#endif
#include "QtMain.h"

#include <string.h>

InputState* input_state;

#ifdef QT_HAS_SDL
extern void mixaudio(void *userdata, Uint8 *stream, int len) {
	NativeMix((short *)stream, len / 4);
}
#endif

std::string System_GetProperty(SystemProperty prop) {
	switch (prop) {
	case SYSPROP_NAME:
#ifdef __SYMBIAN32__
		return "Qt:Symbian";
#elif defined(BLACKBERRY)
		return "Qt:Blackberry";
#elif defined(MAEMO)
		return "Qt:Maemo";
#elif defined(ANDROID)
		return "Qt:Android";
#elif defined(Q_OS_LINUX)
		return "Qt:Linux";
#elif defined(_WIN32)
		return "Qt:Windows";
#elif defined(Q_OS_MAC)
		return "Qt:Mac";
#else
		return "Qt";
#endif
	case SYSPROP_LANGREGION:
		return QLocale::system().name().toStdString();
	default:
		return "";
	}
}

void System_SendMessage(const char *command, const char *parameter) {
	if (!strcmp(command, "finish")) {
		qApp->exit(0);
	}
}

bool System_InputBoxGetString(const char *title, const char *defaultValue, char *outValue, size_t outLength)
{
	QString text = emugl->InputBoxGetQString(QString(title), QString(defaultValue));
	if (text.isEmpty())
		return false;
	strcpy(outValue, text.toStdString().c_str());
	return true;
}

void Vibrate(int length_ms) {
	if (length_ms == -1 || length_ms == -3)
		length_ms = 50;
	else if (length_ms == -2)
		length_ms = 25;
	// Symbian only for now
#if defined(__SYMBIAN32__)
	QFeedbackHapticsEffect effect;
	effect.setIntensity(0.8);
	effect.setDuration(length_ms);
	effect.start();
#endif
}

void LaunchBrowser(const char *url)
{
	QDesktopServices::openUrl(QUrl(url));
}

float CalculateDPIScale()
{
	// Sane default rather than check DPI
#ifdef __SYMBIAN32__
	return 1.4f;
#elif defined(USING_GLES2)
	return 1.2f;
#else
	return 1.0f;
#endif
}

static int mainInternal(QApplication &a)
{
#ifdef MOBILE_DEVICE
	emugl = new MainUI();
	emugl->resize(pixel_xres, pixel_yres);
	emugl->showFullScreen();
#endif
#ifdef __SYMBIAN32__
	// Set RunFast hardware mode for VFPv2.
	User::SetFloatingPointMode(EFpModeRunFast);
	// Disable screensaver
	QScopedPointer<QSystemScreenSaver> ssObject(new QSystemScreenSaver(emugl));
	ssObject->setScreenSaverInhibit();
	QScopedPointer<SymbianMediaKeys> mediakeys(new SymbianMediaKeys());
#endif

#ifdef QT_HAS_SDL
	SDLJoystick joy(true);
	joy.startEventLoop();
	SDL_Init(SDL_INIT_AUDIO);
	SDL_AudioSpec fmt, ret_fmt;
	memset(&fmt, 0, sizeof(fmt));
	fmt.freq = 44100;
	fmt.format = AUDIO_S16;
	fmt.channels = 2;
	fmt.samples = 2048;
	fmt.callback = &mixaudio;
	fmt.userdata = (void *)0;

	if (SDL_OpenAudio(&fmt, &ret_fmt) < 0) {
		ELOG("Failed to open audio: %s", SDL_GetError());
	} else {
		if (ret_fmt.freq != 44100 || ret_fmt.format != AUDIO_S16 || ret_fmt.channels != 2 || fmt.samples != 2048) {
			ELOG("Sound buffer format does not match requested format.");
			ELOG("Output audio freq: %d (requested: %d)", ret_fmt.freq, 44100);
			ELOG("Output audio format: %d (requested: %d)", ret_fmt.format, AUDIO_S16);
			ELOG("Output audio channels: %d (requested: %d)", ret_fmt.channels, 2);
			ELOG("Output audio samples: %d (requested: %d)", ret_fmt.samples, 2048);
		}

		if (ret_fmt.freq != 44100 || ret_fmt.format != AUDIO_S16 || ret_fmt.channels != 2) {
			ELOG("Provided output format does not match requirement, turning audio off");
			SDL_CloseAudio();
		} else {
			ELOG("Provided output audio format is usable, thus using it");
		}
	}

	// Audio must be unpaused _after_ NativeInit()
	SDL_PauseAudio(0);
#else
	QScopedPointer<QThread> thread(new QThread);
	QScopedPointer<MainAudio> audio(new MainAudio());
	audio->moveToThread(thread.data());
	QObject::connect(thread.data(), SIGNAL(started()), audio.data(), SLOT(run()));
	thread->start();
#endif
	int ret = a.exec();
#ifndef QT_HAS_SDL
	thread->quit();
#endif
	return ret;
}

#ifndef QT_HAS_SDL
Q_DECL_EXPORT
#endif
int main(int argc, char *argv[])
{
#if defined(Q_OS_LINUX) && !defined(MAEMO)
	QApplication::setAttribute(Qt::AA_X11InitThreads, true);
#endif
	QApplication a(argc, argv);
	QSize res = QApplication::desktop()->screenGeometry().size();
	if (res.width() < res.height())
		res.transpose();
	pixel_xres = res.width();
	pixel_yres = res.height();
	g_dpi_scale = CalculateDPIScale();
	dp_xres = (int)(pixel_xres * g_dpi_scale); dp_yres = (int)(pixel_yres * g_dpi_scale);
	net::Init();
#ifdef __SYMBIAN32__
	const char *savegame_dir = "E:/PPSSPP/";
	const char *assets_dir = "E:/PPSSPP/";
#elif defined(BLACKBERRY)
	const char *savegame_dir = "/accounts/1000/shared/misc/";
	const char *assets_dir = "app/native/assets/";
#elif defined(MAEMO)
	const char *savegame_dir = "/home/user/MyDocs/PPSSPP/";
	const char *assets_dir = "/opt/PPSSPP/";
#elif defined(ANDROID)
	const char *savegame_dir = QStandardPaths::standardLocations(QStandardPaths::HomeLocation).at(0).toStdString().c_str();
	const char *assets_dir = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation).at(0).toStdString().c_str();
	setenv("QT_USE_ANDROID_NATIVE_DIALOGS", "1", 1); // Which Qt version does this need?
#else
	const char *savegame_dir = "./";
	const char *assets_dir = "./";
#endif
	NativeInit(argc, (const char **)argv, savegame_dir, assets_dir, "BADCOFFEE");

	int ret = mainInternal(a);

#ifndef MOBILE_DEVICE
	exit(0);
#endif
	NativeShutdownGraphics();
	SDL_PauseAudio(1);
	SDL_CloseAudio();
	NativeShutdown();
	net::Shutdown();
	return ret;
}

<|endoftext|>


<commit_before>/** Copyright (C) 2016 European Spallation Source */

#include <cspec/CSPECData.h>
#include <cspecgen/CspecArgs.h>
#include <cstring>
#include <inttypes.h>
#include <iostream>
#include <libs/include/Socket.h>
#include <libs/include/Timer.h>
#include <libs/include/gccintel.h>
#include <unistd.h>

using namespace std;

const int TSC_MHZ = 2900;

int main(int argc, char *argv[]) {
  DGArgs opts(argc, argv); // Parse command line opts

  char buffer[9000];
  unsigned int seqno = 1;

  const int B1M = 1000000;
  Socket::Endpoint local("0.0.0.0", 0);
  Socket::Endpoint remote(opts.dest_ip.c_str(), opts.port);

  UDPClient DataSource(local, remote);
  DataSource.buflen(opts.buflen);
  DataSource.setbuffers(opts.sndbuf, 0);
  DataSource.printbuffers();

  CSPECData cspec;
  int ndata = 100;
  int size = cspec.generate(buffer, 9000, ndata);
  assert(size == ndata * cspec.datasize);

  uint64_t tx_total = 0;
  uint64_t tx = 0;
  uint64_t txp = 0;
  uint64_t tsc0 = rdtsc();
  uint64_t tsc1 = rdtsc();
  uint64_t tsc;
  for (;;) {
    tsc = rdtsc();
    if (unlikely((tx_total + tx) >= (long unsigned int)opts.txGB * 1000000000) {
      cout << "Sent " << tx_total + tx << " bytes." << endl;
      cout << "done" << endl;
      exit(0);
    }

    // Sleep to throttle down speed
    if (unlikely((tsc - tsc1) >= TSC_MHZ * 10000)) {
      usleep(opts.speed_level * 1000);
      tsc1 = rdtsc();
    }

    // Send data
    int wrsize = DataSource.send(buffer, size);
    if (wrsize > 0) {
      tx += wrsize;
      txp++;
      seqno++;
    } else {
      cout << "unable to send" << endl;
    }

    if (unlikely(((tsc - tsc0) / TSC_MHZ) >= opts.updint * 1000000)) {
      tx_total += tx;
      printf("Tx rate: %8.2f Mbps, tx %5" PRIu64 " MB (total: %7" PRIu64
             " MB) %ld usecs\n",
             tx * 8.0 / (((tsc - tsc0) / TSC_MHZ) / 1000000.0) / B1M, tx / B1M,
             tx_total / B1M, ((tsc - tsc0) / TSC_MHZ));
      tx = 0;
      tsc0 = rdtsc();
    }
  }
}
<commit_msg>ooops missing parenthesis<commit_after>/** Copyright (C) 2016 European Spallation Source */

#include <cspec/CSPECData.h>
#include <cspecgen/CspecArgs.h>
#include <cstring>
#include <inttypes.h>
#include <iostream>
#include <libs/include/Socket.h>
#include <libs/include/Timer.h>
#include <libs/include/gccintel.h>
#include <unistd.h>

using namespace std;

const int TSC_MHZ = 2900;

int main(int argc, char *argv[]) {
  DGArgs opts(argc, argv); // Parse command line opts

  char buffer[9000];
  unsigned int seqno = 1;

  const int B1M = 1000000;
  Socket::Endpoint local("0.0.0.0", 0);
  Socket::Endpoint remote(opts.dest_ip.c_str(), opts.port);

  UDPClient DataSource(local, remote);
  DataSource.buflen(opts.buflen);
  DataSource.setbuffers(opts.sndbuf, 0);
  DataSource.printbuffers();

  CSPECData cspec;
  int ndata = 100;
  int size = cspec.generate(buffer, 9000, ndata);
  assert(size == ndata * cspec.datasize);

  uint64_t tx_total = 0;
  uint64_t tx = 0;
  uint64_t txp = 0;
  uint64_t tsc0 = rdtsc();
  uint64_t tsc1 = rdtsc();
  uint64_t tsc;
  for (;;) {
    tsc = rdtsc();
    if (unlikely((tx_total + tx) >= (long unsigned int)opts.txGB * 1000000000)) {
      cout << "Sent " << tx_total + tx << " bytes." << endl;
      cout << "done" << endl;
      exit(0);
    }

    // Sleep to throttle down speed
    if (unlikely((tsc - tsc1) >= TSC_MHZ * 10000)) {
      usleep(opts.speed_level * 1000);
      tsc1 = rdtsc();
    }

    // Send data
    int wrsize = DataSource.send(buffer, size);
    if (wrsize > 0) {
      tx += wrsize;
      txp++;
      seqno++;
    } else {
      cout << "unable to send" << endl;
    }

    if (unlikely(((tsc - tsc0) / TSC_MHZ) >= opts.updint * 1000000)) {
      tx_total += tx;
      printf("Tx rate: %8.2f Mbps, tx %5" PRIu64 " MB (total: %7" PRIu64
             " MB) %ld usecs\n",
             tx * 8.0 / (((tsc - tsc0) / TSC_MHZ) / 1000000.0) / B1M, tx / B1M,
             tx_total / B1M, ((tsc - tsc0) / TSC_MHZ));
      tx = 0;
      tsc0 = rdtsc();
    }
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2003 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __HASHMAP_HH__
#define __HASHMAP_HH__

#if defined(__GNUC__) && __GNUC__ >= 3
#include <ext/hash_map>
#else
#include <hash_map>
#endif

#include <string>

#include "sim/host.hh"

#if defined(__GNUC__) && __GNUC__ >= 3
    #define __hash_namespace __gnu_cxx
#else
    #define __hash_namespace std
#endif

namespace m5 {
    using ::__hash_namespace::hash_multimap;
    using ::__hash_namespace::hash_map;
    using ::__hash_namespace::hash;
}

///////////////////////////////////
// Some default Hashing Functions
//

namespace __hash_namespace {
    template<>
    struct hash<uint64_t> {
        size_t operator()(uint64_t r) const {
            return r;
        }
    };

    template<>
    struct hash<Counter> {
        size_t operator()(Counter r) const {
            return r;
        };
    };

    template<>
    struct hash<std::string> {
        size_t operator()(const std::string &s) const {
            return(__stl_hash_string(s.c_str()));
        }
    };
}

#endif // __HASHMAP_HH__
<commit_msg>Make the simulator compile on an Itanium.<commit_after>/*
 * Copyright (c) 2003 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __HASHMAP_HH__
#define __HASHMAP_HH__

#if defined(__GNUC__) && __GNUC__ >= 3
#include <ext/hash_map>
#else
#include <hash_map>
#endif

#include <string>

#include "sim/host.hh"

#if defined(__GNUC__) && __GNUC__ >= 3
    #define __hash_namespace __gnu_cxx
#else
    #define __hash_namespace std
#endif

namespace m5 {
    using ::__hash_namespace::hash_multimap;
    using ::__hash_namespace::hash_map;
    using ::__hash_namespace::hash;
}

///////////////////////////////////
// Some default Hashing Functions
//

namespace __hash_namespace {
#if !defined(__LP64__)
    template<>
    struct hash<uint64_t> {
        size_t operator()(uint64_t r) const {
            return r;
        }
    };

    template<>
    struct hash<int64_t> {
        size_t operator()(int64_t r) const {
            return r;
        };
    };
#endif

    template<>
    struct hash<std::string> {
        size_t operator()(const std::string &s) const {
            return(__stl_hash_string(s.c_str()));
        }
    };
}

#endif // __HASHMAP_HH__
<|endoftext|>


<commit_before>#include <iostream>

#define NOMINMAX // fckng Windows

#include "vtrc-client/vtrc-client.h"
#include "vtrc-common/vtrc-thread-pool.h"
#include "vtrc-common/vtrc-stub-wrapper.h"
#include "vtrc-common/vtrc-random-device.h"

#include "protocol/hello.pb.h"

#include "boost/lexical_cast.hpp"

#include "openssl/err.h"
#include "openssl/rand.h"

#if defined(X509_NAME)
#undef X509_NAME
#endif

#include "openssl/ssl.h"

#include "../protocol/ssl-wrapper.h"

using namespace vtrc;

const std::string CERTF = "../server.crt";

namespace {

    typedef howto::hello_ssl_service_Stub   stub_type;
    typedef common::stub_wrapper<stub_type> stub_wrap;

    void on_connect( )
    {
        std::cout << "connect...";
    }
    void on_ready( )
    {
        std::cout << "ready...";
    }
    void on_disconnect( )
    {
        std::cout << "disconnect...";
    }

    void ssl_throw( const char *add )
    {
        std::string err(add);
        err += ": ";
        size_t final = err.size( );
        err.resize( final + 1024 );
        ERR_error_string_n(ERR_get_error( ), &err[final], err.size( ) - final );
        throw std::runtime_error( err );
    }
}

int verify_callback( X509_STORE_CTX *x509, void */*p*/ )
{
    char subject[512];
    int ver = X509_verify_cert(x509);
    if( ver <= 0 ) {
        int err = X509_STORE_CTX_get_error(x509);
        char errorbuf[1024];
        ERR_error_string_n(err, errorbuf, 1024);
        std::cout << "Cert is not valid " << errorbuf << "\n";
    }
    X509 *cc = X509_STORE_CTX_get_current_cert( x509 );
    if( !cc ) {
        ssl_throw("ds");
    }
    X509_NAME *sn = X509_get_subject_name( cc );
    X509_NAME_oneline(sn, subject, 256);
    std::cout << "Verify call: " << subject << "\n";

    /// we don't care, cuz "Hello, world!"
    return 1;
}

class my_ssl_wrapper: public ssl_wrapper_client {
public:
    my_ssl_wrapper( )
        :ssl_wrapper_client(TLSv1_2_client_method( ))
    { }
private:
    void init_context( )
    {
        SSL_CTX_set_mode( get_context( ), SSL_MODE_AUTO_RETRY           );
        SSL_CTX_set_mode( get_context( ), SSL_MODE_ENABLE_PARTIAL_WRITE );
        SSL_CTX_set_mode( get_context( ), SSL_MODE_RELEASE_BUFFERS      );

        SSL_CTX_set_cert_verify_callback( get_context( ), verify_callback, 0 );

        int err = SSL_CTX_load_verify_locations( get_context( ),
                                                 CERTF.c_str( ), 0 );
        if( err == 0 ) {
            ssl_throw("SSL_CTX_load_verify_locations");
        }
    }
};

std::string send_data( stub_wrap &stub, my_ssl_wrapper &ssl,
                       const std::string &data, bool decode = true )
{
    howto::request_message  req;
    howto::response_message res;

    req.set_block( ssl.encrypt( data ) );
    //std::cout << "packed: " << req.block( ).size( ) << "\n";

    stub.call( &stub_type::send_block, &req, &res );
    std::string result;
    if( decode ) {
        result = ssl.decrypt( res.block( ) );
    } else {
        ssl.get_in( ).write( res.block( ) );
    }
//    std::cout << "result: " << result.size( ) << " "
//              << res.block( ).size( ) << "\n";
    return result;
}

void connect_handshake( stub_wrap &stub )
{
    my_ssl_wrapper ssl;
    ssl.init( );
    howto::request_message  req;
    howto::response_message res;
    std::string data;
    while (!ssl.init_finished( )) {

        std::string res_data = ssl.do_handshake( );

        if( !res_data.empty( ) ) {
            req.set_block( res_data );
            stub.call( &stub_type::send_block, &req, &res );
            data = res.block( );
            if( !data.empty( ) ) { //
                ssl.get_in( ).write( data.c_str( ), data.size( ) );
            }
        }
    }

    std::cout << "Init success!\n";

    int i = 0;

    std::cout << i++ << ": " << send_data( stub, ssl, "Hello, World1" )
              << "\n";
    std::cout << i++ << ": " << send_data( stub, ssl, "Hello, World2", false )
              << "\n";
    std::cout << i++ << ": " << send_data( stub, ssl, "Hello, World3" )
              << "\n";

    std::string test(41, '!');
    std::cout << i++ << ": " << send_data( stub, ssl, test ) << "\n";
}

int main( int argc, const char **argv )
{
    common::thread_pool tp( 1 );

    const char *address = "127.0.0.1";
    unsigned short port = 56560;

    if( argc > 2 ) {
        address = argv[1];
        port = boost::lexical_cast<unsigned short>( argv[2] );
    } else if( argc > 1 ) {
        port = boost::lexical_cast<unsigned short>( argv[1] );
    }

    vtrc::common::random_device rd(true);
    std::string seed = rd.generate_block( 1024 );

    RAND_seed( seed.c_str( ), seed.size( ) );

    SSL_load_error_strings( );
    SSLeay_add_ssl_algorithms( );

    try {

        client::vtrc_client_sptr cl =
                         client::vtrc_client::create( tp.get_io_service( ) );

        cl->on_connect_connect( on_connect );
        cl->on_ready_connect( on_ready );
        cl->on_disconnect_connect( on_disconnect );

        std::cout <<  "Connecting..." << std::endl;

        cl->connect( address, port );
        std::cout << "Ok" << std::endl;

        vtrc::unique_ptr<common::rpc_channel> channel(cl->create_channel( ));

        stub_wrap hello(channel.get( ));

        connect_handshake( hello );

    } catch( const std::exception &ex ) {
        std::cerr << "Hello, world failed: " << ex.what( ) << "\n";
    }

    tp.stop( );
    tp.join_all( );

    /// make valgrind happy.
    google::protobuf::ShutdownProtobufLibrary( );

    return 0;
}
<commit_msg>connection closure<commit_after>#include <iostream>

#if !defined(NOMINMAX)
#define NOMINMAX // fckng Windows
#endif

#include "vtrc-client/vtrc-client.h"
#include "vtrc-common/vtrc-thread-pool.h"
#include "vtrc-common/vtrc-stub-wrapper.h"
#include "vtrc-common/vtrc-random-device.h"

#include "protocol/hello.pb.h"

#include "boost/lexical_cast.hpp"

#include "openssl/err.h"
#include "openssl/rand.h"

#if defined(X509_NAME)
#undef X509_NAME
#endif

#include "openssl/ssl.h"

#include "../protocol/ssl-wrapper.h"

using namespace vtrc;

const std::string CERTF = "../server.crt";

namespace {

    typedef howto::hello_ssl_service_Stub   stub_type;
    typedef common::stub_wrapper<stub_type> stub_wrap;

    void on_connect( )
    {
        std::cout << "connect...";
    }
    void on_ready( )
    {
        std::cout << "ready...";
    }
    void on_disconnect( )
    {
        std::cout << "disconnect...";
    }

    void ssl_throw( const char *add )
    {
        std::string err(add);
        err += ": ";
        size_t final = err.size( );
        err.resize( final + 1024 );
        ERR_error_string_n(ERR_get_error( ), &err[final], err.size( ) - final );
        throw std::runtime_error( err );
    }
}

int verify_callback( X509_STORE_CTX *x509, void */*p*/ )
{
    char subject[512];
    int ver = X509_verify_cert(x509);
    if( ver <= 0 ) {
        int err = X509_STORE_CTX_get_error(x509);
        char errorbuf[1024];
        ERR_error_string_n(err, errorbuf, 1024);
        std::cout << "Cert is not valid " << errorbuf << "\n";
    }
    X509 *cc = X509_STORE_CTX_get_current_cert( x509 );
    if( !cc ) {
        ssl_throw("ds");
    }
    X509_NAME *sn = X509_get_subject_name( cc );
    X509_NAME_oneline(sn, subject, 256);
    std::cout << "Verify call: " << subject << "\n";

    /// we don't care, cuz "Hello, world!"
    return 1;
}

class my_ssl_wrapper: public ssl_wrapper_client {
public:
    my_ssl_wrapper( )
        :ssl_wrapper_client(TLSv1_2_client_method( ))
    { }
private:
    void init_context( )
    {
        SSL_CTX_set_mode( get_context( ), SSL_MODE_AUTO_RETRY           );
        SSL_CTX_set_mode( get_context( ), SSL_MODE_ENABLE_PARTIAL_WRITE );
        SSL_CTX_set_mode( get_context( ), SSL_MODE_RELEASE_BUFFERS      );

        SSL_CTX_set_cert_verify_callback( get_context( ), verify_callback, 0 );

        int err = SSL_CTX_load_verify_locations( get_context( ),
                                                 CERTF.c_str( ), 0 );
        if( err == 0 ) {
            ssl_throw("SSL_CTX_load_verify_locations");
        }
    }
};

std::string send_data( stub_wrap &stub, my_ssl_wrapper &ssl,
                       const std::string &data, bool decode = true )
{
    howto::request_message  req;
    howto::response_message res;

    req.set_block( ssl.encrypt( data ) );
    //std::cout << "packed: " << req.block( ).size( ) << "\n";

    stub.call( &stub_type::send_block, &req, &res );
    std::string result;
    if( decode ) {
        result = ssl.decrypt( res.block( ) );
    } else {
        ssl.get_in( ).write( res.block( ) );
    }
//    std::cout << "result: " << result.size( ) << " "
//              << res.block( ).size( ) << "\n";
    return result;
}

void connect_handshake( stub_wrap &stub )
{
    my_ssl_wrapper ssl;
    ssl.init( );
    howto::request_message  req;
    howto::response_message res;
    std::string data;
    while (!ssl.init_finished( )) {

        std::string res_data = ssl.do_handshake( );

        if( !res_data.empty( ) ) {
            req.set_block( res_data );
            stub.call( &stub_type::send_block, &req, &res );
            data = res.block( );
            if( !data.empty( ) ) { //
                ssl.get_in( ).write( data.c_str( ), data.size( ) );
            }
        }
    }

    std::cout << "Init success!\n";

    int i = 0;

    std::cout << i++ << ": " << send_data( stub, ssl, "Hello, World1" )
              << "\n";
    std::cout << i++ << ": " << send_data( stub, ssl, "Hello, World2", false )
              << "\n";
    std::cout << i++ << ": " << send_data( stub, ssl, "Hello, World3" )
              << "\n";

    std::string test(41, '!');
    std::cout << i++ << ": " << send_data( stub, ssl, test ) << "\n";
}

int main( int argc, const char **argv )
{
    common::thread_pool tp( 1 );

    const char *address = "127.0.0.1";
    unsigned short port = 56560;

    if( argc > 2 ) {
        address = argv[1];
        port = boost::lexical_cast<unsigned short>( argv[2] );
    } else if( argc > 1 ) {
        port = boost::lexical_cast<unsigned short>( argv[1] );
    }

    vtrc::common::random_device rd(true);
    std::string seed = rd.generate_block( 1024 );

    RAND_seed( seed.c_str( ), seed.size( ) );

    SSL_load_error_strings( );
    SSLeay_add_ssl_algorithms( );

    try {

        client::vtrc_client_sptr cl =
                         client::vtrc_client::create( tp.get_io_service( ) );

        cl->on_connect_connect( on_connect );
        cl->on_ready_connect( on_ready );
        cl->on_disconnect_connect( on_disconnect );

        std::cout <<  "Connecting..." << std::endl;

        cl->connect( address, port );
        std::cout << "Ok" << std::endl;

        vtrc::unique_ptr<common::rpc_channel> channel(cl->create_channel( ));

        stub_wrap hello(channel.get( ));

        connect_handshake( hello );

    } catch( const std::exception &ex ) {
        std::cerr << "Hello, world failed: " << ex.what( ) << "\n";
    }

    tp.stop( );
    tp.join_all( );

    /// make valgrind happy.
    google::protobuf::ShutdownProtobufLibrary( );

    return 0;
}
<|endoftext|>


<commit_before>//
// Created by manu343726 on 4/08/15.
//

#ifndef CTTI_HASH_HPP
#define CTTI_HASH_HPP

#include <functional>
#include "detail/hash.hpp"
#include "detail/pretty_function.hpp"
#include "detail/string.hpp"

#ifdef CTTI_DEBUG_ID_FUNCTIONS
#include <iostream>
#include <string>

#ifndef CTTI_CONSTEXPR_ID
#define CTTI_CONSTEXPR_ID
#endif
#else
#ifndef CTTI_CONSTEXPR_ID
#define CTTI_CONSTEXPR_ID constexpr
#endif
#endif
namespace ctti
{
    struct type_id_t
    {
        constexpr type_id_t(const detail::string& name) :
            name_{name}
        {}

        type_id_t& operator=(const type_id_t&) = default;

        constexpr detail::hash_t hash() const
        {
            return name_.hash();
        }

        // note: name().c_str() isn't null-terminated properly!
        constexpr detail::string name() const
        {
            return name_;
        }

        friend constexpr bool operator==(const type_id_t& lhs, const type_id_t& rhs)
        {
            return lhs.hash() == rhs.hash();
        }

        friend constexpr bool operator!=(const type_id_t& lhs, const type_id_t& rhs)
        {
            return !(lhs == rhs);
        }

    private:
        detail::string name_;
    };

    struct unnamed_type_id_t
    {
        constexpr unnamed_type_id_t(const detail::hash_t hash) :
            _hash{hash}
        {}

        unnamed_type_id_t& operator=(const unnamed_type_id_t&) = default;

        constexpr detail::hash_t hash() const
        {
			return _hash;
        }

        friend constexpr bool operator==(const unnamed_type_id_t& lhs, const unnamed_type_id_t& rhs)
        {
            return lhs.hash() == rhs.hash();
        }

        friend constexpr bool operator!=(const unnamed_type_id_t& lhs, const unnamed_type_id_t& rhs)
        {
            return !(lhs == rhs);
        }

    private:
        detail::hash_t _hash;
    };

    using type_index = unnamed_type_id_t; // To mimic std::type_index when using maps

    template<std::size_t N>
    constexpr ctti::unnamed_type_id_t id_from_name(const char (&typeName)[N])
    {
        return detail::sid_hash(N - 1, typeName);
    }

    constexpr ctti::unnamed_type_id_t id_from_name(const char* typeName, std::size_t length)
    {
        return detail::sid_hash(length, typeName);
    }

    ctti::unnamed_type_id_t id_from_name(const std::string& typeName)
    {
        return detail::sid_hash(typeName.size(), typeName.data());
    }

    namespace detail
    {
        template<typename T>
	CTTI_CONSTEXPR_ID ctti::type_id_t type_id()
        {
            static_assert(CTTI_TYPE_ID_PRETTY_FUNCTION_END - CTTI_TYPE_ID_PRETTY_FUNCTION_BEGIN <= max_string_length, "CTTI_PRETTY_FUNCTION out of range");

#ifdef CTTI_DEBUG_ID_FUNCTIONS
            std::string name{ CTTI_TYPE_ID_PRETTY_FUNCTION + CTTI_TYPE_ID_PRETTY_FUNCTION_BEGIN, CTTI_TYPE_ID_PRETTY_FUNCTION_END - CTTI_TYPE_ID_PRETTY_FUNCTION_BEGIN - 1};

            std::cout << "PRETTY_FUNCTION: " << CTTI_TYPE_ID_PRETTY_FUNCTION << std::endl;
            std::cout << "Range: [" << CTTI_TYPE_ID_PRETTY_FUNCTION_BEGIN << "," << CTTI_TYPE_ID_PRETTY_FUNCTION_END << ")" << std::endl;
            std::cout << "Name: " << name << std::endl;
#endif
            // one-liner required by MSVC :(
            return detail::make_string<CTTI_TYPE_ID_PRETTY_FUNCTION_BEGIN, CTTI_TYPE_ID_PRETTY_FUNCTION_END>(CTTI_TYPE_ID_PRETTY_FUNCTION);
        }

        template<typename T>
        CTTI_CONSTEXPR_ID ctti::unnamed_type_id_t unnamed_type_id()
        {
            // one-liner required by MSVC :(
            static_assert(CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_BEGIN < CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_END, "CTTI unnamed type id wrong range");

#ifdef CTTI_DEBUG_ID_FUNCTIONS
            std::string name{ CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION + CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_BEGIN, CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_END - CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_BEGIN - 1};

            std::cout << "PRETTY_FUNCTION: " << CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION << std::endl;
            std::cout << "Range: [" << CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_BEGIN << "," << CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_END << ")" << std::endl;
            std::cout << "Name: " << name << std::endl;
            std::cout << "Name size: " << name.size() << std::endl;
            std::cout << "Name size (computed from range): " << (CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_END - CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_BEGIN - 1) << std::endl;

            return id_from_name(name);
#else
            return id_from_name(
                CTTI_TYPE_ID_PRETTY_FUNCTION + CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_BEGIN,
                CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_END - CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_BEGIN - 1
            );
#endif
        }
    }

    /**
     * Returns type information at compile-time for a value
     * of type T. Decay is applied to argument type first, use
     * ctti::type_id<decltype(arg)>() to preserve references and cv qualifiers.
     */
    template<typename T>
    constexpr type_id_t type_id(T&&)
    {
        return detail::type_id<typename std::decay<T>::type>();
    }

    /**
     * Returns type information at compile-time for type T.
     */
    template<typename T>
    constexpr type_id_t type_id()
    {
        return detail::type_id<T>();
    }

    /**
     * Returns unnamed type information at compile-time for a value
     * of type T. Decay is applied to argument type first, use
     * ctti::type_id<decltype(arg)>() to preserve references and cv qualifiers.
     */
    template<typename T>
    constexpr unnamed_type_id_t unnamed_type_id(T&&)
    {
        return detail::unnamed_type_id<typename std::decay<T>::type>();
    }

    /**
     * Returns unnamed type information at compile-time for type T.
     */
    template<typename T>
    constexpr unnamed_type_id_t unnamed_type_id()
    {
        return detail::unnamed_type_id<T>();
    }

    //assert commented out, GCC 5.2.0 ICE here.
    //static_assert(type_id<void>() == type_id<void>(), "ctti::type_id_t instances must be constant expressions");
}

namespace std
{
    template<>
    struct hash<ctti::type_id_t>
    {
        constexpr std::size_t operator()(const ctti::type_id_t& id) const
        {
            // quiet warning about possible loss of data
            return std::size_t(id.hash());
        }
    };
}

#endif //CTTI_HASH_HPP
<commit_msg>std::hash specialization for ctti::unnamed_type_id<commit_after>//
// Created by manu343726 on 4/08/15.
//

#ifndef CTTI_HASH_HPP
#define CTTI_HASH_HPP

#include <functional>
#include "detail/hash.hpp"
#include "detail/pretty_function.hpp"
#include "detail/string.hpp"

#ifdef CTTI_DEBUG_ID_FUNCTIONS
#include <iostream>
#include <string>

#ifndef CTTI_CONSTEXPR_ID
#define CTTI_CONSTEXPR_ID
#endif
#else
#ifndef CTTI_CONSTEXPR_ID
#define CTTI_CONSTEXPR_ID constexpr
#endif
#endif
namespace ctti
{
    struct type_id_t
    {
        constexpr type_id_t(const detail::string& name) :
            name_{name}
        {}

        type_id_t& operator=(const type_id_t&) = default;

        constexpr detail::hash_t hash() const
        {
            return name_.hash();
        }

        // note: name().c_str() isn't null-terminated properly!
        constexpr detail::string name() const
        {
            return name_;
        }

        friend constexpr bool operator==(const type_id_t& lhs, const type_id_t& rhs)
        {
            return lhs.hash() == rhs.hash();
        }

        friend constexpr bool operator!=(const type_id_t& lhs, const type_id_t& rhs)
        {
            return !(lhs == rhs);
        }

    private:
        detail::string name_;
    };

    struct unnamed_type_id_t
    {
        constexpr unnamed_type_id_t(const detail::hash_t hash) :
            _hash{hash}
        {}

        unnamed_type_id_t& operator=(const unnamed_type_id_t&) = default;

        constexpr detail::hash_t hash() const
        {
			return _hash;
        }

        friend constexpr bool operator==(const unnamed_type_id_t& lhs, const unnamed_type_id_t& rhs)
        {
            return lhs.hash() == rhs.hash();
        }

        friend constexpr bool operator!=(const unnamed_type_id_t& lhs, const unnamed_type_id_t& rhs)
        {
            return !(lhs == rhs);
        }

    private:
        detail::hash_t _hash;
    };

    using type_index = unnamed_type_id_t; // To mimic std::type_index when using maps

    template<std::size_t N>
    constexpr ctti::unnamed_type_id_t id_from_name(const char (&typeName)[N])
    {
        return detail::sid_hash(N - 1, typeName);
    }

    constexpr ctti::unnamed_type_id_t id_from_name(const char* typeName, std::size_t length)
    {
        return detail::sid_hash(length, typeName);
    }

    ctti::unnamed_type_id_t id_from_name(const std::string& typeName)
    {
        return detail::sid_hash(typeName.size(), typeName.data());
    }

    namespace detail
    {
        template<typename T>
	CTTI_CONSTEXPR_ID ctti::type_id_t type_id()
        {
            static_assert(CTTI_TYPE_ID_PRETTY_FUNCTION_END - CTTI_TYPE_ID_PRETTY_FUNCTION_BEGIN <= max_string_length, "CTTI_PRETTY_FUNCTION out of range");

#ifdef CTTI_DEBUG_ID_FUNCTIONS
            std::string name{ CTTI_TYPE_ID_PRETTY_FUNCTION + CTTI_TYPE_ID_PRETTY_FUNCTION_BEGIN, CTTI_TYPE_ID_PRETTY_FUNCTION_END - CTTI_TYPE_ID_PRETTY_FUNCTION_BEGIN - 1};

            std::cout << "PRETTY_FUNCTION: " << CTTI_TYPE_ID_PRETTY_FUNCTION << std::endl;
            std::cout << "Range: [" << CTTI_TYPE_ID_PRETTY_FUNCTION_BEGIN << "," << CTTI_TYPE_ID_PRETTY_FUNCTION_END << ")" << std::endl;
            std::cout << "Name: " << name << std::endl;
#endif
            // one-liner required by MSVC :(
            return detail::make_string<CTTI_TYPE_ID_PRETTY_FUNCTION_BEGIN, CTTI_TYPE_ID_PRETTY_FUNCTION_END>(CTTI_TYPE_ID_PRETTY_FUNCTION);
        }

        template<typename T>
        CTTI_CONSTEXPR_ID ctti::unnamed_type_id_t unnamed_type_id()
        {
            // one-liner required by MSVC :(
            static_assert(CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_BEGIN < CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_END, "CTTI unnamed type id wrong range");

#ifdef CTTI_DEBUG_ID_FUNCTIONS
            std::string name{ CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION + CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_BEGIN, CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_END - CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_BEGIN - 1};

            std::cout << "PRETTY_FUNCTION: " << CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION << std::endl;
            std::cout << "Range: [" << CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_BEGIN << "," << CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_END << ")" << std::endl;
            std::cout << "Name: " << name << std::endl;
            std::cout << "Name size: " << name.size() << std::endl;
            std::cout << "Name size (computed from range): " << (CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_END - CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_BEGIN - 1) << std::endl;

            return id_from_name(name);
#else
            return id_from_name(
                CTTI_TYPE_ID_PRETTY_FUNCTION + CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_BEGIN,
                CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_END - CTTI_UNNAMED_TYPE_ID_PRETTY_FUNCTION_BEGIN - 1
            );
#endif
        }
    }

    /**
     * Returns type information at compile-time for a value
     * of type T. Decay is applied to argument type first, use
     * ctti::type_id<decltype(arg)>() to preserve references and cv qualifiers.
     */
    template<typename T>
    constexpr type_id_t type_id(T&&)
    {
        return detail::type_id<typename std::decay<T>::type>();
    }

    /**
     * Returns type information at compile-time for type T.
     */
    template<typename T>
    constexpr type_id_t type_id()
    {
        return detail::type_id<T>();
    }

    /**
     * Returns unnamed type information at compile-time for a value
     * of type T. Decay is applied to argument type first, use
     * ctti::type_id<decltype(arg)>() to preserve references and cv qualifiers.
     */
    template<typename T>
    constexpr unnamed_type_id_t unnamed_type_id(T&&)
    {
        return detail::unnamed_type_id<typename std::decay<T>::type>();
    }

    /**
     * Returns unnamed type information at compile-time for type T.
     */
    template<typename T>
    constexpr unnamed_type_id_t unnamed_type_id()
    {
        return detail::unnamed_type_id<T>();
    }

    //assert commented out, GCC 5.2.0 ICE here.
    //static_assert(type_id<void>() == type_id<void>(), "ctti::type_id_t instances must be constant expressions");
}

namespace std
{
    template<>
    struct hash<ctti::type_id_t>
    {
        constexpr std::size_t operator()(const ctti::type_id_t& id) const
        {
            // quiet warning about possible loss of data
            return std::size_t(id.hash());
        }
    };

    template<>
    struct hash<ctti::unnamed_type_id_t>
    {
        constexpr std::size_t operator()(const ctti::unnamed_type_id_t& id) const
        {
            // quiet warning about possible loss of data
            return std::size_t(id.hash());
        }
    };
}

#endif //CTTI_HASH_HPP
<|endoftext|>


<commit_before>#pragma once

#ifndef RAZ_SUBMESH_HPP
#define RAZ_SUBMESH_HPP

#include <memory>

#include "RaZ/Render/GraphicObjects.hpp"

namespace Raz {

enum class RenderMode : unsigned int {
  POINT    = 0, // GL_POINTS
  LINE     = 1, // GL_LINES
  TRIANGLE = 4  // GL_TRIANGLES
};

class Submesh;
using SubmeshPtr = std::unique_ptr<Submesh>;

class Submesh {
public:
  Submesh() = default;
  explicit Submesh(RenderMode renderMode) : m_renderMode{ renderMode } {}
  Submesh(const Submesh&) = delete;
  Submesh(Submesh&&) = default;

  const VertexArray& getVao() const { return m_vao; }
  const VertexBuffer& getVbo() const { return m_vbo; }
  const ElementBuffer& getEbo() const { return m_vao.getEbo(); }
  const std::vector<Vertex>& getVertices() const { return m_vbo.getVertices(); }
  std::vector<Vertex>& getVertices() { return m_vbo.getVertices(); }
  std::size_t getVertexCount() const { return m_vbo.getVertices().size(); }
  const std::vector<unsigned int>& getIndices() const { return m_vao.getEbo().getIndices(); }
  std::vector<unsigned int>& getIndices() { return m_vao.getEbo().getIndices(); }
  std::size_t getIndexCount() const { return getEbo().getIndices().size(); }
  RenderMode getRenderMode() const { return m_renderMode; }
  std::size_t getMaterialIndex() const { return m_materialIndex; }

  void setRenderMode(RenderMode renderMode) { m_renderMode = renderMode; }
  void setMaterialIndex(std::size_t materialIndex) { m_materialIndex = materialIndex; }

  template <typename... Args>
  static SubmeshPtr create(Args&&... args) { return std::make_unique<Submesh>(std::forward<Args>(args)...); }

  /// Loads the submesh's data (vertices & indices) onto the graphics card.
  void load() const;
  /// Draws the submesh in the scene.
  void draw() const;

  Submesh& operator=(const Submesh&) = delete;
  Submesh& operator=(Submesh&&) = default;

private:
  void loadVertices() const;
  void loadIndices() const;

  VertexArray m_vao {};
  VertexBuffer m_vbo {};
  RenderMode m_renderMode = RenderMode::TRIANGLE;

  std::size_t m_materialIndex {};
};

} // namespace Raz

#endif // RAZ_SUBMESH_HPP
<commit_msg>[Render/Submesh] Reworked Submesh functions according to EBO changes<commit_after>#pragma once

#ifndef RAZ_SUBMESH_HPP
#define RAZ_SUBMESH_HPP

#include <memory>

#include "RaZ/Render/GraphicObjects.hpp"

namespace Raz {

enum class RenderMode : unsigned int {
  POINT    = 0, // GL_POINTS
  LINE     = 1, // GL_LINES
  TRIANGLE = 4  // GL_TRIANGLES
};

class Submesh;
using SubmeshPtr = std::unique_ptr<Submesh>;

class Submesh {
public:
  Submesh() = default;
  explicit Submesh(RenderMode renderMode) : m_renderMode{ renderMode } {}
  Submesh(const Submesh&) = delete;
  Submesh(Submesh&&) noexcept = default;

  const std::vector<Vertex>& getVertices() const { return m_vbo.getVertices(); }
  std::vector<Vertex>& getVertices() { return m_vbo.getVertices(); }
  std::size_t getVertexCount() const { return getVertices().size(); }
  const std::vector<unsigned int>& getTriangleIndices() const { return m_vao.getEbo().getTriangleIndices(); }
  std::vector<unsigned int>& getTriangleIndices() { return m_vao.getEbo().getTriangleIndices(); }
  const std::vector<unsigned int>& getLineIndices() const { return m_vao.getEbo().getLineIndices(); }
  std::vector<unsigned int>& getLineIndices() { return m_vao.getEbo().getLineIndices(); }
  std::size_t getTriangleIndexCount() const { return getLineIndices().size(); }
  std::size_t getLineIndexCount() const { return getLineIndices().size(); }
  RenderMode getRenderMode() const { return m_renderMode; }
  std::size_t getMaterialIndex() const { return m_materialIndex; }

  void setRenderMode(RenderMode renderMode) { m_renderMode = renderMode; }
  void setMaterialIndex(std::size_t materialIndex) { m_materialIndex = materialIndex; }

  template <typename... Args>
  static SubmeshPtr create(Args&&... args) { return std::make_unique<Submesh>(std::forward<Args>(args)...); }

  /// Loads the submesh's data (vertices & indices) onto the graphics card.
  void load() const;
  /// Draws the submesh in the scene.
  void draw() const;

  Submesh& operator=(const Submesh&) = delete;
  Submesh& operator=(Submesh&&) noexcept = default;

private:
  void loadVertices() const;
  void loadIndices() const;

  VertexArray m_vao {};
  VertexBuffer m_vbo {};
  RenderMode m_renderMode = RenderMode::TRIANGLE;

  std::size_t m_materialIndex {};
};

} // namespace Raz

#endif // RAZ_SUBMESH_HPP
<|endoftext|>