<commit_before>// wake.cpp - written and placed in the public domain by Wei Dai

#include "pch.h"
#include "wake.h"

NAMESPACE_BEGIN(CryptoPP)

void WAKE_TestInstantiations()
{
	WAKE_OFB<>::Encryption x2;
	WAKE_OFB<>::Decryption x4;
}

inline word32 WAKE_Base::M(word32 x, word32 y)
{
	word32 w = x+y;
	return (w>>8) ^ t[w & 0xff];
}

void WAKE_Base::GenKey(word32 k0, word32 k1, word32 k2, word32 k3)
{
	// this code is mostly copied from David Wheeler's paper "A Bulk Data Encryption Algorithm"
	signed int x, z, p;
	// x and z were declared as "long" in Wheeler's paper, which is a signed type. I don't know if that was intentional, but it's too late to change it now. -- Wei 7/4/2010
	CRYPTOPP_COMPILE_ASSERT(sizeof(x) == 4);
	static unsigned int tt[10]= {
		0x726a8f3b,								 // table
		0xe69a3b5c,
		0xd3c71fe5,
		0xab3c73d2,
		0x4d3a8eb3,
		0x0396d6e8,
		0x3d4c2f7a,
		0x9ee27cf3, } ;
	t[0] = k0;
	t[1] = k1;
	t[2] = k2;
	t[3] = k3;
	for (p=4 ; p<256 ; p++)
	{
	  x=t[p-4]+t[p-1] ; 					   // fill t
	  t[p]= (x>>3) ^ tt[x&7] ;
	}

	for (p=0 ; p<23 ; p++)
		t[p]+=t[p+89] ; 		  // mix first entries
	x=t[33] ; z=t[59] | 0x01000001 ;
	z=z&0xff7fffff ;
	for (p=0 ; p<256 ; p++) {		//change top byte to
	  x=(x&0xff7fffff)+z ; 		 // a permutation etc
	  t[p]=(t[p] & 0x00ffffff) ^ x ; }

	t[256]=t[0] ;
	byte y=byte(x);
	for (p=0 ; p<256 ; p++) {	  // further change perm.
	  t[p]=t[y=byte(t[p^y]^y)] ;  // and other digits
	  t[y]=t[p+1] ;  }
}

template <class B>
void WAKE_Policy<B>::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
{
	word32 k0, k1, k2, k3;
	BlockGetAndPut<word32, BigEndian>::Get(key)(r3)(r4)(r5)(r6)(k0)(k1)(k2)(k3);
	GenKey(k0, k1, k2, k3);
}

// OFB
template <class B>
void WAKE_Policy<B>::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
{
#define WAKE_OUTPUT(x)\
	while (iterationCount--)\
	{\
		CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, r6);\
		r3 = M(r3, r6);\
		r4 = M(r4, r3);\
		r5 = M(r5, r4);\
		r6 = M(r6, r5);\
		output += 4;\
		if (!(x & INPUT_NULL))\
			input += 4;\
	}

	typedef word32 WordType;
	CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(WAKE_OUTPUT, 0);
}
/*
template <class B>
void WAKE_ROFB_Policy<B>::Iterate(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount)
{
	KeystreamOutput<B> keystreamOperation(operation, output, input);

	while (iterationCount--)
	{
		keystreamOperation(r6);
		r3 = M(r3, r6);
		r4 = M(r4, r3);
		r5 = M(r5, r4);
		r6 = M(r6, r5);
	}
}
*/
template class WAKE_Policy<BigEndian>;
template class WAKE_Policy<LittleEndian>;
//template class WAKE_ROFB_Policy<BigEndian>;
//template class WAKE_ROFB_Policy<LittleEndian>;

NAMESPACE_END
<commit_msg>Update wake.cpp<commit_after>// wake.cpp - written and placed in the public domain by Wei Dai

#include "pch.h"
#include "wake.h"

NAMESPACE_BEGIN(CryptoPP)

void WAKE_TestInstantiations()
{
	WAKE_OFB<>::Encryption x2;
	WAKE_OFB<>::Decryption x4;
}

inline word32 WAKE_Base::M(word32 x, word32 y)
{
	word32 w = x+y;
	return (w>>8) ^ t[w & 0xff];
}

void WAKE_Base::GenKey(word32 k0, word32 k1, word32 k2, word32 k3)
{
	// this code is mostly copied from David Wheeler's paper "A Bulk Data Encryption Algorithm"
	signed int x, z, p;
	// x and z were declared as "long" in Wheeler's paper, which is a signed type. I don't know if that was intentional, but it's too late to change it now. -- Wei 7/4/2010
	CRYPTOPP_COMPILE_ASSERT(sizeof(x) == 4);
	static int tt[10]= {
		0x726a8f3b,								 // table
		0xe69a3b5c,
		0xd3c71fe5,
		0xab3c73d2,
		0x4d3a8eb3,
		0x0396d6e8,
		0x3d4c2f7a,
		0x9ee27cf3, } ;
	t[0] = k0;
	t[1] = k1;
	t[2] = k2;
	t[3] = k3;
	for (p=4 ; p<256 ; p++)
	{
	  x=t[p-4]+t[p-1] ; 					   // fill t
	  t[p]= (x>>3) ^ tt[x&7] ;
	}

	for (p=0 ; p<23 ; p++)
		t[p]+=t[p+89] ; 		  // mix first entries
	x=t[33] ; z=t[59] | 0x01000001 ;
	z=z&0xff7fffff ;
	for (p=0 ; p<256 ; p++) {		//change top byte to
	  x=(x&0xff7fffff)+z ; 		 // a permutation etc
	  t[p]=(t[p] & 0x00ffffff) ^ x ; }

	t[256]=t[0] ;
	byte y=byte(x);
	for (p=0 ; p<256 ; p++) {	  // further change perm.
	  t[p]=t[y=byte(t[p^y]^y)] ;  // and other digits
	  t[y]=t[p+1] ;  }
}

template <class B>
void WAKE_Policy<B>::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
{
	word32 k0, k1, k2, k3;
	BlockGetAndPut<word32, BigEndian>::Get(key)(r3)(r4)(r5)(r6)(k0)(k1)(k2)(k3);
	GenKey(k0, k1, k2, k3);
}

// OFB
template <class B>
void WAKE_Policy<B>::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
{
#define WAKE_OUTPUT(x)\
	while (iterationCount--)\
	{\
		CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, r6);\
		r3 = M(r3, r6);\
		r4 = M(r4, r3);\
		r5 = M(r5, r4);\
		r6 = M(r6, r5);\
		output += 4;\
		if (!(x & INPUT_NULL))\
			input += 4;\
	}

	typedef word32 WordType;
	CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(WAKE_OUTPUT, 0);
}
/*
template <class B>
void WAKE_ROFB_Policy<B>::Iterate(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount)
{
	KeystreamOutput<B> keystreamOperation(operation, output, input);

	while (iterationCount--)
	{
		keystreamOperation(r6);
		r3 = M(r3, r6);
		r4 = M(r4, r3);
		r5 = M(r5, r4);
		r6 = M(r6, r5);
	}
}
*/
template class WAKE_Policy<BigEndian>;
template class WAKE_Policy<LittleEndian>;
//template class WAKE_ROFB_Policy<BigEndian>;
//template class WAKE_ROFB_Policy<LittleEndian>;

NAMESPACE_END
<|endoftext|>


<commit_before>/*
 * Process URLs in a CSS stream.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "css_processor.hxx"
#include "css_parser.hxx"
#include "css_util.hxx"
#include "penv.hxx"
#include "strmap.hxx"
#include "widget/Widget.hxx"
#include "widget/RewriteUri.hxx"
#include "tpool.hxx"
#include "bp_global.hxx"
#include "escape_css.hxx"
#include "istream/istream.hxx"
#include "istream/istream_replace.hxx"
#include "istream/istream_string.hxx"
#include "istream/istream_tee.hxx"
#include "pool.hxx"

#include <daemon/log.h>

#include <glib.h>

#include <assert.h>
#include <string.h>

struct CssProcessor {
    struct pool *pool, *caller_pool;

    Widget *container;
    struct processor_env *env;
    unsigned options;

    Istream *replace;

    CssParser *parser;
    bool had_input;

    struct UriRewrite {
        enum uri_mode mode;

        char view[64];
    };

    UriRewrite uri_rewrite;
};

static inline bool
css_processor_option_rewrite_url(const CssProcessor *processor)
{
    return (processor->options & CSS_PROCESSOR_REWRITE_URL) != 0;
}

static inline bool
css_processor_option_prefix_class(const CssProcessor *processor)
{
    return (processor->options & CSS_PROCESSOR_PREFIX_CLASS) != 0;
}

static inline bool
css_processor_option_prefix_id(const CssProcessor *processor)
{
    return (processor->options & CSS_PROCESSOR_PREFIX_ID) != 0;
}

static void
css_processor_replace_add(CssProcessor *processor,
                          off_t start, off_t end,
                          Istream *istream)
{
    istream_replace_add(*processor->replace, start, end, istream);
}

/*
 * css_parser_handler
 *
 */

static void
css_processor_parser_class_name(const CssParserValue *name, void *ctx)
{
    CssProcessor *processor = (CssProcessor *)ctx;

    assert(!name->value.IsEmpty());

    if (!css_processor_option_prefix_class(processor))
        return;

    unsigned n = underscore_prefix(name->value.begin(), name->value.end());
    if (n == 3) {
        /* triple underscore: add widget path prefix */

        const char *prefix = processor->container->GetPrefix();
        if (prefix == nullptr)
            return;

        css_processor_replace_add(processor, name->start, name->start + 3,
                                  istream_string_new(processor->pool,
                                                     prefix));
    } else if (n == 2) {
        /* double underscore: add class name prefix */

        const char *class_name = processor->container->GetQuotedClassName();
        if (class_name == nullptr)
            return;

        css_processor_replace_add(processor, name->start, name->start + 2,
                                  istream_string_new(processor->pool,
                                                     class_name));
    }
}

static void
css_processor_parser_xml_id(const CssParserValue *name, void *ctx)
{
    CssProcessor *processor = (CssProcessor *)ctx;

    assert(!name->value.IsEmpty());

    if (!css_processor_option_prefix_id(processor))
        return;

    unsigned n = underscore_prefix(name->value.begin(), name->value.end());
    if (n == 3) {
        /* triple underscore: add widget path prefix */

        const char *prefix = processor->container->GetPrefix();
        if (prefix == nullptr)
            return;

        css_processor_replace_add(processor, name->start, name->start + 3,
                                  istream_string_new(processor->pool,
                                                     prefix));
    } else if (n == 2) {
        /* double underscore: add class name prefix */

        const char *class_name = processor->container->GetQuotedClassName();
        if (class_name == nullptr)
            return;

        css_processor_replace_add(processor, name->start, name->start + 1,
                                  istream_string_new(processor->pool,
                                                     class_name));
    }
}

static void
css_processor_parser_block(void *ctx)
{
    CssProcessor *processor = (CssProcessor *)ctx;

    processor->uri_rewrite.mode = URI_MODE_PARTIAL;
    processor->uri_rewrite.view[0] = 0;
}

static void
css_processor_parser_property_keyword(const char *name, const char *value,
                                      off_t start, off_t end, void *ctx)
{
    CssProcessor *processor = (CssProcessor *)ctx;

    if (css_processor_option_rewrite_url(processor) &&
        strcmp(name, "-c-mode") == 0) {
        processor->uri_rewrite.mode = parse_uri_mode(value);
        css_processor_replace_add(processor, start, end, nullptr);
    }

    if (css_processor_option_rewrite_url(processor) &&
        strcmp(name, "-c-view") == 0) {
        g_strlcpy(processor->uri_rewrite.view, value,
                  sizeof(processor->uri_rewrite.view));
        css_processor_replace_add(processor, start, end, nullptr);
    }
}

