<commit_before>/*

Copyright (c) 2007, 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/config.hpp"

#if defined TORRENT_DEBUG || defined TORRENT_ASIO_DEBUGGING || TORRENT_RELEASE_ASSERTS

#ifdef __APPLE__
#include <AvailabilityMacros.h>
#endif

#include <string>
#include <cstring>
#include <stdlib.h>

// uClibc++ doesn't have cxxabi.h
#if defined __GNUC__ && __GNUC__ >= 3 \
	&& !defined __UCLIBCXX_MAJOR__

#include <cxxabi.h>

std::string demangle(char const* name)
{
// in case this string comes
	// this is needed on linux
	char const* start = strchr(name, '(');
	if (start != 0)
	{
		++start;
	}
	else
	{
		// this is needed on macos x
		start = strstr(name, "0x");
		if (start != 0)
		{
			start = strchr(start, ' ');
			if (start != 0) ++start;
			else start = name;
		}
		else start = name;
	}

	char const* end = strchr(start, '+');
	if (end) while (*(end-1) == ' ') --end;

	std::string in;
	if (end == 0) in.assign(start);
	else in.assign(start, end);

	size_t len;
	int status;
	char* unmangled = ::abi::__cxa_demangle(in.c_str(), 0, &len, &status);
	if (unmangled == 0) return in;
	std::string ret(unmangled);
	free(unmangled);
	return ret;
}
#elif defined WIN32

#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 // XP

#include "windows.h"
#include "dbghelp.h"

std::string demangle(char const* name)
{
	char demangled_name[256];
	if (UnDecorateSymbolName(name, demangled_name, sizeof(demangled_name), UNDNAME_NO_THROW_SIGNATURES) == 0)
		demangled_name[0] = 0;
	return demangled_name;
}

#else
std::string demangle(char const* name) { return name; }
#endif

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include "libtorrent/version.hpp"

// execinfo.h is available in the MacOS X 10.5 SDK.
#if (defined __linux__ || (defined __APPLE__ && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050))
#include <execinfo.h>

TORRENT_EXPORT void print_backtrace(char* out, int len, int max_depth)
{
	void* stack[50];
	int size = backtrace(stack, 50);
	char** symbols = backtrace_symbols(stack, size);

	for (int i = 1; i < size && len > 0; ++i)
	{
		int ret = snprintf(out, len, "%d: %s\n", i, demangle(symbols[i]).c_str());
		out += ret;
		len -= ret;
		if (i - 1 == max_depth && max_depth > 0) break;
	}

	free(symbols);
}

#elif defined WIN32

#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 // XP

#include "windows.h"
#include "libtorrent/utf8.hpp"

#include "winbase.h"
#include "dbghelp.h"

TORRENT_EXPORT void print_backtrace(char* out, int len, int max_depth)
{
	typedef USHORT (*RtlCaptureStackBackTrace_t)(
		__in ULONG FramesToSkip,
		__in ULONG FramesToCapture,
		__out PVOID *BackTrace,
		__out_opt PULONG BackTraceHash);

	static RtlCaptureStackBackTrace_t RtlCaptureStackBackTrace = 0;

	if (RtlCaptureStackBackTrace == 0)
	{
		// we don't actually have to free this library, everyone has it loaded
		HMODULE lib = LoadLibrary(TEXT("kernel32.dll"));
		RtlCaptureStackBackTrace = (RtlCaptureStackBackTrace_t)GetProcAddress(lib, "RtlCaptureStackBackTrace");
		if (RtlCaptureStackBackTrace == 0)
		{
			out[0] = 0;
			return;
		}
	}

	int i;
	void* stack[50];
	int size = CaptureStackBackTrace(0, 50, stack, 0);

	SYMBOL_INFO* symbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR), 1);
	symbol->MaxNameLen = MAX_SYM_NAME;
	symbol->SizeOfStruct = sizeof(SYMBOL_INFO);

	HANDLE p = GetCurrentProcess();
	static bool sym_initialized = false;
	if (!sym_initialized)
	{
		sym_initialized = true;
		SymInitialize(p, NULL, true);
	}
	for (i = 0; i < size && len > 0; ++i)
	{
		int ret;
		if (SymFromAddr(p, uintptr_t(stack[i]), 0, symbol))
			ret = snprintf(out, len, "%d: %s\n", i, symbol->Name);
		else
			ret = snprintf(out, len, "%d: <unknown>\n", i);

		out += ret;
		len -= ret;
		if (i == max_depth && max_depth > 0) break;
	}
	free(symbol);
}

#else

TORRENT_EXPORT void print_backtrace(char* out, int len, int max_depth) {}

#endif

#if TORRENT_PRODUCTION_ASSERTS
char const* libtorrent_assert_log = "asserts.log";
#endif

TORRENT_EXPORT void assert_fail(char const* expr, int line, char const* file
	, char const* function, char const* value)
{
#if TORRENT_PRODUCTION_ASSERTS
	FILE* out = fopen(libtorrent_assert_log, "a+");
	if (out == 0) out = stderr;
#else
	FILE* out = stderr;
#endif

	char stack[8192];
	print_backtrace(stack, sizeof(stack), 0);

	fprintf(out, "assertion failed. Please file a bugreport at "
		"http://code.rasterbar.com/libtorrent/newticket\n"
		"Please include the following information:\n\n"
		"version: " LIBTORRENT_VERSION "\n"
		"%s\n"
		"file: '%s'\n"
		"line: %d\n"
		"function: %s\n"
		"expression: %s\n"
		"%s%s\n"
		"stack:\n"
		"%s\n"
		, LIBTORRENT_REVISION, file, line, function, expr
		, value ? value : "", value ? "\n" : ""
		, stack);

	// if production asserts are defined, don't abort, just print the error
#if TORRENT_PRODUCTION_ASSERTS
	if (out != stderr) fclose(out);
#else
 	// send SIGINT to the current process
 	// to break into the debugger
 	raise(SIGINT);
 	abort();
#endif
}

#else

TORRENT_EXPORT void assert_fail(char const* expr, int line, char const* file, char const* function) {}

#endif

<commit_msg>fix msvc-8 debug build<commit_after>/*

Copyright (c) 2007, 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/config.hpp"

#if defined TORRENT_DEBUG || defined TORRENT_ASIO_DEBUGGING || TORRENT_RELEASE_ASSERTS

#ifdef __APPLE__
#include <AvailabilityMacros.h>
#endif

#include <string>
#include <cstring>
#include <stdlib.h>

// uClibc++ doesn't have cxxabi.h
#if defined __GNUC__ && __GNUC__ >= 3 \
	&& !defined __UCLIBCXX_MAJOR__

#include <cxxabi.h>

std::string demangle(char const* name)
{
// in case this string comes
	// this is needed on linux
	char const* start = strchr(name, '(');
	if (start != 0)
	{
		++start;
	}
	else
	{
		// this is needed on macos x
		start = strstr(name, "0x");
		if (start != 0)
		{
			start = strchr(start, ' ');
			if (start != 0) ++start;
			else start = name;
		}
		else start = name;
	}

	char const* end = strchr(start, '+');
	if (end) while (*(end-1) == ' ') --end;

	std::string in;
	if (end == 0) in.assign(start);
	else in.assign(start, end);

	size_t len;
	int status;
	char* unmangled = ::abi::__cxa_demangle(in.c_str(), 0, &len, &status);
	if (unmangled == 0) return in;
	std::string ret(unmangled);
	free(unmangled);
	return ret;
}
#elif defined WIN32

#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 // XP

#include "windows.h"
#include "dbghelp.h"

std::string demangle(char const* name)
{
	char demangled_name[256];
	if (UnDecorateSymbolName(name, demangled_name, sizeof(demangled_name), UNDNAME_NO_THROW_SIGNATURES) == 0)
		demangled_name[0] = 0;
	return demangled_name;
}

#else
std::string demangle(char const* name) { return name; }
#endif

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include "libtorrent/version.hpp"

// execinfo.h is available in the MacOS X 10.5 SDK.
#if (defined __linux__ || (defined __APPLE__ && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050))
#include <execinfo.h>

TORRENT_EXPORT void print_backtrace(char* out, int len, int max_depth)
{
	void* stack[50];
	int size = backtrace(stack, 50);
	char** symbols = backtrace_symbols(stack, size);

	for (int i = 1; i < size && len > 0; ++i)
	{
		int ret = snprintf(out, len, "%d: %s\n", i, demangle(symbols[i]).c_str());
		out += ret;
		len -= ret;
		if (i - 1 == max_depth && max_depth > 0) break;
	}

	free(symbols);
}

// visual studio 9 and up appears to support this
#elif defined WIN32 && _MSC_VER >= 1500

#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 // XP

#include "windows.h"
#include "libtorrent/utf8.hpp"

#include "winbase.h"
#include "dbghelp.h"

TORRENT_EXPORT void print_backtrace(char* out, int len, int max_depth)
{
	typedef USHORT (*RtlCaptureStackBackTrace_t)(
		__in ULONG FramesToSkip,
		__in ULONG FramesToCapture,
		__out PVOID *BackTrace,
		__out_opt PULONG BackTraceHash);

	static RtlCaptureStackBackTrace_t RtlCaptureStackBackTrace = 0;

	if (RtlCaptureStackBackTrace == 0)
	{
		// we don't actually have to free this library, everyone has it loaded
		HMODULE lib = LoadLibrary(TEXT("kernel32.dll"));
		RtlCaptureStackBackTrace = (RtlCaptureStackBackTrace_t)GetProcAddress(lib, "RtlCaptureStackBackTrace");
		if (RtlCaptureStackBackTrace == 0)
		{
			out[0] = 0;
			return;
		}
	}

	int i;
	void* stack[50];
	int size = CaptureStackBackTrace(0, 50, stack, 0);

	SYMBOL_INFO* symbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR), 1);
	symbol->MaxNameLen = MAX_SYM_NAME;
	symbol->SizeOfStruct = sizeof(SYMBOL_INFO);

	HANDLE p = GetCurrentProcess();
	static bool sym_initialized = false;
	if (!sym_initialized)
	{
		sym_initialized = true;
		SymInitialize(p, NULL, true);
	}
	for (i = 0; i < size && len > 0; ++i)
	{
		int ret;
		if (SymFromAddr(p, uintptr_t(stack[i]), 0, symbol))
			ret = snprintf(out, len, "%d: %s\n", i, symbol->Name);
		else
			ret = snprintf(out, len, "%d: <unknown>\n", i);

		out += ret;
		len -= ret;
		if (i == max_depth && max_depth > 0) break;
	}
	free(symbol);
}

#else

TORRENT_EXPORT void print_backtrace(char* out, int len, int max_depth) {}

#endif

#if TORRENT_PRODUCTION_ASSERTS
char const* libtorrent_assert_log = "asserts.log";
#endif

TORRENT_EXPORT void assert_fail(char const* expr, int line, char const* file
	, char const* function, char const* value)
{
#if TORRENT_PRODUCTION_ASSERTS
	FILE* out = fopen(libtorrent_assert_log, "a+");
	if (out == 0) out = stderr;
#else
	FILE* out = stderr;
#endif

	char stack[8192];
	print_backtrace(stack, sizeof(stack), 0);

	fprintf(out, "assertion failed. Please file a bugreport at "
		"http://code.rasterbar.com/libtorrent/newticket\n"
		"Please include the following information:\n\n"
		"version: " LIBTORRENT_VERSION "\n"
		"%s\n"
		"file: '%s'\n"
		"line: %d\n"
		"function: %s\n"
		"expression: %s\n"
		"%s%s\n"
		"stack:\n"
		"%s\n"
		, LIBTORRENT_REVISION, file, line, function, expr
		, value ? value : "", value ? "\n" : ""
		, stack);

	// if production asserts are defined, don't abort, just print the error
#if TORRENT_PRODUCTION_ASSERTS
	if (out != stderr) fclose(out);
#else
 	// send SIGINT to the current process
 	// to break into the debugger
 	raise(SIGINT);
 	abort();
#endif
}

#else

TORRENT_EXPORT void assert_fail(char const* expr, int line, char const* file, char const* function) {}

#endif

<|endoftext|>


<commit_before>// Copyright (c) 2011 Vince Durham
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "script.h"
#include "auxpow.h"
#include "init.h"

using namespace std;
using namespace boost;

unsigned char pchMergedMiningHeader[] = { 0xfa, 0xbe, 'm', 'm' } ;

void RemoveMergedMiningHeader(vector<unsigned char>& vchAux)
{
    if (vchAux.begin() != std::search(vchAux.begin(), vchAux.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader)))
        throw runtime_error("merged mining aux too short");
    vchAux.erase(vchAux.begin(), vchAux.begin() + sizeof(pchMergedMiningHeader));
}

bool CAuxPow::Check(uint256 hashAuxBlock, int nChainID)
{
    if (nIndex != 0)
        return error("AuxPow is not a generate");

    if (!fTestNet && parentBlock.GetChainID() == nChainID)
        return error("Aux POW parent has our chain ID");

    if (vChainMerkleBranch.size() > 30)
        return error("Aux POW chain merkle branch too long");

    // Check that the chain merkle root is in the coinbase
    uint256 nRootHash = CBlock::CheckMerkleBranch(hashAuxBlock, vChainMerkleBranch, nChainIndex);
    vector<unsigned char> vchRootHash(nRootHash.begin(), nRootHash.end());
    std::reverse(vchRootHash.begin(), vchRootHash.end()); // correct endian

    // Check that we are in the parent block merkle tree
    if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != parentBlock.hashMerkleRoot)
        return error("Aux POW merkle root incorrect");

    const CScript script = vin[0].scriptSig;

    // Check that the same work is not submitted twice to our chain.
    //

    CScript::const_iterator pcHead =
        std::search(script.begin(), script.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader));

    CScript::const_iterator pc =
        std::search(script.begin(), script.end(), vchRootHash.begin(), vchRootHash.end());

    if (pc == script.end())
        return error("Aux POW missing chain merkle root in parent coinbase");

    if (pcHead != script.end())
    {
        // Enforce only one chain merkle root by checking that a single instance of the merged
        // mining header exists just before.
        if (script.end() != std::search(pcHead + 1, script.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader)))
            return error("Multiple merged mining headers in coinbase");
        if (pcHead + sizeof(pchMergedMiningHeader) != pc)
            return error("Merged mining header is not just before chain merkle root");
    }
    else
    {
        // For backward compatibility.
        // Enforce only one chain merkle root by checking that it starts early in the coinbase.
        // 8-12 bytes are enough to encode extraNonce and nBits.
        if (pc - script.begin() > 20)
            return error("Aux POW chain merkle root must start in the first 20 bytes of the parent coinbase");
    }

    // Ensure we are at a deterministic point in the merkle leaves by hashing
    // a nonce and our chain ID and comparing to the index.
    pc += vchRootHash.size();
    if (script.end() - pc < 8)
        return error("Aux POW missing chain merkle tree size and nonce in parent coinbase");

    int nSize;
    memcpy(&nSize, &pc[0], 4);
    if (nSize != (1 << vChainMerkleBranch.size()))
        return error("Aux POW merkle branch size does not match parent coinbase");

    int nNonce;
    memcpy(&nNonce, &pc[4], 4);

    // Choose a pseudo-random slot in the chain merkle tree
    // but have it be fixed for a size/nonce/chain combination.
    //
    // This prevents the same work from being used twice for the
    // same chain while reducing the chance that two chains clash
    // for the same slot.
    int rand = nNonce;
    rand = rand * 1103515245 + 12345;
    rand += nChainID;
    rand = rand * 1103515245 + 12345;

    if (nChainIndex != (rand % nSize))
        return error("Aux POW wrong index");

    return true;
}

CScript MakeCoinbaseWithAux(unsigned int nHeight, unsigned int nExtraNonce,
  vector<unsigned char>& vchAux) {
    vector<unsigned char> vchAuxWithHeader(UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader));
    vchAuxWithHeader.insert(vchAuxWithHeader.end(), vchAux.begin(), vchAux.end());

    // Push OP_2 just in case we want versioning later
    /* BIP34: v2 coin base must start with nHeight */
    return CScript() << nHeight << CBigNum(nExtraNonce) << COINBASE_FLAGS << OP_2 << vchAuxWithHeader;
}

