<commit_before>/*
 *  This file is part of Poedit (https://poedit.net)
 *
 *  Copyright (C) 1999-2016 Vaclav Slavik
 *  Copyright (C) 2005 Olivier Sannier
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a
 *  copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 *  DEALINGS IN THE SOFTWARE.
 *
 */

#include "cat_sorting.h"

#include <unicode/unistr.h>
#include "str_helpers.h"

#include <wx/config.h>
#include <wx/log.h>

/*static*/ SortOrder SortOrder::Default()
{
    SortOrder order;

    wxString by = wxConfig::Get()->Read("/sort_by", "file-order");
    long ctxt = wxConfig::Get()->Read("/sort_group_by_context", 0L);
    long untrans = wxConfig::Get()->Read("/sort_untrans_first", 0L);
    long errors = wxConfig::Get()->Read("/sort_errors_first", 1L);

    if ( by == "source" )
        order.by = By_Source;
    else if ( by == "translation" )
        order.by = By_Translation;
    else
        order.by = By_FileOrder;

    order.groupByContext = (ctxt != 0);
    order.untransFirst = (untrans != 0);
    order.errorsFirst = (errors != 0);

    return order;
}

void SortOrder::Save()
{
    wxString bystr;
    switch ( by )
    {
        case By_FileOrder:
            bystr = "file-order";
            break;
        case By_Source:
            bystr = "source";
            break;
        case By_Translation:
            bystr = "translation";
            break;
    }

    wxConfig::Get()->Write("/sort_by", bystr);
    wxConfig::Get()->Write("/sort_group_by_context", groupByContext);
    wxConfig::Get()->Write("/sort_untrans_first", untransFirst);
    wxConfig::Get()->Write("/sort_errors_first", errorsFirst);
}

CatalogItemsComparator::CatalogItemsComparator(const Catalog& catalog, const SortOrder& order)
    : m_catalog(catalog), m_order(order)
{
    UErrorCode err = U_ZERO_ERROR;
    switch (m_order.by)
    {
        case SortOrder::By_Source:
            // TODO: allow non-English source languages too
            m_collator.reset(icu::Collator::createInstance(catalog.GetSourceLanguage().ToIcu(), err));
            break;

        case SortOrder::By_Translation:
            m_collator.reset(icu::Collator::createInstance(catalog.GetLanguage().ToIcu(), err));
            break;

        case SortOrder::By_FileOrder:
            break;
    }

    if (!U_SUCCESS(err) || err == U_USING_FALLBACK_WARNING)
    {
        wxLogTrace("poedit", "warning: not using collation for %s (%s)",
                   catalog.GetLanguage().Code(), u_errorName(err));
    }

    if (m_collator)
    {
        // Case-insensitive comparison:
        m_collator->setStrength(icu::Collator::SECONDARY);
    }
}

bool CatalogItemsComparator::operator()(int i, int j) const
{
    const CatalogItem& a = Item(i);
    const CatalogItem& b = Item(j);

    if ( m_order.errorsFirst )
    {
        if ( a.GetValidity() == CatalogItem::Val_Invalid && b.GetValidity() != CatalogItem::Val_Invalid )
            return true;
        else if ( a.GetValidity() != CatalogItem::Val_Invalid && b.GetValidity() == CatalogItem::Val_Invalid )
            return false;
    }

    if ( m_order.untransFirst )
    {
        if ( !a.IsTranslated() && b.IsTranslated() )
            return true;
        else if ( a.IsTranslated() && !b.IsTranslated() )
            return false;

        if ( a.IsFuzzy() && !b.IsFuzzy() )
            return true;
        else if ( !a.IsFuzzy() && b.IsFuzzy() )
            return false;
    }

    if ( m_order.groupByContext )
    {
        if ( a.HasContext() && !b.HasContext() )
            return true;
        else if ( !a.HasContext() && b.HasContext() )
            return false;
        else if ( a.HasContext() && b.HasContext() )
        {
            int r = CompareStrings(a.GetContext(), b.GetContext());
            if ( r != 0 )
                return r < 0;
        }
    }

    switch ( m_order.by )
    {
        case SortOrder::By_FileOrder:
        {
            return i < j;
        }

        case SortOrder::By_Source:
        {
            int r = CompareStrings(a.GetString(), b.GetString());
            if ( r != 0 )
                return r < 0;
            break;
        }

        case SortOrder::By_Translation:
        {
            int r = CompareStrings(a.GetTranslation(), b.GetTranslation());
            if ( r != 0 )
                return r < 0;
            break;
        }
    }

    // As last resort, sort by position in file. Note that this means that
    // no two items are considered equal w.r.t. sort order; this ensures stable
    // ordering.
    return i < j;
}

int CatalogItemsComparator::CompareStrings(wxString a, wxString b) const
{
    a.Replace("&", "");
    a.Replace("_", "");

    b.Replace("&", "");
    b.Replace("_", "");

    if (m_collator)
    {
        UErrorCode err = U_ZERO_ERROR;
#if wxUSE_UNICODE_UTF8
        return m_collator->compareUTF8(a.wx_str(), b.wx_str(), err);
#elif SIZEOF_WCHAR_T == 2
        return m_collator->compare(a.wx_str(), a.length(), b.wx_str(), b.length(), err);
#else
        return m_collator->compare(str::to_icu(a), str::to_icu(b), err);
#endif
    }
    else
    {
        return a.CmpNoCase(b);
    }
}
<commit_msg>Remove outdated TODO comment<commit_after>/*
 *  This file is part of Poedit (https://poedit.net)
 *
 *  Copyright (C) 1999-2016 Vaclav Slavik
 *  Copyright (C) 2005 Olivier Sannier
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a
 *  copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 *  DEALINGS IN THE SOFTWARE.
 *
 */

#include "cat_sorting.h"

#include <unicode/unistr.h>
#include "str_helpers.h"

#include <wx/config.h>
#include <wx/log.h>

/*static*/ SortOrder SortOrder::Default()
{
    SortOrder order;

    wxString by = wxConfig::Get()->Read("/sort_by", "file-order");
    long ctxt = wxConfig::Get()->Read("/sort_group_by_context", 0L);
    long untrans = wxConfig::Get()->Read("/sort_untrans_first", 0L);
    long errors = wxConfig::Get()->Read("/sort_errors_first", 1L);

    if ( by == "source" )
        order.by = By_Source;
    else if ( by == "translation" )
        order.by = By_Translation;
    else
        order.by = By_FileOrder;

    order.groupByContext = (ctxt != 0);
    order.untransFirst = (untrans != 0);
    order.errorsFirst = (errors != 0);

    return order;
}

void SortOrder::Save()
{
    wxString bystr;
    switch ( by )
    {
        case By_FileOrder:
            bystr = "file-order";
            break;
        case By_Source:
            bystr = "source";
            break;
        case By_Translation:
            bystr = "translation";
            break;
    }

    wxConfig::Get()->Write("/sort_by", bystr);
    wxConfig::Get()->Write("/sort_group_by_context", groupByContext);
    wxConfig::Get()->Write("/sort_untrans_first", untransFirst);
    wxConfig::Get()->Write("/sort_errors_first", errorsFirst);
}

CatalogItemsComparator::CatalogItemsComparator(const Catalog& catalog, const SortOrder& order)
    : m_catalog(catalog), m_order(order)
{
    UErrorCode err = U_ZERO_ERROR;
    switch (m_order.by)
    {
        case SortOrder::By_Source:
            m_collator.reset(icu::Collator::createInstance(catalog.GetSourceLanguage().ToIcu(), err));
            break;

        case SortOrder::By_Translation:
            m_collator.reset(icu::Collator::createInstance(catalog.GetLanguage().ToIcu(), err));
            break;

        case SortOrder::By_FileOrder:
            break;
    }

    if (!U_SUCCESS(err) || err == U_USING_FALLBACK_WARNING)
    {
        wxLogTrace("poedit", "warning: not using collation for %s (%s)",
                   catalog.GetLanguage().Code(), u_errorName(err));
    }

    if (m_collator)
    {
        // Case-insensitive comparison:
        m_collator->setStrength(icu::Collator::SECONDARY);
    }
}

bool CatalogItemsComparator::operator()(int i, int j) const
{
    const CatalogItem& a = Item(i);
    const CatalogItem& b = Item(j);

    if ( m_order.errorsFirst )
    {
        if ( a.GetValidity() == CatalogItem::Val_Invalid && b.GetValidity() != CatalogItem::Val_Invalid )
            return true;
        else if ( a.GetValidity() != CatalogItem::Val_Invalid && b.GetValidity() == CatalogItem::Val_Invalid )
            return false;
    }

    if ( m_order.untransFirst )
    {
        if ( !a.IsTranslated() && b.IsTranslated() )
            return true;
        else if ( a.IsTranslated() && !b.IsTranslated() )
            return false;

        if ( a.IsFuzzy() && !b.IsFuzzy() )
            return true;
        else if ( !a.IsFuzzy() && b.IsFuzzy() )
            return false;
    }

    if ( m_order.groupByContext )
    {
        if ( a.HasContext() && !b.HasContext() )
            return true;
        else if ( !a.HasContext() && b.HasContext() )
            return false;
        else if ( a.HasContext() && b.HasContext() )
        {
            int r = CompareStrings(a.GetContext(), b.GetContext());
            if ( r != 0 )
                return r < 0;
        }
    }

    switch ( m_order.by )
    {
        case SortOrder::By_FileOrder:
        {
            return i < j;
        }

        case SortOrder::By_Source:
        {
            int r = CompareStrings(a.GetString(), b.GetString());
            if ( r != 0 )
                return r < 0;
            break;
        }

        case SortOrder::By_Translation:
        {
            int r = CompareStrings(a.GetTranslation(), b.GetTranslation());
            if ( r != 0 )
                return r < 0;
            break;
        }
    }

    // As last resort, sort by position in file. Note that this means that
    // no two items are considered equal w.r.t. sort order; this ensures stable
    // ordering.
    return i < j;
}

int CatalogItemsComparator::CompareStrings(wxString a, wxString b) const
{
    a.Replace("&", "");
    a.Replace("_", "");

    b.Replace("&", "");
    b.Replace("_", "");

    if (m_collator)
    {
        UErrorCode err = U_ZERO_ERROR;
#if wxUSE_UNICODE_UTF8
        return m_collator->compareUTF8(a.wx_str(), b.wx_str(), err);
#elif SIZEOF_WCHAR_T == 2
        return m_collator->compare(a.wx_str(), a.length(), b.wx_str(), b.length(), err);
#else
        return m_collator->compare(str::to_icu(a), str::to_icu(b), err);
#endif
    }
    else
    {
        return a.CmpNoCase(b);
    }
}
<|endoftext|>


<commit_before>#include <nan.h>
#include <iostream>
#include <unordered_map>
#include <string>
#include "FractalGenerator.h"

#define JS_LENGTH_CHECK(info, length) if (info.Length() < length) {	\
	Nan::ThrowTypeError("Wrong number of arguments, must be at least " #length);	\
	return;	\
}

#define JS_TYPE_CHECK(info, index, typeCheck) if (!info[index]->typeCheck()) {	\
	Nan::ThrowTypeError("Wrong argument type, failed test " #typeCheck);	\
	return;	\
}

std::unordered_map<std::string, FractalGenerator *> generators;