static void
css_processor_parser_url(const CssParserValue *url, void *ctx)
{
    CssProcessor *processor = (CssProcessor *)ctx;

    if (!css_processor_option_rewrite_url(processor))
        return;

    Istream *istream =
        rewrite_widget_uri(*processor->pool,
                           *processor->env,
                           *global_translate_cache,
                           *processor->container,
                           url->value,
                           processor->uri_rewrite.mode, false,
                           processor->uri_rewrite.view[0] != 0
                           ? processor->uri_rewrite.view : nullptr,
                           &css_escape_class);
    if (istream != nullptr)
        css_processor_replace_add(processor, url->start, url->end, istream);
}

static void
css_processor_parser_import(const CssParserValue *url, void *ctx)
{
    CssProcessor *processor = (CssProcessor *)ctx;

    if (!css_processor_option_rewrite_url(processor))
        return;

    Istream *istream =
        rewrite_widget_uri(*processor->pool,
                           *processor->env,
                           *global_translate_cache,
                           *processor->container,
                           url->value,
                           URI_MODE_PARTIAL, false, nullptr,
                           &css_escape_class);
    if (istream != nullptr)
        css_processor_replace_add(processor, url->start, url->end, istream);
}

static void
css_processor_parser_eof(void *ctx, off_t length gcc_unused)
{
    CssProcessor *processor = (CssProcessor *)ctx;

    assert(processor->parser != nullptr);

    processor->parser = nullptr;

    istream_replace_finish(*processor->replace);
}

static void
css_processor_parser_error(GError *error, void *ctx)
{
    CssProcessor *processor = (CssProcessor *)ctx;

    assert(processor->parser != nullptr);

    processor->parser = nullptr;

    g_error_free(error);
}

static constexpr CssParserHandler css_processor_parser_handler = {
    .class_name = css_processor_parser_class_name,
    .xml_id = css_processor_parser_xml_id,
    .block = css_processor_parser_block,
    .property_keyword = css_processor_parser_property_keyword,
    .url = css_processor_parser_url,
    .import = css_processor_parser_import,
    .eof = css_processor_parser_eof,
    .error = css_processor_parser_error,
};

/*
 * constructor
 *
 */

Istream *
css_processor(struct pool &caller_pool, Istream &input,
              Widget &widget,
              struct processor_env &env,
              unsigned options)
{
    struct pool *pool = pool_new_linear(&caller_pool, "css_processor", 32768);
    auto processor = NewFromPool<CssProcessor>(*pool);
    processor->pool = pool;
    processor->caller_pool = &caller_pool;

    processor->container = &widget;
    processor->env = &env;
    processor->options = options;

    Istream *tee = istream_tee_new(*processor->pool, input,
                                   *env.event_loop,
                                   true, true);
    processor->replace = istream_replace_new(*processor->pool,
                                             istream_tee_second(*tee));

    processor->parser = css_parser_new(*processor->pool, *tee, false,
                                       css_processor_parser_handler,
                                       processor);
    pool_unref(processor->pool);

    return processor->replace;
}
<commit_msg>css_processor: add constructor<commit_after>/*
 * Process URLs in a CSS stream.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "css_processor.hxx"
#include "css_parser.hxx"
#include "css_util.hxx"
#include "penv.hxx"
#include "strmap.hxx"
#include "widget/Widget.hxx"
#include "widget/RewriteUri.hxx"
#include "tpool.hxx"
#include "bp_global.hxx"
#include "escape_css.hxx"
#include "istream/istream.hxx"
#include "istream/istream_replace.hxx"
#include "istream/istream_string.hxx"
#include "istream/istream_tee.hxx"
#include "pool.hxx"

#include <daemon/log.h>

#include <glib.h>

#include <assert.h>
#include <string.h>

struct CssProcessor {
    struct pool *pool, *caller_pool;

    Widget *container;
    struct processor_env *env;
    unsigned options;

    Istream *replace;

    CssParser *parser;
    bool had_input;

    struct UriRewrite {
        enum uri_mode mode;

        char view[64];
    };

    UriRewrite uri_rewrite;

    CssProcessor(struct pool &_pool, struct pool &_caller_pool, Istream &tee,
                 Widget &_container,
                 struct processor_env &_env,
                 unsigned _options);
};

static inline bool
css_processor_option_rewrite_url(const CssProcessor *processor)
{
    return (processor->options & CSS_PROCESSOR_REWRITE_URL) != 0;
}

static inline bool
css_processor_option_prefix_class(const CssProcessor *processor)
{
    return (processor->options & CSS_PROCESSOR_PREFIX_CLASS) != 0;
}

static inline bool
css_processor_option_prefix_id(const CssProcessor *processor)
{
    return (processor->options & CSS_PROCESSOR_PREFIX_ID) != 0;
}

static void
css_processor_replace_add(CssProcessor *processor,
                          off_t start, off_t end,
                          Istream *istream)
{
    istream_replace_add(*processor->replace, start, end, istream);
}

/*
 * css_parser_handler
 *
 */

static void
css_processor_parser_class_name(const CssParserValue *name, void *ctx)
{
    CssProcessor *processor = (CssProcessor *)ctx;

    assert(!name->value.IsEmpty());

    if (!css_processor_option_prefix_class(processor))
        return;

    unsigned n = underscore_prefix(name->value.begin(), name->value.end());
    if (n == 3) {
        /* triple underscore: add widget path prefix */

        const char *prefix = processor->container->GetPrefix();
        if (prefix == nullptr)
            return;

        css_processor_replace_add(processor, name->start, name->start + 3,
                                  istream_string_new(processor->pool,
                                                     prefix));
    } else if (n == 2) {
        /* double underscore: add class name prefix */

        const char *class_name = processor->container->GetQuotedClassName();
        if (class_name == nullptr)
            return;

        css_processor_replace_add(processor, name->start, name->start + 2,
                                  istream_string_new(processor->pool,
                                                     class_name));
    }
}

static void
css_processor_parser_xml_id(const CssParserValue *name, void *ctx)
{
    CssProcessor *processor = (CssProcessor *)ctx;

    assert(!name->value.IsEmpty());

    if (!css_processor_option_prefix_id(processor))
        return;

    unsigned n = underscore_prefix(name->value.begin(), name->value.end());
    if (n == 3) {
        /* triple underscore: add widget path prefix */

        const char *prefix = processor->container->GetPrefix();
        if (prefix == nullptr)
            return;

        css_processor_replace_add(processor, name->start, name->start + 3,
                                  istream_string_new(processor->pool,
                                                     prefix));
    } else if (n == 2) {
        /* double underscore: add class name prefix */

        const char *class_name = processor->container->GetQuotedClassName();
        if (class_name == nullptr)
            return;

        css_processor_replace_add(processor, name->start, name->start + 1,
                                  istream_string_new(processor->pool,
                                                     class_name));
    }
}

static void
css_processor_parser_block(void *ctx)
{
    CssProcessor *processor = (CssProcessor *)ctx;

    processor->uri_rewrite.mode = URI_MODE_PARTIAL;
    processor->uri_rewrite.view[0] = 0;
}

static void
css_processor_parser_property_keyword(const char *name, const char *value,
                                      off_t start, off_t end, void *ctx)
{
    CssProcessor *processor = (CssProcessor *)ctx;

    if (css_processor_option_rewrite_url(processor) &&
        strcmp(name, "-c-mode") == 0) {
        processor->uri_rewrite.mode = parse_uri_mode(value);
        css_processor_replace_add(processor, start, end, nullptr);
    }

    if (css_processor_option_rewrite_url(processor) &&
        strcmp(name, "-c-view") == 0) {
        g_strlcpy(processor->uri_rewrite.view, value,
                  sizeof(processor->uri_rewrite.view));
        css_processor_replace_add(processor, start, end, nullptr);
    }
}

static void
css_processor_parser_url(const CssParserValue *url, void *ctx)
{
    CssProcessor *processor = (CssProcessor *)ctx;

    if (!css_processor_option_rewrite_url(processor))
        return;

    Istream *istream =
        rewrite_widget_uri(*processor->pool,
                           *processor->env,
                           *global_translate_cache,
                           *processor->container,
                           url->value,
                           processor->uri_rewrite.mode, false,
                           processor->uri_rewrite.view[0] != 0
                           ? processor->uri_rewrite.view : nullptr,
                           &css_escape_class);
    if (istream != nullptr)
        css_processor_replace_add(processor, url->start, url->end, istream);
}

static void
css_processor_parser_import(const CssParserValue *url, void *ctx)
{
    CssProcessor *processor = (CssProcessor *)ctx;

    if (!css_processor_option_rewrite_url(processor))
        return;

    Istream *istream =
        rewrite_widget_uri(*processor->pool,
                           *processor->env,
                           *global_translate_cache,
                           *processor->container,
                           url->value,
                           URI_MODE_PARTIAL, false, nullptr,
                           &css_escape_class);
    if (istream != nullptr)
        css_processor_replace_add(processor, url->start, url->end, istream);
}

static void
css_processor_parser_eof(void *ctx, off_t length gcc_unused)
{
    CssProcessor *processor = (CssProcessor *)ctx;

    assert(processor->parser != nullptr);

    processor->parser = nullptr;

    istream_replace_finish(*processor->replace);
}

static void
css_processor_parser_error(GError *error, void *ctx)
{
    CssProcessor *processor = (CssProcessor *)ctx;

    assert(processor->parser != nullptr);

    processor->parser = nullptr;

    g_error_free(error);
}

static constexpr CssParserHandler css_processor_parser_handler = {
    .class_name = css_processor_parser_class_name,
    .xml_id = css_processor_parser_xml_id,
    .block = css_processor_parser_block,
    .property_keyword = css_processor_parser_property_keyword,
    .url = css_processor_parser_url,
    .import = css_processor_parser_import,
    .eof = css_processor_parser_eof,
    .error = css_processor_parser_error,
};

/*
 * constructor
 *
 */

inline
CssProcessor::CssProcessor(struct pool &_pool, struct pool &_caller_pool,
                           Istream &tee,
                           Widget &_container,
                           struct processor_env &_env,
                           unsigned _options)
    :pool(&_pool), caller_pool(&_caller_pool),
     container(&_container), env(&_env),
     options(_options),
     replace(istream_replace_new(*pool, istream_tee_second(tee))),
     parser(css_parser_new(*pool, tee, false,
                           css_processor_parser_handler, this)) {}

Istream *
css_processor(struct pool &caller_pool, Istream &input,
              Widget &widget,
              struct processor_env &env,
              unsigned options)
{
    struct pool *pool = pool_new_linear(&caller_pool, "css_processor", 32768);

    Istream *tee = istream_tee_new(*pool, input,
                                   *env.event_loop,
                                   true, true);

    auto processor = NewFromPool<CssProcessor>(*pool, *pool, caller_pool, *tee,
                                               widget, env,
                                               options);
    pool_unref(pool);

    return processor->replace;
}
<|endoftext|>


<commit_before>/*****************************************************************************
 * libVLC backend for the Phonon library                                     *
 *                                                                           *
 * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com>               *
 * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com>                *
 * Copyright (C) 2009 Fathi Boudra <fabo@kde.org>                            *
 * Copyright (C) 2009-2010 vlc-phonon AUTHORS                                *
 *                                                                           *
 * This program is free software; you can redistribute it and/or             *
 * modify it under the terms of the GNU Lesser General Public                *
 * License as published by the Free Software Foundation; either              *
 * version 2.1 of the License, or (at your option) any later version.        *
 *                                                                           *
 * This program is distributed in the hope that it will be useful,           *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
 * Lesser General Public License for more details.                           *
 *                                                                           *
 * You should have received a copy of the GNU Lesser General Public          *
 * License along with this package; if not, write to the Free Software       *
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA *
 *****************************************************************************/