void IncrementExtraNonceWithAux(CBlock* pblock, CBlockIndex* pindexPrev,
  unsigned int& nExtraNonce, vector<unsigned char>& vchAux) {

    // Update nExtraNonce
    static uint256 hashPrevBlock;
    if (hashPrevBlock != pblock->hashPrevBlock)
    {
        nExtraNonce = 0;
        hashPrevBlock = pblock->hashPrevBlock;
    }
    ++nExtraNonce;

    pblock->vtx[0].vin[0].scriptSig = MakeCoinbaseWithAux(pindexPrev->nHeight + 1, nExtraNonce, vchAux);
    pblock->hashMerkleRoot = pblock->BuildMerkleTree();
}
<commit_msg>MakeCoinbaseWithAux() Fixed<commit_after>// Copyright (c) 2011 Vince Durham
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "script.h"
#include "auxpow.h"
#include "init.h"

using namespace std;
using namespace boost;

unsigned char pchMergedMiningHeader[] = { 0xfa, 0xbe, 'm', 'm' } ;

void RemoveMergedMiningHeader(vector<unsigned char>& vchAux)
{
    if (vchAux.begin() != std::search(vchAux.begin(), vchAux.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader)))
        throw runtime_error("merged mining aux too short");
    vchAux.erase(vchAux.begin(), vchAux.begin() + sizeof(pchMergedMiningHeader));
}