typedef struct {
	v8::Global<v8::Function> jsCallback;
	std::string id;
} FractalData;

void fractalDoneCallback(v8::Isolate *isolate, v8::Local<v8::Object> buffer,
		bool halted, void *customData) {
	FractalData *fd = (FractalData *) customData;

	v8::Local<v8::Function> func = fd->jsCallback.Get(isolate);
	v8::Local<v8::Value> args[] = { Nan::New(halted), buffer };
	func->Call(isolate->GetCurrentContext(), func, 2, args);

	generators.erase(fd->id);

	fd->jsCallback.Reset();
	delete fd;
}

void createFractalGenerator(const Nan::FunctionCallbackInfo<v8::Value> &info) {
	/*
	 * Args:
	 * String	uuid			: frctal id
	 * Function	doneCallback	: callback for when the fractal is done
	 * Buffer	buffer			: the buffer the fractal should write to
	 * Int		width			: the image width of the fractal
	 * Int		height			: the image height of the fractal
	 * Double	fractalWidth	: the complex width (real) of the fractal
	 * Double	fractalHeight	: the complex height (imaginary) of the fractal
	 * Double	fractalX		: the complex x (real) start of the fractal (x+ is right)
	 * Double	fractalY		: the complex y (imaginary) start of the fractal (y+ is down)
	 * Int		iterations		: the number of iterations before a pixel turns black
	 */

	// type checks
	JS_LENGTH_CHECK(info, 10)
	JS_TYPE_CHECK(info, 0, IsString)
	JS_TYPE_CHECK(info, 1, IsFunction)
	JS_TYPE_CHECK(info, 2, IsObject)
	JS_TYPE_CHECK(info, 3, IsNumber)
	JS_TYPE_CHECK(info, 4, IsNumber)
	JS_TYPE_CHECK(info, 5, IsNumber)
	JS_TYPE_CHECK(info, 6, IsNumber)
	JS_TYPE_CHECK(info, 7, IsNumber)
	JS_TYPE_CHECK(info, 8, IsNumber)
	JS_TYPE_CHECK(info, 9, IsNumber)

	// get args
	std::string uuid(*v8::String::Utf8Value(info[0]));
	v8::Local<v8::Function> doneCallback = info[1].As<v8::Function>();
	v8::Local<v8::Object> buffer = info[2]->ToObject();
	int width = info[3]->Int32Value();
	int height = info[4]->Int32Value();
	double fractalWidth = info[5]->NumberValue();
	double fractalHeight = info[6]->NumberValue();
	double fractalX = info[7]->NumberValue();
	double fractalY = info[8]->NumberValue();
	int iterations = info[9]->Int32Value();

	FractalData *fd = new FractalData;
	fd->id = uuid;
	fd->jsCallback = v8::Global<v8::Function>();
	fd->jsCallback.Reset(info.GetIsolate(), doneCallback);

	FractalGenerator *gen = new FractalGenerator(uuid, info.GetIsolate(),
			fractalDoneCallback, buffer, fd, width, height, fractalWidth,
			fractalHeight, fractalX, fractalY, iterations);
	generators.insert(std::pair<std::string, FractalGenerator *>(uuid, gen));
}

void startGenerator(const Nan::FunctionCallbackInfo<v8::Value> &info) {
	/*
	 * Args:
	 * String	uuid	: uuid of the fractal
	 */

	JS_LENGTH_CHECK(info, 1)
	JS_TYPE_CHECK(info, 0, IsString)

	std::string uuid(*v8::String::Utf8Value(info[0]));
	if (generators.find(uuid) != generators.end()) {
		generators[uuid]->start();
	} else {
		Nan::ThrowRangeError(
				(std::string("No fractal with uuid ") + uuid).c_str());
	}
}

void getProgress(const Nan::FunctionCallbackInfo<v8::Value> &info) {
	// uuid is argument
	JS_LENGTH_CHECK(info, 1)
	JS_TYPE_CHECK(info, 0, IsString)

	std::string uuid(*v8::String::Utf8Value(info[0]));
	if (generators.find(uuid) != generators.end()) {
		info.GetReturnValue().Set(generators[uuid]->getProgress());
	} else {
		Nan::ThrowRangeError(
				(std::string("No fractal with uuid ") + uuid).c_str());
	}
}

void containsFractal(const Nan::FunctionCallbackInfo<v8::Value> &info) {
	// uuid is argument
	JS_LENGTH_CHECK(info, 1)
	JS_TYPE_CHECK(info, 0, IsString)

	std::string uuid(*v8::String::Utf8Value(info[0]));
	info.GetReturnValue().Set(generators.find(uuid) != generators.end());
}

void listFractals(const Nan::FunctionCallbackInfo<v8::Value> &info) {
	// no arguments
	v8::Local<v8::Array> fractals = Nan::New<v8::Array>(generators.size());
	auto it = generators.begin();
	for (int i = 0; i < generators.size(); i++) {
		fractals->Set(i, Nan::New(it->first).ToLocalChecked());
		it++;
	}
	info.GetReturnValue().Set(fractals);
}

void haltFractal(const Nan::FunctionCallbackInfo<v8::Value> &info) {
// uuid is argument
	JS_LENGTH_CHECK(info, 1)
	JS_TYPE_CHECK(info, 0, IsString)

	std::string uuid(*v8::String::Utf8Value(info[0]));
	if (generators.find(uuid) != generators.end()) {
		generators[uuid]->halt();
	} else {
		Nan::ThrowRangeError(
				(std::string("No fractal with uuid ") + uuid).c_str());
	}
}

void haltAllFractals(const Nan::FunctionCallbackInfo<v8::Value> &info) {
// no arguments
	for (const auto &elem : generators) {
		elem.second->halt();
	}
}

void init(v8::Local<v8::Object> exports) {
	exports->Set(Nan::New("createFractalGenerator").ToLocalChecked(),
			Nan::New<v8::FunctionTemplate>(createFractalGenerator)->GetFunction());
	exports->Set(Nan::New("startGenerator").ToLocalChecked(),
			Nan::New<v8::FunctionTemplate>(startGenerator)->GetFunction());
	exports->Set(Nan::New("getProgress").ToLocalChecked(),
			Nan::New<v8::FunctionTemplate>(getProgress)->GetFunction());
	exports->Set(Nan::New("containsFractal").ToLocalChecked(),
			Nan::New<v8::FunctionTemplate>(containsFractal)->GetFunction());

}

NODE_MODULE(fractal_service_native, init)
<commit_msg>Add api pointers to new functions<commit_after>#include <nan.h>
#include <iostream>
#include <unordered_map>
#include <string>
#include "FractalGenerator.h"

#define JS_LENGTH_CHECK(info, length) if (info.Length() < length) {	\
	Nan::ThrowTypeError("Wrong number of arguments, must be at least " #length);	\
	return;	\
}

#define JS_TYPE_CHECK(info, index, typeCheck) if (!info[index]->typeCheck()) {	\
	Nan::ThrowTypeError("Wrong argument type, failed test " #typeCheck);	\
	return;	\
}

std::unordered_map<std::string, FractalGenerator *> generators;

typedef struct {
	v8::Global<v8::Function> jsCallback;
	std::string id;
} FractalData;

void fractalDoneCallback(v8::Isolate *isolate, v8::Local<v8::Object> buffer,
		bool halted, void *customData) {
	FractalData *fd = (FractalData *) customData;

	v8::Local<v8::Function> func = fd->jsCallback.Get(isolate);
	v8::Local<v8::Value> args[] = { Nan::New(halted), buffer };
	func->Call(isolate->GetCurrentContext(), func, 2, args);

	generators.erase(fd->id);

	fd->jsCallback.Reset();
	delete fd;
}

void createFractalGenerator(const Nan::FunctionCallbackInfo<v8::Value> &info) {
	/*
	 * Args:
	 * String	uuid			: frctal id
	 * Function	doneCallback	: callback for when the fractal is done
	 * Buffer	buffer			: the buffer the fractal should write to
	 * Int		width			: the image width of the fractal
	 * Int		height			: the image height of the fractal
	 * Double	fractalWidth	: the complex width (real) of the fractal
	 * Double	fractalHeight	: the complex height (imaginary) of the fractal
	 * Double	fractalX		: the complex x (real) start of the fractal (x+ is right)
	 * Double	fractalY		: the complex y (imaginary) start of the fractal (y+ is down)
	 * Int		iterations		: the number of iterations before a pixel turns black
	 */

	// type checks
	JS_LENGTH_CHECK(info, 10)
	JS_TYPE_CHECK(info, 0, IsString)
	JS_TYPE_CHECK(info, 1, IsFunction)
	JS_TYPE_CHECK(info, 2, IsObject)
	JS_TYPE_CHECK(info, 3, IsNumber)
	JS_TYPE_CHECK(info, 4, IsNumber)
	JS_TYPE_CHECK(info, 5, IsNumber)
	JS_TYPE_CHECK(info, 6, IsNumber)
	JS_TYPE_CHECK(info, 7, IsNumber)
	JS_TYPE_CHECK(info, 8, IsNumber)
	JS_TYPE_CHECK(info, 9, IsNumber)

	// get args
	std::string uuid(*v8::String::Utf8Value(info[0]));
	v8::Local<v8::Function> doneCallback = info[1].As<v8::Function>();
	v8::Local<v8::Object> buffer = info[2]->ToObject();
	int width = info[3]->Int32Value();
	int height = info[4]->Int32Value();
	double fractalWidth = info[5]->NumberValue();
	double fractalHeight = info[6]->NumberValue();
	double fractalX = info[7]->NumberValue();
	double fractalY = info[8]->NumberValue();
	int iterations = info[9]->Int32Value();

	FractalData *fd = new FractalData;
	fd->id = uuid;
	fd->jsCallback = v8::Global<v8::Function>();
	fd->jsCallback.Reset(info.GetIsolate(), doneCallback);

	FractalGenerator *gen = new FractalGenerator(uuid, info.GetIsolate(),
			fractalDoneCallback, buffer, fd, width, height, fractalWidth,
			fractalHeight, fractalX, fractalY, iterations);
	generators.insert(std::pair<std::string, FractalGenerator *>(uuid, gen));
}

void startGenerator(const Nan::FunctionCallbackInfo<v8::Value> &info) {
	/*
	 * Args:
	 * String	uuid	: uuid of the fractal
	 */

	JS_LENGTH_CHECK(info, 1)
	JS_TYPE_CHECK(info, 0, IsString)

	std::string uuid(*v8::String::Utf8Value(info[0]));
	if (generators.find(uuid) != generators.end()) {
		generators[uuid]->start();
	} else {
		Nan::ThrowRangeError(
				(std::string("No fractal with uuid ") + uuid).c_str());
	}
}

void getProgress(const Nan::FunctionCallbackInfo<v8::Value> &info) {
	// uuid is argument
	JS_LENGTH_CHECK(info, 1)
	JS_TYPE_CHECK(info, 0, IsString)

	std::string uuid(*v8::String::Utf8Value(info[0]));
	if (generators.find(uuid) != generators.end()) {
		info.GetReturnValue().Set(generators[uuid]->getProgress());
	} else {
		Nan::ThrowRangeError(
				(std::string("No fractal with uuid ") + uuid).c_str());
	}
}