#include "devicemanager.h"

#ifdef PHONON_PULSESUPPORT
#  include <phonon/pulsesupport.h>
#endif

#include <vlc/vlc.h>

#include "backend.h"
#include "debug.h"
#include "libvlc.h"

QT_BEGIN_NAMESPACE

namespace Phonon
{
namespace VLC
{

DeviceInfo::DeviceInfo(const QByteArray &name,
                       const QString &description,
                       bool isAdvanced)
{
    // Get an id
    static int counter = 0;
    id = counter++;

    // Get name and description for the device
    this->name = name;
    this->description = description;
    this->isAdvanced = isAdvanced;
    capabilities = None;
}

DeviceManager::DeviceManager(Backend *parent)
    : QObject(parent)
    , m_backend(parent)
{
    Q_ASSERT(parent);
#ifdef __GNUC__
#warning capture code needs rewrite, was removed due to brokeneness
#endif
    m_deviceLists << &m_audioOutputDeviceList
                  << &m_audioCaptureDeviceList
                  << &m_videoCaptureDeviceList;
    updateDeviceList();
}

DeviceManager::~DeviceManager()
{
    foreach (const QList<DeviceInfo> *list, m_deviceLists) {
        const_cast<QList<DeviceInfo> *>(list)->clear();
    }
}

bool DeviceManager::canOpenDevice() const
{
    return true;
}

int DeviceManager::deviceId(const QByteArray &name) const
{
    foreach (const QList<DeviceInfo> *list, m_deviceLists) {
        foreach (const DeviceInfo &device, *list) {
            if (device.name == name)
                return device.id;
        }
    }

    return -1;
}

QString DeviceManager::deviceDescription(int id) const
{
    foreach (const QList<DeviceInfo> *list, m_deviceLists) {
        foreach (const DeviceInfo &device, *list) {
            if (device.id == id)
                return QString(device.name);
        }
    }

    return QString();
}

void DeviceManager::updateDeviceSublist(const QList<DeviceInfo> &newDevices, QList<DeviceInfo> &deviceList)
{
    // New and old device counts
    int newDeviceCount = newDevices.count();
    int oldDeviceCount = deviceList.count();

    for (int i = 0; i < newDeviceCount; ++i) {
        int id = deviceId(newDevices[i].name);
        if (id == -1) {
            // This is a new device, add it
            deviceList.append(newDevices[i]);
            id = deviceId(newDevices[i].name);
            emit deviceAdded(id);

            debug() << "Added backend device" << newDevices[i].name.data() << "with id" << id;
        }
    }

    if (newDeviceCount < oldDeviceCount) {
        // A device was removed
        for (int i = oldDeviceCount - 1; i >= 0; --i) {
            QByteArray currId = deviceList[i].name;
            bool b_found = false;
            for (int k = newDeviceCount - 1; k >= 0; --k) {
                if (currId == newDevices[k].name) {
                    b_found = true;
                    break;
                }
            }
            if (!b_found) {
                emit deviceRemoved(deviceId(currId));
                deviceList.removeAt(i);
            }
        }
    }
}

void DeviceManager::updateDeviceList()
{
    // Lists for audio output devices
    QList<DeviceInfo> audioOutputDeviceList;
    audioOutputDeviceList.append(DeviceInfo("default"));
    audioOutputDeviceList.last().capabilities = DeviceInfo::AudioOutput;

    if (!LibVLC::self || !libvlc)
        return;

    // Get the list of available audio outputs
    libvlc_audio_output_t *p_ao_list = libvlc_audio_output_list_get(libvlc);
    if (!p_ao_list) {
        error() << "libVLC:" << LibVLC::errorMessage();
    }
    libvlc_audio_output_t *p_start = p_ao_list;

    bool checkpulse = false;
#ifdef PHONON_PULSESUPPORT
    PulseSupport *pulse = PulseSupport::getInstance();
    checkpulse = pulse->isActive();
#endif
    bool haspulse = false;
    while (p_ao_list) {
        if (checkpulse && strcmp(p_ao_list->psz_name, "pulse") == 0) {
            audioOutputDeviceList.last().isAdvanced = false;
            audioOutputDeviceList.last().accessList.append(DeviceAccess("pulse", "default"));
            haspulse = true;
            break;
        }

        DeviceInfo device(audioOutput->psz_name,
                          audioOutput->psz_description,
                          true);
        device.accessList.append(DeviceAccess(audioOutput->psz_name, QString()));
        device.capabilities = DeviceInfo::AudioOutput;
        audioOutputDeviceList.append(device);

        p_ao_list = p_ao_list->p_next;
    }
    libvlc_audio_output_list_release(p_start);

#ifdef PHONON_PULSESUPPORT
    if (haspulse) {
        return;
    }
    pulse->enable(false);
#endif

    updateDeviceSublist(audioOutputDeviceList, m_audioOutputDeviceList);
}

const QList<DeviceInfo> DeviceManager::audioCaptureDevices() const
{
    return m_audioCaptureDeviceList;
}

const QList<DeviceInfo> DeviceManager::videoCaptureDevices() const
{
    return m_videoCaptureDeviceList;
}

const QList<DeviceInfo> DeviceManager::audioOutputDevices() const
{
    return m_audioOutputDeviceList;
}

}
}

QT_END_NAMESPACE
<commit_msg>qstrcmp > strcmp<commit_after>/*****************************************************************************
 * libVLC backend for the Phonon library                                     *
 *                                                                           *
 * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com>               *
 * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com>                *
 * Copyright (C) 2009 Fathi Boudra <fabo@kde.org>                            *
 * Copyright (C) 2009-2010 vlc-phonon AUTHORS                                *
 *                                                                           *
 * This program is free software; you can redistribute it and/or             *
 * modify it under the terms of the GNU Lesser General Public                *
 * License as published by the Free Software Foundation; either              *
 * version 2.1 of the License, or (at your option) any later version.        *
 *                                                                           *
 * This program is distributed in the hope that it will be useful,           *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
 * Lesser General Public License for more details.                           *
 *                                                                           *
 * You should have received a copy of the GNU Lesser General Public          *
 * License along with this package; if not, write to the Free Software       *
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA *
 *****************************************************************************/

#include "devicemanager.h"

#ifdef PHONON_PULSESUPPORT
#  include <phonon/pulsesupport.h>
#endif

#include <vlc/vlc.h>

#include "backend.h"
#include "debug.h"
#include "libvlc.h"

QT_BEGIN_NAMESPACE