bool CAuxPow::Check(uint256 hashAuxBlock, int nChainID)
{
    if (nIndex != 0)
        return error("AuxPow is not a generate");

    if (!fTestNet && parentBlock.GetChainID() == nChainID)
        return error("Aux POW parent has our chain ID");

    if (vChainMerkleBranch.size() > 30)
        return error("Aux POW chain merkle branch too long");

    // Check that the chain merkle root is in the coinbase
    uint256 nRootHash = CBlock::CheckMerkleBranch(hashAuxBlock, vChainMerkleBranch, nChainIndex);
    vector<unsigned char> vchRootHash(nRootHash.begin(), nRootHash.end());
    std::reverse(vchRootHash.begin(), vchRootHash.end()); // correct endian

    // Check that we are in the parent block merkle tree
    if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != parentBlock.hashMerkleRoot)
        return error("Aux POW merkle root incorrect");

    const CScript script = vin[0].scriptSig;

    // Check that the same work is not submitted twice to our chain.
    //

    CScript::const_iterator pcHead =
        std::search(script.begin(), script.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader));

    CScript::const_iterator pc =
        std::search(script.begin(), script.end(), vchRootHash.begin(), vchRootHash.end());

    if (pc == script.end())
        return error("Aux POW missing chain merkle root in parent coinbase");

    if (pcHead != script.end())
    {
        // Enforce only one chain merkle root by checking that a single instance of the merged
        // mining header exists just before.
        if (script.end() != std::search(pcHead + 1, script.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader)))
            return error("Multiple merged mining headers in coinbase");
        if (pcHead + sizeof(pchMergedMiningHeader) != pc)
            return error("Merged mining header is not just before chain merkle root");
    }
    else
    {
        // For backward compatibility.
        // Enforce only one chain merkle root by checking that it starts early in the coinbase.
        // 8-12 bytes are enough to encode extraNonce and nBits.
        if (pc - script.begin() > 20)
            return error("Aux POW chain merkle root must start in the first 20 bytes of the parent coinbase");
    }

    // Ensure we are at a deterministic point in the merkle leaves by hashing
    // a nonce and our chain ID and comparing to the index.
    pc += vchRootHash.size();
    if (script.end() - pc < 8)
        return error("Aux POW missing chain merkle tree size and nonce in parent coinbase");

    int nSize;
    memcpy(&nSize, &pc[0], 4);
    if (nSize != (1 << vChainMerkleBranch.size()))
        return error("Aux POW merkle branch size does not match parent coinbase");

    int nNonce;
    memcpy(&nNonce, &pc[4], 4);

    // Choose a pseudo-random slot in the chain merkle tree
    // but have it be fixed for a size/nonce/chain combination.
    //
    // This prevents the same work from being used twice for the
    // same chain while reducing the chance that two chains clash
    // for the same slot.
    int rand = nNonce;
    rand = rand * 1103515245 + 12345;
    rand += nChainID;
    rand = rand * 1103515245 + 12345;

    if (nChainIndex != (rand % nSize))
        return error("Aux POW wrong index");

    return true;
}

CScript MakeCoinbaseWithAux(unsigned int nHeight, unsigned int nExtraNonce,
  vector<unsigned char>& vchAux) {
    vector<unsigned char> vchAuxWithHeader(UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader));
    vchAuxWithHeader.insert(vchAuxWithHeader.end(), vchAux.begin(), vchAux.end());

    // Push OP_2 just in case we want versioning later
    /* BIP34: v2 coin base must start with nHeight */
    return(((CScript() << nHeight << CBigNum(nExtraNonce)) + COINBASE_FLAGS) << OP_2 << vchAuxWithHeader);
}

void IncrementExtraNonceWithAux(CBlock* pblock, CBlockIndex* pindexPrev,
  unsigned int& nExtraNonce, vector<unsigned char>& vchAux) {

    // Update nExtraNonce
    static uint256 hashPrevBlock;
    if (hashPrevBlock != pblock->hashPrevBlock)
    {
        nExtraNonce = 0;
        hashPrevBlock = pblock->hashPrevBlock;
    }
    ++nExtraNonce;

    pblock->vtx[0].vin[0].scriptSig = MakeCoinbaseWithAux(pindexPrev->nHeight + 1, nExtraNonce, vchAux);
    pblock->hashMerkleRoot = pblock->BuildMerkleTree();
}
<|endoftext|>


<commit_before><commit_msg>Remove iOS references in chrome_browser_main_extra_parts_profiles.cc<commit_after><|endoftext|>


<commit_before>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * A Use Case for In Situ visulization frameworks (Conduit, SENSEI)
 *
 * Each processor contributes to a subset of all variables
 * Each variable is written by a subset of all processes
 * The per-writer-blocks in a variable have different sizes
 * The variable cannot be nicely defined as a global array
 *
 * We still define the variables in this writer as global arrays but
 * with k+1 dimensions for each variable, where the extra dimension is
 * used as an index to the writer blocks. The other dimensions are
 * defined as huge numbers to cover all possible dimension sizes on each
 * process.
 *
 * The reader needs to discover the content of each variable block-by-block.
 * It cannot rely on the global shape of the variable as most of it is empty.
 *
 * The global dimensions of a global array MUST NOT change over time.
 * The decomposition of the array across the processes, however, can change
 * between output steps.
 *
 * Created on: Jul 11, 2017
 *      Author: pnorbert
 */

#include <algorithm> // std::transform
#include <iostream>
#include <vector>

#include <adios2.h>
#ifdef ADIOS2_HAVE_MPI
#include <mpi.h>
MPI_Comm writerComm;
#endif

const int NSTEPS = 5;
const int BIGDIM = 1000;

/* Variables:
   a: size 8,  written by rank 0 (5 elements) and rank 1 (3 elements)
   b: size 9,  written by rank 0 (5 elements) and rank 2 (4 elements)
   c: size 10, written by rank 0 (5 elements) and rank 3 (5 elements)
   d: size 7,  written by rank 1 (3 elements) and rank 2 (4 elements)

   Variables in the output:
   2D arrays, 4 x BIGDIM
*/

// Which process writes which variables
std::vector<std::vector<std::string>> VarTree = {
    {"a", "b", "c"}, {"a", "d"}, {"b", "d"}, {"c"}};

// What size of data do they write
std::vector<std::vector<size_t>> SizesTree = {
    {5, 5, 5}, {3, 3}, {4, 4}, {5, 5}};

std::string argEngine = "BPFile";
adios2::Params engineParams;

void ProcessArgs(int rank, int argc, char *argv[])
{
    if (argc > 1)
    {
        argEngine = argv[1];
    }
    std::string elc = argEngine;
    std::transform(elc.begin(), elc.end(), elc.begin(), ::tolower);
    if (elc == "sst")
    {
        engineParams["MarshalMethod"] = "BP";
    }
    else if (elc == "insitumpi")
    {
        engineParams["verbose"] = "3";
    }
}