void containsFractal(const Nan::FunctionCallbackInfo<v8::Value> &info) {
	// uuid is argument
	JS_LENGTH_CHECK(info, 1)
	JS_TYPE_CHECK(info, 0, IsString)

	std::string uuid(*v8::String::Utf8Value(info[0]));
	info.GetReturnValue().Set(generators.find(uuid) != generators.end());
}

void listFractals(const Nan::FunctionCallbackInfo<v8::Value> &info) {
	// no arguments
	v8::Local<v8::Array> fractals = Nan::New<v8::Array>(generators.size());
	auto it = generators.begin();
	for (int i = 0; i < generators.size(); i++) {
		fractals->Set(i, Nan::New(it->first).ToLocalChecked());
		it++;
	}
	info.GetReturnValue().Set(fractals);
}

void haltFractal(const Nan::FunctionCallbackInfo<v8::Value> &info) {
	// uuid is argument
	JS_LENGTH_CHECK(info, 1)
	JS_TYPE_CHECK(info, 0, IsString)

	std::string uuid(*v8::String::Utf8Value(info[0]));
	if (generators.find(uuid) != generators.end()) {
		generators[uuid]->halt();
	} else {
		Nan::ThrowRangeError(
				(std::string("No fractal with uuid ") + uuid).c_str());
	}
}

void haltAllFractals(const Nan::FunctionCallbackInfo<v8::Value> &info) {
	// no arguments
	for (const auto &elem : generators) {
		elem.second->halt();
	}
}

void init(v8::Local<v8::Object> exports) {
	exports->Set(Nan::New("createFractalGenerator").ToLocalChecked(),
			Nan::New<v8::FunctionTemplate>(createFractalGenerator)->GetFunction());
	exports->Set(Nan::New("startGenerator").ToLocalChecked(),
			Nan::New<v8::FunctionTemplate>(startGenerator)->GetFunction());
	exports->Set(Nan::New("getProgress").ToLocalChecked(),
			Nan::New<v8::FunctionTemplate>(getProgress)->GetFunction());
	exports->Set(Nan::New("containsFractal").ToLocalChecked(),
			Nan::New<v8::FunctionTemplate>(containsFractal)->GetFunction());
	exports->Set(Nan::New("listFractals").ToLocalChecked(),
			Nan::New<v8::FunctionTemplate>(listFractals)->GetFunction());
	exports->Set(Nan::New("haltFractal").ToLocalChecked(),
			Nan::New<v8::FunctionTemplate>(haltFractal)->GetFunction());
	exports->Set(Nan::New("haltAllFractals").ToLocalChecked(),
			Nan::New<v8::FunctionTemplate>(haltAllFractals)->GetFunction());

}

NODE_MODULE(fractal_service_native, init)
<|endoftext|>


<commit_before>#include "heart_cell_sim.h"
#include <QApplication>
#include <QSettings>
#include <QMessageBox>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QCoreApplication::setOrganizationName("Hund lab BME OSU");
    QCoreApplication::setOrganizationDomain("http://hundlab.org");
    QCoreApplication::setApplicationName("LongQt");

    Simulation window;
    window.show();
    QSettings settings;
    if(settings.value("showHelp",true).toBool()
        &&QMessageBox::Discard ==
        QMessageBox::information(0,"Welcome!", "LongQt is a program for modeling cardiac potentials. As you go through this program keep a few things in mind. First, if you would like more information about something hover your mouse above its name and information will pop up. Second, default values have been provided for all options so if you don't know what an option does it's ok to simply skip it. And finally have fun!\n If you would like to re-enable this text after discarding it use the Restore Defaults button in the About dialog."
        ,QMessageBox::Ok|QMessageBox::Discard,QMessageBox::Ok)) {
        settings.setValue("showHelp",false);
    }

    return a.exec();
}
<commit_msg>changed from discard to ignore<commit_after>#include "heart_cell_sim.h"
#include <QApplication>
#include <QSettings>
#include <QMessageBox>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QCoreApplication::setOrganizationName("Hund lab BME OSU");
    QCoreApplication::setOrganizationDomain("http://hundlab.org");
    QCoreApplication::setApplicationName("LongQt");

    Simulation window;
    window.show();
    QSettings settings;
    if(settings.value("showHelp",true).toBool()
        &&QMessageBox::Ignore ==
        QMessageBox::information(0,"Welcome!", "LongQt is a program for modeling cardiac potentials. As you go through this program keep a few things in mind. First, if you would like more information about something hover your mouse above its name and information will pop up. Second, default values have been provided for all options so if you don't know what an option does it's ok to simply skip it. And finally have fun!\n If you would like to re-enable this text after discarding it use the Restore Defaults button in the About dialog."
        ,QMessageBox::Ok|QMessageBox::Ignore,QMessageBox::Ok)) {
        settings.setValue("showHelp",false);
    }

    return a.exec();
}
<|endoftext|>


<commit_before>#pragma once

#include <Word.hxx>

#define _E(rest) E##rest##_ = E##rest

namespace linux {

template <typename Success, typename Failure>
struct Result
{
    explicit
    operator
    bool() const
    {
        return this->__word > 0xFFFFFFFFFFFFF000UL;
    }

    Failure
    failure() const
    {
        return static_cast<Failure>(-this->__word);
    }

    Success
    success() const
    {
        return static_cast<Success>(this->__word);
    }

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

    Word
    __word;
};

}
<commit_msg>if (auto _ = …) → switch (auto _ = …)<commit_after>#pragma once

#include <Word.hxx>

#define _E(rest) E##rest##_ = E##rest

namespace linux {

template <typename Success, typename Failure>
struct Result
{
    enum Kind { SUCCESS, FAILURE };

    operator
    Kind() const
    {
        return __builtin_expect(this->__word <= 0xFFFFFFFFFFFFF000UL, 1) ? SUCCESS : FAILURE;
    }

    Failure
    failure() const
    {
        return static_cast<Failure>(-this->__word);
    }

    Success
    success() const
    {
        return static_cast<Success>(this->__word);
    }

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

    Word
    __word;
};

}
<|endoftext|>


<commit_before>/*
 * Copyright 2007-2017 Content Management AG
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * 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.
 *
 * 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
 * FOUNDATION 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 "lhttp_stock.hxx"
#include "lhttp_address.hxx"
#include "stock/Stock.hxx"
#include "stock/MapStock.hxx"
#include "stock/MultiStock.hxx"
#include "stock/Class.hxx"
#include "stock/Item.hxx"
#include "pool/tpool.hxx"
#include "AllocatorPtr.hxx"
#include "lease.hxx"
#include "child_stock.hxx"
#include "spawn/JailParams.hxx"
#include "spawn/Prepared.hxx"
#include "event/SocketEvent.hxx"
#include "event/TimerEvent.hxx"
#include "net/UniqueSocketDescriptor.hxx"
#include "io/Logger.hxx"
#include "util/RuntimeError.hxx"
#include "util/Exception.hxx"

#include <assert.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>

class LhttpStock final : StockClass, ChildStockClass {
    ChildStock child_stock;
    MultiStock mchild_stock;
    StockMap hstock;

public:
    LhttpStock(unsigned limit, unsigned max_idle,
               EventLoop &event_loop, SpawnService &spawn_service,
               SocketDescriptor log_socket,
               const ChildErrorLogOptions &log_options) noexcept;

    void FadeAll() noexcept {
        hstock.FadeAll();
        child_stock.GetStockMap().FadeAll();
        mchild_stock.FadeAll();
    }

    void FadeTag(const char *tag) noexcept;

    StockMap &GetConnectionStock() noexcept {
        return hstock;
    }

private:
    /* virtual methods from class StockClass */
    void Create(CreateStockItem c, StockRequest request,
                CancellablePointer &cancel_ptr) override;

    /* virtual methods from class ChildStockClass */
    int GetChildSocketType(void *info) const noexcept override;
    const char *GetChildTag(void *info) const noexcept override;
    void PrepareChild(void *info, UniqueSocketDescriptor &&fd,
                      PreparedChildProcess &p) override;
};

class LhttpConnection final : LoggerDomainFactory, StockItem {
    LazyDomainLogger logger;

    StockItem *child = nullptr;

    struct lease_ref lease_ref;

    UniqueSocketDescriptor fd;
    SocketEvent event;
    TimerEvent idle_timeout_event;

public:
    explicit LhttpConnection(CreateStockItem c) noexcept
        :StockItem(c),
         logger(*this),
         event(c.stock.GetEventLoop(), BIND_THIS_METHOD(EventCallback)),
         idle_timeout_event(c.stock.GetEventLoop(),
                            BIND_THIS_METHOD(OnIdleTimeout)) {}

    ~LhttpConnection() noexcept override;

    void Connect(MultiStock &child_stock,
                 const char *key, StockRequest &&request,
                 unsigned concurrency);

    SocketDescriptor GetSocket() const noexcept {
        assert(fd.IsDefined());
        return fd;
    }

    gcc_pure
    const char *GetTag() const noexcept {
        assert(child != nullptr);

        return child_stock_item_get_tag(*child);
    }

    void SetSite(const char *site) noexcept {
        child_stock_item_set_site(*child, site);
    }

    void SetUri(const char *uri) noexcept {
        child_stock_item_set_uri(*child, uri);
    }

private:
    void EventCallback(unsigned events) noexcept;
    void OnIdleTimeout() noexcept;

    /* virtual methods from LoggerDomainFactory */
    std::string MakeLoggerDomain() const noexcept override {
        return GetStockName();
    }

    /* virtual methods from class StockItem */
    bool Borrow() noexcept override {
        event.Cancel();
        idle_timeout_event.Cancel();
        return true;
    }

    bool Release() noexcept override {
        event.ScheduleRead();
        idle_timeout_event.Schedule(std::chrono::minutes(5));
        return true;
    }
};

inline void
LhttpConnection::Connect(MultiStock &child_stock,
                         const char *key, StockRequest &&request,
                         unsigned concurrency)
{
    try {
        child = child_stock.GetNow(key, std::move(request), concurrency,
                                   lease_ref);
    } catch (...) {
        delete this;
        std::throw_with_nested(FormatRuntimeError("Failed to launch LHTTP server '%s'",
                                                  key));
    }

    try {
        fd = child_stock_item_connect(*child);
    } catch (...) {
        delete this;
        std::throw_with_nested(FormatRuntimeError("Failed to connect to LHTTP server '%s'",
                                                  key));
    }

    event.Open(fd);
    InvokeCreateSuccess();
}

static const char *
lhttp_stock_key(struct pool *pool, const LhttpAddress *address) noexcept
{
    return address->GetServerId(AllocatorPtr(*pool));
}

/*
 * libevent callback
 *
 */

inline void
LhttpConnection::EventCallback(unsigned) noexcept
{
    char buffer;
    ssize_t nbytes = fd.Read(&buffer, sizeof(buffer));
    if (nbytes < 0)
        logger(2, "error on idle LHTTP connection: ", strerror(errno));
    else if (nbytes > 0)
        logger(2, "unexpected data from idle LHTTP connection");

    InvokeIdleDisconnect();
}

inline void
LhttpConnection::OnIdleTimeout() noexcept
{
    InvokeIdleDisconnect();
}

/*
 * child_stock class
 *
 */

int
LhttpStock::GetChildSocketType(void *info) const noexcept
{
    const auto &address = *(const LhttpAddress *)info;

    int type = SOCK_STREAM;
    if (!address.blocking)
        type |= SOCK_NONBLOCK;

    return type;
}