namespace Phonon
{
namespace VLC
{

DeviceInfo::DeviceInfo(const QByteArray &name,
                       const QString &description,
                       bool isAdvanced)
{
    // Get an id
    static int counter = 0;
    id = counter++;

    // Get name and description for the device
    this->name = name;
    this->description = description;
    this->isAdvanced = isAdvanced;
    capabilities = None;
}

DeviceManager::DeviceManager(Backend *parent)
    : QObject(parent)
    , m_backend(parent)
{
    Q_ASSERT(parent);
#ifdef __GNUC__
#warning capture code needs rewrite, was removed due to brokeneness
#endif
    m_deviceLists << &m_audioOutputDeviceList
                  << &m_audioCaptureDeviceList
                  << &m_videoCaptureDeviceList;
    updateDeviceList();
}

DeviceManager::~DeviceManager()
{
    foreach (const QList<DeviceInfo> *list, m_deviceLists) {
        const_cast<QList<DeviceInfo> *>(list)->clear();
    }
}

bool DeviceManager::canOpenDevice() const
{
    return true;
}

int DeviceManager::deviceId(const QByteArray &name) const
{
    foreach (const QList<DeviceInfo> *list, m_deviceLists) {
        foreach (const DeviceInfo &device, *list) {
            if (device.name == name)
                return device.id;
        }
    }

    return -1;
}

QString DeviceManager::deviceDescription(int id) const
{
    foreach (const QList<DeviceInfo> *list, m_deviceLists) {
        foreach (const DeviceInfo &device, *list) {
            if (device.id == id)
                return QString(device.name);
        }
    }

    return QString();
}

void DeviceManager::updateDeviceSublist(const QList<DeviceInfo> &newDevices, QList<DeviceInfo> &deviceList)
{
    // New and old device counts
    int newDeviceCount = newDevices.count();
    int oldDeviceCount = deviceList.count();

    for (int i = 0; i < newDeviceCount; ++i) {
        int id = deviceId(newDevices[i].name);
        if (id == -1) {
            // This is a new device, add it
            deviceList.append(newDevices[i]);
            id = deviceId(newDevices[i].name);
            emit deviceAdded(id);

            debug() << "Added backend device" << newDevices[i].name.data() << "with id" << id;
        }
    }

    if (newDeviceCount < oldDeviceCount) {
        // A device was removed
        for (int i = oldDeviceCount - 1; i >= 0; --i) {
            QByteArray currId = deviceList[i].name;
            bool b_found = false;
            for (int k = newDeviceCount - 1; k >= 0; --k) {
                if (currId == newDevices[k].name) {
                    b_found = true;
                    break;
                }
            }
            if (!b_found) {
                emit deviceRemoved(deviceId(currId));
                deviceList.removeAt(i);
            }
        }
    }
}

void DeviceManager::updateDeviceList()
{
    // Lists for audio output devices
    QList<DeviceInfo> audioOutputDeviceList;
    audioOutputDeviceList.append(DeviceInfo("default"));
    audioOutputDeviceList.last().capabilities = DeviceInfo::AudioOutput;

    if (!LibVLC::self || !libvlc)
        return;

    // Get the list of available audio outputs
    libvlc_audio_output_t *p_ao_list = libvlc_audio_output_list_get(libvlc);
    if (!p_ao_list) {
        error() << "libVLC:" << LibVLC::errorMessage();
    }
    libvlc_audio_output_t *p_start = p_ao_list;

    bool checkpulse = false;
#ifdef PHONON_PULSESUPPORT
    PulseSupport *pulse = PulseSupport::getInstance();
    checkpulse = pulse->isActive();
#endif
    bool haspulse = false;
    while (p_ao_list) {
        if (checkpulse && strcmp(p_ao_list->psz_name, "pulse") == 0) {
        if (checkpulse && qstrcmp(audioOutput->psz_name, "pulse") == 0) {
            audioOutputDeviceList.last().isAdvanced = false;
            audioOutputDeviceList.last().accessList.append(DeviceAccess("pulse", "default"));
            haspulse = true;
            break;
        }

        DeviceInfo device(audioOutput->psz_name,
                          audioOutput->psz_description,
                          true);
        device.accessList.append(DeviceAccess(audioOutput->psz_name, QString()));
        device.capabilities = DeviceInfo::AudioOutput;
        audioOutputDeviceList.append(device);

        p_ao_list = p_ao_list->p_next;
    }
    libvlc_audio_output_list_release(p_start);

#ifdef PHONON_PULSESUPPORT
    if (haspulse) {
        return;
    }
    pulse->enable(false);
#endif

    updateDeviceSublist(audioOutputDeviceList, m_audioOutputDeviceList);
}

const QList<DeviceInfo> DeviceManager::audioCaptureDevices() const
{
    return m_audioCaptureDeviceList;
}

const QList<DeviceInfo> DeviceManager::videoCaptureDevices() const
{
    return m_videoCaptureDeviceList;
}

const QList<DeviceInfo> DeviceManager::audioOutputDevices() const
{
    return m_audioOutputDeviceList;
}

}
}

QT_END_NAMESPACE
<|endoftext|>


<commit_before>#include "iopin.h"

namespace drv {

std::set<IoPin*> IoPin::livingPins; //allocate storage for static variables.
IoPin::null IoPin::null::_null;

//move constructor:
IoPin::IoPin(IoPin &&other) : _pin(PrimitiveIoPin::null()) {
	*this = std::move(other);
}

IoPin& IoPin::operator=(IoPin &&other) {
	_pin = other._pin;
	other._pin = IoPin::null::ref()._pin;
	livingPins.insert(this);
    livingPins.erase(&other);
    return *this;
}

}<commit_msg>Fix move assignment<commit_after>#include "iopin.h"

namespace drv {

std::set<IoPin*> IoPin::livingPins; //allocate storage for static variables.
IoPin::null IoPin::null::_null;

//move constructor:
IoPin::IoPin(IoPin &&other) : _pin(PrimitiveIoPin::null()) {
	*this = std::move(other);
}

IoPin& IoPin::operator=(IoPin &&other) {
	_invertReads = other._invertReads;
    _invertWrites = other._invertWrites;
    _defaultState = other._defaultState;
	_pin = other._pin;
	other._pin = IoPin::null::ref()._pin;
	livingPins.insert(this);
    livingPins.erase(&other);
    return *this;
}

}<|endoftext|>


<commit_before><commit_msg>fixes The-OpenROAD-Project/OpenLane#928<commit_after><|endoftext|>


<commit_before>#include "Enemy.h"
#include "SceneHandler.h"
#include "Input.h"
#include <iostream>
#include <cstdlib>
#include <time.h>

Enemy::Enemy(bool UFO, float speed, float xPos, float yPos)
{
	m_bUFO = UFO;
	m_bMoveRight = true;
	m_fSpeed = speed;
	m_bScreenEdge = false;
	m_bCanShoot = false;
	m_bDead = false;
	m_spPosition = std::make_shared<glm::vec2>(xPos, yPos);
	m_spRenderer = std::make_shared<aie::Renderer2D>();
	m_iTexture = 0;
	m_iTextureSize = 50;
	m_fTimer = 0;
	m_bullet = Bullet(Vector2(m_spPosition->x, m_spPosition->y), Direction::DOWN);
	InitTextures();
	m_fTime = 1.0f;
	m_fTimers = 0.0f;
	m_iHealth = 3;
	m_bullet.m_bulletActive = !m_bullet.m_bulletActive;
	m_bullet.m_bulletActive = !m_bullet.m_bulletActive;
	m_bullet.ChangePosition(Vector2(m_spPosition->x, m_spPosition->y));
	srand(time(NULL));
}

Enemy::~Enemy()
{
	//delete m_bullet;
}

void Enemy::InitTextures()
{
	if (m_bUFO)
	{
		m_vTextures.push_back(std::make_shared<aie::Texture>("./textures/UFO.png"));
		m_vTextures.push_back(std::make_shared<aie::Texture>("./textures/UFO_Dead.png"));
		m_fMaxLeft = -50;
		m_fMaxRight = 1300;
	}
	else
	{
		m_vTextures.push_back(std::make_shared<aie::Texture>("./textures/Enemy1_0.png"));
		m_vTextures.push_back(std::make_shared<aie::Texture>("./textures/Enemy1_1.png"));
		m_vTextures.push_back(std::make_shared<aie::Texture>("./textures/Enemy_Explode.png"));
		m_fMaxLeft = 50;
		m_fMaxRight = 1300;
	}
}

/// update enemy
void Enemy::Update(float deltatime)
{
	if (!m_bDead) {
		if (!m_bullet.m_bulletActive) {
			int check = rand() % 2;

			if (check)
			{
				m_fTimers += deltatime;
			}

			if (m_fTimers >= m_fTime && check)
			{
				m_fTimers = 0;
				m_bullet.m_bulletActive = !m_bullet.m_bulletActive;
				m_bullet.ChangePosition(Vector2(m_spPosition->x, m_spPosition->y));
			}
		}

		// animate enemy
		textureSwap(deltatime);
		// check enemy direction
		enemyDirection();
		// shoot bullet
		if (m_bullet.m_bulletActive) {
			m_bullet.Update(deltatime);
		}

		// update enemy position
		moveEnemy(deltatime);
	}
	else
	{
		m_bullet.m_bulletActive = false;
	}
}

/// draw enemy to screen
void Enemy::Draw(aie::Renderer2D& renderer)
{
	if (!m_bDead)
	{
		renderer.drawSprite(m_vTextures[m_iTexture].get(), m_spPosition->x, m_spPosition->y, m_iTextureSize, m_iTextureSize, 0, 0);
	}
	else
	{
		//renderer.drawSprite(m_vTextures.back().get(), m_spPosition->x, m_spPosition->y, m_iTextureSize, m_iTextureSize, 0, 0);
	}

	// draw bullet is there is one
	if (m_bullet.m_bulletActive) {
		m_bullet.Draw(renderer);
	}
}

std::shared_ptr<glm::vec2> Enemy::position()
{
	return m_spPosition;
}

std::shared_ptr<aie::Texture> Enemy::texture(int id)
{
	return m_vTextures[id];
}

bool Enemy::hitEdge()
{
	return m_bHitEdge;
}

bool Enemy::hitEdge(bool swap)
{
	m_bHitEdge = swap;
	return m_bHitEdge;
}

void Enemy::changeDirection()
{
	m_bMoveRight = !m_bMoveRight;
}

bool Enemy::collisionCheck(Bullet& bullet)
{
	if (m_iHealth <= 0)
	{
		setDead(true);
		SceneHandler::RemoveAlien();
		SceneHandler::scoreNumeric += 1;
	}
	if (m_spPosition->x > bullet.GetPosition().x - m_iTextureSize / 2 &&
		m_spPosition->x < bullet.GetPosition().x + m_iTextureSize / 2 &&
		m_spPosition->y > bullet.GetPosition().y - m_iTextureSize / 2 &&
		m_spPosition->y < bullet.GetPosition().y + m_iTextureSize / 2)
	{
		// Destroy/de-activate bullet here...
		bullet.m_bulletActive = false;
		bullet.ChangePosition(Vector2(10000, 10000));
		m_iHealth--;
	}

	return m_bDead;
}

bool Enemy::isDead()
{
	return m_bDead;
}

void Enemy::setDead(bool status)
{
	m_bDead = status;
}

/// shoot bullet
void Enemy::shot(float deltatime)
{
	if (m_bullet.m_bulletActive)
	{
		m_bullet.Update(deltatime);
	}
}

Bullet& Enemy::GetBullet()
{
	return m_bullet;
}

/// swap enemies texture overtime
void Enemy::textureSwap(float deltatime)
{
	if (m_fTimer <= 1.5) {
		m_fTimer += deltatime;
	}
	else {
		m_fTimer = 0;
		// swap texture
		m_iTexture = (m_iTexture == 0 ? 1 : 0);
	}
}

void Enemy::moveEnemy(float deltatime)
{
	// move right
	if (m_bMoveRight) {
		m_spPosition->x += m_fSpeed * deltatime;
	}
	// move left
	if (!m_bMoveRight) {
		m_spPosition->x -= m_fSpeed * deltatime;
	}
}

void Enemy::enemyDirection()
{
	// if moving left and hits the left edge, move right
	if (m_spPosition->x < 50) {
		m_bMoveRight = true;
	}
	// if moving right and hits the right edge, move left
	if (m_spPosition->x > 1200) {
		m_bMoveRight = false;
	}
}
<commit_msg>---codingPhilosopher-- Patched out early enemy rebound Game is now beatifully challenging :D<commit_after>#include "Enemy.h"
#include "SceneHandler.h"
#include "Input.h"
#include <iostream>
#include <cstdlib>
#include <time.h>

Enemy::Enemy(bool UFO, float speed, float xPos, float yPos)
{
	m_bUFO = UFO;
	m_bMoveRight = true;
	m_fSpeed = speed;
	m_bScreenEdge = false;
	m_bCanShoot = false;
	m_bDead = false;
	m_spPosition = std::make_shared<glm::vec2>(xPos, yPos);
	m_spRenderer = std::make_shared<aie::Renderer2D>();
	m_iTexture = 0;
	m_iTextureSize = 50;
	m_fTimer = 0;
	m_bullet = Bullet(Vector2(m_spPosition->x, m_spPosition->y), Direction::DOWN);
	InitTextures();
	m_fTime = 1.0f;
	m_fTimers = 0.0f;
	m_iHealth = 3;
	m_bullet.m_bulletActive = !m_bullet.m_bulletActive;
	m_bullet.m_bulletActive = !m_bullet.m_bulletActive;
	m_bullet.ChangePosition(Vector2(m_spPosition->x, m_spPosition->y));
	srand(time(NULL));
}

Enemy::~Enemy()
{
	//delete m_bullet;
}

void Enemy::InitTextures()
{
	if (m_bUFO)
	{
		m_vTextures.push_back(std::make_shared<aie::Texture>("./textures/UFO.png"));
		m_vTextures.push_back(std::make_shared<aie::Texture>("./textures/UFO_Dead.png"));
		m_fMaxLeft = -50;
		m_fMaxRight = 1300;
	}
	else
	{
		m_vTextures.push_back(std::make_shared<aie::Texture>("./textures/Enemy1_0.png"));
		m_vTextures.push_back(std::make_shared<aie::Texture>("./textures/Enemy1_1.png"));
		m_vTextures.push_back(std::make_shared<aie::Texture>("./textures/Enemy_Explode.png"));
		m_fMaxLeft = 50;
		m_fMaxRight = 1250;
	}
}

/// update enemy
void Enemy::Update(float deltatime)
{
	if (!m_bDead) {
		if (!m_bullet.m_bulletActive) {
			int check = rand() % 2;

			if (check)
			{
				m_fTimers += deltatime;
			}

			if (m_fTimers >= m_fTime && check)
			{
				m_fTimers = 0;
				m_bullet.m_bulletActive = !m_bullet.m_bulletActive;
				m_bullet.ChangePosition(Vector2(m_spPosition->x, m_spPosition->y));
			}
		}

		// animate enemy
		textureSwap(deltatime);
		// check enemy direction
		enemyDirection();
		// shoot bullet
		if (m_bullet.m_bulletActive) {
			m_bullet.Update(deltatime);
		}

		// update enemy position
		moveEnemy(deltatime);
	}
	else
	{
		m_bullet.m_bulletActive = false;
	}
}

/// draw enemy to screen
void Enemy::Draw(aie::Renderer2D& renderer)
{
	if (!m_bDead)
	{
		renderer.drawSprite(m_vTextures[m_iTexture].get(), m_spPosition->x, m_spPosition->y, m_iTextureSize, m_iTextureSize, 0, 0);
	}
	else
	{
		//renderer.drawSprite(m_vTextures.back().get(), m_spPosition->x, m_spPosition->y, m_iTextureSize, m_iTextureSize, 0, 0);
	}

	// draw bullet is there is one
	if (m_bullet.m_bulletActive) {
		m_bullet.Draw(renderer);
	}
}

std::shared_ptr<glm::vec2> Enemy::position()
{
	return m_spPosition;
}

std::shared_ptr<aie::Texture> Enemy::texture(int id)
{
	return m_vTextures[id];
}

bool Enemy::hitEdge()
{
	return m_bHitEdge;
}

bool Enemy::hitEdge(bool swap)
{
	m_bHitEdge = swap;
	return m_bHitEdge;
}

void Enemy::changeDirection()
{
	m_bMoveRight = !m_bMoveRight;
}

bool Enemy::collisionCheck(Bullet& bullet)
{
	if (m_iHealth <= 0)
	{
		setDead(true);
		SceneHandler::RemoveAlien();
		SceneHandler::scoreNumeric += 1;
	}
	if (m_spPosition->x > bullet.GetPosition().x - m_iTextureSize / 2 &&
		m_spPosition->x < bullet.GetPosition().x + m_iTextureSize / 2 &&
		m_spPosition->y > bullet.GetPosition().y - m_iTextureSize / 2 &&
		m_spPosition->y < bullet.GetPosition().y + m_iTextureSize / 2)
	{
		// Destroy/de-activate bullet here...
		bullet.m_bulletActive = false;
		bullet.ChangePosition(Vector2(10000, 10000));
		m_iHealth--;
	}

	return m_bDead;
}

bool Enemy::isDead()
{
	return m_bDead;
}

void Enemy::setDead(bool status)
{
	m_bDead = status;
}

/// shoot bullet
void Enemy::shot(float deltatime)
{
	if (m_bullet.m_bulletActive)
	{
		m_bullet.Update(deltatime);
	}
}

Bullet& Enemy::GetBullet()
{
	return m_bullet;
}

/// swap enemies texture overtime
void Enemy::textureSwap(float deltatime)
{
	if (m_fTimer <= 1.5) {
		m_fTimer += deltatime;
	}
	else {
		m_fTimer = 0;
		// swap texture
		m_iTexture = (m_iTexture == 0 ? 1 : 0);
	}
}

void Enemy::moveEnemy(float deltatime)
{
	// move right
	if (m_bMoveRight) {
		m_spPosition->x += m_fSpeed * deltatime;
	}
	// move left
	if (!m_bMoveRight) {
		m_spPosition->x -= m_fSpeed * deltatime;
	}
}

void Enemy::enemyDirection()
{
	// if moving left and hits the left edge, move right
	if (m_spPosition->x < m_fMaxLeft) {
		m_bMoveRight = true;
	}
	// if moving right and hits the right edge, move left
	if (m_spPosition->x > m_fMaxRight) {
		m_bMoveRight = false;
	}
}
<|endoftext|>


<commit_before>#include <gdf/gdf.h>

#define GETNAME(x) case x: return #x;

const char * gdf_error_get_name(gdf_error errcode) {
    switch (errcode) {
    // There must be one entry per enum values in gdf_error.
    GETNAME(GDF_SUCCESS)
    GETNAME(GDF_CUDA_ERROR)
    GETNAME(GDF_UNSUPPORTED_DTYPE)
    GETNAME(GDF_COLUMN_SIZE_MISMATCH)
    GETNAME(GDF_COLUMN_SIZE_TOO_BIG)
    GETNAME(GDF_DATASET_EMPTY)
    GETNAME(GDF_VALIDITY_MISSING)
    GETNAME(GDF_VALIDITY_UNSUPPORTED)
    GETNAME(GDF_INVALID_API_CALL)
    GETNAME(GDF_JOIN_DTYPE_MISMATCH)
    GETNAME(GDF_JOIN_TOO_MANY_COLUMNS)
    GETNAME(GDF_UNSUPPORTED_METHOD)
    GETNAME(GDF_INVALID_AGGREGATOR)
    GETNAME(GDF_INVALID_HASH_FUNCTION)
    GETNAME(GDF_PARTITION_DTYPE_MISMATCH)
    GETNAME(GDF_HASH_TABLE_INSERT_FAILURE)
    GETNAME(GDF_UNSUPPORTED_JOIN_TYPE)
    GETNAME(GDF_DTYPE_MISMATCH)
    GETNAME(GDF_MEMORYMANAGER_ERROR)
    default:
        // This means we are missing an entry above for a gdf_error value.
        return "Internal error. Unknown error code.";
    }
}
<commit_msg>Added missing error enums from gdf_get_error_name()<commit_after>#include <gdf/gdf.h>

#define GETNAME(x) case x: return #x;

const char * gdf_error_get_name(gdf_error errcode) {
    switch (errcode) {
    // There must be one entry per enum values in gdf_error.
    GETNAME(GDF_SUCCESS)
    GETNAME(GDF_CUDA_ERROR)
    GETNAME(GDF_UNSUPPORTED_DTYPE)
    GETNAME(GDF_COLUMN_SIZE_MISMATCH)
    GETNAME(GDF_COLUMN_SIZE_TOO_BIG)
    GETNAME(GDF_DATASET_EMPTY)
    GETNAME(GDF_VALIDITY_MISSING)
    GETNAME(GDF_VALIDITY_UNSUPPORTED)
    GETNAME(GDF_INVALID_API_CALL)
    GETNAME(GDF_JOIN_DTYPE_MISMATCH)
    GETNAME(GDF_JOIN_TOO_MANY_COLUMNS)
    GETNAME(GDF_DTYPE_MISMATCH)
    GETNAME(GDF_UNSUPPORTED_METHOD)
    GETNAME(GDF_INVALID_AGGREGATOR)
    GETNAME(GDF_INVALID_HASH_FUNCTION)
    GETNAME(GDF_PARTITION_DTYPE_MISMATCH)
    GETNAME(GDF_HASH_TABLE_INSERT_FAILURE)
    GETNAME(GDF_UNSUPPORTED_JOIN_TYPE)
    GETNAME(GDF_C_ERROR)
    GETNAME(GDF_FILE_ERROR)
    GETNAME(GDF_MEMORYMANAGER_ERROR)
    default:
        // This means we are missing an entry above for a gdf_error value.
        return "Internal error. Unknown error code.";
    }
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2003, Arvid Norberg
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 author 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.

*/

#include "libtorrent/pch.hpp"

#include <string>
#include <stdexcept>
#include <sstream>
#include <iomanip>
#include <cctype>
#include <algorithm>
#include <iostream>
#include <limits>

#include <boost/optional.hpp>
#include <boost/array.hpp>

#include "libtorrent/assert.hpp"
#include "libtorrent/escape_string.hpp"

namespace libtorrent
{

	// lexical_cast's result depends on the locale. We need
	// a well defined result
	boost::array<char, 3 + std::numeric_limits<size_type>::digits10> to_string(size_type n)
	{
		boost::array<char, 3 + std::numeric_limits<size_type>::digits10> ret;
		char *p = &ret.back();;
		*p = '\0';
		unsigned_size_type un = n;
		if (n < 0)  un = -un;
		do {
			*--p = '0' + un % 10;
			un /= 10;
		} while (un);
		if (n < 0) *--p = '-';
		std::memmove(&ret.front(), p, sizeof(ret.elems));
		return ret;
	}

	std::string unescape_string(std::string const& s)
	{
		std::string ret;
		for (std::string::const_iterator i = s.begin(); i != s.end(); ++i)
		{
			if(*i == '+')
			{
				ret += ' ';
			}
			else if (*i != '%')
			{
				ret += *i;
			}
			else
			{
				++i;
				if (i == s.end())
#ifdef BOOST_NO_EXCEPTIONS
					return ret;
#else
					throw std::runtime_error("invalid escaped string");
#endif

				int high;
				if(*i >= '0' && *i <= '9') high = *i - '0';
				else if(*i >= 'A' && *i <= 'F') high = *i + 10 - 'A';
				else if(*i >= 'a' && *i <= 'f') high = *i + 10 - 'a';
				else
#ifdef BOOST_NO_EXCEPTIONS
					return ret;
#else
					throw std::runtime_error("invalid escaped string");
#endif

				++i;
				if (i == s.end())
#ifdef BOOST_NO_EXCEPTIONS
					return ret;
#else
					throw std::runtime_error("invalid escaped string");
#endif

				int low;
				if(*i >= '0' && *i <= '9') low = *i - '0';
				else if(*i >= 'A' && *i <= 'F') low = *i + 10 - 'A';
				else if(*i >= 'a' && *i <= 'f') low = *i + 10 - 'a';
				else
#ifdef BOOST_NO_EXCEPTIONS
					return ret;
#else
					throw std::runtime_error("invalid escaped string");
#endif

				ret += char(high * 16 + low);
			}
		}
		return ret;
	}

	std::string escape_string(const char* str, int len)
	{
		TORRENT_ASSERT(str != 0);
		TORRENT_ASSERT(len >= 0);
		// http://www.ietf.org/rfc/rfc2396.txt
		// section 2.3
		// some trackers seems to require that ' is escaped
//		static const char unreserved_chars[] = "-_.!~*'()";
		static const char unreserved_chars[] = "-_.!~*()"
			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
			"0123456789";

		std::stringstream ret;
		ret << std::hex << std::setfill('0');
		for (int i = 0; i < len; ++i)
		{
			if (std::count(
					unreserved_chars
					, unreserved_chars+sizeof(unreserved_chars)-1
					, *str))
			{
				ret << *str;
			}
			else
			{
				ret << '%'
					<< std::setw(2)
					<< (int)static_cast<unsigned char>(*str);
			}
			++str;
		}
		return ret.str();
	}

	std::string escape_path(const char* str, int len)
	{
		TORRENT_ASSERT(str != 0);
		TORRENT_ASSERT(len >= 0);
		static const char unreserved_chars[] = "/-_.!~*()"
			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
			"0123456789";

		std::stringstream ret;
		ret << std::hex << std::setfill('0');
		for (int i = 0; i < len; ++i)
		{
			if (std::count(
					unreserved_chars
					, unreserved_chars+sizeof(unreserved_chars)-1
					, *str))
			{
				ret << *str;
			}
			else
			{
				ret << '%'
					<< std::setw(2)
					<< (int)static_cast<unsigned char>(*str);
			}
			++str;
		}
		return ret.str();
	}

	std::string base64encode(const std::string& s)
	{
		static const char base64_table[] =
		{
			'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
			'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
			'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
			'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
			'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
			'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
			'w', 'x', 'y', 'z', '0', '1', '2', '3',
			'4', '5', '6', '7', '8', '9', '+', '/'
		};

		unsigned char inbuf[3];
		unsigned char outbuf[4];

		std::string ret;
		for (std::string::const_iterator i = s.begin(); i != s.end();)
		{
			// available input is 1,2 or 3 bytes
			// since we read 3 bytes at a time at most
			int available_input = (std::min)(3, (int)std::distance(i, s.end()));

			// clear input buffer
			std::fill(inbuf, inbuf+3, 0);

			// read a chunk of input into inbuf
			std::copy(i, i + available_input, inbuf);
			i += available_input;

			// encode inbuf to outbuf
			outbuf[0] = (inbuf[0] & 0xfc) >> 2;
			outbuf[1] = ((inbuf[0] & 0x03) << 4) | ((inbuf [1] & 0xf0) >> 4);
			outbuf[2] = ((inbuf[1] & 0x0f) << 2) | ((inbuf [2] & 0xc0) >> 6);
			outbuf[3] = inbuf[2] & 0x3f;

			// write output
			for (int j = 0; j < available_input+1; ++j)
			{
				ret += base64_table[outbuf[j]];
			}

			// write pad
			for (int j = 0; j < 3 - available_input; ++j)
			{
				ret += '=';
			}
		}
		return ret;
	}

	std::string base32encode(std::string const& s)
	{
		static const char base32_table[] =
		{
			'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
			'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
			'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
			'Y', 'Z', '2', '3', '4', '5', '6', '7'
		};

		int input_output_mapping[] = {0, 2, 4, 5, 7, 8};

		unsigned char inbuf[5];
		unsigned char outbuf[8];

		std::string ret;
		for (std::string::const_iterator i = s.begin(); i != s.end();)
		{
			int available_input = (std::min)(5, (int)std::distance(i, s.end()));

			// clear input buffer
			std::fill(inbuf, inbuf+5, 0);

			// read a chunk of input into inbuf
			std::copy(i, i + available_input, inbuf);
			i += available_input;

			// encode inbuf to outbuf
			outbuf[0] = (inbuf[0] & 0xf8) >> 3;
			outbuf[1] = ((inbuf[0] & 0x07) << 2) | ((inbuf[1] & 0xc0) >> 6);
			outbuf[2] = ((inbuf[1] & 0x3e) >> 1);
			outbuf[3] = ((inbuf[1] & 0x01) << 4) | ((inbuf[2] & 0xf0) >> 4);
			outbuf[4] = ((inbuf[2] & 0x0f) << 1) | ((inbuf[3] & 0x80) >> 7);
			outbuf[5] = ((inbuf[3] & 0x7c) >> 2);
			outbuf[6] = ((inbuf[3] & 0x03) << 3) | ((inbuf[4] & 0xe0) >> 5);
			outbuf[7] = inbuf[4] & 0x1f;

			// write output
			int num_out = input_output_mapping[available_input];
			for (int j = 0; j < num_out; ++j)
			{
				ret += base32_table[outbuf[j]];
			}

			// write pad
			for (int j = 0; j < 8 - num_out; ++j)
			{
				ret += '=';
			}
		}
		return ret;
	}

	std::string base32decode(std::string const& s)
	{
		unsigned char inbuf[8];
		unsigned char outbuf[5];

		std::string ret;
		for (std::string::const_iterator i = s.begin(); i != s.end();)
		{
			int available_input = (std::min)(8, (int)std::distance(i, s.end()));

			int pad_start = 0;
			if (available_input < 8) pad_start = available_input;

			// clear input buffer
			std::fill(inbuf, inbuf+8, 0);
			for (int j = 0; j < available_input; ++j)
			{
				char in = std::toupper(*i++);
				if (in >= 'A' && in <= 'Z')
					inbuf[j] = in - 'A';
				else if (in >= '2' && in <= '7')
					inbuf[j] = in - '2' + ('Z' - 'A') + 1;
				else if (in == '=')
				{
					inbuf[j] = 0;
					if (pad_start == 0) pad_start = j;
				}
				else if (in == '1')
					inbuf[j] = 'I' - 'A';
				else
					return std::string();
				TORRENT_ASSERT(inbuf[j] == (inbuf[j] & 0x1f));
			}

			// decode inbuf to outbuf
			outbuf[0] = inbuf[0] << 3;
			outbuf[0] |= inbuf[1] >> 2;
			outbuf[1] = (inbuf[1] & 0x3) << 6;
			outbuf[1] |= inbuf[2] << 1;
			outbuf[1] |= (inbuf[3] & 0x10) >> 4;
			outbuf[2] = (inbuf[3] & 0x0f) << 4;
			outbuf[2] |= (inbuf[4] & 0x1e) >> 1;
			outbuf[3] = (inbuf[4] & 0x01) << 7;
			outbuf[3] |= (inbuf[5] & 0x1f) << 2;
			outbuf[3] |= (inbuf[6] & 0x18) >> 3;
			outbuf[4] = (inbuf[6] & 0x07) << 5;
			outbuf[4] |= inbuf[7];

			int input_output_mapping[] = {5, 1, 1, 2, 2, 3, 4, 4, 5};
			int num_out = input_output_mapping[pad_start];

			// write output
			std::copy(outbuf, outbuf + num_out, std::back_inserter(ret));
		}
		return ret;
	}

	boost::optional<std::string> url_has_argument(
		std::string const& url, std::string argument)
	{
		size_t i = url.find('?');
		if (i == std::string::npos) return boost::optional<std::string>();
		++i;

		argument += '=';

		if (url.compare(i, argument.size(), argument) == 0)
		{
			size_t pos = i + argument.size();
			return url.substr(pos, url.find('&', pos) - pos);
		}
		argument.insert(0, "&");
		i = url.find(argument, i);
		if (i == std::string::npos) return boost::optional<std::string>();
		size_t pos = i + argument.size();
		return url.substr(pos, url.find('&', pos) - pos);
	}

	TORRENT_EXPORT std::string to_hex(std::string const& s)
	{
		std::string ret;
		char const* digits = "0123456789abcdef";
		for (std::string::const_iterator i = s.begin(); i != s.end(); ++i)
		{
			ret += digits[((unsigned char)*i) >> 4];
			ret += digits[((unsigned char)*i) & 0xf];
		}
		return ret;
	}

}

<commit_msg>added missing include<commit_after>/*

Copyright (c) 2003, Arvid Norberg
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 author 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.

*/

#include "libtorrent/pch.hpp"

#include <string>
#include <stdexcept>
#include <sstream>
#include <iomanip>
#include <cctype>
#include <algorithm>
#include <iostream>
#include <limits>
#include <cstring>

#include <boost/optional.hpp>
#include <boost/array.hpp>

#include "libtorrent/assert.hpp"
#include "libtorrent/escape_string.hpp"

namespace libtorrent
{

	// lexical_cast's result depends on the locale. We need
	// a well defined result
	boost::array<char, 3 + std::numeric_limits<size_type>::digits10> to_string(size_type n)
	{
		boost::array<char, 3 + std::numeric_limits<size_type>::digits10> ret;
		char *p = &ret.back();;
		*p = '\0';
		unsigned_size_type un = n;
		if (n < 0)  un = -un;
		do {
			*--p = '0' + un % 10;
			un /= 10;
		} while (un);
		if (n < 0) *--p = '-';
		std::memmove(&ret.front(), p, sizeof(ret.elems));
		return ret;
	}

	std::string unescape_string(std::string const& s)
	{
		std::string ret;
		for (std::string::const_iterator i = s.begin(); i != s.end(); ++i)
		{
			if(*i == '+')
			{
				ret += ' ';
			}
			else if (*i != '%')
			{
				ret += *i;
			}
			else
			{
				++i;
				if (i == s.end())
#ifdef BOOST_NO_EXCEPTIONS
					return ret;
#else
					throw std::runtime_error("invalid escaped string");
#endif

				int high;
				if(*i >= '0' && *i <= '9') high = *i - '0';
				else if(*i >= 'A' && *i <= 'F') high = *i + 10 - 'A';
				else if(*i >= 'a' && *i <= 'f') high = *i + 10 - 'a';
				else
#ifdef BOOST_NO_EXCEPTIONS
					return ret;
#else
					throw std::runtime_error("invalid escaped string");
#endif

				++i;
				if (i == s.end())
#ifdef BOOST_NO_EXCEPTIONS
					return ret;
#else
					throw std::runtime_error("invalid escaped string");
#endif

				int low;
				if(*i >= '0' && *i <= '9') low = *i - '0';
				else if(*i >= 'A' && *i <= 'F') low = *i + 10 - 'A';
				else if(*i >= 'a' && *i <= 'f') low = *i + 10 - 'a';
				else
#ifdef BOOST_NO_EXCEPTIONS
					return ret;
#else
					throw std::runtime_error("invalid escaped string");
#endif

				ret += char(high * 16 + low);
			}
		}
		return ret;
	}

	std::string escape_string(const char* str, int len)
	{
		TORRENT_ASSERT(str != 0);
		TORRENT_ASSERT(len >= 0);
		// http://www.ietf.org/rfc/rfc2396.txt
		// section 2.3
		// some trackers seems to require that ' is escaped
//		static const char unreserved_chars[] = "-_.!~*'()";
		static const char unreserved_chars[] = "-_.!~*()"
			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
			"0123456789";

		std::stringstream ret;
		ret << std::hex << std::setfill('0');
		for (int i = 0; i < len; ++i)
		{
			if (std::count(
					unreserved_chars
					, unreserved_chars+sizeof(unreserved_chars)-1
					, *str))
			{
				ret << *str;
			}
			else
			{
				ret << '%'
					<< std::setw(2)
					<< (int)static_cast<unsigned char>(*str);
			}
			++str;
		}
		return ret.str();
	}

	std::string escape_path(const char* str, int len)
	{
		TORRENT_ASSERT(str != 0);
		TORRENT_ASSERT(len >= 0);
		static const char unreserved_chars[] = "/-_.!~*()"
			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
			"0123456789";

		std::stringstream ret;
		ret << std::hex << std::setfill('0');
		for (int i = 0; i < len; ++i)
		{
			if (std::count(
					unreserved_chars
					, unreserved_chars+sizeof(unreserved_chars)-1
					, *str))
			{
				ret << *str;
			}
			else
			{
				ret << '%'
					<< std::setw(2)
					<< (int)static_cast<unsigned char>(*str);
			}
			++str;
		}
		return ret.str();
	}

	std::string base64encode(const std::string& s)
	{
		static const char base64_table[] =
		{
			'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
			'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
			'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
			'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
			'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
			'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
			'w', 'x', 'y', 'z', '0', '1', '2', '3',
			'4', '5', '6', '7', '8', '9', '+', '/'
		};

		unsigned char inbuf[3];
		unsigned char outbuf[4];

		std::string ret;
		for (std::string::const_iterator i = s.begin(); i != s.end();)
		{
			// available input is 1,2 or 3 bytes
			// since we read 3 bytes at a time at most
			int available_input = (std::min)(3, (int)std::distance(i, s.end()));

			// clear input buffer
			std::fill(inbuf, inbuf+3, 0);

			// read a chunk of input into inbuf
			std::copy(i, i + available_input, inbuf);
			i += available_input;

			// encode inbuf to outbuf
			outbuf[0] = (inbuf[0] & 0xfc) >> 2;
			outbuf[1] = ((inbuf[0] & 0x03) << 4) | ((inbuf [1] & 0xf0) >> 4);
			outbuf[2] = ((inbuf[1] & 0x0f) << 2) | ((inbuf [2] & 0xc0) >> 6);
			outbuf[3] = inbuf[2] & 0x3f;

			// write output
			for (int j = 0; j < available_input+1; ++j)
			{
				ret += base64_table[outbuf[j]];
			}

			// write pad
			for (int j = 0; j < 3 - available_input; ++j)
			{
				ret += '=';
			}
		}
		return ret;
	}

	std::string base32encode(std::string const& s)
	{
		static const char base32_table[] =
		{
			'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
			'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
			'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
			'Y', 'Z', '2', '3', '4', '5', '6', '7'
		};

		int input_output_mapping[] = {0, 2, 4, 5, 7, 8};

		unsigned char inbuf[5];
		unsigned char outbuf[8];

		std::string ret;
		for (std::string::const_iterator i = s.begin(); i != s.end();)
		{
			int available_input = (std::min)(5, (int)std::distance(i, s.end()));

			// clear input buffer
			std::fill(inbuf, inbuf+5, 0);

			// read a chunk of input into inbuf
			std::copy(i, i + available_input, inbuf);
			i += available_input;

			// encode inbuf to outbuf
			outbuf[0] = (inbuf[0] & 0xf8) >> 3;
			outbuf[1] = ((inbuf[0] & 0x07) << 2) | ((inbuf[1] & 0xc0) >> 6);
			outbuf[2] = ((inbuf[1] & 0x3e) >> 1);
			outbuf[3] = ((inbuf[1] & 0x01) << 4) | ((inbuf[2] & 0xf0) >> 4);
			outbuf[4] = ((inbuf[2] & 0x0f) << 1) | ((inbuf[3] & 0x80) >> 7);
			outbuf[5] = ((inbuf[3] & 0x7c) >> 2);
			outbuf[6] = ((inbuf[3] & 0x03) << 3) | ((inbuf[4] & 0xe0) >> 5);
			outbuf[7] = inbuf[4] & 0x1f;

			// write output
			int num_out = input_output_mapping[available_input];
			for (int j = 0; j < num_out; ++j)
			{
				ret += base32_table[outbuf[j]];
			}

			// write pad
			for (int j = 0; j < 8 - num_out; ++j)
			{
				ret += '=';
			}
		}
		return ret;
	}

	std::string base32decode(std::string const& s)
	{
		unsigned char inbuf[8];
		unsigned char outbuf[5];

		std::string ret;
		for (std::string::const_iterator i = s.begin(); i != s.end();)
		{
			int available_input = (std::min)(8, (int)std::distance(i, s.end()));

			int pad_start = 0;
			if (available_input < 8) pad_start = available_input;

			// clear input buffer
			std::fill(inbuf, inbuf+8, 0);
			for (int j = 0; j < available_input; ++j)
			{
				char in = std::toupper(*i++);
				if (in >= 'A' && in <= 'Z')
					inbuf[j] = in - 'A';
				else if (in >= '2' && in <= '7')
					inbuf[j] = in - '2' + ('Z' - 'A') + 1;
				else if (in == '=')
				{
					inbuf[j] = 0;
					if (pad_start == 0) pad_start = j;
				}
				else if (in == '1')
					inbuf[j] = 'I' - 'A';
				else
					return std::string();
				TORRENT_ASSERT(inbuf[j] == (inbuf[j] & 0x1f));
			}

			// decode inbuf to outbuf
			outbuf[0] = inbuf[0] << 3;
			outbuf[0] |= inbuf[1] >> 2;
			outbuf[1] = (inbuf[1] & 0x3) << 6;
			outbuf[1] |= inbuf[2] << 1;
			outbuf[1] |= (inbuf[3] & 0x10) >> 4;
			outbuf[2] = (inbuf[3] & 0x0f) << 4;
			outbuf[2] |= (inbuf[4] & 0x1e) >> 1;
			outbuf[3] = (inbuf[4] & 0x01) << 7;
			outbuf[3] |= (inbuf[5] & 0x1f) << 2;
			outbuf[3] |= (inbuf[6] & 0x18) >> 3;
			outbuf[4] = (inbuf[6] & 0x07) << 5;
			outbuf[4] |= inbuf[7];

			int input_output_mapping[] = {5, 1, 1, 2, 2, 3, 4, 4, 5};
			int num_out = input_output_mapping[pad_start];

			// write output
			std::copy(outbuf, outbuf + num_out, std::back_inserter(ret));
		}
		return ret;
	}

	boost::optional<std::string> url_has_argument(
		std::string const& url, std::string argument)
	{
		size_t i = url.find('?');
		if (i == std::string::npos) return boost::optional<std::string>();
		++i;

		argument += '=';

		if (url.compare(i, argument.size(), argument) == 0)
		{
			size_t pos = i + argument.size();
			return url.substr(pos, url.find('&', pos) - pos);
		}
		argument.insert(0, "&");
		i = url.find(argument, i);
		if (i == std::string::npos) return boost::optional<std::string>();
		size_t pos = i + argument.size();
		return url.substr(pos, url.find('&', pos) - pos);
	}

	TORRENT_EXPORT std::string to_hex(std::string const& s)
	{
		std::string ret;
		char const* digits = "0123456789abcdef";
		for (std::string::const_iterator i = s.begin(); i != s.end(); ++i)
		{
			ret += digits[((unsigned char)*i) >> 4];
			ret += digits[((unsigned char)*i) & 0xf];
		}
		return ret;
	}

}

<|endoftext|>


<commit_before>#include "vulkan.hpp"
#include "vulkan_symbol_wrapper.h"
#include <stdexcept>
#include <vector>
#include "vulkan_events.hpp"

#ifdef HAVE_GLFW
#include <GLFW/glfw3.h>
#endif

#ifdef HAVE_DYLIB
#include <dlfcn.h>
#endif

using namespace std;

//#undef VULKAN_DEBUG

namespace Vulkan
{
Context::Context(const char **instance_ext, uint32_t instance_ext_count, const char **device_ext,
                 uint32_t device_ext_count)
    : owned_instance(true)
    , owned_device(true)
{
	if (!create_instance(instance_ext, instance_ext_count))
	{
		destroy();
		throw runtime_error("Failed to create Vulkan instance.");
	}

	VkPhysicalDeviceFeatures features = {};
	if (!create_device(VK_NULL_HANDLE, VK_NULL_HANDLE, device_ext, device_ext_count, nullptr, 0, &features))
	{
		destroy();
		throw runtime_error("Failed to create Vulkan device.");
	}
}

bool Context::init_loader(PFN_vkGetInstanceProcAddr addr)
{
	if (!addr)
	{
#ifdef HAVE_DYLIB
		static void *module;
		if (!module)
		{
			module = dlopen("libvulkan.so", RTLD_LOCAL | RTLD_LAZY);
			if (!module)
				return false;
		}

		addr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(dlsym(module, "vkGetInstanceProcAddr"));
		if (!addr)
			return false;
#else
		return false;
#endif
	}

	vulkan_symbol_wrapper_init(addr);
	return vulkan_symbol_wrapper_load_global_symbols();
}

Context::Context(VkInstance instance, VkPhysicalDevice gpu, VkDevice device, VkQueue queue, uint32_t queue_family)
    : device(device)
    , instance(instance)
    , gpu(gpu)
    , queue(queue)
    , queue_family(queue_family)
    , owned_instance(false)
    , owned_device(false)
{
	vulkan_symbol_wrapper_load_core_instance_symbols(instance);
	vulkan_symbol_wrapper_load_core_device_symbols(device);

	vkGetPhysicalDeviceProperties(gpu, &gpu_props);
	vkGetPhysicalDeviceMemoryProperties(gpu, &mem_props);
}

Context::Context(VkInstance instance, VkPhysicalDevice gpu, VkSurfaceKHR surface,
                 const char **required_device_extensions, unsigned num_required_device_extensions,
                 const char **required_device_layers, unsigned num_required_device_layers,
                 const VkPhysicalDeviceFeatures *required_features)
    : instance(instance)
    , owned_instance(false)
    , owned_device(true)
{
	vulkan_symbol_wrapper_load_core_instance_symbols(instance);
	if (!create_device(gpu, surface, required_device_extensions, num_required_device_extensions, required_device_layers,
	                   num_required_device_layers, required_features))
	{
		destroy();
		throw runtime_error("Failed to create Vulkan device.");
	}
}

void Context::destroy()
{
	if (device != VK_NULL_HANDLE)
		vkDeviceWaitIdle(device);

#ifdef VULKAN_DEBUG
	if (debug_callback)
		vkDestroyDebugReportCallbackEXT(instance, debug_callback, nullptr);
#endif

	if (owned_device && device != VK_NULL_HANDLE)
		vkDestroyDevice(device, nullptr);
	if (owned_instance && instance != VK_NULL_HANDLE)
		vkDestroyInstance(instance, nullptr);
}

Context::~Context()
{
	destroy();
}

const VkApplicationInfo &Context::get_application_info()
{
	static const VkApplicationInfo info = {
		VK_STRUCTURE_TYPE_APPLICATION_INFO, nullptr, "paraLLEl PSX", 0, "paraLLEl PSX", 0, VK_MAKE_VERSION(1, 0, 18),
	};
	return info;
}

#ifdef VULKAN_DEBUG
static VKAPI_ATTR VkBool32 VKAPI_CALL vulkan_debug_cb(VkDebugReportFlagsEXT flags,
                                                      VkDebugReportObjectTypeEXT objectType, uint64_t object,
                                                      size_t location, int32_t messageCode, const char *pLayerPrefix,
                                                      const char *pMessage, void *pUserData)
{
	(void)objectType;
	(void)object;
	(void)location;
	(void)messageCode;
	(void)pUserData;

	if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
	{
		fprintf(stderr, "[Vulkan]: Error: %s: %s\n", pLayerPrefix, pMessage);
	}
	else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT)
	{
		fprintf(stderr, "[Vulkan]: Warning: %s: %s\n", pLayerPrefix, pMessage);
	}
	else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
	{
		//fprintf(stderr, "[Vulkan]: Performance warning: %s: %s\n", pLayerPrefix, pMessage);
	}
	else
	{
		fprintf(stderr, "[Vulkan]: Information: %s: %s\n", pLayerPrefix, pMessage);
	}

	return VK_FALSE;
}
#endif

bool Context::create_instance(const char **instance_ext, uint32_t instance_ext_count)
{
	VkInstanceCreateInfo info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
	info.pApplicationInfo = &get_application_info();

	vector<const char *> instance_exts;
	vector<const char *> instance_layers;
	for (uint32_t i = 0; i < instance_ext_count; i++)
		instance_exts.push_back(instance_ext[i]);

#ifdef VULKAN_DEBUG
	instance_exts.push_back("VK_EXT_debug_report");
	instance_layers.push_back("VK_LAYER_LUNARG_standard_validation");
#endif

	info.enabledExtensionCount = instance_exts.size();
	info.ppEnabledExtensionNames = instance_exts.empty() ? nullptr : instance_exts.data();
	info.enabledLayerCount = instance_layers.size();
	info.ppEnabledLayerNames = instance_layers.empty() ? nullptr : instance_layers.data();

	if (vkCreateInstance(&info, nullptr, &instance) != VK_SUCCESS)
		return false;

	vulkan_symbol_wrapper_load_core_instance_symbols(instance);

#ifdef VULKAN_DEBUG
	VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, vkCreateDebugReportCallbackEXT);
	VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, vkDebugReportMessageEXT);
	VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, vkDestroyDebugReportCallbackEXT);

	{
		VkDebugReportCallbackCreateInfoEXT info = { VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT };
		info.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT |
		             VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
		info.pfnCallback = vulkan_debug_cb;
		vkCreateDebugReportCallbackEXT(instance, &info, NULL, &debug_callback);
	}