int main(int argc, char *argv[])
{
    int rank = 0, nproc = 1;
#ifdef ADIOS2_HAVE_MPI
    MPI_Init(&argc, &argv);
    int wrank, wnproc;
    MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
    MPI_Comm_size(MPI_COMM_WORLD, &wnproc);
    const unsigned int color = 1;
    MPI_Comm_split(MPI_COMM_WORLD, color, wrank, &writerComm);
    MPI_Comm_rank(writerComm, &rank);
    MPI_Comm_size(writerComm, &nproc);
#endif

    const int maxProc = VarTree.size();
    if (nproc > maxProc)
    {
        if (!rank)
        {
            std::cout
                << "ERROR: Maximum number of processors for this example is "
                << maxProc << std::endl;
        }
        exit(1);
    }

    ProcessArgs(rank, argc, argv);
    if (!rank)
    {
        std::cout << "Writer: ADIOS2 Engine set to: " << argEngine
                  << "   Parameters:";
        for (auto &p : engineParams)
        {
            std::cout << "    " << p.first << " = " << p.second;
        }
        std::cout << std::endl;
    }

#ifdef ADIOS2_HAVE_MPI
    adios2::ADIOS adios(writerComm);
#else
    adios2::ADIOS adios;
#endif

    // We have a varying number of vars on each processor
    const int nvars = VarTree[rank].size();
    // A 1D array for each variable
    std::vector<std::vector<double>> Vars(nvars);
    for (int i = 0; i < nvars; i++)
    {
        Vars[i].resize(SizesTree[rank][i]);
    }

    std::vector<adios2::Variable<double>> ADIOSVars(nvars);

    try
    {
        adios2::IO io = adios.DeclareIO("Output");
        io.SetEngine(argEngine);
        io.SetParameters(engineParams);
        for (int i = 0; i < nvars; i++)
        {
            size_t nelems = SizesTree[rank][i];
            Vars[i].resize(nelems);
            ADIOSVars[i] = io.DefineVariable<double>(
                VarTree[rank][i], {(unsigned int)nproc, BIGDIM});
        }

        adios2::Engine writer = io.Open("output.bp", adios2::Mode::Write);

        for (int step = 0; step < NSTEPS; step++)
        {
            writer.BeginStep();

            for (int i = 0; i < nvars; i++)
            {
                size_t nelems = SizesTree[rank][i];
                for (int j = 0; j < nelems; j++)
                {
                    Vars[i][j] = (double)step / 100.0 + (double)rank;
                }

                // Make a 2D selection to describe the local dimensions of the
                // variable we write and its offsets in the global spaces
                // adios2::SelectionBoundingBox sel();
                ADIOSVars[i].SetSelection(adios2::Box<adios2::Dims>(
                    {static_cast<size_t>(rank), 0},
                    {1, static_cast<size_t>(nelems)}));
                writer.Put<double>(ADIOSVars[i], Vars[i].data());
            }

            // Indicate we are done for this step.
            // Disk I/O will be performed during this call unless
            // time aggregation postpones all of that to some later step
            writer.EndStep();
        }

        // Called once: indicate that we are done with this output for the run
        writer.Close();
    }
    catch (std::invalid_argument &e)
    {
        if (rank == 0)
        {
            std::cout << "Invalid argument exception, STOPPING PROGRAM\n";
            std::cout << e.what() << "\n";
        }
    }
    catch (std::ios_base::failure &e)
    {
        if (rank == 0)
        {
            std::cout << "System exception, STOPPING PROGRAM\n";
            std::cout << e.what() << "\n";
        }
    }
    catch (std::exception &e)
    {
        if (rank == 0)
        {
            std::cout << "Exception, STOPPING PROGRAM\n";
            std::cout << e.what() << "\n";
        }
    }

#ifdef ADIOS2_HAVE_MPI
    MPI_Finalize();
#endif

    return 0;
}
<commit_msg>fix type conversion warnings<commit_after>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * A Use Case for In Situ visulization frameworks (Conduit, SENSEI)
 *
 * Each processor contributes to a subset of all variables
 * Each variable is written by a subset of all processes
 * The per-writer-blocks in a variable have different sizes
 * The variable cannot be nicely defined as a global array
 *
 * We still define the variables in this writer as global arrays but
 * with k+1 dimensions for each variable, where the extra dimension is
 * used as an index to the writer blocks. The other dimensions are
 * defined as huge numbers to cover all possible dimension sizes on each
 * process.
 *
 * The reader needs to discover the content of each variable block-by-block.
 * It cannot rely on the global shape of the variable as most of it is empty.
 *
 * The global dimensions of a global array MUST NOT change over time.
 * The decomposition of the array across the processes, however, can change
 * between output steps.
 *
 * Created on: Jul 11, 2017
 *      Author: pnorbert
 */

#include <algorithm> // std::transform
#include <iostream>
#include <vector>

#include <adios2.h>
#ifdef ADIOS2_HAVE_MPI
#include <mpi.h>
MPI_Comm writerComm;
#endif

const size_t NSTEPS = 5;
const size_t BIGDIM = 1000;

/* Variables:
   a: size 8,  written by rank 0 (5 elements) and rank 1 (3 elements)
   b: size 9,  written by rank 0 (5 elements) and rank 2 (4 elements)
   c: size 10, written by rank 0 (5 elements) and rank 3 (5 elements)
   d: size 7,  written by rank 1 (3 elements) and rank 2 (4 elements)

   Variables in the output:
   2D arrays, 4 x BIGDIM
*/

// Which process writes which variables
std::vector<std::vector<std::string>> VarTree = {
    {"a", "b", "c"}, {"a", "d"}, {"b", "d"}, {"c"}};

// What size of data do they write
std::vector<std::vector<size_t>> SizesTree = {
    {5, 5, 5}, {3, 3}, {4, 4}, {5, 5}};

std::string argEngine = "BPFile";
adios2::Params engineParams;

void ProcessArgs(int rank, int argc, char *argv[])
{
    if (argc > 1)
    {
        argEngine = argv[1];
    }
    std::string elc = argEngine;
    std::transform(elc.begin(), elc.end(), elc.begin(), ::tolower);
    if (elc == "sst")
    {
        engineParams["MarshalMethod"] = "BP";
    }
    else if (elc == "insitumpi")
    {
        engineParams["verbose"] = "5";
    }
}