const char *
LhttpStock::GetChildTag(void *info) const noexcept
{
    const auto &address = *(const LhttpAddress *)info;

    return address.options.tag;
}

void
LhttpStock::PrepareChild(void *info, UniqueSocketDescriptor &&fd,
                         PreparedChildProcess &p)
{
    const auto &address = *(const LhttpAddress *)info;

    p.SetStdin(std::move(fd));
    address.CopyTo(p);
}

/*
 * stock class
 *
 */

void
LhttpStock::Create(CreateStockItem c, StockRequest request,
                   gcc_unused CancellablePointer &cancel_ptr)
{
    const auto *address = (const LhttpAddress *)request.get();

    assert(address != nullptr);
    assert(address->path != nullptr);

    auto *connection = new LhttpConnection(c);

    connection->Connect(mchild_stock,
                        c.GetStockName(), std::move(request),
                        address->concurrency);
}

LhttpConnection::~LhttpConnection() noexcept
{
    if (fd.IsDefined()) {
        event.Cancel();
        fd.Close();
    }

    if (child != nullptr)
        lease_ref.Release(true);
}

/*
 * interface
 *
 */

inline
LhttpStock::LhttpStock(unsigned limit, unsigned max_idle,
                       EventLoop &event_loop, SpawnService &spawn_service,
                       SocketDescriptor log_socket,
                       const ChildErrorLogOptions &log_options) noexcept
    :child_stock(event_loop, spawn_service,
                 *this,
                 64,
                 log_socket, log_options,
                 limit, max_idle),
     mchild_stock(child_stock.GetStockMap()),
     hstock(event_loop, *this, limit, max_idle) {}

void
LhttpStock::FadeTag(const char *tag) noexcept
{
    assert(tag != nullptr);

    hstock.FadeIf([tag](const StockItem &item){
            const auto &connection = (const LhttpConnection &)item;
            const char *tag2 = connection.GetTag();
            return tag2 != nullptr && strcmp(tag, tag2) == 0;
        });

    mchild_stock.FadeIf([tag](const StockItem &item){
            const char *tag2 = child_stock_item_get_tag(item);
            return tag2 != nullptr && strcmp(tag, tag2) == 0;
        });

    child_stock.FadeTag(tag);
}

LhttpStock *
lhttp_stock_new(unsigned limit, unsigned max_idle,
                EventLoop &event_loop, SpawnService &spawn_service,
                SocketDescriptor log_socket,
                const ChildErrorLogOptions &log_options) noexcept
{
    return new LhttpStock(limit, max_idle, event_loop, spawn_service,
                          log_socket, log_options);
}

void
lhttp_stock_free(LhttpStock *ls) noexcept
{
    delete ls;
}

void
lhttp_stock_fade_all(LhttpStock &ls) noexcept
{
    ls.FadeAll();
}

void
lhttp_stock_fade_tag(LhttpStock &ls, const char *tag) noexcept
{
    ls.FadeTag(tag);
}

StockItem *
lhttp_stock_get(LhttpStock *lhttp_stock,
                const LhttpAddress *address)
{
    const auto *const jail = address->options.jail;
    if (jail != nullptr)
        jail->Check();

    union {
        const LhttpAddress *in;
        void *out;
    } deconst = { .in = address };

    const TempPoolLease tpool;
    return lhttp_stock->GetConnectionStock().GetNow(lhttp_stock_key(tpool, address),
                                                    ToNopPointer(deconst.out));
}

SocketDescriptor
lhttp_stock_item_get_socket(const StockItem &item) noexcept
{
    const auto *connection = (const LhttpConnection *)&item;

    return connection->GetSocket();
}

FdType
lhttp_stock_item_get_type(gcc_unused const StockItem &item) noexcept
{
    return FdType::FD_SOCKET;
}

void
lhttp_stock_item_set_site(StockItem &item, const char *site) noexcept
{
    auto &connection = (LhttpConnection &)item;
    connection.SetSite(site);
}

void
lhttp_stock_item_set_uri(StockItem &item, const char *uri) noexcept
{
    auto &connection = (LhttpConnection &)item;
    connection.SetUri(uri);
}
<commit_msg>lhttp_stock: use `const_cast`<commit_after>/*
 * Copyright 2007-2017 Content Management AG
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * 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.
 *
 * 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
 * FOUNDATION 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 "lhttp_stock.hxx"
#include "lhttp_address.hxx"
#include "stock/Stock.hxx"
#include "stock/MapStock.hxx"
#include "stock/MultiStock.hxx"
#include "stock/Class.hxx"
#include "stock/Item.hxx"
#include "pool/tpool.hxx"
#include "AllocatorPtr.hxx"
#include "lease.hxx"
#include "child_stock.hxx"
#include "spawn/JailParams.hxx"
#include "spawn/Prepared.hxx"
#include "event/SocketEvent.hxx"
#include "event/TimerEvent.hxx"
#include "net/UniqueSocketDescriptor.hxx"
#include "io/Logger.hxx"
#include "util/RuntimeError.hxx"
#include "util/Exception.hxx"

#include <assert.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>

class LhttpStock final : StockClass, ChildStockClass {
    ChildStock child_stock;
    MultiStock mchild_stock;
    StockMap hstock;

public:
    LhttpStock(unsigned limit, unsigned max_idle,
               EventLoop &event_loop, SpawnService &spawn_service,
               SocketDescriptor log_socket,
               const ChildErrorLogOptions &log_options) noexcept;

    void FadeAll() noexcept {
        hstock.FadeAll();
        child_stock.GetStockMap().FadeAll();
        mchild_stock.FadeAll();
    }

    void FadeTag(const char *tag) noexcept;

    StockMap &GetConnectionStock() noexcept {
        return hstock;
    }

private:
    /* virtual methods from class StockClass */
    void Create(CreateStockItem c, StockRequest request,
                CancellablePointer &cancel_ptr) override;

    /* virtual methods from class ChildStockClass */
    int GetChildSocketType(void *info) const noexcept override;
    const char *GetChildTag(void *info) const noexcept override;
    void PrepareChild(void *info, UniqueSocketDescriptor &&fd,
                      PreparedChildProcess &p) override;
};

class LhttpConnection final : LoggerDomainFactory, StockItem {
    LazyDomainLogger logger;

    StockItem *child = nullptr;

    struct lease_ref lease_ref;

    UniqueSocketDescriptor fd;
    SocketEvent event;
    TimerEvent idle_timeout_event;

public:
    explicit LhttpConnection(CreateStockItem c) noexcept
        :StockItem(c),
         logger(*this),
         event(c.stock.GetEventLoop(), BIND_THIS_METHOD(EventCallback)),
         idle_timeout_event(c.stock.GetEventLoop(),
                            BIND_THIS_METHOD(OnIdleTimeout)) {}

    ~LhttpConnection() noexcept override;

    void Connect(MultiStock &child_stock,
                 const char *key, StockRequest &&request,
                 unsigned concurrency);

    SocketDescriptor GetSocket() const noexcept {
        assert(fd.IsDefined());
        return fd;
    }

    gcc_pure
    const char *GetTag() const noexcept {
        assert(child != nullptr);

        return child_stock_item_get_tag(*child);
    }

    void SetSite(const char *site) noexcept {
        child_stock_item_set_site(*child, site);
    }

    void SetUri(const char *uri) noexcept {
        child_stock_item_set_uri(*child, uri);
    }

private:
    void EventCallback(unsigned events) noexcept;
    void OnIdleTimeout() noexcept;

    /* virtual methods from LoggerDomainFactory */
    std::string MakeLoggerDomain() const noexcept override {
        return GetStockName();
    }

    /* virtual methods from class StockItem */
    bool Borrow() noexcept override {
        event.Cancel();
        idle_timeout_event.Cancel();
        return true;
    }

    bool Release() noexcept override {
        event.ScheduleRead();
        idle_timeout_event.Schedule(std::chrono::minutes(5));
        return true;
    }
};

inline void
LhttpConnection::Connect(MultiStock &child_stock,
                         const char *key, StockRequest &&request,
                         unsigned concurrency)
{
    try {
        child = child_stock.GetNow(key, std::move(request), concurrency,
                                   lease_ref);
    } catch (...) {
        delete this;
        std::throw_with_nested(FormatRuntimeError("Failed to launch LHTTP server '%s'",
                                                  key));
    }

    try {
        fd = child_stock_item_connect(*child);
    } catch (...) {
        delete this;
        std::throw_with_nested(FormatRuntimeError("Failed to connect to LHTTP server '%s'",
                                                  key));
    }

    event.Open(fd);
    InvokeCreateSuccess();
}

static const char *
lhttp_stock_key(struct pool *pool, const LhttpAddress *address) noexcept
{
    return address->GetServerId(AllocatorPtr(*pool));
}

/*
 * libevent callback
 *
 */

inline void
LhttpConnection::EventCallback(unsigned) noexcept
{
    char buffer;
    ssize_t nbytes = fd.Read(&buffer, sizeof(buffer));
    if (nbytes < 0)
        logger(2, "error on idle LHTTP connection: ", strerror(errno));
    else if (nbytes > 0)
        logger(2, "unexpected data from idle LHTTP connection");

    InvokeIdleDisconnect();
}

inline void
LhttpConnection::OnIdleTimeout() noexcept
{
    InvokeIdleDisconnect();
}

/*
 * child_stock class
 *
 */

int
LhttpStock::GetChildSocketType(void *info) const noexcept
{
    const auto &address = *(const LhttpAddress *)info;

    int type = SOCK_STREAM;
    if (!address.blocking)
        type |= SOCK_NONBLOCK;

    return type;
}

const char *
LhttpStock::GetChildTag(void *info) const noexcept
{
    const auto &address = *(const LhttpAddress *)info;

    return address.options.tag;
}

void
LhttpStock::PrepareChild(void *info, UniqueSocketDescriptor &&fd,
                         PreparedChildProcess &p)
{
    const auto &address = *(const LhttpAddress *)info;

    p.SetStdin(std::move(fd));
    address.CopyTo(p);
}

/*
 * stock class
 *
 */

void
LhttpStock::Create(CreateStockItem c, StockRequest request,
                   gcc_unused CancellablePointer &cancel_ptr)
{
    const auto *address = (const LhttpAddress *)request.get();

    assert(address != nullptr);
    assert(address->path != nullptr);

    auto *connection = new LhttpConnection(c);

    connection->Connect(mchild_stock,
                        c.GetStockName(), std::move(request),
                        address->concurrency);
}

LhttpConnection::~LhttpConnection() noexcept
{
    if (fd.IsDefined()) {
        event.Cancel();
        fd.Close();
    }

    if (child != nullptr)
        lease_ref.Release(true);
}

/*
 * interface
 *
 */

inline
LhttpStock::LhttpStock(unsigned limit, unsigned max_idle,
                       EventLoop &event_loop, SpawnService &spawn_service,
                       SocketDescriptor log_socket,
                       const ChildErrorLogOptions &log_options) noexcept
    :child_stock(event_loop, spawn_service,
                 *this,
                 64,
                 log_socket, log_options,
                 limit, max_idle),
     mchild_stock(child_stock.GetStockMap()),
     hstock(event_loop, *this, limit, max_idle) {}