#endif
	return true;
}

bool Context::create_device(VkPhysicalDevice gpu, VkSurfaceKHR surface, const char **required_device_extensions,
                            unsigned num_required_device_extensions, const char **required_device_layers,
                            unsigned num_required_device_layers, const VkPhysicalDeviceFeatures *required_features)
{
	if (gpu == VK_NULL_HANDLE)
	{
		uint32_t gpu_count = 0;
		V(vkEnumeratePhysicalDevices(instance, &gpu_count, nullptr));
		vector<VkPhysicalDevice> gpus(gpu_count);
		V(vkEnumeratePhysicalDevices(instance, &gpu_count, gpus.data()));
		gpu = gpus.front();
	}

	this->gpu = gpu;
	vkGetPhysicalDeviceProperties(gpu, &gpu_props);
	vkGetPhysicalDeviceMemoryProperties(gpu, &mem_props);

	uint32_t queue_count;
	vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_count, nullptr);
	vector<VkQueueFamilyProperties> queue_props(queue_count);
	vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_count, queue_props.data());

	if (surface != VK_NULL_HANDLE)
	{
		VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, vkGetPhysicalDeviceSurfaceSupportKHR);
	}

	bool found_queue = false;
	for (unsigned i = 0; i < queue_count; i++)
	{
		VkBool32 supported = surface == VK_NULL_HANDLE;
#ifdef HAVE_GLFW
		supported = glfwGetPhysicalDevicePresentationSupport(instance, gpu, i);
#else
		if (surface != VK_NULL_HANDLE)
			vkGetPhysicalDeviceSurfaceSupportKHR(gpu, i, surface, &supported);
#endif

		VkQueueFlags required = VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT;
		if (supported && ((queue_props[i].queueFlags & required) == required))
		{
			found_queue = true;
			queue_family = i;
			break;
		}
	}

	if (!found_queue)
		return false;

	static const float prio = 1.0f;
	VkDeviceQueueCreateInfo queue_info = { VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO };

	VkDeviceCreateInfo device_info = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
	device_info.pQueueCreateInfos = &queue_info;

	queue_info.queueFamilyIndex = queue_family;
	queue_info.queueCount = 1;
	queue_info.pQueuePriorities = &prio;
	device_info.queueCreateInfoCount = 1;

	// Should query for these, but no big deal for now.
	device_info.ppEnabledExtensionNames = required_device_extensions;
	device_info.enabledExtensionCount = num_required_device_extensions;
	device_info.ppEnabledLayerNames = required_device_layers;
	device_info.enabledLayerCount = num_required_device_layers;

	VkPhysicalDeviceFeatures enabled_features = *required_features;
	{
		VkPhysicalDeviceFeatures features;
		vkGetPhysicalDeviceFeatures(gpu, &features);
		if (features.textureCompressionETC2)
			enabled_features.textureCompressionETC2 = VK_TRUE;
		if (features.textureCompressionBC)
			enabled_features.textureCompressionBC = VK_TRUE;
		if (features.textureCompressionASTC_LDR)
			enabled_features.textureCompressionASTC_LDR = VK_TRUE;
		if (features.fullDrawIndexUint32)
			enabled_features.fullDrawIndexUint32 = VK_TRUE;
	}

	device_info.pEnabledFeatures = &enabled_features;