int main(int argc, char *argv[])
{
    int rank = 0, nproc = 1;
#ifdef ADIOS2_HAVE_MPI
    MPI_Init(&argc, &argv);
    int wrank, wnproc;
    MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
    MPI_Comm_size(MPI_COMM_WORLD, &wnproc);
    const unsigned int color = 1;
    MPI_Comm_split(MPI_COMM_WORLD, color, wrank, &writerComm);
    MPI_Comm_rank(writerComm, &rank);
    MPI_Comm_size(writerComm, &nproc);
#endif

    const size_t maxProc = VarTree.size();
    if (nproc > maxProc)
    {
        if (!rank)
        {
            std::cout
                << "ERROR: Maximum number of processors for this example is "
                << maxProc << std::endl;
        }
        exit(1);
    }

    ProcessArgs(rank, argc, argv);
    if (!rank)
    {
        std::cout << "Writer: ADIOS2 Engine set to: " << argEngine
                  << "   Parameters:";
        for (auto &p : engineParams)
        {
            std::cout << "    " << p.first << " = " << p.second;
        }
        std::cout << std::endl;
    }

#ifdef ADIOS2_HAVE_MPI
    adios2::ADIOS adios(writerComm);
#else
    adios2::ADIOS adios;
#endif

    // We have a varying number of vars on each processor
    const size_t nvars = VarTree[rank].size();
    // A 1D array for each variable
    std::vector<std::vector<double>> Vars(nvars);
    for (int i = 0; i < nvars; i++)
    {
        Vars[i].resize(SizesTree[rank][i]);
    }

    std::vector<adios2::Variable<double>> ADIOSVars(nvars);

    try
    {
        adios2::IO io = adios.DeclareIO("Output");
        io.SetEngine(argEngine);
        io.SetParameters(engineParams);
        for (int i = 0; i < nvars; i++)
        {
            size_t nelems = SizesTree[rank][i];
            Vars[i].resize(nelems);
            ADIOSVars[i] = io.DefineVariable<double>(
                VarTree[rank][i], {(unsigned int)nproc, BIGDIM});
        }

        adios2::Engine writer = io.Open("output.bp", adios2::Mode::Write);

        for (int step = 0; step < NSTEPS; step++)
        {
            writer.BeginStep();

            for (int i = 0; i < nvars; i++)
            {
                size_t nelems = SizesTree[rank][i];
                for (int j = 0; j < nelems; j++)
                {
                    Vars[i][j] = ((double)step + 1.0) / 100.0 + (double)rank;
                }

                // Make a 2D selection to describe the local dimensions of the
                // variable we write and its offsets in the global spaces
                // adios2::SelectionBoundingBox sel();
                ADIOSVars[i].SetSelection(adios2::Box<adios2::Dims>(
                    {static_cast<size_t>(rank), 0},
                    {1, static_cast<size_t>(nelems)}));
                writer.Put<double>(ADIOSVars[i], Vars[i].data());
            }

            // Indicate we are done for this step.
            // Disk I/O will be performed during this call unless
            // time aggregation postpones all of that to some later step
            writer.EndStep();
        }

        // Called once: indicate that we are done with this output for the run
        writer.Close();
    }
    catch (std::invalid_argument &e)
    {
        if (rank == 0)
        {
            std::cout << "Invalid argument exception, STOPPING PROGRAM\n";
            std::cout << e.what() << "\n";
        }
    }
    catch (std::ios_base::failure &e)
    {
        if (rank == 0)
        {
            std::cout << "System exception, STOPPING PROGRAM\n";
            std::cout << e.what() << "\n";
        }
    }
    catch (std::exception &e)
    {
        if (rank == 0)
        {
            std::cout << "Exception, STOPPING PROGRAM\n";
            std::cout << e.what() << "\n";
        }
    }

#ifdef ADIOS2_HAVE_MPI
    MPI_Finalize();
#endif

    return 0;
}
<|endoftext|>


<commit_before>#pragma once

#include "renderer.hpp"

#include "../gl3companion/gldebug.hpp"
#include "../gl3companion/glframebuffers.hpp"
#include "../gl3companion/glresource_types.hpp"
#include "../gl3companion/glshaders.hpp"
#include "../gl3companion/gltexturing.hpp"

#include <vector>

using FramebufferDef = TextureDef;

namespace
{
bool isEqual(TextureDef const& a, TextureDef const& b)
{
        return a.data == b.data
               && a.width == b.width
               && a.height == b.height
               && a.depth == b.depth
               && a.pixelFiller == b.pixelFiller;
}

void framebufferPixelFiller(uint32_t* pixels, int width, int height,
                            int depth, void const* data)
{
        printf("data: %p\n", data);
        // this function is just an identifier
        printf("ERROR: I should not be called, framebuffer: %d\n", *((GLint*)data));
}
}

// persistent datastructure... the core of the infrastructure
class FrameSeries
{
public:
        ~FrameSeries()
        {
                printf("summary:\n");
                printf("program creations: %ld\n", programCreations);
                printf("texture creations: %ld\n", textureCreations);
                printf("mesh creations: %ld\n"
                       "meshes: %ld\n",
                       meshCreations,
                       meshes.size());
                printf("framebuffer creations: %ld\n"
                       "framebuffers: %ld\n",
                       framebufferCreations,
                       framebuffers.size());
        }