void
LhttpStock::FadeTag(const char *tag) noexcept
{
    assert(tag != nullptr);

    hstock.FadeIf([tag](const StockItem &item){
            const auto &connection = (const LhttpConnection &)item;
            const char *tag2 = connection.GetTag();
            return tag2 != nullptr && strcmp(tag, tag2) == 0;
        });

    mchild_stock.FadeIf([tag](const StockItem &item){
            const char *tag2 = child_stock_item_get_tag(item);
            return tag2 != nullptr && strcmp(tag, tag2) == 0;
        });

    child_stock.FadeTag(tag);
}

LhttpStock *
lhttp_stock_new(unsigned limit, unsigned max_idle,
                EventLoop &event_loop, SpawnService &spawn_service,
                SocketDescriptor log_socket,
                const ChildErrorLogOptions &log_options) noexcept
{
    return new LhttpStock(limit, max_idle, event_loop, spawn_service,
                          log_socket, log_options);
}

void
lhttp_stock_free(LhttpStock *ls) noexcept
{
    delete ls;
}

void
lhttp_stock_fade_all(LhttpStock &ls) noexcept
{
    ls.FadeAll();
}

void
lhttp_stock_fade_tag(LhttpStock &ls, const char *tag) noexcept
{
    ls.FadeTag(tag);
}

StockItem *
lhttp_stock_get(LhttpStock *lhttp_stock,
                const LhttpAddress *address)
{
    const auto *const jail = address->options.jail;
    if (jail != nullptr)
        jail->Check();

    const TempPoolLease tpool;
    return lhttp_stock->GetConnectionStock().GetNow(lhttp_stock_key(tpool, address),
                                                    ToNopPointer(const_cast<LhttpAddress *>(address)));
}

SocketDescriptor
lhttp_stock_item_get_socket(const StockItem &item) noexcept
{
    const auto *connection = (const LhttpConnection *)&item;

    return connection->GetSocket();
}

FdType
lhttp_stock_item_get_type(gcc_unused const StockItem &item) noexcept
{
    return FdType::FD_SOCKET;
}

void
lhttp_stock_item_set_site(StockItem &item, const char *site) noexcept
{
    auto &connection = (LhttpConnection &)item;
    connection.SetSite(site);
}

void
lhttp_stock_item_set_uri(StockItem &item, const char *uri) noexcept
{
    auto &connection = (LhttpConnection &)item;
    connection.SetUri(uri);
}
<|endoftext|>


<commit_before>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

#include "tensorflow/lite/delegates/gpu/cl/cl_device.h"

#include <algorithm>
#include <string>
#include <vector>

#include "absl/strings/numbers.h"
#include "absl/strings/str_split.h"
#include "tensorflow/lite/delegates/gpu/cl/util.h"
#include "tensorflow/lite/delegates/gpu/common/status.h"

namespace tflite {
namespace gpu {
namespace cl {

template <>
std::string GetDeviceInfo<std::string>(cl_device_id id, cl_device_info info) {
  size_t size;
  cl_int error = clGetDeviceInfo(id, info, 0, nullptr, &size);
  if (error != CL_SUCCESS) {
    return "";
  }

  std::string result(size - 1, 0);
  error = clGetDeviceInfo(id, info, size, &result[0], nullptr);
  if (error != CL_SUCCESS) {
    return "";
  }
  return result;
}

namespace {
template <typename T>
T GetPlatformInfo(cl_platform_id id, cl_platform_info info) {
  T result;
  cl_int error = clGetPlatformInfo(id, info, sizeof(T), &result, nullptr);
  if (error != CL_SUCCESS) {
    return -1;
  }
  return result;
}

std::string GetPlatformInfo(cl_platform_id id, cl_platform_info info) {
  size_t size;
  cl_int error = clGetPlatformInfo(id, info, 0, nullptr, &size);
  if (error != CL_SUCCESS) {
    return "";
  }

  std::string result(size - 1, 0);
  error = clGetPlatformInfo(id, info, size, &result[0], nullptr);
  if (error != CL_SUCCESS) {
    return "";
  }
  return result;
}

void GetDeviceWorkDimsSizes(cl_device_id id, int3* result) {
  int dims_count =
      GetDeviceInfo<cl_uint>(id, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS);
  if (dims_count < 3) {
    return;
  }
  std::vector<size_t> limits(dims_count);
  cl_int error =
      clGetDeviceInfo(id, CL_DEVICE_MAX_WORK_ITEM_SIZES,
                      sizeof(size_t) * dims_count, limits.data(), nullptr);
  if (error != CL_SUCCESS) {
    return;
  }
  // dims_count must be at least 3 according to spec
  result->x = limits[0];
  result->y = limits[1];
  result->z = limits[2];
}

OpenClVersion ParseCLVersion(const std::string& version) {
  const auto first_dot_pos = version.find_first_of('.');
  if (first_dot_pos == std::string::npos) {
    return OpenClVersion::kCl1_0;
  }
  const int major = version[first_dot_pos - 1] - '0';
  const int minor = version[first_dot_pos + 1] - '0';

  if (major == 1) {
    if (minor == 2) {
      return OpenClVersion::kCl1_2;
    } else if (minor == 1) {
      return OpenClVersion::kCl1_1;
    } else {
      return OpenClVersion::kCl1_0;
    }
  } else if (major == 2) {
    if (minor == 2) {
      return OpenClVersion::kCl2_2;
    } else if (minor == 1) {
      return OpenClVersion::kCl2_1;
    } else {
      return OpenClVersion::kCl2_0;
    }
  } else if (major == 3) {
    return OpenClVersion::kCl3_0;
  } else {
    return OpenClVersion::kCl1_0;
  }
}

GpuVendor ParseVendor(const std::string& device_name,
                      const std::string& vendor_name) {
  std::string d_name = device_name;
  std::string v_name = vendor_name;
  std::transform(d_name.begin(), d_name.end(), d_name.begin(), ::tolower);
  std::transform(v_name.begin(), v_name.end(), v_name.begin(), ::tolower);
  if (d_name.find("qualcomm") != std::string::npos ||
      v_name.find("qualcomm") != std::string::npos) {
    return GpuVendor::kQualcomm;
  } else if (d_name.find("mali") != std::string::npos ||
             v_name.find("mali") != std::string::npos) {
    return GpuVendor::kMali;
  } else if (d_name.find("power") != std::string::npos ||
             v_name.find("power") != std::string::npos) {
    return GpuVendor::kPowerVR;
  } else if (d_name.find("nvidia") != std::string::npos ||
             v_name.find("nvidia") != std::string::npos) {
    return GpuVendor::kNvidia;
  } else if (d_name.find("advanced micro devices") != std::string::npos ||
             v_name.find("advanced micro devices") != std::string::npos) {
    return GpuVendor::kAMD;
  } else if (d_name.find("intel") != std::string::npos ||
             v_name.find("intel") != std::string::npos) {
    return GpuVendor::kIntel;
  } else {
    return GpuVendor::kUnknown;
  }
}

// check that gpu_version belong to range min_version-max_version
// min_version is included and max_version is excluded.
bool IsGPUVersionInRange(int gpu_version, int min_version, int max_version) {
  return gpu_version >= min_version && gpu_version < max_version;
}
}  // namespace

GpuInfo GpuInfoFromDeviceID(cl_device_id id) {
  GpuInfo info;
  const auto device_name = GetDeviceInfo<std::string>(id, CL_DEVICE_NAME);
  const auto vendor_name = GetDeviceInfo<std::string>(id, CL_DEVICE_VENDOR);
  const auto opencl_c_version =
      GetDeviceInfo<std::string>(id, CL_DEVICE_OPENCL_C_VERSION);
  info.gpu_api = GpuApi::kOpenCl;
  info.vendor = ParseVendor(device_name, vendor_name);
  if (info.IsAdreno()) {
    info.adreno_info = AdrenoInfo(opencl_c_version);
  } else if (info.IsMali()) {
    info.mali_info = MaliInfo(device_name);
  }
  info.opencl_info.cl_version = ParseCLVersion(opencl_c_version);
  info.opencl_info.extensions =
      absl::StrSplit(GetDeviceInfo<std::string>(id, CL_DEVICE_EXTENSIONS), ' ');
  info.opencl_info.supports_fp16 = false;
  info.opencl_info.supports_image3d_writes = false;
  for (const auto& ext : info.opencl_info.extensions) {
    if (ext == "cl_khr_fp16") {
      info.opencl_info.supports_fp16 = true;
    }
    if (ext == "cl_khr_3d_image_writes") {
      info.opencl_info.supports_image3d_writes = true;
    }
  }

  cl_device_fp_config f32_config =
      GetDeviceInfo<cl_device_fp_config>(id, CL_DEVICE_SINGLE_FP_CONFIG);
  info.opencl_info.supports_fp32_rtn = f32_config & CL_FP_ROUND_TO_NEAREST;

  if (info.opencl_info.supports_fp16) {
    cl_device_fp_config f16_config;
    auto status = GetDeviceInfo<cl_device_fp_config>(
        id, CL_DEVICE_HALF_FP_CONFIG, &f16_config);
    // AMD supports cl_khr_fp16 but CL_DEVICE_HALF_FP_CONFIG is empty.
    if (status.ok() && !info.IsAMD()) {
      info.opencl_info.supports_fp16_rtn = f16_config & CL_FP_ROUND_TO_NEAREST;
    } else {  // happens on PowerVR
      f16_config = f32_config;
      info.opencl_info.supports_fp16_rtn = info.opencl_info.supports_fp32_rtn;
    }
  } else {
    info.opencl_info.supports_fp16_rtn = false;
  }

  if (info.IsPowerVR() && !info.opencl_info.supports_fp16) {
    // PowerVR doesn't have full support of fp16 and so doesn't list this
    // extension. But it can support fp16 in MADs and as buffers/textures types,
    // so we will use it.
    info.opencl_info.supports_fp16 = true;
    info.opencl_info.supports_fp16_rtn = info.opencl_info.supports_fp32_rtn;
  }

  if (!info.opencl_info.supports_image3d_writes &&
      ((info.IsAdreno() && info.adreno_info.IsAdreno4xx()) ||
       info.IsNvidia())) {
    // in local tests Adreno 430 can write in image 3d, at least on small sizes,
    // but it doesn't have cl_khr_3d_image_writes in list of available
    // extensions
    // The same for NVidia
    info.opencl_info.supports_image3d_writes = true;
  }
  info.opencl_info.compute_units_count =
      GetDeviceInfo<cl_uint>(id, CL_DEVICE_MAX_COMPUTE_UNITS);
  info.opencl_info.image2d_max_width =
      GetDeviceInfo<size_t>(id, CL_DEVICE_IMAGE2D_MAX_WIDTH);
  info.opencl_info.image2d_max_height =
      GetDeviceInfo<size_t>(id, CL_DEVICE_IMAGE2D_MAX_HEIGHT);
  info.opencl_info.buffer_max_size =
      GetDeviceInfo<cl_ulong>(id, CL_DEVICE_MAX_MEM_ALLOC_SIZE);
  if (info.opencl_info.cl_version >= OpenClVersion::kCl1_2) {
    info.opencl_info.image_buffer_max_size =
        GetDeviceInfo<size_t>(id, CL_DEVICE_IMAGE_MAX_BUFFER_SIZE);
    info.opencl_info.image_array_max_layers =
        GetDeviceInfo<size_t>(id, CL_DEVICE_IMAGE_MAX_ARRAY_SIZE);
  }
  info.opencl_info.image3d_max_width =
      GetDeviceInfo<size_t>(id, CL_DEVICE_IMAGE3D_MAX_WIDTH);
  info.opencl_info.image3d_max_height =
      GetDeviceInfo<size_t>(id, CL_DEVICE_IMAGE2D_MAX_HEIGHT);
  info.opencl_info.image3d_max_depth =
      GetDeviceInfo<size_t>(id, CL_DEVICE_IMAGE3D_MAX_DEPTH);
  int3 max_work_group_sizes;
  GetDeviceWorkDimsSizes(id, &max_work_group_sizes);
  info.opencl_info.max_work_group_size_x = max_work_group_sizes.x;
  info.opencl_info.max_work_group_size_y = max_work_group_sizes.y;
  info.opencl_info.max_work_group_size_z = max_work_group_sizes.z;
  info.opencl_info.max_work_group_total_size =
      GetDeviceInfo<size_t>(id, CL_DEVICE_MAX_WORK_GROUP_SIZE);

  if (info.IsIntel()) {
    if (info.SupportsExtension("cl_intel_required_subgroup_size")) {
      size_t sub_groups_count;
      cl_int status =
          clGetDeviceInfo(id, 0x4108 /*CL_DEVICE_SUB_GROUP_SIZES_INTEL*/, 0,
                          nullptr, &sub_groups_count);
      if (status == CL_SUCCESS) {
        std::vector<size_t> sub_group_sizes(sub_groups_count);
        status = clGetDeviceInfo(id, 0x4108 /*CL_DEVICE_SUB_GROUP_SIZES_INTEL*/,
                                 sizeof(size_t) * sub_groups_count,
                                 sub_group_sizes.data(), nullptr);
        if (status == CL_SUCCESS) {
          for (int i = 0; i < sub_groups_count; ++i) {
            info.supported_subgroup_sizes.push_back(sub_group_sizes[i]);
          }
        }
      }
    }
  }
  return info;
}

CLDevice::CLDevice(cl_device_id id, cl_platform_id platform_id)
    : info_(GpuInfoFromDeviceID(id)), id_(id), platform_id_(platform_id) {}

CLDevice::CLDevice(const CLDevice& device)
    : info_(device.info_), id_(device.id_), platform_id_(device.platform_id_) {}

CLDevice& CLDevice::operator=(const CLDevice& device) {
  if (this != &device) {
    info_ = device.info_;
    id_ = device.id_;
    platform_id_ = device.platform_id_;
  }
  return *this;
}

CLDevice::CLDevice(CLDevice&& device)
    : info_(std::move(device.info_)),
      id_(device.id_),
      platform_id_(device.platform_id_) {
  device.id_ = nullptr;
  device.platform_id_ = nullptr;
}

CLDevice& CLDevice::operator=(CLDevice&& device) {
  if (this != &device) {
    id_ = nullptr;
    platform_id_ = nullptr;
    info_ = std::move(device.info_);
    std::swap(id_, device.id_);
    std::swap(platform_id_, device.platform_id_);
  }
  return *this;
}

std::string CLDevice::GetPlatformVersion() const {
  return GetPlatformInfo(platform_id_, CL_PLATFORM_VERSION);
}

void CLDevice::DisableOneLayerTextureArray() {
  info_.adreno_info.support_one_layer_texture_array = false;
}

absl::Status CreateDefaultGPUDevice(CLDevice* result) {
  cl_uint num_platforms;
  clGetPlatformIDs(0, nullptr, &num_platforms);
  if (num_platforms == 0) {
    return absl::UnknownError("No supported OpenCL platform.");
  }
  std::vector<cl_platform_id> platforms(num_platforms);
  clGetPlatformIDs(num_platforms, platforms.data(), nullptr);

  cl_platform_id platform_id = platforms[0];
  cl_uint num_devices;
  clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 0, nullptr, &num_devices);
  if (num_devices == 0) {
    return absl::UnknownError("No GPU on current platform.");
  }