#ifdef VULKAN_DEBUG
	static const char *device_layers[] = { "VK_LAYER_LUNARG_standard_validation" };
	device_info.enabledLayerCount = 1;
	device_info.ppEnabledLayerNames = device_layers;
#endif

	if (vkCreateDevice(gpu, &device_info, nullptr, &device) != VK_SUCCESS)
		return false;

	vulkan_symbol_wrapper_load_core_device_symbols(device);
	vkGetDeviceQueue(device, queue_family, 0, &queue);
	return true;
}
}
<commit_msg>Enable cube image array support.<commit_after>#include "vulkan.hpp"
#include "vulkan_symbol_wrapper.h"
#include <stdexcept>
#include <vector>
#include "vulkan_events.hpp"

#ifdef HAVE_GLFW
#include <GLFW/glfw3.h>
#endif

#ifdef HAVE_DYLIB
#include <dlfcn.h>
#endif

using namespace std;

//#undef VULKAN_DEBUG

namespace Vulkan
{
Context::Context(const char **instance_ext, uint32_t instance_ext_count, const char **device_ext,
                 uint32_t device_ext_count)
    : owned_instance(true)
    , owned_device(true)
{
	if (!create_instance(instance_ext, instance_ext_count))
	{
		destroy();
		throw runtime_error("Failed to create Vulkan instance.");
	}

	VkPhysicalDeviceFeatures features = {};
	if (!create_device(VK_NULL_HANDLE, VK_NULL_HANDLE, device_ext, device_ext_count, nullptr, 0, &features))
	{
		destroy();
		throw runtime_error("Failed to create Vulkan device.");
	}
}

bool Context::init_loader(PFN_vkGetInstanceProcAddr addr)
{
	if (!addr)
	{
#ifdef HAVE_DYLIB
		static void *module;
		if (!module)
		{
			module = dlopen("libvulkan.so", RTLD_LOCAL | RTLD_LAZY);
			if (!module)
				return false;
		}

		addr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(dlsym(module, "vkGetInstanceProcAddr"));
		if (!addr)
			return false;
#else
		return false;
#endif
	}

	vulkan_symbol_wrapper_init(addr);
	return vulkan_symbol_wrapper_load_global_symbols();
}

Context::Context(VkInstance instance, VkPhysicalDevice gpu, VkDevice device, VkQueue queue, uint32_t queue_family)
    : device(device)
    , instance(instance)
    , gpu(gpu)
    , queue(queue)
    , queue_family(queue_family)
    , owned_instance(false)
    , owned_device(false)
{
	vulkan_symbol_wrapper_load_core_instance_symbols(instance);
	vulkan_symbol_wrapper_load_core_device_symbols(device);

	vkGetPhysicalDeviceProperties(gpu, &gpu_props);
	vkGetPhysicalDeviceMemoryProperties(gpu, &mem_props);
}

Context::Context(VkInstance instance, VkPhysicalDevice gpu, VkSurfaceKHR surface,
                 const char **required_device_extensions, unsigned num_required_device_extensions,
                 const char **required_device_layers, unsigned num_required_device_layers,
                 const VkPhysicalDeviceFeatures *required_features)
    : instance(instance)
    , owned_instance(false)
    , owned_device(true)
{
	vulkan_symbol_wrapper_load_core_instance_symbols(instance);
	if (!create_device(gpu, surface, required_device_extensions, num_required_device_extensions, required_device_layers,
	                   num_required_device_layers, required_features))
	{
		destroy();
		throw runtime_error("Failed to create Vulkan device.");
	}
}

void Context::destroy()
{
	if (device != VK_NULL_HANDLE)
		vkDeviceWaitIdle(device);

#ifdef VULKAN_DEBUG
	if (debug_callback)
		vkDestroyDebugReportCallbackEXT(instance, debug_callback, nullptr);
#endif

	if (owned_device && device != VK_NULL_HANDLE)
		vkDestroyDevice(device, nullptr);
	if (owned_instance && instance != VK_NULL_HANDLE)
		vkDestroyInstance(instance, nullptr);
}

Context::~Context()
{
	destroy();
}

const VkApplicationInfo &Context::get_application_info()
{
	static const VkApplicationInfo info = {
		VK_STRUCTURE_TYPE_APPLICATION_INFO, nullptr, "paraLLEl PSX", 0, "paraLLEl PSX", 0, VK_MAKE_VERSION(1, 0, 18),
	};
	return info;
}

#ifdef VULKAN_DEBUG
static VKAPI_ATTR VkBool32 VKAPI_CALL vulkan_debug_cb(VkDebugReportFlagsEXT flags,
                                                      VkDebugReportObjectTypeEXT objectType, uint64_t object,
                                                      size_t location, int32_t messageCode, const char *pLayerPrefix,
                                                      const char *pMessage, void *pUserData)
{
	(void)objectType;
	(void)object;
	(void)location;
	(void)messageCode;
	(void)pUserData;

	if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
	{
		fprintf(stderr, "[Vulkan]: Error: %s: %s\n", pLayerPrefix, pMessage);
	}
	else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT)
	{
		fprintf(stderr, "[Vulkan]: Warning: %s: %s\n", pLayerPrefix, pMessage);
	}
	else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
	{
		//fprintf(stderr, "[Vulkan]: Performance warning: %s: %s\n", pLayerPrefix, pMessage);
	}
	else
	{
		fprintf(stderr, "[Vulkan]: Information: %s: %s\n", pLayerPrefix, pMessage);
	}