        void beginFrame()
        {
                // we should invalidate arrays so as to garbage
                // collect / recycle the now un-needed definitions
                reset(meshHeap);
                reset(textureHeap);
                reset(programHeap);

        struct FramebufferMaterials {
                GLuint framebufferId;
                TextureDef textureDef;
        };

        FramebufferMaterials framebuffer(FramebufferDef framebufferDef)
        {
                auto fbIndex = findOrCreate<FramebufferDef>
                               (framebufferHeap,
                                framebufferDef,
                [&framebufferDef](FramebufferDef const& element) {
                        return isEqual(element, framebufferDef);
                },
                [=](FramebufferDef const& def, size_t framebufferIndex) {
                        framebuffers.resize(1 + framebufferIndex);

                        auto& framebuffer = framebuffers[framebufferIndex];

                        auto txIndex = findOrCreate<TextureDef>
                                       (textureHeap,
                                        framebufferDef,
                        [&framebufferDef](TextureDef const& element) {
                                return isEqual(element, framebufferDef);
                        },
                        [=](TextureDef const& def, size_t index) {
                                textures.resize(index + 1);
                        },
                        [=](size_t indexA, size_t indexB) {
                                std::swap(textures[indexA], textures[indexB]);
                        }
                                       );

                        auto& texture = textures[txIndex];
                        texture.target = GL_TEXTURE_2D;

                        createImageCaptureFramebuffer(framebuffer.resource, texture.resource,
                                                      framebuffer.depthbuffer, { framebufferDef.width, framebufferDef.height });
                        framebufferCreations++;

                        auto textureDef = framebufferDef;
                        textureDef.data.resize(sizeof(GLint));
                        *((GLint*) &textureDef.data.front()) = framebuffer.resource.id;
                        textureDef.pixelFiller = framebufferPixelFiller;

                        textureDefs[txIndex] = textureDef;
                        framebuffer.textureDef = textureDef;
                        framebufferDefs[framebufferIndex] = textureDef;
                },
                [=](size_t indexA, size_t indexB) {
                        std::swap(framebuffers[indexA], framebuffers[indexB]);
                });

                auto const& framebuffer = framebuffers[fbIndex];
                return { framebuffer.resource.id, framebuffer.textureDef };
        }

        struct MeshMaterials {
                GLuint vertexArray;
                size_t indicesCount;
                GLuint indicesBuffer;
                std::vector<GLuint> vertexBuffers;
        };

        MeshMaterials mesh(GeometryDef geometryDef)
        {
                auto meshIndex = findOrCreate<GeometryDef>
                                 (meshHeap,
                                  geometryDef,
                [&geometryDef](GeometryDef const& element) {
                        return element.data == geometryDef.data
                               && element.definer == geometryDef.definer
                               && element.arrayCount == geometryDef.arrayCount;
                },
                [=](GeometryDef const& def, size_t meshIndex) {
                        meshes.resize(1 + meshIndex);

                        auto& mesh = meshes[meshIndex];
                        if (def.definer) {
                                mesh.vertexBuffers.resize(def.arrayCount);
                                mesh.indicesCount = def.definer
                                                    (mesh.indices,
                                                     &mesh.vertexBuffers.front(),
                                                     &def.data.front());
                        }

                        meshCreations++;
                },
                [=](size_t indexA, size_t indexB) {
                        std::swap(meshes.at(indexA), meshes.at(indexB));
                });

                auto const& mesh = meshes.at(meshIndex);
                auto vertexBufferIds = std::vector<GLuint> {};
                std::transform(std::begin(mesh.vertexBuffers),
                               std::end(mesh.vertexBuffers),
                               std::back_inserter(vertexBufferIds),
                [](BufferResource const& element) {
                        return element.id;
                });

                return {
                        mesh.vertexArray.id,
                        mesh.indicesCount,
                        mesh.indices.id,
                        vertexBufferIds
                };
        }

        struct TextureMaterials {
                GLuint textureId;
                GLenum target;
        };

        TextureMaterials texture(TextureDef textureDef)
        {
                auto index = findOrCreate<TextureDef>(textureHeap,
                                                      textureDef,
                [&textureDef](TextureDef const& element) {
                        return isEqual(element, textureDef);
                },
                [=](TextureDef const& def, size_t index) {
                        textures.resize(index + 1);
                        auto& texture = textures[index];

                        if (def.width > 0 && def.height > 0 && def.depth > 0) {
                                texture.target = GL_TEXTURE_3D;
                        } else if (def.width > 0 && def.height > 0) {
                                texture.target = GL_TEXTURE_2D;
                        } else if (def.width > 0) {
                                texture.target = GL_TEXTURE_1D;
                        } else {
                                texture.target = 0;
                        }

                        OGL_TRACE;
                        switch(texture.target) {
                        case GL_TEXTURE_2D:
                                glBindTexture(texture.target, texture.resource.id);
                                defineNonMipmappedARGB32Texture(def.width,
                                                                def.height,
                                [&def](uint32_t* data, int width, int height) {
                                        def.pixelFiller(data, width, height, 0, &def.data.front());
                                });
                                break;
                        case GL_TEXTURE_3D:
                                glBindTexture(texture.target, texture.resource.id);
                                defineNonMipmappedARGB32Texture3d(def.width,
                                                                  def.height,
                                                                  def.depth,
                                [&def](uint32_t* data, int width, int height, int depth) {
                                        def.pixelFiller(data, width, height, depth, &def.data.front());
                                });
                                break;
                        };
                        glBindTexture(texture.target, 0);
                        OGL_TRACE;
                        textureCreations++;
                },
                [=](size_t indexA, size_t indexB) {
                        std::swap(textures[indexA], textures[indexB]);
                });

                auto const& texture = textures[index];

                return { texture.resource.id, texture.target };
        }

        struct ShaderProgramMaterials {
                GLuint programId;
        };

        ShaderProgramMaterials program(ProgramDef programDef)
        {
                auto index = findOrCreate<ProgramDef>
                             (programHeap,
                              programDef,
                [&programDef](ProgramDef const& element) {
                        return element.fragmentShader.source
                               == programDef.fragmentShader.source
                               && element.vertexShader.source
                               == programDef.vertexShader.source;
                },
                [=](ProgramDef const& def, size_t index) {
                        programs.resize(index + 1);
                        vertexShaders.resize(index + 1);
                        fragmentShaders.resize(index + 1);

                        auto& program = programs[index];
                        auto& vertexShader = vertexShaders[index];
                        auto& fragmentShader = fragmentShaders[index];

                        compile(vertexShader, programDef.vertexShader.source);
                        compile(fragmentShader, programDef.fragmentShader.source);
                        link(program, vertexShader, fragmentShader);

                        OGL_TRACE;
                        programCreations++;
                },
                [=](size_t indexA, size_t indexB) {
                        std::swap(programs[indexA], programs[indexB]);
                        std::swap(vertexShaders[indexA], vertexShaders[indexB]);
                        std::swap(fragmentShaders[indexA], fragmentShaders[indexB]);
                });

                return { programs[index].id };
        }

private:
        // returns index to use (and create an entry if missing)
        template <typename ResourceDef>
        size_t findOrCreateDef(std::vector<ResourceDef>& definitions,
                               ResourceDef const& def,
                               std::function<bool(ResourceDef const&)> isDef,
                               size_t firstRecyclableIndex)
        {
                auto existing =
                        std::find_if(std::begin(definitions),
                                     std::end(definitions),
                                     isDef);

                if (existing != std::end(definitions)) {
                        return &(*existing) - &definitions.front();
                } else {
                        auto index = firstRecyclableIndex;
                        if (index >= definitions.size()) {
                                definitions.resize(1 + index);

                        }
                        definitions[index] = def;
                        return index;
                }
        }

        template <typename ResourceDef>
        struct RecyclingHeap {
                size_t firstInactiveIndex;
                size_t firstRecyclableIndex;
                std::vector<ResourceDef>& definitions;
        };

        template <typename ResourceDef>
        void reset(RecyclingHeap<ResourceDef>& heap)
        {
                heap.firstRecyclableIndex = heap.firstInactiveIndex;
                heap.firstInactiveIndex = 0;
        }

        template <typename ResourceDef>
        size_t findOrCreate(RecyclingHeap<ResourceDef>& heap,
                            ResourceDef const& def,
                            std::function<bool(ResourceDef const&)> isDef,
                            std::function<void(ResourceDef const&,size_t)> createAt,
                            std::function<void(size_t,size_t)> swap)
        {
                auto index = findOrCreateDef(heap.definitions,
                                             def,
                                             isDef,
                                             heap.firstRecyclableIndex);
                if (index == heap.firstRecyclableIndex) {
                        heap.firstRecyclableIndex++;
                        createAt(def, index);
                }

                auto newIndex = index;
                if (heap.firstInactiveIndex < newIndex) {
                        newIndex = heap.firstInactiveIndex;

                        std::swap(heap.definitions.at(newIndex), heap.definitions.at(index));
                        swap(newIndex, index);
                }

                heap.firstInactiveIndex = newIndex + 1;

                return newIndex;
        }

        struct Mesh {
                VertexArrayResource vertexArray;
                size_t indicesCount = 0;
                BufferResource indices;
                std::vector<BufferResource> vertexBuffers;
        };

        struct Framebuffer {
                FramebufferResource resource;
                RenderbufferResource depthbuffer;
                TextureDef textureDef;
        };

        std::vector<Framebuffer> framebuffers;
        std::vector<FramebufferDef> framebufferDefs;
        RecyclingHeap<FramebufferDef> framebufferHeap = { 0, 0, framebufferDefs };
        long framebufferCreations = 0;

        std::vector<Mesh> meshes;
        std::vector<GeometryDef> meshDefs;
        RecyclingHeap<GeometryDef> meshHeap = { 0, 0, meshDefs };
        long meshCreations = 0;

        struct Texture {
                TextureResource resource;
                GLenum target;
        };

        std::vector<Texture> textures;
        std::vector<TextureDef> textureDefs;
        RecyclingHeap<TextureDef> textureHeap = { 0, 0, textureDefs };
        long textureCreations = 0;

        std::vector<VertexShaderResource> vertexShaders;
        std::vector<FragmentShaderResource> fragmentShaders;
        std::vector<ShaderProgramResource> programs;
        std::vector<ProgramDef> programDefs;
        RecyclingHeap<ProgramDef> programHeap = { 0, 0, programDefs };
        long programCreations = 0;
};
<commit_msg>reset also the framebuffer heap<commit_after>#pragma once

#include "renderer.hpp"

#include "../gl3companion/gldebug.hpp"
#include "../gl3companion/glframebuffers.hpp"
#include "../gl3companion/glresource_types.hpp"
#include "../gl3companion/glshaders.hpp"
#include "../gl3companion/gltexturing.hpp"

#include <vector>

using FramebufferDef = TextureDef;

namespace
{
bool isEqual(TextureDef const& a, TextureDef const& b)
{
        return a.data == b.data
               && a.width == b.width
               && a.height == b.height
               && a.depth == b.depth
               && a.pixelFiller == b.pixelFiller;
}

void framebufferPixelFiller(uint32_t* pixels, int width, int height,
                            int depth, void const* data)
{
        printf("data: %p\n", data);
        // this function is just an identifier
        printf("ERROR: I should not be called, framebuffer: %d\n", *((GLint*)data));
}
}

// persistent datastructure... the core of the infrastructure
class FrameSeries
{
public:
        ~FrameSeries()
        {
                printf("summary:\n");
                printf("program creations: %ld\n", programCreations);
                printf("texture creations: %ld\n", textureCreations);
                printf("mesh creations: %ld\n"
                       "meshes: %ld\n",
                       meshCreations,
                       meshes.size());
                printf("framebuffer creations: %ld\n"
                       "framebuffers: %ld\n",
                       framebufferCreations,
                       framebuffers.size());
        }

        void beginFrame()
        {
                // we should invalidate arrays so as to garbage
                // collect / recycle the now un-needed definitions
                reset(framebufferHeap);
                reset(meshHeap);
                reset(textureHeap);
                reset(programHeap);
        }

        struct FramebufferMaterials {
                GLuint framebufferId;
                TextureDef textureDef;
        };