  std::vector<cl_device_id> devices(num_devices);
  clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, num_devices, devices.data(),
                 nullptr);

  *result = CLDevice(devices[0], platform_id);
  return absl::OkStatus();
}

}  // namespace cl
}  // namespace gpu
}  // namespace tflite
<commit_msg>Using common function for initialization of gpu_info in OpenCL backend.<commit_after>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

#include "tensorflow/lite/delegates/gpu/cl/cl_device.h"

#include <algorithm>
#include <string>
#include <vector>

#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "tensorflow/lite/delegates/gpu/cl/util.h"
#include "tensorflow/lite/delegates/gpu/common/status.h"

namespace tflite {
namespace gpu {
namespace cl {

template <>
std::string GetDeviceInfo<std::string>(cl_device_id id, cl_device_info info) {
  size_t size;
  cl_int error = clGetDeviceInfo(id, info, 0, nullptr, &size);
  if (error != CL_SUCCESS) {
    return "";
  }

  std::string result(size - 1, 0);
  error = clGetDeviceInfo(id, info, size, &result[0], nullptr);
  if (error != CL_SUCCESS) {
    return "";
  }
  return result;
}

namespace {
template <typename T>
T GetPlatformInfo(cl_platform_id id, cl_platform_info info) {
  T result;
  cl_int error = clGetPlatformInfo(id, info, sizeof(T), &result, nullptr);
  if (error != CL_SUCCESS) {
    return -1;
  }
  return result;
}

std::string GetPlatformInfo(cl_platform_id id, cl_platform_info info) {
  size_t size;
  cl_int error = clGetPlatformInfo(id, info, 0, nullptr, &size);
  if (error != CL_SUCCESS) {
    return "";
  }

  std::string result(size - 1, 0);
  error = clGetPlatformInfo(id, info, size, &result[0], nullptr);
  if (error != CL_SUCCESS) {
    return "";
  }
  return result;
}

void GetDeviceWorkDimsSizes(cl_device_id id, int3* result) {
  int dims_count =
      GetDeviceInfo<cl_uint>(id, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS);
  if (dims_count < 3) {
    return;
  }
  std::vector<size_t> limits(dims_count);
  cl_int error =
      clGetDeviceInfo(id, CL_DEVICE_MAX_WORK_ITEM_SIZES,
                      sizeof(size_t) * dims_count, limits.data(), nullptr);
  if (error != CL_SUCCESS) {
    return;
  }
  // dims_count must be at least 3 according to spec
  result->x = limits[0];
  result->y = limits[1];
  result->z = limits[2];
}

OpenClVersion ParseCLVersion(const std::string& version) {
  const auto first_dot_pos = version.find_first_of('.');
  if (first_dot_pos == std::string::npos) {
    return OpenClVersion::kCl1_0;
  }
  const int major = version[first_dot_pos - 1] - '0';
  const int minor = version[first_dot_pos + 1] - '0';

  if (major == 1) {
    if (minor == 2) {
      return OpenClVersion::kCl1_2;
    } else if (minor == 1) {
      return OpenClVersion::kCl1_1;
    } else {
      return OpenClVersion::kCl1_0;
    }
  } else if (major == 2) {
    if (minor == 2) {
      return OpenClVersion::kCl2_2;
    } else if (minor == 1) {
      return OpenClVersion::kCl2_1;
    } else {
      return OpenClVersion::kCl2_0;
    }
  } else if (major == 3) {
    return OpenClVersion::kCl3_0;
  } else {
    return OpenClVersion::kCl1_0;
  }
}

// check that gpu_version belong to range min_version-max_version
// min_version is included and max_version is excluded.
bool IsGPUVersionInRange(int gpu_version, int min_version, int max_version) {
  return gpu_version >= min_version && gpu_version < max_version;
}
}  // namespace

GpuInfo GpuInfoFromDeviceID(cl_device_id id) {
  GpuInfo info;
  const auto device_name = GetDeviceInfo<std::string>(id, CL_DEVICE_NAME);
  const auto vendor_name = GetDeviceInfo<std::string>(id, CL_DEVICE_VENDOR);
  const auto opencl_c_version =
      GetDeviceInfo<std::string>(id, CL_DEVICE_OPENCL_C_VERSION);
  const std::string gpu_description =
      absl::StrCat(device_name, " ", vendor_name, " ", opencl_c_version);
  GetGpuInfoFromDeviceDescription(gpu_description, GpuApi::kOpenCl, &info);
  info.opencl_info.cl_version = ParseCLVersion(opencl_c_version);
  info.opencl_info.extensions =
      absl::StrSplit(GetDeviceInfo<std::string>(id, CL_DEVICE_EXTENSIONS), ' ');
  info.opencl_info.supports_fp16 = false;
  info.opencl_info.supports_image3d_writes = false;
  for (const auto& ext : info.opencl_info.extensions) {
    if (ext == "cl_khr_fp16") {
      info.opencl_info.supports_fp16 = true;
    }
    if (ext == "cl_khr_3d_image_writes") {
      info.opencl_info.supports_image3d_writes = true;
    }
  }

  cl_device_fp_config f32_config =
      GetDeviceInfo<cl_device_fp_config>(id, CL_DEVICE_SINGLE_FP_CONFIG);
  info.opencl_info.supports_fp32_rtn = f32_config & CL_FP_ROUND_TO_NEAREST;

  if (info.opencl_info.supports_fp16) {
    cl_device_fp_config f16_config;
    auto status = GetDeviceInfo<cl_device_fp_config>(
        id, CL_DEVICE_HALF_FP_CONFIG, &f16_config);
    // AMD supports cl_khr_fp16 but CL_DEVICE_HALF_FP_CONFIG is empty.
    if (status.ok() && !info.IsAMD()) {
      info.opencl_info.supports_fp16_rtn = f16_config & CL_FP_ROUND_TO_NEAREST;
    } else {  // happens on PowerVR
      f16_config = f32_config;
      info.opencl_info.supports_fp16_rtn = info.opencl_info.supports_fp32_rtn;
    }
  } else {
    info.opencl_info.supports_fp16_rtn = false;
  }

  if (info.IsPowerVR() && !info.opencl_info.supports_fp16) {
    // PowerVR doesn't have full support of fp16 and so doesn't list this
    // extension. But it can support fp16 in MADs and as buffers/textures types,
    // so we will use it.
    info.opencl_info.supports_fp16 = true;
    info.opencl_info.supports_fp16_rtn = info.opencl_info.supports_fp32_rtn;
  }

  if (!info.opencl_info.supports_image3d_writes &&
      ((info.IsAdreno() && info.adreno_info.IsAdreno4xx()) ||
       info.IsNvidia())) {
    // in local tests Adreno 430 can write in image 3d, at least on small sizes,
    // but it doesn't have cl_khr_3d_image_writes in list of available
    // extensions
    // The same for NVidia
    info.opencl_info.supports_image3d_writes = true;
  }
  info.opencl_info.compute_units_count =
      GetDeviceInfo<cl_uint>(id, CL_DEVICE_MAX_COMPUTE_UNITS);
  info.opencl_info.image2d_max_width =
      GetDeviceInfo<size_t>(id, CL_DEVICE_IMAGE2D_MAX_WIDTH);
  info.opencl_info.image2d_max_height =
      GetDeviceInfo<size_t>(id, CL_DEVICE_IMAGE2D_MAX_HEIGHT);
  info.opencl_info.buffer_max_size =
      GetDeviceInfo<cl_ulong>(id, CL_DEVICE_MAX_MEM_ALLOC_SIZE);
  if (info.opencl_info.cl_version >= OpenClVersion::kCl1_2) {
    info.opencl_info.image_buffer_max_size =
        GetDeviceInfo<size_t>(id, CL_DEVICE_IMAGE_MAX_BUFFER_SIZE);
    info.opencl_info.image_array_max_layers =
        GetDeviceInfo<size_t>(id, CL_DEVICE_IMAGE_MAX_ARRAY_SIZE);
  }
  info.opencl_info.image3d_max_width =
      GetDeviceInfo<size_t>(id, CL_DEVICE_IMAGE3D_MAX_WIDTH);
  info.opencl_info.image3d_max_height =
      GetDeviceInfo<size_t>(id, CL_DEVICE_IMAGE2D_MAX_HEIGHT);
  info.opencl_info.image3d_max_depth =
      GetDeviceInfo<size_t>(id, CL_DEVICE_IMAGE3D_MAX_DEPTH);
  int3 max_work_group_sizes;
  GetDeviceWorkDimsSizes(id, &max_work_group_sizes);
  info.opencl_info.max_work_group_size_x = max_work_group_sizes.x;
  info.opencl_info.max_work_group_size_y = max_work_group_sizes.y;
  info.opencl_info.max_work_group_size_z = max_work_group_sizes.z;
  info.opencl_info.max_work_group_total_size =
      GetDeviceInfo<size_t>(id, CL_DEVICE_MAX_WORK_GROUP_SIZE);

  if (info.IsIntel()) {
    if (info.SupportsExtension("cl_intel_required_subgroup_size")) {
      size_t sub_groups_count;
      cl_int status =
          clGetDeviceInfo(id, 0x4108 /*CL_DEVICE_SUB_GROUP_SIZES_INTEL*/, 0,
                          nullptr, &sub_groups_count);
      if (status == CL_SUCCESS) {
        std::vector<size_t> sub_group_sizes(sub_groups_count);
        status = clGetDeviceInfo(id, 0x4108 /*CL_DEVICE_SUB_GROUP_SIZES_INTEL*/,
                                 sizeof(size_t) * sub_groups_count,
                                 sub_group_sizes.data(), nullptr);
        if (status == CL_SUCCESS) {
          for (int i = 0; i < sub_groups_count; ++i) {
            info.supported_subgroup_sizes.push_back(sub_group_sizes[i]);
          }
        }
      }
    }
  }
  return info;
}

CLDevice::CLDevice(cl_device_id id, cl_platform_id platform_id)
    : info_(GpuInfoFromDeviceID(id)), id_(id), platform_id_(platform_id) {}

CLDevice::CLDevice(const CLDevice& device)
    : info_(device.info_), id_(device.id_), platform_id_(device.platform_id_) {}

CLDevice& CLDevice::operator=(const CLDevice& device) {
  if (this != &device) {
    info_ = device.info_;
    id_ = device.id_;
    platform_id_ = device.platform_id_;
  }
  return *this;
}

CLDevice::CLDevice(CLDevice&& device)
    : info_(std::move(device.info_)),
      id_(device.id_),
      platform_id_(device.platform_id_) {
  device.id_ = nullptr;
  device.platform_id_ = nullptr;
}

CLDevice& CLDevice::operator=(CLDevice&& device) {
  if (this != &device) {
    id_ = nullptr;
    platform_id_ = nullptr;
    info_ = std::move(device.info_);
    std::swap(id_, device.id_);
    std::swap(platform_id_, device.platform_id_);
  }
  return *this;
}

std::string CLDevice::GetPlatformVersion() const {
  return GetPlatformInfo(platform_id_, CL_PLATFORM_VERSION);
}

void CLDevice::DisableOneLayerTextureArray() {
  info_.adreno_info.support_one_layer_texture_array = false;
}

absl::Status CreateDefaultGPUDevice(CLDevice* result) {
  cl_uint num_platforms;
  clGetPlatformIDs(0, nullptr, &num_platforms);
  if (num_platforms == 0) {
    return absl::UnknownError("No supported OpenCL platform.");
  }
  std::vector<cl_platform_id> platforms(num_platforms);
  clGetPlatformIDs(num_platforms, platforms.data(), nullptr);

  cl_platform_id platform_id = platforms[0];
  cl_uint num_devices;
  clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 0, nullptr, &num_devices);
  if (num_devices == 0) {
    return absl::UnknownError("No GPU on current platform.");
  }