	return VK_FALSE;
}
#endif

bool Context::create_instance(const char **instance_ext, uint32_t instance_ext_count)
{
	VkInstanceCreateInfo info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
	info.pApplicationInfo = &get_application_info();

	vector<const char *> instance_exts;
	vector<const char *> instance_layers;
	for (uint32_t i = 0; i < instance_ext_count; i++)
		instance_exts.push_back(instance_ext[i]);

#ifdef VULKAN_DEBUG
	instance_exts.push_back("VK_EXT_debug_report");
	instance_layers.push_back("VK_LAYER_LUNARG_standard_validation");
#endif

	info.enabledExtensionCount = instance_exts.size();
	info.ppEnabledExtensionNames = instance_exts.empty() ? nullptr : instance_exts.data();
	info.enabledLayerCount = instance_layers.size();
	info.ppEnabledLayerNames = instance_layers.empty() ? nullptr : instance_layers.data();

	if (vkCreateInstance(&info, nullptr, &instance) != VK_SUCCESS)
		return false;

	vulkan_symbol_wrapper_load_core_instance_symbols(instance);

#ifdef VULKAN_DEBUG
	VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, vkCreateDebugReportCallbackEXT);
	VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, vkDebugReportMessageEXT);
	VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, vkDestroyDebugReportCallbackEXT);

	{
		VkDebugReportCallbackCreateInfoEXT info = { VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT };
		info.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT |
		             VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
		info.pfnCallback = vulkan_debug_cb;
		vkCreateDebugReportCallbackEXT(instance, &info, NULL, &debug_callback);
	}