        FramebufferMaterials framebuffer(FramebufferDef framebufferDef)
        {
                auto fbIndex = findOrCreate<FramebufferDef>
                               (framebufferHeap,
                                framebufferDef,
                [&framebufferDef](FramebufferDef const& element) {
                        return isEqual(element, framebufferDef);
                },
                [=](FramebufferDef const& def, size_t framebufferIndex) {
                        framebuffers.resize(1 + framebufferIndex);

                        auto& framebuffer = framebuffers[framebufferIndex];

                        auto txIndex = findOrCreate<TextureDef>
                                       (textureHeap,
                                        framebufferDef,
                        [&framebufferDef](TextureDef const& element) {
                                return isEqual(element, framebufferDef);
                        },
                        [=](TextureDef const& def, size_t index) {
                                textures.resize(index + 1);
                        },
                        [=](size_t indexA, size_t indexB) {
                                std::swap(textures[indexA], textures[indexB]);
                        }
                                       );

                        auto& texture = textures[txIndex];
                        texture.target = GL_TEXTURE_2D;

                        createImageCaptureFramebuffer(framebuffer.resource, texture.resource,
                                                      framebuffer.depthbuffer, { framebufferDef.width, framebufferDef.height });
                        framebufferCreations++;

                        auto textureDef = framebufferDef;
                        textureDef.data.resize(sizeof(GLint));
                        *((GLint*) &textureDef.data.front()) = framebuffer.resource.id;
                        textureDef.pixelFiller = framebufferPixelFiller;

                        textureDefs[txIndex] = textureDef;
                        framebuffer.textureDef = textureDef;
                        framebufferDefs[framebufferIndex] = textureDef;
                },
                [=](size_t indexA, size_t indexB) {
                        std::swap(framebuffers[indexA], framebuffers[indexB]);
                });

                auto const& framebuffer = framebuffers[fbIndex];
                return { framebuffer.resource.id, framebuffer.textureDef };
        }

        struct MeshMaterials {
                GLuint vertexArray;
                size_t indicesCount;
                GLuint indicesBuffer;
                std::vector<GLuint> vertexBuffers;
        };

        MeshMaterials mesh(GeometryDef geometryDef)
        {
                auto meshIndex = findOrCreate<GeometryDef>
                                 (meshHeap,
                                  geometryDef,
                [&geometryDef](GeometryDef const& element) {
                        return element.data == geometryDef.data
                               && element.definer == geometryDef.definer
                               && element.arrayCount == geometryDef.arrayCount;
                },
                [=](GeometryDef const& def, size_t meshIndex) {
                        meshes.resize(1 + meshIndex);

                        auto& mesh = meshes[meshIndex];
                        if (def.definer) {
                                mesh.vertexBuffers.resize(def.arrayCount);
                                mesh.indicesCount = def.definer
                                                    (mesh.indices,
                                                     &mesh.vertexBuffers.front(),
                                                     &def.data.front());
                        }

                        meshCreations++;
                },
                [=](size_t indexA, size_t indexB) {
                        std::swap(meshes.at(indexA), meshes.at(indexB));
                });

                auto const& mesh = meshes.at(meshIndex);
                auto vertexBufferIds = std::vector<GLuint> {};
                std::transform(std::begin(mesh.vertexBuffers),
                               std::end(mesh.vertexBuffers),
                               std::back_inserter(vertexBufferIds),
                [](BufferResource const& element) {
                        return element.id;
                });

                return {
                        mesh.vertexArray.id,
                        mesh.indicesCount,
                        mesh.indices.id,
                        vertexBufferIds
                };
        }

        struct TextureMaterials {
                GLuint textureId;
                GLenum target;
        };

        TextureMaterials texture(TextureDef textureDef)
        {
                auto index = findOrCreate<TextureDef>(textureHeap,
                                                      textureDef,
                [&textureDef](TextureDef const& element) {
                        return isEqual(element, textureDef);
                },
                [=](TextureDef const& def, size_t index) {
                        textures.resize(index + 1);
                        auto& texture = textures[index];

                        if (def.width > 0 && def.height > 0 && def.depth > 0) {
                                texture.target = GL_TEXTURE_3D;
                        } else if (def.width > 0 && def.height > 0) {
                                texture.target = GL_TEXTURE_2D;
                        } else if (def.width > 0) {
                                texture.target = GL_TEXTURE_1D;
                        } else {
                                texture.target = 0;
                        }

                        OGL_TRACE;
                        switch(texture.target) {
                        case GL_TEXTURE_2D:
                                glBindTexture(texture.target, texture.resource.id);
                                defineNonMipmappedARGB32Texture(def.width,
                                                                def.height,
                                [&def](uint32_t* data, int width, int height) {
                                        def.pixelFiller(data, width, height, 0, &def.data.front());
                                });
                                break;
                        case GL_TEXTURE_3D:
                                glBindTexture(texture.target, texture.resource.id);
                                defineNonMipmappedARGB32Texture3d(def.width,
                                                                  def.height,
                                                                  def.depth,
                                [&def](uint32_t* data, int width, int height, int depth) {
                                        def.pixelFiller(data, width, height, depth, &def.data.front());
                                });
                                break;
                        };
                        glBindTexture(texture.target, 0);
                        OGL_TRACE;
                        textureCreations++;
                },
                [=](size_t indexA, size_t indexB) {
                        std::swap(textures[indexA], textures[indexB]);
                });

                auto const& texture = textures[index];

                return { texture.resource.id, texture.target };
        }

        struct ShaderProgramMaterials {
                GLuint programId;
        };

        ShaderProgramMaterials program(ProgramDef programDef)
        {
                auto index = findOrCreate<ProgramDef>
                             (programHeap,
                              programDef,
                [&programDef](ProgramDef const& element) {
                        return element.fragmentShader.source
                               == programDef.fragmentShader.source
                               && element.vertexShader.source
                               == programDef.vertexShader.source;
                },
                [=](ProgramDef const& def, size_t index) {
                        programs.resize(index + 1);
                        vertexShaders.resize(index + 1);
                        fragmentShaders.resize(index + 1);

                        auto& program = programs[index];
                        auto& vertexShader = vertexShaders[index];
                        auto& fragmentShader = fragmentShaders[index];

                        compile(vertexShader, programDef.vertexShader.source);
                        compile(fragmentShader, programDef.fragmentShader.source);
                        link(program, vertexShader, fragmentShader);

                        OGL_TRACE;
                        programCreations++;
                },
                [=](size_t indexA, size_t indexB) {
                        std::swap(programs[indexA], programs[indexB]);
                        std::swap(vertexShaders[indexA], vertexShaders[indexB]);
                        std::swap(fragmentShaders[indexA], fragmentShaders[indexB]);
                });

                return { programs[index].id };
        }

private:
        // returns index to use (and create an entry if missing)
        template <typename ResourceDef>
        size_t findOrCreateDef(std::vector<ResourceDef>& definitions,
                               ResourceDef const& def,
                               std::function<bool(ResourceDef const&)> isDef,
                               size_t firstRecyclableIndex)
        {
                auto existing =
                        std::find_if(std::begin(definitions),
                                     std::end(definitions),
                                     isDef);

                if (existing != std::end(definitions)) {
                        return &(*existing) - &definitions.front();
                } else {
                        auto index = firstRecyclableIndex;
                        if (index >= definitions.size()) {
                                definitions.resize(1 + index);

                        }
                        definitions[index] = def;
                        return index;
                }
        }

        template <typename ResourceDef>
        struct RecyclingHeap {
                size_t firstInactiveIndex;
                size_t firstRecyclableIndex;
                std::vector<ResourceDef>& definitions;
        };

        template <typename ResourceDef>
        void reset(RecyclingHeap<ResourceDef>& heap)
        {
                heap.firstRecyclableIndex = heap.firstInactiveIndex;
                heap.firstInactiveIndex = 0;
        }

        template <typename ResourceDef>
        size_t findOrCreate(RecyclingHeap<ResourceDef>& heap,
                            ResourceDef const& def,
                            std::function<bool(ResourceDef const&)> isDef,
                            std::function<void(ResourceDef const&,size_t)> createAt,
                            std::function<void(size_t,size_t)> swap)
        {
                auto index = findOrCreateDef(heap.definitions,
                                             def,
                                             isDef,
                                             heap.firstRecyclableIndex);
                if (index == heap.firstRecyclableIndex) {
                        heap.firstRecyclableIndex++;
                        createAt(def, index);
                }

                auto newIndex = index;
                if (heap.firstInactiveIndex < newIndex) {
                        newIndex = heap.firstInactiveIndex;

                        std::swap(heap.definitions.at(newIndex), heap.definitions.at(index));
                        swap(newIndex, index);
                }

                heap.firstInactiveIndex = newIndex + 1;

                return newIndex;
        }