  std::vector<cl_device_id> devices(num_devices);
  clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, num_devices, devices.data(),
                 nullptr);

  *result = CLDevice(devices[0], platform_id);
  return absl::OkStatus();
}

}  // namespace cl
}  // namespace gpu
}  // namespace tflite
<|endoftext|>


<commit_before>// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "assert.h"

#include "chainparams.h"
#include "main.h"
#include "util.h"

#include <boost/assign/list_of.hpp>

using namespace boost::assign;

struct SeedSpec6 {
    uint8_t addr[16];
    uint16_t port;
};

#include "chainparamsseeds.h"

//
// Main network
//

// Convert the pnSeeds6 array into usable address objects.
static void convertSeed6(std::vector<CAddress> &vSeedsOut, const SeedSpec6 *data, unsigned int count)
{
    // It'll only connect to one or two seed nodes because once it connects,
    // it'll get a pile of addresses with newer timestamps.
    // Seed nodes are given a random 'last seen time' of between one and two
    // weeks ago.
    const int64_t nOneWeek = 7*24*60*60;
    for (unsigned int i = 0; i < count; i++)
    {
        struct in6_addr ip;
        memcpy(&ip, data[i].addr, sizeof(ip));
        CAddress addr(CService(ip, data[i].port));
        addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
        vSeedsOut.push_back(addr);
    }
}

class CMainParams : public CChainParams {
public:
    CMainParams() {
        // The message start string is designed to be unlikely to occur in normal data.
        // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
        // a large 4-byte int at any alignment.
        pchMessageStart[0] = 0xaa;
        pchMessageStart[1] = 0xa3;
        pchMessageStart[2] = 0xb2;
        pchMessageStart[3] = 0xc4;
        vAlertPubKey = ParseHex("");
        nDefaultPort = 57155;
        nRPCPort = 57154;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20);

        // Build the genesis block. Note that the output of the genesis coinbase cannot
        // be spent as it did not originally exist in the database.
        //
        //CBlock(hash=000001faef25dec4fbcf906e6242621df2c183bf232f263d0ba5b101911e4563, ver=1, hashPrevBlock=0000000000000000000000000000000000000000000000000000000000000000, hashMerkleRoot=12630d16a97f24b287c8c2594dda5fb98c9e6c70fc61d44191931ea2aa08dc90, nTime=1393221600, nBits=1e0fffff, nNonce=164482, vtx=1, vchBlockSig=)
        //  Coinbase(hash=12630d16a9, nTime=1393221600, ver=1, vin.size=1, vout.size=1, nLockTime=0)
        //    CTxIn(COutPoint(0000000000, 4294967295), coinbase 00012a24323020466562203230313420426974636f696e2041544d7320636f6d6520746f20555341)
        //    CTxOut(empty)
        //  vMerkleTree: 12630d16a9
        const char* pszTimestamp = "New genesis for Coinswap of RENOS June/17";
        std::vector<CTxIn> vin;
        vin.resize(1);
        vin[0].scriptSig = CScript() << 0 << CBigNum(42) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
        std::vector<CTxOut> vout;
        vout.resize(1);
        vout[0].SetEmpty();
        CTransaction txNew(1, 1497040584, vin, vout, 0);
        genesis.vtx.push_back(txNew);
        genesis.hashPrevBlock = 0;
        genesis.hashMerkleRoot = genesis.BuildMerkleTree();
        genesis.nVersion = 1;
        genesis.nTime    = 1497040584;
        genesis.nBits    = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce   = 213861;

        hashGenesisBlock = genesis.GetHash();

        assert(hashGenesisBlock == uint256("0x00000e590857f6bf83e3ae07b56528e47565115465f9d4e8ead2c5bffb1a9edc"));
        assert(genesis.hashMerkleRoot == uint256("0xb43b9c01703081ea07d54e271471e7100364535cf55e38763761e384d27970af"));

       	vSeeds.push_back(CDNSSeedData("seed1", "137.74.193.204"));
	vSeeds.push_back(CDNSSeedData("seed2", "137.74.193.204"));
	vSeeds.push_back(CDNSSeedData("seed3", "198.50.180.192"));
	vSeeds.push_back(CDNSSeedData("seed4", "137.74.193.204"));
	vSeeds.push_back(CDNSSeedData("seed5", "137.74.193.204"));
	vSeeds.push_back(CDNSSeedData("seed6", "45.32.196.193"));
	vSeeds.push_back(CDNSSeedData("seed7", "45.32.164.109"));
	vSeeds.push_back(CDNSSeedData("seed8", "45.77.5.93"));
	vSeeds.push_back(CDNSSeedData("seed9", "149.56.128.2"));
	vSeeds.push_back(CDNSSeedData("seed10", "2a01:7e01::f03c:91ff:fe7b:8e41"));
	vSeeds.push_back(CDNSSeedData("seed11", "45.77.58.26"));
	vSeeds.push_back(CDNSSeedData("seed12", "45.77.37.208"));
	vSeeds.push_back(CDNSSeedData("seed13", "174.67.252.25"));
	vSeeds.push_back(CDNSSeedData("seed14", "79.137.34.194"));
	vSeeds.push_back(CDNSSeedData("seed15", "144.217.166.140"));
	vSeeds.push_back(CDNSSeedData("seed16", "2001:bc8:4700:2000::3e39"));
	vSeeds.push_back(CDNSSeedData("seed17", "104.238.184.213"));
	vSeeds.push_back(CDNSSeedData("seed18", "93.186.193.158"));
	vSeeds.push_back(CDNSSeedData("seed19", "51.15.52.23"));
	vSeeds.push_back(CDNSSeedData("seed20", "198.50.171.20"));
	vSeeds.push_back(CDNSSeedData("seed21", "147.135.233.42"));
	vSeeds.push_back(CDNSSeedData("seed22", "45.79.216.189"));
	vSeeds.push_back(CDNSSeedData("seed23", "2600:3c02::f03c:91ff:fe3e:dbbb"));
	vSeeds.push_back(CDNSSeedData("seed24", "45.63.68.182"));
	vSeeds.push_back(CDNSSeedData("seed25", "90.215.122.71"));
	vSeeds.push_back(CDNSSeedData("seed26", "82.43.204.158"));
	vSeeds.push_back(CDNSSeedData("seed27", "5.189.142.181"));
	vSeeds.push_back(CDNSSeedData("seed28", "2001:4ca0:0:fe00:0:5efe:a96:caa4"));
	vSeeds.push_back(CDNSSeedData("seed29", "193.90.142.13"));
	vSeeds.push_back(CDNSSeedData("seed30", "35.165.42.90"));
	vSeeds.push_back(CDNSSeedData("seed31", "2.62.187.203"));
	vSeeds.push_back(CDNSSeedData("seed32", "192.210.128.100"));
	vSeeds.push_back(CDNSSeedData("seed33", "2a02:f680:1:1100::60d2"));
	vSeeds.push_back(CDNSSeedData("seed34", "80.89.233.124"));
	vSeeds.push_back(CDNSSeedData("seed35", "203.59.230.190"));
	vSeeds.push_back(CDNSSeedData("seed36", "222.5.183.201"));
	vSeeds.push_back(CDNSSeedData("seed37", "104.237.153.253"));
	vSeeds.push_back(CDNSSeedData("seed38", "147.135.233.45"));
	vSeeds.push_back(CDNSSeedData("seed39", "2a01:7e01::f03c:91ff:fe92:d170"));
	vSeeds.push_back(CDNSSeedData("seed40", "172.104.86.169"));
	vSeeds.push_back(CDNSSeedData("seed41", "45.63.89.184"));
	vSeeds.push_back(CDNSSeedData("seed42", "2600:3c01::f03c:91ff:fed4:f07"));
	vSeeds.push_back(CDNSSeedData("seed43", "108.61.197.30"));
	vSeeds.push_back(CDNSSeedData("seed44", "45.77.80.196"));
	vSeeds.push_back(CDNSSeedData("seed45", "147.135.233.33"));
	vSeeds.push_back(CDNSSeedData("seed46", "2400:8902::f03c:91ff:fe3e:dbbf"));
	vSeeds.push_back(CDNSSeedData("seed47", "147.135.233.35"));
	vSeeds.push_back(CDNSSeedData("seed48", "2607:fea8:131f:f75a::7"));
	vSeeds.push_back(CDNSSeedData("seed49", "2001:0:9d38:6ab8:20a5:1a6c:fdc1:4434"));
	vSeeds.push_back(CDNSSeedData("seed50", "45.32.130.36"));
	vSeeds.push_back(CDNSSeedData("seed51", "45.77.82.231"));
	vSeeds.push_back(CDNSSeedData("seed52", "2001:0:9d38:6abd:34db:f25:899b:5608"));
	vSeeds.push_back(CDNSSeedData("seed53", "2001:0:9d38:90d7:3ce3:11d9:b08f:2a28"));
	vSeeds.push_back(CDNSSeedData("seed54", "2001:0:9d38:953c:10df:211c:41b4:9198"));