#endif
	return true;
}

bool Context::create_device(VkPhysicalDevice gpu, VkSurfaceKHR surface, const char **required_device_extensions,
                            unsigned num_required_device_extensions, const char **required_device_layers,
                            unsigned num_required_device_layers, const VkPhysicalDeviceFeatures *required_features)
{
	if (gpu == VK_NULL_HANDLE)
	{
		uint32_t gpu_count = 0;
		V(vkEnumeratePhysicalDevices(instance, &gpu_count, nullptr));
		vector<VkPhysicalDevice> gpus(gpu_count);
		V(vkEnumeratePhysicalDevices(instance, &gpu_count, gpus.data()));
		gpu = gpus.front();
	}

	this->gpu = gpu;
	vkGetPhysicalDeviceProperties(gpu, &gpu_props);
	vkGetPhysicalDeviceMemoryProperties(gpu, &mem_props);

	uint32_t queue_count;
	vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_count, nullptr);
	vector<VkQueueFamilyProperties> queue_props(queue_count);
	vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_count, queue_props.data());

	if (surface != VK_NULL_HANDLE)
	{
		VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, vkGetPhysicalDeviceSurfaceSupportKHR);
	}

	bool found_queue = false;
	for (unsigned i = 0; i < queue_count; i++)
	{
		VkBool32 supported = surface == VK_NULL_HANDLE;
#ifdef HAVE_GLFW
		supported = glfwGetPhysicalDevicePresentationSupport(instance, gpu, i);
#else
		if (surface != VK_NULL_HANDLE)
			vkGetPhysicalDeviceSurfaceSupportKHR(gpu, i, surface, &supported);
#endif

		VkQueueFlags required = VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT;
		if (supported && ((queue_props[i].queueFlags & required) == required))
		{
			found_queue = true;
			queue_family = i;
			break;
		}
	}

	if (!found_queue)
		return false;

	static const float prio = 1.0f;
	VkDeviceQueueCreateInfo queue_info = { VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO };

	VkDeviceCreateInfo device_info = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
	device_info.pQueueCreateInfos = &queue_info;

	queue_info.queueFamilyIndex = queue_family;
	queue_info.queueCount = 1;
	queue_info.pQueuePriorities = &prio;
	device_info.queueCreateInfoCount = 1;

	// Should query for these, but no big deal for now.
	device_info.ppEnabledExtensionNames = required_device_extensions;
	device_info.enabledExtensionCount = num_required_device_extensions;
	device_info.ppEnabledLayerNames = required_device_layers;
	device_info.enabledLayerCount = num_required_device_layers;

	VkPhysicalDeviceFeatures enabled_features = *required_features;
	{
		VkPhysicalDeviceFeatures features;
		vkGetPhysicalDeviceFeatures(gpu, &features);
		if (features.textureCompressionETC2)
			enabled_features.textureCompressionETC2 = VK_TRUE;
		if (features.textureCompressionBC)
			enabled_features.textureCompressionBC = VK_TRUE;
		if (features.textureCompressionASTC_LDR)
			enabled_features.textureCompressionASTC_LDR = VK_TRUE;
		if (features.fullDrawIndexUint32)
			enabled_features.fullDrawIndexUint32 = VK_TRUE;
		if (features.imageCubeArray)
			enabled_features.imageCubeArray = VK_TRUE;
	}

	device_info.pEnabledFeatures = &enabled_features;

#ifdef VULKAN_DEBUG
	static const char *device_layers[] = { "VK_LAYER_LUNARG_standard_validation" };
	device_info.enabledLayerCount = 1;
	device_info.ppEnabledLayerNames = device_layers;
#endif

	if (vkCreateDevice(gpu, &device_info, nullptr, &device) != VK_SUCCESS)
		return false;

	vulkan_symbol_wrapper_load_core_device_symbols(device);
	vkGetDeviceQueue(device, queue_family, 0, &queue);
	return true;
}
}
<|endoftext|>