        struct Mesh {
                VertexArrayResource vertexArray;
                size_t indicesCount = 0;
                BufferResource indices;
                std::vector<BufferResource> vertexBuffers;
        };

        struct Framebuffer {
                FramebufferResource resource;
                RenderbufferResource depthbuffer;
                TextureDef textureDef;
        };

        std::vector<Framebuffer> framebuffers;
        std::vector<FramebufferDef> framebufferDefs;
        RecyclingHeap<FramebufferDef> framebufferHeap = { 0, 0, framebufferDefs };
        long framebufferCreations = 0;

        std::vector<Mesh> meshes;
        std::vector<GeometryDef> meshDefs;
        RecyclingHeap<GeometryDef> meshHeap = { 0, 0, meshDefs };
        long meshCreations = 0;

        struct Texture {
                TextureResource resource;
                GLenum target;
        };

        std::vector<Texture> textures;
        std::vector<TextureDef> textureDefs;
        RecyclingHeap<TextureDef> textureHeap = { 0, 0, textureDefs };
        long textureCreations = 0;

        std::vector<VertexShaderResource> vertexShaders;
        std::vector<FragmentShaderResource> fragmentShaders;
        std::vector<ShaderProgramResource> programs;
        std::vector<ProgramDef> programDefs;
        RecyclingHeap<ProgramDef> programHeap = { 0, 0, programDefs };
        long programCreations = 0;
};
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ftools.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 07:59:24 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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 library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basegfx.hxx"

#ifndef _BGFX_NUMERIC_FTOOLS_HXX
#include <basegfx/numeric/ftools.hxx>
#endif

namespace basegfx
{
    // init static member of class fTools
    double ::basegfx::fTools::mfSmallValue = 0.000000001;
} // end of namespace basegfx

// eof
<commit_msg>INTEGRATION: CWS changefileheader (1.5.60); FILE MERGED 2008/04/01 10:48:13 thb 1.5.60.2: #i85898# Stripping all external header guards 2008/03/28 16:05:50 rt 1.5.60.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: ftools.cxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basegfx.hxx"
#include <basegfx/numeric/ftools.hxx>

namespace basegfx
{
    // init static member of class fTools
    double ::basegfx::fTools::mfSmallValue = 0.000000001;
} // end of namespace basegfx

// eof
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016-2018 mvs developers
 *
 * This file is part of metaverse-explorer.
 *
 * metaverse-explorer is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <metaverse/explorer/define.hpp>
#include <metaverse/explorer/extensions/command_extension.hpp>
#include <metaverse/explorer/extensions/command_extension_func.hpp>
#include <metaverse/explorer/extensions/command_assistant.hpp>

namespace libbitcoin {
namespace explorer {
namespace commands {

class signmultisigtx: public command_extension
{
public:
    static const char* symbol() { return "signmultisigtx";}
    const char* name() override { return symbol();}
    bool category(int bs) override { return (ctgy_extension & bs ) == bs; }
    const char* description() override { return "signmultisigtx "; }

    arguments_metadata& load_arguments() override
    {
        return get_argument_metadata()
               .add("ACCOUNTNAME", 1)
               .add("ACCOUNTAUTH", 1)
               .add("TRANSACTION", 1);
    }

    void load_fallbacks (std::istream& input,
                         po::variables_map& variables) override
    {
        const auto raw = requires_raw_input();
        load_input(auth_.name, "ACCOUNTNAME", variables, input, raw);
        load_input(auth_.auth, "ACCOUNTAUTH", variables, input, raw);
        load_input(argument_.transaction, "TRANSACTION", variables, input, raw);
    }

    options_metadata& load_options() override
    {
        using namespace po;
        options_description& options = get_option_metadata();
        options.add_options()
        (
            BX_HELP_VARIABLE ",h",
            value<bool>()->zero_tokens(),
            "Get a description and instructions for this command."
        )
        (
            "ACCOUNTNAME",
            value<std::string>(&auth_.name)->required(),
            BX_ACCOUNT_NAME
        )
        (
            "ACCOUNTAUTH",
            value<std::string>(&auth_.auth)->required(),
            BX_ACCOUNT_AUTH
        )
        (
            "TRANSACTION",
            value<explorer::config::transaction>(&argument_.transaction)->required(),
            "The input Base16 transaction to sign."
        )
        (
            "selfpublickey,s",
            value<std::string>(&option_.self_publickey)->default_value(""),
            "The private key of this public key will be used to sign."
        )
        (
            "broadcast,b",
            value<bool>(&option_.broadcast_flag)->default_value(false)->zero_tokens(),
            "Broadcast the tx automatically if it is fullly signed, enabled by default."
        );

        return options;
    }

    void set_defaults_from_config (po::variables_map& variables) override
    {
    }

    console_result invoke (Json::Value& jv_output,
                           libbitcoin::server::server_node& node) override;

    struct argument
    {
        explorer::config::transaction transaction;
    } argument_;

    struct option
    {
        option()
            : broadcast_flag(false)
            , self_publickey("")
        {}

        bool broadcast_flag;
        std::string self_publickey;
    } option_;

};

} // namespace commands
} // namespace explorer
} // namespace libbitcoin

<commit_msg>update document.<commit_after>/**
 * Copyright (c) 2016-2018 mvs developers
 *
 * This file is part of metaverse-explorer.
 *
 * metaverse-explorer is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <metaverse/explorer/define.hpp>
#include <metaverse/explorer/extensions/command_extension.hpp>
#include <metaverse/explorer/extensions/command_extension_func.hpp>
#include <metaverse/explorer/extensions/command_assistant.hpp>

namespace libbitcoin {
namespace explorer {
namespace commands {

class signmultisigtx: public command_extension
{
public:
    static const char* symbol() { return "signmultisigtx";}
    const char* name() override { return symbol();}
    bool category(int bs) override { return (ctgy_extension & bs ) == bs; }
    const char* description() override { return "signmultisigtx "; }

    arguments_metadata& load_arguments() override
    {
        return get_argument_metadata()
               .add("ACCOUNTNAME", 1)
               .add("ACCOUNTAUTH", 1)
               .add("TRANSACTION", 1);
    }

    void load_fallbacks (std::istream& input,
                         po::variables_map& variables) override
    {
        const auto raw = requires_raw_input();
        load_input(auth_.name, "ACCOUNTNAME", variables, input, raw);
        load_input(auth_.auth, "ACCOUNTAUTH", variables, input, raw);
        load_input(argument_.transaction, "TRANSACTION", variables, input, raw);
    }

    options_metadata& load_options() override
    {
        using namespace po;
        options_description& options = get_option_metadata();
        options.add_options()
        (
            BX_HELP_VARIABLE ",h",
            value<bool>()->zero_tokens(),
            "Get a description and instructions for this command."
        )
        (
            "ACCOUNTNAME",
            value<std::string>(&auth_.name)->required(),
            BX_ACCOUNT_NAME
        )
        (
            "ACCOUNTAUTH",
            value<std::string>(&auth_.auth)->required(),
            BX_ACCOUNT_AUTH
        )
        (
            "TRANSACTION",
            value<explorer::config::transaction>(&argument_.transaction)->required(),
            "The input Base16 transaction to sign."
        )
        (
            "selfpublickey,s",
            value<std::string>(&option_.self_publickey)->default_value(""),
            "The private key of this public key will be used to sign."
        )
        (
            "broadcast,b",
            value<bool>(&option_.broadcast_flag)->default_value(false)->zero_tokens(),
            "Broadcast the tx automatically if it is fullly signed, disabled by default."
        );

        return options;
    }

    void set_defaults_from_config (po::variables_map& variables) override
    {
    }

    console_result invoke (Json::Value& jv_output,
                           libbitcoin::server::server_node& node) override;

    struct argument
    {
        explorer::config::transaction transaction;
    } argument_;

    struct option
    {
        option()
            : broadcast_flag(false)
            , self_publickey("")
        {}

        bool broadcast_flag;
        std::string self_publickey;
    } option_;

};

} // namespace commands
} // namespace explorer
} // namespace libbitcoin

<|endoftext|>