        base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,60);
        base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,28);
        base58Prefixes[SECRET_KEY] =     std::vector<unsigned char>(1,150);
        base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container<std::vector<unsigned char> >();
        base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container<std::vector<unsigned char> >();

        convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main));

        nLastPOWBlock = 6000;
    }

    virtual const CBlock& GenesisBlock() const { return genesis; }
    virtual Network NetworkID() const { return CChainParams::MAIN; }

    virtual const vector<CAddress>& FixedSeeds() const {
        return vFixedSeeds;
    }
protected:
    CBlock genesis;
    vector<CAddress> vFixedSeeds;
};
static CMainParams mainParams;

//
// Testnet
//

class CTestNetParams : public CMainParams {
public:
    CTestNetParams() {
        // The message start string is designed to be unlikely to occur in normal data.
        // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
        // a large 4-byte int at any alignment.
        pchMessageStart[0] = 0xa1;
        pchMessageStart[1] = 0x79;
        pchMessageStart[2] = 0xa4;
        pchMessageStart[3] = 0xa2;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 16);
        vAlertPubKey = ParseHex("");
        nDefaultPort = 57255;
        nRPCPort = 57254;
        strDataDir = "testnet";

        // Modify the testnet genesis block so the timestamp is valid for a later start.
        genesis.nBits  = 1497040584;
        genesis.nNonce = 213861;

        assert(hashGenesisBlock == uint256("0x00000e590857f6bf83e3ae07b56528e47565115465f9d4e8ead2c5bffb1a9edc"));

        vFixedSeeds.clear();
        vSeeds.clear();

        base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
        base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
        base58Prefixes[SECRET_KEY]     = std::vector<unsigned char>(1,229);
        base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container<std::vector<unsigned char> >();
        base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x35)(0x83)(0x94).convert_to_container<std::vector<unsigned char> >();

        convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test));

        nLastPOWBlock = 0x7fffffff;
    }
    virtual Network NetworkID() const { return CChainParams::TESTNET; }
};
static CTestNetParams testNetParams;

static CChainParams *pCurrentParams = &mainParams;

const CChainParams &Params() {
    return *pCurrentParams;
}

void SelectParams(CChainParams::Network network) {
    switch (network) {
        case CChainParams::MAIN:
            pCurrentParams = &mainParams;
            break;
        case CChainParams::TESTNET:
            pCurrentParams = &testNetParams;
            break;
        default:
            assert(false && "Unimplemented network");
            return;
    }
}

bool SelectParamsFromCommandLine() {

    bool fTestNet = GetBoolArg("-testnet", false);

    if (fTestNet) {
        SelectParams(CChainParams::TESTNET);
    } else {
        SelectParams(CChainParams::MAIN);
    }
    return true;
}
<commit_msg>Revert "Updated dns seed list. Will now sync on first runs"<commit_after>// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "assert.h"

#include "chainparams.h"
#include "main.h"
#include "util.h"

#include <boost/assign/list_of.hpp>

using namespace boost::assign;

struct SeedSpec6 {
    uint8_t addr[16];
    uint16_t port;
};

#include "chainparamsseeds.h"

//
// Main network
//

// Convert the pnSeeds6 array into usable address objects.
static void convertSeed6(std::vector<CAddress> &vSeedsOut, const SeedSpec6 *data, unsigned int count)
{
    // It'll only connect to one or two seed nodes because once it connects,
    // it'll get a pile of addresses with newer timestamps.
    // Seed nodes are given a random 'last seen time' of between one and two
    // weeks ago.
    const int64_t nOneWeek = 7*24*60*60;
    for (unsigned int i = 0; i < count; i++)
    {
        struct in6_addr ip;
        memcpy(&ip, data[i].addr, sizeof(ip));
        CAddress addr(CService(ip, data[i].port));
        addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
        vSeedsOut.push_back(addr);
    }
}

class CMainParams : public CChainParams {
public:
    CMainParams() {
        // The message start string is designed to be unlikely to occur in normal data.
        // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
        // a large 4-byte int at any alignment.
        pchMessageStart[0] = 0xaa;
        pchMessageStart[1] = 0xa3;
        pchMessageStart[2] = 0xb2;
        pchMessageStart[3] = 0xc4;
        vAlertPubKey = ParseHex("");
        nDefaultPort = 57155;
        nRPCPort = 57154;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20);

        // Build the genesis block. Note that the output of the genesis coinbase cannot
        // be spent as it did not originally exist in the database.
        //
        //CBlock(hash=000001faef25dec4fbcf906e6242621df2c183bf232f263d0ba5b101911e4563, ver=1, hashPrevBlock=0000000000000000000000000000000000000000000000000000000000000000, hashMerkleRoot=12630d16a97f24b287c8c2594dda5fb98c9e6c70fc61d44191931ea2aa08dc90, nTime=1393221600, nBits=1e0fffff, nNonce=164482, vtx=1, vchBlockSig=)
        //  Coinbase(hash=12630d16a9, nTime=1393221600, ver=1, vin.size=1, vout.size=1, nLockTime=0)
        //    CTxIn(COutPoint(0000000000, 4294967295), coinbase 00012a24323020466562203230313420426974636f696e2041544d7320636f6d6520746f20555341)
        //    CTxOut(empty)
        //  vMerkleTree: 12630d16a9
        const char* pszTimestamp = "New genesis for Coinswap of RENOS June/17";
        std::vector<CTxIn> vin;
        vin.resize(1);
        vin[0].scriptSig = CScript() << 0 << CBigNum(42) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
        std::vector<CTxOut> vout;
        vout.resize(1);
        vout[0].SetEmpty();
        CTransaction txNew(1, 1497040584, vin, vout, 0);
        genesis.vtx.push_back(txNew);
        genesis.hashPrevBlock = 0;
        genesis.hashMerkleRoot = genesis.BuildMerkleTree();
        genesis.nVersion = 1;
        genesis.nTime    = 1497040584;
        genesis.nBits    = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce   = 213861;

        hashGenesisBlock = genesis.GetHash();

        assert(hashGenesisBlock == uint256("0x00000e590857f6bf83e3ae07b56528e47565115465f9d4e8ead2c5bffb1a9edc"));
        assert(genesis.hashMerkleRoot == uint256("0xb43b9c01703081ea07d54e271471e7100364535cf55e38763761e384d27970af"));

        vSeeds.push_back(CDNSSeedData("seed1", "45.32.164.109"));
        vSeeds.push_back(CDNSSeedData("seed2", "45.32.163.3"));
        vSeeds.push_back(CDNSSeedData("seed3", "45.32.173.218"));
        vSeeds.push_back(CDNSSeedData("seed4", "45.32.196.193"));

        base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,60);
        base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,28);
        base58Prefixes[SECRET_KEY] =     std::vector<unsigned char>(1,150);
        base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container<std::vector<unsigned char> >();
        base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container<std::vector<unsigned char> >();

        convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main));

        nLastPOWBlock = 6000;
    }

    virtual const CBlock& GenesisBlock() const { return genesis; }
    virtual Network NetworkID() const { return CChainParams::MAIN; }

    virtual const vector<CAddress>& FixedSeeds() const {
        return vFixedSeeds;
    }
protected:
    CBlock genesis;
    vector<CAddress> vFixedSeeds;
};
static CMainParams mainParams;

//
// Testnet
//

class CTestNetParams : public CMainParams {
public:
    CTestNetParams() {
        // The message start string is designed to be unlikely to occur in normal data.
        // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
        // a large 4-byte int at any alignment.
        pchMessageStart[0] = 0xa1;
        pchMessageStart[1] = 0x79;
        pchMessageStart[2] = 0xa4;
        pchMessageStart[3] = 0xa2;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 16);
        vAlertPubKey = ParseHex("");
        nDefaultPort = 57255;
        nRPCPort = 57254;
        strDataDir = "testnet";

        // Modify the testnet genesis block so the timestamp is valid for a later start.
        genesis.nBits  = 1497040584;
        genesis.nNonce = 213861;

        assert(hashGenesisBlock == uint256("0x00000e590857f6bf83e3ae07b56528e47565115465f9d4e8ead2c5bffb1a9edc"));

        vFixedSeeds.clear();
        vSeeds.clear();

        base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
        base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
        base58Prefixes[SECRET_KEY]     = std::vector<unsigned char>(1,229);
        base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container<std::vector<unsigned char> >();
        base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x35)(0x83)(0x94).convert_to_container<std::vector<unsigned char> >();

        convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test));

        nLastPOWBlock = 0x7fffffff;
    }
    virtual Network NetworkID() const { return CChainParams::TESTNET; }
};
static CTestNetParams testNetParams;

static CChainParams *pCurrentParams = &mainParams;

const CChainParams &Params() {
    return *pCurrentParams;
}

void SelectParams(CChainParams::Network network) {
    switch (network) {
        case CChainParams::MAIN:
            pCurrentParams = &mainParams;
            break;
        case CChainParams::TESTNET:
            pCurrentParams = &testNetParams;
            break;
        default:
            assert(false && "Unimplemented network");
            return;
    }
}

bool SelectParamsFromCommandLine() {

    bool fTestNet = GetBoolArg("-testnet", false);

    if (fTestNet) {
        SelectParams(CChainParams::TESTNET);
    } else {
        SelectParams(CChainParams::MAIN);
    }
    return true;
}
<|endoftext|>