<commit_before>#include "envoy/config/bootstrap/v3/bootstrap.pb.h"
#include "envoy/network/filter.h"
#include "envoy/registry/registry.h"

#include "common/network/utility.h"

#include "test/config/utility.h"
#include "test/integration/integration.h"
#include "test/test_common/logging.h"
#include "test/test_common/simulated_time_system.h"

#include "gtest/gtest.h"

namespace Envoy {
namespace {

class ConnectionLimitIntegrationTest : public testing::TestWithParam<Network::Address::IpVersion>,
                                       public Event::TestUsingSimulatedTime,
                                       public BaseIntegrationTest {
public:
  ConnectionLimitIntegrationTest()
      : BaseIntegrationTest(GetParam(), ConfigHelper::tcpProxyConfig()) {}

  void setEmptyListenerLimit() {
    config_helper_.addRuntimeOverride("envoy.resource_limits.listener.listener_0.connection_limit",
                                      "");
  }

  void setListenerLimit(const uint32_t num_conns) {
    config_helper_.addRuntimeOverride("envoy.resource_limits.listener.listener_0.connection_limit",
                                      std::to_string(num_conns));
  }

  void setGlobalLimit(std::string&& num_conns) {
    config_helper_.addRuntimeOverride("overload.global_downstream_max_connections", num_conns);
  }

  void initialize() override { BaseIntegrationTest::initialize(); }

  // Assumes a limit of 2 connections.
  void doTest(std::function<void()> init_func, std::string&& check_stat) {
    init_func();

    std::vector<IntegrationTcpClientPtr> tcp_clients;
    std::vector<FakeRawConnectionPtr> raw_conns;
    tcp_clients.emplace_back(makeTcpConnection(lookupPort("listener_0")));
    raw_conns.emplace_back();
    ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(raw_conns.back()));
    ASSERT_TRUE(tcp_clients.back()->connected());

    tcp_clients.emplace_back(makeTcpConnection(lookupPort("listener_0")));
    raw_conns.emplace_back();
    ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(raw_conns.back()));
    ASSERT_TRUE(tcp_clients.back()->connected());

    tcp_clients.emplace_back(makeTcpConnection(lookupPort("listener_0")));
    raw_conns.emplace_back();
    ASSERT_FALSE(
        fake_upstreams_[0]->waitForRawConnection(raw_conns.back(), std::chrono::milliseconds(500)));
    tcp_clients.back()->waitForDisconnect();

    // Get rid of the client that failed to connect.
    tcp_clients.back()->close();
    tcp_clients.pop_back();

    // Close the first connection that was successful so that we can open a new successful
    // connection.
    tcp_clients.front()->close();
    ASSERT_TRUE(raw_conns.front()->waitForDisconnect());

    tcp_clients.emplace_back(makeTcpConnection(lookupPort("listener_0")));
    raw_conns.emplace_back();
    ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(raw_conns.back()));
    ASSERT_TRUE(tcp_clients.back()->connected());

    const bool isV4 = (version_ == Network::Address::IpVersion::v4);
    auto local_address = isV4 ? Network::Utility::getCanonicalIpv4LoopbackAddress()
                              : Network::Utility::getIpv6LoopbackAddress();

    const std::string counter_prefix = (isV4 ? "listener.127.0.0.1_0." : "listener.[__1]_0.");

    test_server_->waitForCounterEq(counter_prefix + check_stat, 1);

    for (auto& tcp_client : tcp_clients) {
      tcp_client->close();
    }

    tcp_clients.clear();
    raw_conns.clear();
  }
};

INSTANTIATE_TEST_SUITE_P(IpVersions, ConnectionLimitIntegrationTest,
                         testing::ValuesIn(TestEnvironment::getIpVersionsForTest()),
                         TestUtility::ipTestParamsToString);

TEST_P(ConnectionLimitIntegrationTest, TestListenerLimit) {
  std::function<void()> init_func = [this]() {
    setListenerLimit(2);
    initialize();
  };

  doTest(init_func, "downstream_cx_overflow");
}

TEST_P(ConnectionLimitIntegrationTest, TestEmptyGlobalCxRuntimeLimit) {
  const std::string log_line = "no configured limit to the number of allowed active connections.";
  EXPECT_LOG_CONTAINS("warn", log_line, { initialize(); });
}

TEST_P(ConnectionLimitIntegrationTest, TestEmptyListenerRuntimeLimit) {
  const std::string log_line =
      "Listener connection limit runtime key "
      "envoy.resource_limits.listener.listener_0.connection_limit is empty. There are currently "
      "no limitations on the number of accepted connections for listener listener_0.";
  EXPECT_LOG_CONTAINS("warn", log_line, {
    setEmptyListenerLimit();
    initialize();
  });
}

TEST_P(ConnectionLimitIntegrationTest, TestGlobalLimit) {
  std::function<void()> init_func = [this]() {
    // Includes twice the number of connections expected because the tracking is performed via a
    // static variable and the fake upstream has a listener. This causes upstream connections to the
    // fake upstream to also be tracked as part of the global downstream connection tracking.
    setGlobalLimit("4");
    initialize();
  };

  doTest(init_func, "downstream_global_cx_overflow");
}

TEST_P(ConnectionLimitIntegrationTest, TestBothLimits) {
  std::function<void()> init_func = [this]() {
    // Setting the listener limit to a much higher value and making sure the right stat gets
    // incremented when both limits are set.
    setGlobalLimit("4");
    setListenerLimit(100);
    initialize();
  };

  doTest(init_func, "downstream_global_cx_overflow");
}

} // namespace
} // namespace Envoy
<commit_msg>test: fixing a race in cx_limit_integration_test (#12233)<commit_after>#include "envoy/config/bootstrap/v3/bootstrap.pb.h"
#include "envoy/network/filter.h"
#include "envoy/registry/registry.h"

#include "common/network/utility.h"

#include "test/config/utility.h"
#include "test/integration/integration.h"
#include "test/test_common/logging.h"
#include "test/test_common/simulated_time_system.h"

#include "gtest/gtest.h"

namespace Envoy {
namespace {

class ConnectionLimitIntegrationTest : public testing::TestWithParam<Network::Address::IpVersion>,
                                       public Event::TestUsingSimulatedTime,
                                       public BaseIntegrationTest {
public:
  ConnectionLimitIntegrationTest()
      : BaseIntegrationTest(GetParam(), ConfigHelper::tcpProxyConfig()) {}

  void setEmptyListenerLimit() {
    config_helper_.addRuntimeOverride("envoy.resource_limits.listener.listener_0.connection_limit",
                                      "");
  }

  void setListenerLimit(const uint32_t num_conns) {
    config_helper_.addRuntimeOverride("envoy.resource_limits.listener.listener_0.connection_limit",
                                      std::to_string(num_conns));
  }

  void setGlobalLimit(std::string&& num_conns) {
    config_helper_.addRuntimeOverride("overload.global_downstream_max_connections", num_conns);
  }

  void initialize() override { BaseIntegrationTest::initialize(); }

  AssertionResult waitForConnections(uint32_t envoy_downstream_connections) {
    // The multiplier of 2 is because both Envoy's downstream connections and
    // the test server's downstream connections are counted by the global
    // counter.
    uint32_t expected_connections = envoy_downstream_connections * 2;

    for (int i = 0; i < 10; ++i) {
      if (Network::AcceptedSocketImpl::acceptedSocketCount() == expected_connections) {
        return AssertionSuccess();
      }
      timeSystem().advanceTimeWait(std::chrono::milliseconds(500));
    }
    if (Network::AcceptedSocketImpl::acceptedSocketCount() == expected_connections) {
      return AssertionSuccess();
    }
    return AssertionFailure();
  }

  // Assumes a limit of 2 connections.
  void doTest(std::function<void()> init_func, std::string&& check_stat) {
    init_func();

    std::vector<IntegrationTcpClientPtr> tcp_clients;
    std::vector<FakeRawConnectionPtr> raw_conns;
    tcp_clients.emplace_back(makeTcpConnection(lookupPort("listener_0")));
    raw_conns.emplace_back();
    ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(raw_conns.back()));
    ASSERT_TRUE(tcp_clients.back()->connected());

    tcp_clients.emplace_back(makeTcpConnection(lookupPort("listener_0")));
    raw_conns.emplace_back();
    ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(raw_conns.back()));
    ASSERT_TRUE(tcp_clients.back()->connected());

    tcp_clients.emplace_back(makeTcpConnection(lookupPort("listener_0")));
    raw_conns.emplace_back();
    ASSERT_FALSE(
        fake_upstreams_[0]->waitForRawConnection(raw_conns.back(), std::chrono::milliseconds(500)));
    tcp_clients.back()->waitForDisconnect();

    // Get rid of the client that failed to connect.
    tcp_clients.back()->close();
    tcp_clients.pop_back();

    // Close the first connection that was successful so that we can open a new successful
    // connection.
    tcp_clients.front()->close();
    ASSERT_TRUE(raw_conns.front()->waitForDisconnect());

    // Make sure to not try to connect again until the acceptedSocketCount is updated.
    ASSERT_TRUE(waitForConnections(1));
    tcp_clients.emplace_back(makeTcpConnection(lookupPort("listener_0")));
    raw_conns.emplace_back();
    ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(raw_conns.back()));
    ASSERT_TRUE(tcp_clients.back()->connected());

    const bool isV4 = (version_ == Network::Address::IpVersion::v4);
    auto local_address = isV4 ? Network::Utility::getCanonicalIpv4LoopbackAddress()
                              : Network::Utility::getIpv6LoopbackAddress();

    const std::string counter_prefix = (isV4 ? "listener.127.0.0.1_0." : "listener.[__1]_0.");

    test_server_->waitForCounterEq(counter_prefix + check_stat, 1);

    for (auto& tcp_client : tcp_clients) {
      tcp_client->close();
    }

    tcp_clients.clear();
    raw_conns.clear();
  }
};

INSTANTIATE_TEST_SUITE_P(IpVersions, ConnectionLimitIntegrationTest,
                         testing::ValuesIn(TestEnvironment::getIpVersionsForTest()),
                         TestUtility::ipTestParamsToString);

TEST_P(ConnectionLimitIntegrationTest, TestListenerLimit) {
  std::function<void()> init_func = [this]() {
    setListenerLimit(2);
    initialize();
  };

  doTest(init_func, "downstream_cx_overflow");
}

TEST_P(ConnectionLimitIntegrationTest, TestEmptyGlobalCxRuntimeLimit) {
  const std::string log_line = "no configured limit to the number of allowed active connections.";
  EXPECT_LOG_CONTAINS("warn", log_line, { initialize(); });
}

TEST_P(ConnectionLimitIntegrationTest, TestEmptyListenerRuntimeLimit) {
  const std::string log_line =
      "Listener connection limit runtime key "
      "envoy.resource_limits.listener.listener_0.connection_limit is empty. There are currently "
      "no limitations on the number of accepted connections for listener listener_0.";
  EXPECT_LOG_CONTAINS("warn", log_line, {
    setEmptyListenerLimit();
    initialize();
  });
}

TEST_P(ConnectionLimitIntegrationTest, TestGlobalLimit) {
  std::function<void()> init_func = [this]() {
    // Includes twice the number of connections expected because the tracking is performed via a
    // static variable and the fake upstream has a listener. This causes upstream connections to the
    // fake upstream to also be tracked as part of the global downstream connection tracking.
    setGlobalLimit("4");
    initialize();
  };

  doTest(init_func, "downstream_global_cx_overflow");
}

TEST_P(ConnectionLimitIntegrationTest, TestBothLimits) {
  std::function<void()> init_func = [this]() {
    // Setting the listener limit to a much higher value and making sure the right stat gets
    // incremented when both limits are set.
    setGlobalLimit("4");
    setListenerLimit(100);
    initialize();
  };

  doTest(init_func, "downstream_global_cx_overflow");
}

} // namespace
} // namespace Envoy
<|endoftext|>


<commit_before>#include "stdafx.h"
#include <algorithm>
#include <memory>
#include <OleAuto.h>//<OAIdl.h>

//VBA比較関数型  vbCompFunc  の宣言 (VBCallbackFuncと同一)
//VBAにおけるシグネチャは
// Function comp(ByRef elem As Variant, ByRef dummy As Variant) As Variant
typedef VARIANT (__stdcall *vbCompFunc)(VARIANT*, VARIANT*);

__int32 __stdcall Dimension(const VARIANT* pv);
void safeArrayBounds(SAFEARRAY* pArray, UINT dim, SAFEARRAYBOUND bounds[]);

class compareByVBAfunc   {
    VARIANT*    begin;
    vbCompFunc  comp;
public:
    compareByVBAfunc(VARIANT* pA, vbCompFunc f) : begin(pA), comp(f) { }
    bool operator ()(__int32 i, __int32 j) const
    {
        return (*comp)(begin + i, begin + j).lVal ? true: false;
    }
};

//1次元昇順
class compFunctor  {
    VARIANT*    begin;
public:
    compFunctor(VARIANT* pA) : begin(pA) { }
    bool operator ()(__int32 i, __int32 j) const
    {
        return VARCMP_LT == VarCmp(begin + i, begin + j, LANG_JAPANESE, 0);
    }
};

//2次元昇順
class compDictionaryFunctor  {
    VARIANT*    begin;
    void set(__int32 k, SAFEARRAY*&  pArray, SAFEARRAYBOUND& bound) const
    {
        if ( 1 == Dimension(begin + k) )
        {
            pArray = ( 0 == (VT_BYREF & begin[k].vt) )?  (begin[k].parray): (*begin[k].pparray);
            safeArrayBounds(pArray, 1, &bound);
        }
        else
        {
            pArray = nullptr;
        }
    }
public:
    compDictionaryFunctor(VARIANT* pA) : begin(pA) { }
    bool operator ()(__int32 i, __int32 j) const
    {
        SAFEARRAY*  pArray1, *pArray2;
        SAFEARRAYBOUND bound1, bound2;
        set(i, pArray1, bound1);
        set(j, pArray2, bound2);
        if ( pArray1 == nullptr || pArray2 == nullptr )     return false;
        VARIANT Var1, Var2;
        for ( ULONG k = 0; k < bound1.cElements && k < bound2.cElements; ++k )
        {
            auto index1 = static_cast<LONG>(k + bound1.lLbound);
            auto index2 = static_cast<LONG>(k + bound2.lLbound);
            ::SafeArrayGetElement(pArray1, &index1, &Var1);
            ::SafeArrayGetElement(pArray2, &index2, &Var2);
            if ( VARCMP_LT == VarCmp(&Var1, &Var2, LANG_JAPANESE, 0) )
                return true;
            if ( VARCMP_LT == VarCmp(&Var2, &Var1, LANG_JAPANESE, 0) )
                return false;
        }
        return false;
    }
};

VARIANT __stdcall stdsort(VARIANT* array, __int32 pComp)
{
    VARIANT      ret;
    ::VariantInit(&ret);
    if ( 1 != Dimension(array) )            return ret;
    SAFEARRAY* pArray = ( 0 == (VT_BYREF & array->vt) )?  (array->parray): (*array->pparray);
    SAFEARRAYBOUND bound = {1, 0};   //要素数、LBound
    safeArrayBounds(pArray, 1, &bound);
    std::unique_ptr<__int32[]>	index(new __int32[bound.cElements]);
    std::unique_ptr<VARIANT[]>	VArray(new VARIANT[bound.cElements]);
    for ( ULONG i = 0; i < bound.cElements; ++i )
    {
        index[i] = static_cast<__int32>(i);
        auto j = static_cast<LONG>(i + bound.lLbound);
        ::SafeArrayGetElement(pArray, &j, &VArray[i]);
    }
    if ( 0 < pComp )
    {
        compareByVBAfunc functor(VArray.get(), reinterpret_cast<vbCompFunc>(pComp));
        std::sort(index.get(), index.get() + bound.cElements, functor);
    }
    else if ( -1 == pComp ) //1次元昇順
    {
        compFunctor   functor(VArray.get());
        std::sort(index.get(), index.get() + bound.cElements, functor);
    }
    else if ( -2 == pComp  ) //2次元昇順
    {
        compDictionaryFunctor   functor(VArray.get());
        std::sort(index.get(), index.get() + bound.cElements, functor);
    }
    //-------------------------------------------------------
    SAFEARRAYBOUND boundRet = { bound.cElements, 0};   //要素数、LBound
    SAFEARRAY* retArray = ::SafeArrayCreate(VT_VARIANT, 1, &boundRet);
    VARIANT elem;
    ::VariantInit(&elem);
    elem.vt = VT_I4;
    for ( LONG i = 0; i < static_cast<LONG>(bound.cElements); ++i )
    {
        elem.lVal = index[i];
        ::SafeArrayPutElement(retArray, &i, &elem);
    }
    ret.vt = VT_ARRAY | VT_VARIANT;
    ret.parray = retArray;
    return      ret;
}
<commit_msg>stdsortのバグ修正<commit_after>#include "stdafx.h"
#include <algorithm>
#include <memory>
#include <OleAuto.h>//<OAIdl.h>

//VBA比較関数型  vbCompFunc  の宣言 (VBCallbackFuncと同一)
//VBAにおけるシグネチャは
// Function comp(ByRef elem As Variant, ByRef dummy As Variant) As Variant
typedef VARIANT (__stdcall *vbCompFunc)(VARIANT*, VARIANT*);

__int32 __stdcall Dimension(const VARIANT* pv);
void safeArrayBounds(SAFEARRAY* pArray, UINT dim, SAFEARRAYBOUND bounds[]);

class compareByVBAfunc   {
    VARIANT*    begin;
    vbCompFunc  comp;
public:
    compareByVBAfunc(VARIANT* pA, vbCompFunc f) : begin(pA), comp(f) { }
    bool operator ()(__int32 i, __int32 j) const
    {
        return (*comp)(begin + i, begin + j).lVal ? true: false;
    }
};

//1次元昇順
class compFunctor  {
    VARIANT*    begin;
public:
    compFunctor(VARIANT* pA) : begin(pA) { }
    bool operator ()(__int32 i, __int32 j) const
    {
        return VARCMP_LT == VarCmp(begin + i, begin + j, LANG_JAPANESE, 0);
    }
};

//2次元昇順
class compDictionaryFunctor  {
    VARIANT*    begin;
    void set(__int32 k, SAFEARRAY*&  pArray, SAFEARRAYBOUND& bound) const
    {
        if ( 1 == Dimension(begin + k) )
        {
            pArray = ( 0 == (VT_BYREF & begin[k].vt) )?  (begin[k].parray): (*begin[k].pparray);
            safeArrayBounds(pArray, 1, &bound);
        }
        else
        {
            pArray = nullptr;
        }
    }
public:
    compDictionaryFunctor(VARIANT* pA) : begin(pA) { }
    bool operator ()(__int32 i, __int32 j) const
    {
        SAFEARRAY*  pArray1, *pArray2;
        SAFEARRAYBOUND bound1, bound2;
        set(i, pArray1, bound1);
        set(j, pArray2, bound2);
        if ( pArray1 == nullptr || pArray2 == nullptr )     return false;
        VARIANT Var1, Var2;
        for ( ULONG k = 0; k < bound1.cElements && k < bound2.cElements; ++k )
        {
            auto index1 = static_cast<LONG>(k + bound1.lLbound);
            auto index2 = static_cast<LONG>(k + bound2.lLbound);
            ::SafeArrayGetElement(pArray1, &index1, &Var1);
            ::SafeArrayGetElement(pArray2, &index2, &Var2);
            if ( VARCMP_LT == VarCmp(&Var1, &Var2, LANG_JAPANESE, 0) )
                return true;
            if ( VARCMP_LT == VarCmp(&Var2, &Var1, LANG_JAPANESE, 0) )
                return false;
        }
        return false;
    }
};

VARIANT __stdcall stdsort(VARIANT* array, __int32 pComp)
{
    VARIANT      ret;
    ::VariantInit(&ret);
    if ( 1 != Dimension(array) )            return ret;
    SAFEARRAY* pArray = ( 0 == (VT_BYREF & array->vt) )?  (array->parray): (*array->pparray);
    SAFEARRAYBOUND bound = {1, 0};   //要素数、LBound
    safeArrayBounds(pArray, 1, &bound);
    std::unique_ptr<__int32[]>	index(new __int32[bound.cElements]);
    std::unique_ptr<VARIANT[]>	VArray(new VARIANT[bound.cElements]);
    for ( ULONG i = 0; i < bound.cElements; ++i )
    {
        index[i] = static_cast<__int32>(i);
        auto j = static_cast<LONG>(i + bound.lLbound);
        ::SafeArrayGetElement(pArray, &j, &VArray[i]);
    }
    if ( 0 < pComp )
    {
        compareByVBAfunc functor(VArray.get(), reinterpret_cast<vbCompFunc>(pComp));
        std::sort(index.get(), index.get() + bound.cElements, functor);
    }
    else if ( -1 == pComp ) //1次元昇順
    {
        compFunctor   functor(VArray.get());
        std::sort(index.get(), index.get() + bound.cElements, functor);
    }
    else if ( -2 == pComp  ) //2次元昇順
    {
        compDictionaryFunctor   functor(VArray.get());
        std::sort(index.get(), index.get() + bound.cElements, functor);
    }
    //-------------------------------------------------------
    SAFEARRAYBOUND boundRet = { bound.cElements, 0};   //要素数、LBound
    SAFEARRAY* retArray = ::SafeArrayCreate(VT_VARIANT, 1, &boundRet);
    VARIANT elem;
    ::VariantInit(&elem);
    elem.vt = VT_I4;
    for ( LONG i = 0; i < static_cast<LONG>(bound.cElements); ++i )
    {
        elem.lVal = index[i] + bound.lLbound;
        ::SafeArrayPutElement(retArray, &i, &elem);
    }
    ret.vt = VT_ARRAY | VT_VARIANT;
    ret.parray = retArray;
    return      ret;
}
<|endoftext|>


<commit_before>#include "StdAfx.h"

#include "utypes.h"
#include <assert.h>
#include <stdlib.h>

#ifdef WIN32

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>

typedef ULONGLONG (WINAPI GetTickCount64Proc)(void);
static GetTickCount64Proc *pt2GetTickCount64;
static GetTickCount64Proc *pt2RealGetTickCount;

static uint64 startPerformanceCounter;
static uint64 startGetTickCount;
// MSVC 6 standard doesn't like division with uint64s
static double counterPerMicrosecond;

uint64 UTGetTickCount64()
{
	if (pt2GetTickCount64) {
		return pt2GetTickCount64();
	}
	if (pt2RealGetTickCount) {
		uint64 v = pt2RealGetTickCount();
		// fix return value from GetTickCount
		return (DWORD)v | ((v >> 0x18) & 0xFFFFFFFF00000000);
	}
	return (uint64)GetTickCount();
}

uint32 UTP_GetMilliseconds()
{
	return GetTickCount();
}

void Time_Initialize()
{
	HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
	pt2GetTickCount64 = (GetTickCount64Proc*)GetProcAddress(kernel32, "GetTickCount64");
	// not a typo. GetTickCount actually returns 64 bits
	pt2RealGetTickCount = (GetTickCount64Proc*)GetProcAddress(kernel32, "GetTickCount");

	uint64 frequency;
	QueryPerformanceCounter((LARGE_INTEGER*)&startPerformanceCounter);
	QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
	counterPerMicrosecond = (double)frequency / 1000000.0f;
	startGetTickCount = UTGetTickCount64();
}

int64 abs64(int64 x) { return x < 0 ? -x : x; }

uint64 UTP_GetMicroseconds()
{
	static bool time_init = false;
	if (!time_init) {
		time_init = true;
		Time_Initialize();
	}

	uint64 counter;
	uint64 tick;

	QueryPerformanceCounter((LARGE_INTEGER*) &counter);
	tick = UTGetTickCount64();

	// unfortunately, QueryPerformanceCounter is not guaranteed
	// to be monotonic. Make it so.
	int64 ret = (int64)(((int64)counter - (int64)startPerformanceCounter) / counterPerMicrosecond);
	// if the QPC clock leaps more than one second off GetTickCount64()
	// something is seriously fishy. Adjust QPC to stay monotonic
	int64 tick_diff = tick - startGetTickCount;
	if (abs64(ret / 100000 - tick_diff / 100) > 10) {
		startPerformanceCounter -= (uint64)((int64)(tick_diff * 1000 - ret) * counterPerMicrosecond);
		ret = (int64)((counter - startPerformanceCounter) / counterPerMicrosecond);
	}
	return ret;
}

#else //!WIN32

#include <time.h>
#include <sys/time.h>		// Linux needs both time.h and sys/time.h
#include <stdlib.h>

#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#if defined(__APPLE__)
#include <mach/mach_time.h>

uint64 UTP_GetMicroseconds()
{
	// http://developer.apple.com/mac/library/qa/qa2004/qa1398.html
	// http://www.macresearch.org/tutorial_performance_and_time
	static mach_timebase_info_data_t sTimebaseInfo;
	static uint64_t start_tick = 0;
	uint64_t tick;
	// Returns a counter in some fraction of a nanoseconds
	tick = mach_absolute_time();
	if (sTimebaseInfo.denom == 0) {
		// Get the timer ratio to convert mach_absolute_time to nanoseconds
		mach_timebase_info(&sTimebaseInfo);
		start_tick = tick;
	}
	// Calculate the elapsed time, convert it to microseconds and return it.
	return ((tick - start_tick) * sTimebaseInfo.numer) / (sTimebaseInfo.denom * 1000);
}

#elif _POSIX_TIMERS && defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK >= 0) && defined(CLOCK_MONOTONIC)

uint64 UTP_GetMicroseconds()
{
	timespec t;
	int status = clock_gettime(CLOCK_MONOTONIC, &t);
#ifdef _DEBUG
	if (status) printf("clock_gettime returned %d - error %d %s", status, errno, ::strerror(errno));
#endif
	assert(status == 0);
	uint64 tick = uint64(t.tv_sec) * 1000000 + uint64(t.tv_nsec) / 1000;
	return tick;
}

#else

#warning "Using non-monotonic function gettimeofday() in UTP_GetMicroseconds()"
// Fallback

uint64 UTP_GetMicroseconds()
{
	static time_t start_time = 0;

	timeval t;
	::gettimeofday(&t, NULL);

	// avoid overflow by subtracting the seconds
	if (start_time == 0) start_time = t.tv_sec;

	return uint64(t.tv_sec - start_time) * 1000000 + (t.tv_usec);
}
#endif

uint32 UTP_GetMilliseconds()
{
	return UTP_GetMicroseconds() / 1000;
}

#endif

#define UDP_IPV4_OVERHEAD (20+8)
#define UDP_IPV6_OVERHEAD (40+8)
#define UDP_TEREDO_OVERHEAD (UDP_IPV4_OVERHEAD + UDP_IPV6_OVERHEAD)

#define ETHERNET_MTU 1500
#define IPV4_HEADER_SIZE 20
#define IPV6_HEADER_SIZE 40
#define UDP_HEADER_SIZE 8
#define GRE_HEADER_SIZE 24
#define PPPOE_HEADER_SIZE 8
#define MPPE_HEADER_SIZE 2
#define TEREDO_MTU 1280

#define UDP_IPV4_MTU (ETHERNET_MTU - IPV4_HEADER_SIZE - UDP_HEADER_SIZE - GRE_HEADER_SIZE - PPPOE_HEADER_SIZE - MPPE_HEADER_SIZE)
#define UDP_IPV6_MTU (ETHERNET_MTU - IPV6_HEADER_SIZE - UDP_HEADER_SIZE - GRE_HEADER_SIZE - PPPOE_HEADER_SIZE - MPPE_HEADER_SIZE)
#define UDP_TEREDO_MTU (TEREDO_MTU - UDP_HEADER_SIZE)

uint16 UTP_GetUDPMTU(const struct sockaddr *remote, socklen_t remotelen)
{
	// Since we don't know the local address of the interface,
	// be conservative and assume all IPv6 connections are Teredo.
	return remote->sa_family == AF_INET6 ? UDP_TEREDO_MTU : UDP_IPV4_MTU;
}

uint16 UTP_GetUDPOverhead(const struct sockaddr *remote, socklen_t remotelen)
{
	// Since we don't know the local address of the interface,
	// be conservative and assume all IPv6 connections are Teredo.
	return remote->sa_family == AF_INET6 ? UDP_TEREDO_OVERHEAD : UDP_IPV4_OVERHEAD;
}

uint32 UTP_Random()
{
	return rand();
}
<commit_msg>use existing constants<commit_after>#include "StdAfx.h"

#include "utypes.h"
#include <assert.h>
#include <stdlib.h>

#ifdef WIN32

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>

typedef ULONGLONG (WINAPI GetTickCount64Proc)(void);
static GetTickCount64Proc *pt2GetTickCount64;
static GetTickCount64Proc *pt2RealGetTickCount;

static uint64 startPerformanceCounter;
static uint64 startGetTickCount;
// MSVC 6 standard doesn't like division with uint64s
static double counterPerMicrosecond;

uint64 UTGetTickCount64()
{
	if (pt2GetTickCount64) {
		return pt2GetTickCount64();
	}
	if (pt2RealGetTickCount) {
		uint64 v = pt2RealGetTickCount();
		// fix return value from GetTickCount
		return (DWORD)v | ((v >> 0x18) & 0xFFFFFFFF00000000);
	}
	return (uint64)GetTickCount();
}

uint32 UTP_GetMilliseconds()
{
	return GetTickCount();
}

void Time_Initialize()
{
	HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
	pt2GetTickCount64 = (GetTickCount64Proc*)GetProcAddress(kernel32, "GetTickCount64");
	// not a typo. GetTickCount actually returns 64 bits
	pt2RealGetTickCount = (GetTickCount64Proc*)GetProcAddress(kernel32, "GetTickCount");

	uint64 frequency;
	QueryPerformanceCounter((LARGE_INTEGER*)&startPerformanceCounter);
	QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
	counterPerMicrosecond = (double)frequency / 1000000.0f;
	startGetTickCount = UTGetTickCount64();
}

int64 abs64(int64 x) { return x < 0 ? -x : x; }

uint64 UTP_GetMicroseconds()
{
	static bool time_init = false;
	if (!time_init) {
		time_init = true;
		Time_Initialize();
	}

	uint64 counter;
	uint64 tick;

	QueryPerformanceCounter((LARGE_INTEGER*) &counter);
	tick = UTGetTickCount64();

	// unfortunately, QueryPerformanceCounter is not guaranteed
	// to be monotonic. Make it so.
	int64 ret = (int64)(((int64)counter - (int64)startPerformanceCounter) / counterPerMicrosecond);
	// if the QPC clock leaps more than one second off GetTickCount64()
	// something is seriously fishy. Adjust QPC to stay monotonic
	int64 tick_diff = tick - startGetTickCount;
	if (abs64(ret / 100000 - tick_diff / 100) > 10) {
		startPerformanceCounter -= (uint64)((int64)(tick_diff * 1000 - ret) * counterPerMicrosecond);
		ret = (int64)((counter - startPerformanceCounter) / counterPerMicrosecond);
	}
	return ret;
}

#else //!WIN32

#include <time.h>
#include <sys/time.h>		// Linux needs both time.h and sys/time.h
#include <stdlib.h>

#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#if defined(__APPLE__)
#include <mach/mach_time.h>

uint64 UTP_GetMicroseconds()
{
	// http://developer.apple.com/mac/library/qa/qa2004/qa1398.html
	// http://www.macresearch.org/tutorial_performance_and_time
	static mach_timebase_info_data_t sTimebaseInfo;
	static uint64_t start_tick = 0;
	uint64_t tick;
	// Returns a counter in some fraction of a nanoseconds
	tick = mach_absolute_time();
	if (sTimebaseInfo.denom == 0) {
		// Get the timer ratio to convert mach_absolute_time to nanoseconds
		mach_timebase_info(&sTimebaseInfo);
		start_tick = tick;
	}
	// Calculate the elapsed time, convert it to microseconds and return it.
	return ((tick - start_tick) * sTimebaseInfo.numer) / (sTimebaseInfo.denom * 1000);
}

#elif _POSIX_TIMERS && defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK >= 0) && defined(CLOCK_MONOTONIC)

uint64 UTP_GetMicroseconds()
{
	timespec t;
	int status = clock_gettime(CLOCK_MONOTONIC, &t);
#ifdef _DEBUG
	if (status) printf("clock_gettime returned %d - error %d %s", status, errno, ::strerror(errno));
#endif
	assert(status == 0);
	uint64 tick = uint64(t.tv_sec) * 1000000 + uint64(t.tv_nsec) / 1000;
	return tick;
}

#else

#warning "Using non-monotonic function gettimeofday() in UTP_GetMicroseconds()"
// Fallback

uint64 UTP_GetMicroseconds()
{
	static time_t start_time = 0;

	timeval t;
	::gettimeofday(&t, NULL);

	// avoid overflow by subtracting the seconds
	if (start_time == 0) start_time = t.tv_sec;

	return uint64(t.tv_sec - start_time) * 1000000 + (t.tv_usec);
}
#endif

uint32 UTP_GetMilliseconds()
{
	return UTP_GetMicroseconds() / 1000;
}

#endif

#define ETHERNET_MTU 1500
#define IPV4_HEADER_SIZE 20
#define IPV6_HEADER_SIZE 40
#define UDP_HEADER_SIZE 8
#define GRE_HEADER_SIZE 24
#define PPPOE_HEADER_SIZE 8
#define MPPE_HEADER_SIZE 2
#define TEREDO_MTU 1280

#define UDP_IPV4_OVERHEAD (IPV4_HEADER_SIZE + UDP_HEADER_SIZE)
#define UDP_IPV6_OVERHEAD (IPV6_HEADER_SIZE + UDP_HEADER_SIZE)
#define UDP_TEREDO_OVERHEAD (UDP_IPV4_OVERHEAD + UDP_IPV6_OVERHEAD)

#define UDP_IPV4_MTU (ETHERNET_MTU - IPV4_HEADER_SIZE - UDP_HEADER_SIZE - GRE_HEADER_SIZE - PPPOE_HEADER_SIZE - MPPE_HEADER_SIZE)
#define UDP_IPV6_MTU (ETHERNET_MTU - IPV6_HEADER_SIZE - UDP_HEADER_SIZE - GRE_HEADER_SIZE - PPPOE_HEADER_SIZE - MPPE_HEADER_SIZE)
#define UDP_TEREDO_MTU (TEREDO_MTU - UDP_HEADER_SIZE)

uint16 UTP_GetUDPMTU(const struct sockaddr *remote, socklen_t remotelen)
{
	// Since we don't know the local address of the interface,
	// be conservative and assume all IPv6 connections are Teredo.
	return remote->sa_family == AF_INET6 ? UDP_TEREDO_MTU : UDP_IPV4_MTU;
}

uint16 UTP_GetUDPOverhead(const struct sockaddr *remote, socklen_t remotelen)
{
	// Since we don't know the local address of the interface,
	// be conservative and assume all IPv6 connections are Teredo.
	return remote->sa_family == AF_INET6 ? UDP_TEREDO_OVERHEAD : UDP_IPV4_OVERHEAD;
}

uint32 UTP_Random()
{
	return rand();
}
<|endoftext|>


<commit_before>#include "tensorflow_types.hpp"

// TODO: Capture error text rather than PyError_Print
// TODO: Capture ... (named and un-named args) and forward to call
// TODO: py_object_convert (convert from Python to R)

using namespace Rcpp;

// https://docs.python.org/2/c-api/object.html

// [[Rcpp::export]]
void py_initialize() {
  ::Py_Initialize();
}

// [[Rcpp::export]]
void py_finalize() {
  ::Py_Finalize();
}

// helper function to wrap a PyObject in an XPtr
PyObjectPtr py_object_ptr(PyObject* object, bool decref = true) {
  PyObjectPtr ptr(object);
  ptr.attr("class") = "py_object";
  return ptr;
}

//' @export
// [[Rcpp::export]]
void py_run_string(const std::string& code)
{
  ::PyRun_SimpleString(code.c_str());
}

//' @export
// [[Rcpp::export]]
void py_run_file(const std::string& file)
{
  FILE* fp = ::fopen(file.c_str(), "r");
  if (fp)
    ::PyRun_SimpleFile(fp, file.c_str());
  else
    stop("Unable to read script file '%s' (does the file exist?)", file);
}

//' @export
// [[Rcpp::export]]
PyObjectPtr py_main_module() {
  return py_object_ptr(::PyImport_AddModule("__main__"), false);
}

//' @export
// [[Rcpp::export]]
PyObjectPtr py_import(const std::string& module) {
  PyObject* pModule = ::PyImport_ImportModule(module.c_str());
  if (pModule == NULL) {
    ::PyErr_Print();
    stop("Unable to import module '%s'", module);
  }
  return py_object_ptr(pModule);
}

//' @export
// [[Rcpp::export(print.py_object)]]
void py_object_print(PyObjectPtr pObject) {
  ::PyObject_Print(pObject.get(), stdout, Py_PRINT_RAW);
}

//' @export
// [[Rcpp::export]]
PyObjectPtr py_object_get_attr(PyObjectPtr pObject, const std::string& name) {
  PyObject* attr = ::PyObject_GetAttrString(pObject.get(), name.c_str());
  if (attr == NULL) {
    ::PyErr_Print();
    stop("Attribute '%s' not found.", name);
  }
  return py_object_ptr(attr);
}

//' @export
// [[Rcpp::export]]
bool py_object_is_callable(PyObjectPtr pObject) {
  return ::PyCallable_Check(pObject.get()) == 1;
}

//' @export
// [[Rcpp::export]]
PyObjectPtr py_object_call(PyObjectPtr pObject) {
  PyObject *args = PyTuple_New(0);
  PyObject *keywords = ::PyDict_New();
  PyObject* res = ::PyObject_Call(pObject.get(), args, keywords);
  Py_DECREF(args);
  Py_DECREF(keywords);
  if (res == NULL) {
    ::PyErr_Print();
    stop("Error calling python function");
  }
  return py_object_ptr(res);
}
<commit_msg>add todo<commit_after>#include "tensorflow_types.hpp"

// TODO: Capture error text rather than PyError_Print
// TODO: Capture ... (named and un-named args) and forward to call
// TODO: py_object_convert (convert from Python to R)
// TODO: consider R6 wrapper (would allow custom $ functions)

using namespace Rcpp;

// https://docs.python.org/2/c-api/object.html

// [[Rcpp::export]]
void py_initialize() {
  ::Py_Initialize();
}

// [[Rcpp::export]]
void py_finalize() {
  ::Py_Finalize();
}

// helper function to wrap a PyObject in an XPtr
PyObjectPtr py_object_ptr(PyObject* object, bool decref = true) {
  PyObjectPtr ptr(object);
  ptr.attr("class") = "py_object";
  return ptr;
}

//' @export
// [[Rcpp::export]]
void py_run_string(const std::string& code)
{
  ::PyRun_SimpleString(code.c_str());
}

//' @export
// [[Rcpp::export]]
void py_run_file(const std::string& file)
{
  FILE* fp = ::fopen(file.c_str(), "r");
  if (fp)
    ::PyRun_SimpleFile(fp, file.c_str());
  else
    stop("Unable to read script file '%s' (does the file exist?)", file);
}

//' @export
// [[Rcpp::export]]
PyObjectPtr py_main_module() {
  return py_object_ptr(::PyImport_AddModule("__main__"), false);
}

//' @export
// [[Rcpp::export]]
PyObjectPtr py_import(const std::string& module) {
  PyObject* pModule = ::PyImport_ImportModule(module.c_str());
  if (pModule == NULL) {
    ::PyErr_Print();
    stop("Unable to import module '%s'", module);
  }
  return py_object_ptr(pModule);
}

//' @export
// [[Rcpp::export(print.py_object)]]
void py_object_print(PyObjectPtr pObject) {
  ::PyObject_Print(pObject.get(), stdout, Py_PRINT_RAW);
}

//' @export
// [[Rcpp::export]]
PyObjectPtr py_object_get_attr(PyObjectPtr pObject, const std::string& name) {
  PyObject* attr = ::PyObject_GetAttrString(pObject.get(), name.c_str());
  if (attr == NULL) {
    ::PyErr_Print();
    stop("Attribute '%s' not found.", name);
  }
  return py_object_ptr(attr);
}

//' @export
// [[Rcpp::export]]
bool py_object_is_callable(PyObjectPtr pObject) {
  return ::PyCallable_Check(pObject.get()) == 1;
}

//' @export
// [[Rcpp::export]]
PyObjectPtr py_object_call(PyObjectPtr pObject) {
  PyObject *args = PyTuple_New(0);
  PyObject *keywords = ::PyDict_New();
  PyObject* res = ::PyObject_Call(pObject.get(), args, keywords);
  Py_DECREF(args);
  Py_DECREF(keywords);
  if (res == NULL) {
    ::PyErr_Print();
    stop("Error calling python function");
  }
  return py_object_ptr(res);
}
<|endoftext|>


<commit_before>// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/debug/trace_event.h"
#include "cc/debug/rendering_stats.h"
#include "cc/layers/content_layer_client.h"
#include "cc/resources/picture.h"
#include "skia/ext/analysis_canvas.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkDrawFilter.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/utils/SkPictureUtils.h"
#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/skia_util.h"

namespace {
// URI label for a lazily decoded SkPixelRef.
const char kLabelLazyDecoded[] = "lazy";

class DisableLCDTextFilter : public SkDrawFilter {
 public:
  // SkDrawFilter interface.
  virtual bool filter(SkPaint* paint, SkDrawFilter::Type type) OVERRIDE {
    if (type != SkDrawFilter::kText_Type)
      return true;

    paint->setLCDRenderText(false);
    return true;
  }
};
}  // namespace

namespace cc {

scoped_refptr<Picture> Picture::Create(gfx::Rect layer_rect) {
  return make_scoped_refptr(new Picture(layer_rect));
}

Picture::Picture(gfx::Rect layer_rect)
    : layer_rect_(layer_rect) {
}

Picture::Picture(const skia::RefPtr<SkPicture>& picture,
                 gfx::Rect layer_rect,
                 gfx::Rect opaque_rect) :
    layer_rect_(layer_rect),
    opaque_rect_(opaque_rect),
    picture_(picture) {
}

Picture::~Picture() {
}

scoped_refptr<Picture> Picture::GetCloneForDrawingOnThread(
    unsigned thread_index) const {
  // SkPicture is not thread-safe to rasterize with, this returns a clone
  // to rasterize with on a specific thread.
  CHECK_GT(clones_.size(), thread_index);
  return clones_[thread_index];
}

void Picture::CloneForDrawing(int num_threads) {
  TRACE_EVENT1("cc", "Picture::CloneForDrawing", "num_threads", num_threads);

  DCHECK(picture_);
  scoped_array<SkPicture> clones(new SkPicture[num_threads]);
  picture_->clone(&clones[0], num_threads);

  clones_.clear();
  for (int i = 0; i < num_threads; i++) {
    scoped_refptr<Picture> clone = make_scoped_refptr(
        new Picture(skia::AdoptRef(new SkPicture(clones[i])),
                    layer_rect_,
                    opaque_rect_));
    clones_.push_back(clone);
  }
}

void Picture::Record(ContentLayerClient* painter,
                     RenderingStats* stats,
                     const SkTileGridPicture::TileGridInfo& tile_grid_info) {
  TRACE_EVENT2("cc", "Picture::Record",
               "width", layer_rect_.width(), "height", layer_rect_.height());

  // Record() should only be called once.
  DCHECK(!picture_);
  DCHECK(!tile_grid_info.fTileInterval.isEmpty());
  picture_ = skia::AdoptRef(new SkTileGridPicture(
      layer_rect_.width(), layer_rect_.height(), tile_grid_info));

  SkCanvas* canvas = picture_->beginRecording(
      layer_rect_.width(),
      layer_rect_.height(),
      SkPicture::kUsePathBoundsForClip_RecordingFlag |
      SkPicture::kOptimizeForClippedPlayback_RecordingFlag);

  canvas->save();
  canvas->translate(SkFloatToScalar(-layer_rect_.x()),
                    SkFloatToScalar(-layer_rect_.y()));

  SkPaint paint;
  paint.setAntiAlias(false);
  paint.setXfermodeMode(SkXfermode::kClear_Mode);
  SkRect layer_skrect = SkRect::MakeXYWH(layer_rect_.x(),
                                         layer_rect_.y(),
                                         layer_rect_.width(),
                                         layer_rect_.height());
  canvas->clipRect(layer_skrect);
  canvas->drawRect(layer_skrect, paint);

  gfx::RectF opaque_layer_rect;
  base::TimeTicks begin_paint_time;
  if (stats)
    begin_paint_time = base::TimeTicks::Now();
  painter->PaintContents(canvas, layer_rect_, &opaque_layer_rect);
  if (stats) {
    stats->total_paint_time += base::TimeTicks::Now() - begin_paint_time;
    stats->total_pixels_painted +=
        layer_rect_.width() * layer_rect_.height();
  }

  canvas->restore();
  picture_->endRecording();

  opaque_rect_ = gfx::ToEnclosedRect(opaque_layer_rect);
}

void Picture::Raster(
    SkCanvas* canvas,
    gfx::Rect content_rect,
    float contents_scale,
    bool enable_lcd_text) {
  TRACE_EVENT2("cc", "Picture::Raster",
               "layer width", layer_rect_.width(),
               "layer height", layer_rect_.height());
  DCHECK(picture_);

  DisableLCDTextFilter disable_lcd_text_filter;

  canvas->save();
  canvas->clipRect(gfx::RectToSkRect(content_rect));
  canvas->scale(contents_scale, contents_scale);
  canvas->translate(layer_rect_.x(), layer_rect_.y());
  // Pictures by default have LCD text enabled.
  if (!enable_lcd_text)
    canvas->setDrawFilter(&disable_lcd_text_filter);
  canvas->drawPicture(*picture_);
  canvas->restore();
}

void Picture::GatherPixelRefs(const gfx::Rect& layer_rect,
                              std::list<skia::LazyPixelRef*>& pixel_ref_list) {
  DCHECK(picture_);
  SkData* pixel_refs = SkPictureUtils::GatherPixelRefs(
      picture_.get(), SkRect::MakeXYWH(layer_rect.x(),
                                       layer_rect.y(),
                                       layer_rect.width(),
                                       layer_rect.height()));
  if (!pixel_refs)
    return;

  void* data = const_cast<void*>(pixel_refs->data());
  if (!data) {
    pixel_refs->unref();
    return;
  }

  SkPixelRef** refs = reinterpret_cast<SkPixelRef**>(data);
  for (size_t i = 0; i < pixel_refs->size() / sizeof(*refs); ++i) {
    if (*refs && (*refs)->getURI() && !strncmp(
        (*refs)->getURI(), kLabelLazyDecoded, 4)) {
      pixel_ref_list.push_back(static_cast<skia::LazyPixelRef*>(*refs));
    }
    refs++;
  }
  pixel_refs->unref();
}

}  // namespace cc
<commit_msg>cc: Temporarily disable tile grid optimization<commit_after>// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/debug/trace_event.h"
#include "cc/debug/rendering_stats.h"
#include "cc/layers/content_layer_client.h"
#include "cc/resources/picture.h"
#include "skia/ext/analysis_canvas.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkDrawFilter.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/utils/SkPictureUtils.h"
#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/skia_util.h"

namespace {
// URI label for a lazily decoded SkPixelRef.
const char kLabelLazyDecoded[] = "lazy";

class DisableLCDTextFilter : public SkDrawFilter {
 public:
  // SkDrawFilter interface.
  virtual bool filter(SkPaint* paint, SkDrawFilter::Type type) OVERRIDE {
    if (type != SkDrawFilter::kText_Type)
      return true;

    paint->setLCDRenderText(false);
    return true;
  }
};
}  // namespace

namespace cc {

scoped_refptr<Picture> Picture::Create(gfx::Rect layer_rect) {
  return make_scoped_refptr(new Picture(layer_rect));
}

Picture::Picture(gfx::Rect layer_rect)
    : layer_rect_(layer_rect) {
}

Picture::Picture(const skia::RefPtr<SkPicture>& picture,
                 gfx::Rect layer_rect,
                 gfx::Rect opaque_rect) :
    layer_rect_(layer_rect),
    opaque_rect_(opaque_rect),
    picture_(picture) {
}

Picture::~Picture() {
}

scoped_refptr<Picture> Picture::GetCloneForDrawingOnThread(
    unsigned thread_index) const {
  // SkPicture is not thread-safe to rasterize with, this returns a clone
  // to rasterize with on a specific thread.
  CHECK_GT(clones_.size(), thread_index);
  return clones_[thread_index];
}

void Picture::CloneForDrawing(int num_threads) {
  TRACE_EVENT1("cc", "Picture::CloneForDrawing", "num_threads", num_threads);

  DCHECK(picture_);
  scoped_array<SkPicture> clones(new SkPicture[num_threads]);
  picture_->clone(&clones[0], num_threads);

  clones_.clear();
  for (int i = 0; i < num_threads; i++) {
    scoped_refptr<Picture> clone = make_scoped_refptr(
        new Picture(skia::AdoptRef(new SkPicture(clones[i])),
                    layer_rect_,
                    opaque_rect_));
    clones_.push_back(clone);
  }
}

void Picture::Record(ContentLayerClient* painter,
                     RenderingStats* stats,
                     const SkTileGridPicture::TileGridInfo& tile_grid_info) {
  TRACE_EVENT2("cc", "Picture::Record",
               "width", layer_rect_.width(), "height", layer_rect_.height());

  // Record() should only be called once.
  DCHECK(!picture_);
  DCHECK(!tile_grid_info.fTileInterval.isEmpty());
  // TODO(enne): Turn back on tile grid after
  // https://code.google.com/p/skia/issues/detail?id=1209 is fixed.
  picture_ = skia::AdoptRef(new SkPicture());

  SkCanvas* canvas = picture_->beginRecording(
      layer_rect_.width(),
      layer_rect_.height(),
      SkPicture::kUsePathBoundsForClip_RecordingFlag |
      SkPicture::kOptimizeForClippedPlayback_RecordingFlag);

  canvas->save();
  canvas->translate(SkFloatToScalar(-layer_rect_.x()),
                    SkFloatToScalar(-layer_rect_.y()));

  SkPaint paint;
  paint.setAntiAlias(false);
  paint.setXfermodeMode(SkXfermode::kClear_Mode);
  SkRect layer_skrect = SkRect::MakeXYWH(layer_rect_.x(),
                                         layer_rect_.y(),
                                         layer_rect_.width(),
                                         layer_rect_.height());
  canvas->clipRect(layer_skrect);
  canvas->drawRect(layer_skrect, paint);

  gfx::RectF opaque_layer_rect;
  base::TimeTicks begin_paint_time;
  if (stats)
    begin_paint_time = base::TimeTicks::Now();
  painter->PaintContents(canvas, layer_rect_, &opaque_layer_rect);
  if (stats) {
    stats->total_paint_time += base::TimeTicks::Now() - begin_paint_time;
    stats->total_pixels_painted +=
        layer_rect_.width() * layer_rect_.height();
  }

  canvas->restore();
  picture_->endRecording();

  opaque_rect_ = gfx::ToEnclosedRect(opaque_layer_rect);
}

void Picture::Raster(
    SkCanvas* canvas,
    gfx::Rect content_rect,
    float contents_scale,
    bool enable_lcd_text) {
  TRACE_EVENT2("cc", "Picture::Raster",
               "layer width", layer_rect_.width(),
               "layer height", layer_rect_.height());
  DCHECK(picture_);

  DisableLCDTextFilter disable_lcd_text_filter;

  canvas->save();
  canvas->clipRect(gfx::RectToSkRect(content_rect));
  canvas->scale(contents_scale, contents_scale);
  canvas->translate(layer_rect_.x(), layer_rect_.y());
  // Pictures by default have LCD text enabled.
  if (!enable_lcd_text)
    canvas->setDrawFilter(&disable_lcd_text_filter);
  canvas->drawPicture(*picture_);
  canvas->restore();
}

void Picture::GatherPixelRefs(const gfx::Rect& layer_rect,
                              std::list<skia::LazyPixelRef*>& pixel_ref_list) {
  DCHECK(picture_);
  SkData* pixel_refs = SkPictureUtils::GatherPixelRefs(
      picture_.get(), SkRect::MakeXYWH(layer_rect.x(),
                                       layer_rect.y(),
                                       layer_rect.width(),
                                       layer_rect.height()));
  if (!pixel_refs)
    return;

  void* data = const_cast<void*>(pixel_refs->data());
  if (!data) {
    pixel_refs->unref();
    return;
  }

  SkPixelRef** refs = reinterpret_cast<SkPixelRef**>(data);
  for (size_t i = 0; i < pixel_refs->size() / sizeof(*refs); ++i) {
    if (*refs && (*refs)->getURI() && !strncmp(
        (*refs)->getURI(), kLabelLazyDecoded, 4)) {
      pixel_ref_list.push_back(static_cast<skia::LazyPixelRef*>(*refs));
    }
    refs++;
  }
  pixel_refs->unref();
}

}  // namespace cc
<|endoftext|>


<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 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 "random.h"

#include "crypto/sha512.h"
#include "support/cleanse.h"
#ifdef WIN32
#include "compat.h" // for Windows API
#include <wincrypt.h>
#endif
#include "util.h"             // for LogPrint()
#include "utilstrencodings.h" // for GetTime()

#include <stdlib.h>
#include <limits>

#ifndef WIN32
#include <sys/time.h>
#endif

#ifdef HAVE_SYS_GETRANDOM
#include <sys/syscall.h>
#include <linux/random.h>
#endif
#ifdef HAVE_GETENTROPY
#include <unistd.h>
#endif
#ifdef HAVE_SYSCTL_ARND
#include <sys/sysctl.h>
#endif

#include <openssl/err.h>
#include <openssl/rand.h>

static void RandFailure()
{
    LogPrintf("Failed to read randomness, aborting\n");
    abort();
}

static inline int64_t GetPerformanceCounter()
{
    int64_t nCounter = 0;
#ifdef WIN32
    QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
#else
    timeval t;
    gettimeofday(&t, NULL);
    nCounter = (int64_t)(t.tv_sec * 1000000 + t.tv_usec);
#endif
    return nCounter;
}

void RandAddSeed()
{
    // Seed with CPU performance counter
    int64_t nCounter = GetPerformanceCounter();
    RAND_add(&nCounter, sizeof(nCounter), 1.5);
    memory_cleanse((void*)&nCounter, sizeof(nCounter));
}

static void RandAddSeedPerfmon()
{
    RandAddSeed();

#ifdef WIN32
    // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
    // Seed with the entire set of perfmon data

    // This can take up to 2 seconds, so only do it every 10 minutes
    static int64_t nLastPerfmon;
    if (GetTime() < nLastPerfmon + 10 * 60)
        return;
    nLastPerfmon = GetTime();

    std::vector<unsigned char> vData(250000, 0);
    long ret = 0;
    unsigned long nSize = 0;
    const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
    while (true) {
        nSize = vData.size();
        ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, vData.data(), &nSize);
        if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
            break;
        vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially
    }
    RegCloseKey(HKEY_PERFORMANCE_DATA);
    if (ret == ERROR_SUCCESS) {
        RAND_add(vData.data(), nSize, nSize / 100.0);
        memory_cleanse(vData.data(), nSize);
        LogPrint("rand", "%s: %lu bytes\n", __func__, nSize);
    } else {
        static bool warned = false; // Warn only once
        if (!warned) {
            LogPrintf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret);
            warned = true;
        }
    }
#endif
}

#ifndef WIN32
/** Fallback: get 32 bytes of system entropy from /dev/urandom. The most
 * compatible way to get cryptographic randomness on UNIX-ish platforms.
 */
void GetDevURandom(unsigned char *ent32)
{
    int f = open("/dev/urandom", O_RDONLY);
    if (f == -1) {
        RandFailure();
    }
    int have = 0;
    do {
        ssize_t n = read(f, ent32 + have, NUM_OS_RANDOM_BYTES - have);
        if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) {
            RandFailure();
        }
        have += n;
    } while (have < NUM_OS_RANDOM_BYTES);
    close(f);
}
#endif

/** Get 32 bytes of system entropy. */
void GetOSRand(unsigned char *ent32)
{
#if defined(WIN32)
    HCRYPTPROV hProvider;
    int ret = CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
    if (!ret) {
        RandFailure();
    }
    ret = CryptGenRandom(hProvider, NUM_OS_RANDOM_BYTES, ent32);
    if (!ret) {
        RandFailure();
    }
    CryptReleaseContext(hProvider, 0);
#elif defined(HAVE_SYS_GETRANDOM)
    /* Linux. From the getrandom(2) man page:
     * "If the urandom source has been initialized, reads of up to 256 bytes
     * will always return as many bytes as requested and will not be
     * interrupted by signals."
     */
    int rv = syscall(SYS_getrandom, ent32, NUM_OS_RANDOM_BYTES, 0);
    if (rv != NUM_OS_RANDOM_BYTES) {
        if (rv < 0 && errno == ENOSYS) {
            /* Fallback for kernel <3.17: the return value will be -1 and errno
             * ENOSYS if the syscall is not available, in that case fall back
             * to /dev/urandom.
             */
            GetDevURandom(ent32);
        } else {
            RandFailure();
        }
    }
#elif defined(HAVE_GETENTROPY)
    /* On OpenBSD this can return up to 256 bytes of entropy, will return an
     * error if more are requested.
     * The call cannot return less than the requested number of bytes.
     */
    if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
        RandFailure();
    }
#elif defined(HAVE_SYSCTL_ARND)
    /* FreeBSD and similar. It is possible for the call to return less
     * bytes than requested, so need to read in a loop.
     */
    static const int name[2] = {CTL_KERN, KERN_ARND};
    int have = 0;
    do {
        size_t len = NUM_OS_RANDOM_BYTES - have;
        if (sysctl(name, ARRAYLEN(name), ent32 + have, &len, NULL, 0) != 0) {
            RandFailure();
        }
        have += len;
    } while (have < NUM_OS_RANDOM_BYTES);
#else
    /* Fall back to /dev/urandom if there is no specific method implemented to
     * get system entropy for this OS.
     */
    GetDevURandom(ent32);
#endif
}

void GetRandBytes(unsigned char* buf, int num)
{
    if (RAND_bytes(buf, num) != 1) {
        RandFailure();
    }
}

void GetStrongRandBytes(unsigned char* out, int num)
{
    assert(num <= 32);
    CSHA512 hasher;
    unsigned char buf[64];

    // First source: OpenSSL's RNG
    RandAddSeedPerfmon();
    GetRandBytes(buf, 32);
    hasher.Write(buf, 32);

    // Second source: OS RNG
    GetOSRand(buf);
    hasher.Write(buf, 32);

    // Produce output
    hasher.Finalize(buf);
    memcpy(out, buf, num);
    memory_cleanse(buf, 64);
}

uint64_t GetRand(uint64_t nMax)
{
    if (nMax == 0)
        return 0;

    // The range of the random source must be a multiple of the modulus
    // to give every possible output value an equal possibility
    uint64_t nRange = (std::numeric_limits<uint64_t>::max() / nMax) * nMax;
    uint64_t nRand = 0;
    do {
        GetRandBytes((unsigned char*)&nRand, sizeof(nRand));
    } while (nRand >= nRange);
    return (nRand % nMax);
}

int GetRandInt(int nMax)
{
    return GetRand(nMax);
}

uint256 GetRandHash()
{
    uint256 hash;
    GetRandBytes((unsigned char*)&hash, sizeof(hash));
    return hash;
}

uint32_t insecure_rand_Rz = 11;
uint32_t insecure_rand_Rw = 11;
void seed_insecure_rand(bool fDeterministic)
{
    // The seed values have some unlikely fixed points which we avoid.
    if (fDeterministic) {
        insecure_rand_Rz = insecure_rand_Rw = 11;
    } else {
        uint32_t tmp;
        do {
            GetRandBytes((unsigned char*)&tmp, 4);
        } while (tmp == 0 || tmp == 0x9068ffffU);
        insecure_rand_Rz = tmp;
        do {
            GetRandBytes((unsigned char*)&tmp, 4);
        } while (tmp == 0 || tmp == 0x464fffffU);
        insecure_rand_Rw = tmp;
    }
}

bool Random_SanityCheck()
{
    /* This does not measure the quality of randomness, but it does test that
     * OSRandom() overwrites all 32 bytes of the output given a maximum
     * number of tries.
     */
    static const ssize_t MAX_TRIES = 1024;
    uint8_t data[NUM_OS_RANDOM_BYTES];
    bool overwritten[NUM_OS_RANDOM_BYTES] = {}; /* Tracks which bytes have been overwritten at least once */
    int num_overwritten;
    int tries = 0;
    /* Loop until all bytes have been overwritten at least once, or max number tries reached */
    do {
        memset(data, 0, NUM_OS_RANDOM_BYTES);
        GetOSRand(data);
        for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
            overwritten[x] |= (data[x] != 0);
        }

        num_overwritten = 0;
        for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
            if (overwritten[x]) {
                num_overwritten += 1;
            }
        }

        tries += 1;
    } while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES);
    return (num_overwritten == NUM_OS_RANDOM_BYTES); /* If this failed, bailed out after too many tries */
}
<commit_msg>Maintain state across GetStrongRandBytes calls<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 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 "random.h"

#include "crypto/sha512.h"
#include "support/cleanse.h"
#ifdef WIN32
#include "compat.h" // for Windows API
#include <wincrypt.h>
#endif
#include "util.h"             // for LogPrint()
#include "utilstrencodings.h" // for GetTime()

#include <stdlib.h>
#include <limits>

#ifndef WIN32
#include <sys/time.h>
#endif

#ifdef HAVE_SYS_GETRANDOM
#include <sys/syscall.h>
#include <linux/random.h>
#endif
#ifdef HAVE_GETENTROPY
#include <unistd.h>
#endif
#ifdef HAVE_SYSCTL_ARND
#include <sys/sysctl.h>
#endif

#include <mutex>

#include <openssl/err.h>
#include <openssl/rand.h>

static void RandFailure()
{
    LogPrintf("Failed to read randomness, aborting\n");
    abort();
}

static inline int64_t GetPerformanceCounter()
{
    int64_t nCounter = 0;
#ifdef WIN32
    QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
#else
    timeval t;
    gettimeofday(&t, NULL);
    nCounter = (int64_t)(t.tv_sec * 1000000 + t.tv_usec);
#endif
    return nCounter;
}

void RandAddSeed()
{
    // Seed with CPU performance counter
    int64_t nCounter = GetPerformanceCounter();
    RAND_add(&nCounter, sizeof(nCounter), 1.5);
    memory_cleanse((void*)&nCounter, sizeof(nCounter));
}

static void RandAddSeedPerfmon()
{
    RandAddSeed();

#ifdef WIN32
    // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
    // Seed with the entire set of perfmon data

    // This can take up to 2 seconds, so only do it every 10 minutes
    static int64_t nLastPerfmon;
    if (GetTime() < nLastPerfmon + 10 * 60)
        return;
    nLastPerfmon = GetTime();

    std::vector<unsigned char> vData(250000, 0);
    long ret = 0;
    unsigned long nSize = 0;
    const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
    while (true) {
        nSize = vData.size();
        ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, vData.data(), &nSize);
        if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
            break;
        vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially
    }
    RegCloseKey(HKEY_PERFORMANCE_DATA);
    if (ret == ERROR_SUCCESS) {
        RAND_add(vData.data(), nSize, nSize / 100.0);
        memory_cleanse(vData.data(), nSize);
        LogPrint("rand", "%s: %lu bytes\n", __func__, nSize);
    } else {
        static bool warned = false; // Warn only once
        if (!warned) {
            LogPrintf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret);
            warned = true;
        }
    }
#endif
}

#ifndef WIN32
/** Fallback: get 32 bytes of system entropy from /dev/urandom. The most
 * compatible way to get cryptographic randomness on UNIX-ish platforms.
 */
void GetDevURandom(unsigned char *ent32)
{
    int f = open("/dev/urandom", O_RDONLY);
    if (f == -1) {
        RandFailure();
    }
    int have = 0;
    do {
        ssize_t n = read(f, ent32 + have, NUM_OS_RANDOM_BYTES - have);
        if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) {
            RandFailure();
        }
        have += n;
    } while (have < NUM_OS_RANDOM_BYTES);
    close(f);
}
#endif

/** Get 32 bytes of system entropy. */
void GetOSRand(unsigned char *ent32)
{
#if defined(WIN32)
    HCRYPTPROV hProvider;
    int ret = CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
    if (!ret) {
        RandFailure();
    }
    ret = CryptGenRandom(hProvider, NUM_OS_RANDOM_BYTES, ent32);
    if (!ret) {
        RandFailure();
    }
    CryptReleaseContext(hProvider, 0);
#elif defined(HAVE_SYS_GETRANDOM)
    /* Linux. From the getrandom(2) man page:
     * "If the urandom source has been initialized, reads of up to 256 bytes
     * will always return as many bytes as requested and will not be
     * interrupted by signals."
     */
    int rv = syscall(SYS_getrandom, ent32, NUM_OS_RANDOM_BYTES, 0);
    if (rv != NUM_OS_RANDOM_BYTES) {
        if (rv < 0 && errno == ENOSYS) {
            /* Fallback for kernel <3.17: the return value will be -1 and errno
             * ENOSYS if the syscall is not available, in that case fall back
             * to /dev/urandom.
             */
            GetDevURandom(ent32);
        } else {
            RandFailure();
        }
    }
#elif defined(HAVE_GETENTROPY)
    /* On OpenBSD this can return up to 256 bytes of entropy, will return an
     * error if more are requested.
     * The call cannot return less than the requested number of bytes.
     */
    if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
        RandFailure();
    }
#elif defined(HAVE_SYSCTL_ARND)
    /* FreeBSD and similar. It is possible for the call to return less
     * bytes than requested, so need to read in a loop.
     */
    static const int name[2] = {CTL_KERN, KERN_ARND};
    int have = 0;
    do {
        size_t len = NUM_OS_RANDOM_BYTES - have;
        if (sysctl(name, ARRAYLEN(name), ent32 + have, &len, NULL, 0) != 0) {
            RandFailure();
        }
        have += len;
    } while (have < NUM_OS_RANDOM_BYTES);
#else
    /* Fall back to /dev/urandom if there is no specific method implemented to
     * get system entropy for this OS.
     */
    GetDevURandom(ent32);
#endif
}

void GetRandBytes(unsigned char* buf, int num)
{
    if (RAND_bytes(buf, num) != 1) {
        RandFailure();
    }
}

static std::mutex cs_rng_state;
static unsigned char rng_state[32] = {0};
static uint64_t rng_counter = 0;

void GetStrongRandBytes(unsigned char* out, int num)
{
    assert(num <= 32);
    CSHA512 hasher;
    unsigned char buf[64];

    // First source: OpenSSL's RNG
    RandAddSeedPerfmon();
    GetRandBytes(buf, 32);
    hasher.Write(buf, 32);

    // Second source: OS RNG
    GetOSRand(buf);
    hasher.Write(buf, 32);

    // Combine with and update state
    {
        std::unique_lock<std::mutex> lock(cs_rng_state);
        hasher.Write(rng_state, sizeof(rng_state));
        hasher.Write((const unsigned char*)&rng_counter, sizeof(rng_counter));
        ++rng_counter;
        hasher.Finalize(buf);
        memcpy(rng_state, buf + 32, 32);
    }

    // Produce output
    memcpy(out, buf, num);
    memory_cleanse(buf, 64);
}

uint64_t GetRand(uint64_t nMax)
{
    if (nMax == 0)
        return 0;

    // The range of the random source must be a multiple of the modulus
    // to give every possible output value an equal possibility
    uint64_t nRange = (std::numeric_limits<uint64_t>::max() / nMax) * nMax;
    uint64_t nRand = 0;
    do {
        GetRandBytes((unsigned char*)&nRand, sizeof(nRand));
    } while (nRand >= nRange);
    return (nRand % nMax);
}

int GetRandInt(int nMax)
{
    return GetRand(nMax);
}

uint256 GetRandHash()
{
    uint256 hash;
    GetRandBytes((unsigned char*)&hash, sizeof(hash));
    return hash;
}

uint32_t insecure_rand_Rz = 11;
uint32_t insecure_rand_Rw = 11;
void seed_insecure_rand(bool fDeterministic)
{
    // The seed values have some unlikely fixed points which we avoid.
    if (fDeterministic) {
        insecure_rand_Rz = insecure_rand_Rw = 11;
    } else {
        uint32_t tmp;
        do {
            GetRandBytes((unsigned char*)&tmp, 4);
        } while (tmp == 0 || tmp == 0x9068ffffU);
        insecure_rand_Rz = tmp;
        do {
            GetRandBytes((unsigned char*)&tmp, 4);
        } while (tmp == 0 || tmp == 0x464fffffU);
        insecure_rand_Rw = tmp;
    }
}

bool Random_SanityCheck()
{
    /* This does not measure the quality of randomness, but it does test that
     * OSRandom() overwrites all 32 bytes of the output given a maximum
     * number of tries.
     */
    static const ssize_t MAX_TRIES = 1024;
    uint8_t data[NUM_OS_RANDOM_BYTES];
    bool overwritten[NUM_OS_RANDOM_BYTES] = {}; /* Tracks which bytes have been overwritten at least once */
    int num_overwritten;
    int tries = 0;
    /* Loop until all bytes have been overwritten at least once, or max number tries reached */
    do {
        memset(data, 0, NUM_OS_RANDOM_BYTES);
        GetOSRand(data);
        for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
            overwritten[x] |= (data[x] != 0);
        }

        num_overwritten = 0;
        for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
            if (overwritten[x]) {
                num_overwritten += 1;
            }
        }

        tries += 1;
    } while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES);
    return (num_overwritten == NUM_OS_RANDOM_BYTES); /* If this failed, bailed out after too many tries */
}
<|endoftext|>


<commit_before>#include "mswin.h"
#include "random.h"
#include "compiler.h"

// The xorshift family of PRNGs was introduced in [1].
// This particular generator, "xorshift64* A_1(12; 25; 27).M_32", is suggested in [2].

// [1] George Marsaglia (2003) http://www.jstatsoft.org/article/view/v008i14/xorshift.pdf
// [2] Sebastiano Vigna (2014) http://arxiv.org/abs/1402.6246

void rng_t::initialize (std::uint64_t seed)
{
  state = 4101842887655102017ull;
  state ^= seed;
  state = get ();
}

NOINLINE
std::uint64_t rng_t::get ()
{
  state ^= state >> 12;
  state ^= state << 25;
  state ^= state >> 27;
  return state * 2685821657736338717ull;
}

#include "random-util.h"

  // 18480	  12580	    224	  31284	   7a34	.obj/x64/tiny/polymorph.exe
  // 19264	  11464	    104	  30832	   7870	.obj/x86/tiny/polymorph.exe

  // 18464	  12580	    224	  31268	   7a24	.obj/x64/tiny/polymorph.exe
  // 19248	  11464	    104	  30816	   7860	.obj/x86/tiny/polymorph.exe

  // 18448	  12580	    224	  31252	   7a14	.obj/x64/tiny/polymorph.exe
  // 19236	  11464	    104	  30804	   7854	.obj/x86/tiny/polymorph.exe

// Random floating-point number uniformly distributed on the interval [a, b).
float get_float (rng_t & rng, float a, float b)
{
  return a + 0x1.000000P-064f * (b - a) * rng.get ();
}

// Return a random vector uniformly distributed in
// the interior of a sphere centre the origin.
v4f get_vector_in_ball (rng_t & rng, float radius)
{
  union {
    __m128i i128;
    std::uint64_t u64 [2];
  };
  v4f v, vsq;
  v4f lim = { 0x1.000000P+062f, 0.0f, 0.0f, 0.0f, };
  do {
    u64 [0] = rng.get ();
    u64 [1] = rng.get () & 0xffffffff;
    v = _mm_cvtepi32_ps (i128);
    vsq = dot (v, v);
  }
  while (_mm_comige_ss (vsq, lim));
  return _mm_set1_ps (0x1.000000P-31f * radius) * v;
}

// Return a random vector uniformly distributed in
// the box [0,1)^3.
v4f get_vector_in_box (rng_t & rng)
{
  union {
    __m128i i128;
    std::uint64_t u64 [2];
  };
  u64 [0] = rng.get () & 0x7fffffff7fffffff;
  u64 [1] = rng.get () & 0x7fffffff;
  v4f v = _mm_cvtepi32_ps (i128);
  return _mm_set1_ps (0x1.000000P-031f) * v;
}
<commit_msg>random.cpp: remove commented-out rough work<commit_after>#include "mswin.h"
#include "random.h"
#include "compiler.h"

// The xorshift family of PRNGs was introduced in [1].
// This particular generator, "xorshift64* A_1(12; 25; 27).M_32", is suggested in [2].

// [1] George Marsaglia (2003) http://www.jstatsoft.org/article/view/v008i14/xorshift.pdf
// [2] Sebastiano Vigna (2014) http://arxiv.org/abs/1402.6246

void rng_t::initialize (std::uint64_t seed)
{
  state = 4101842887655102017ull;
  state ^= seed;
  state = get ();
}

NOINLINE
std::uint64_t rng_t::get ()
{
  state ^= state >> 12;
  state ^= state << 25;
  state ^= state >> 27;
  return state * 2685821657736338717ull;
}

#include "random-util.h"

// Random floating-point number uniformly distributed on the interval [a, b).
float get_float (rng_t & rng, float a, float b)
{
  return a + 0x1.000000P-064f * (b - a) * rng.get ();
}

// Return a random vector uniformly distributed in
// the interior of a sphere centre the origin.
v4f get_vector_in_ball (rng_t & rng, float radius)
{
  union {
    __m128i i128;
    std::uint64_t u64 [2];
  };
  v4f v, vsq;
  v4f lim = { 0x1.000000P+062f, 0.0f, 0.0f, 0.0f, };
  do {
    u64 [0] = rng.get ();
    u64 [1] = rng.get () & 0xffffffff;
    v = _mm_cvtepi32_ps (i128);
    vsq = dot (v, v);
  }
  while (_mm_comige_ss (vsq, lim));
  return _mm_set1_ps (0x1.000000P-31f * radius) * v;
}

// Return a random vector uniformly distributed in
// the box [0,1)^3.
v4f get_vector_in_box (rng_t & rng)
{
  union {
    __m128i i128;
    std::uint64_t u64 [2];
  };
  u64 [0] = rng.get () & 0x7fffffff7fffffff;
  u64 [1] = rng.get () & 0x7fffffff;
  v4f v = _mm_cvtepi32_ps (i128);
  return _mm_set1_ps (0x1.000000P-031f) * v;
}
<|endoftext|>


<commit_before>/*************************************************
* Shanks-Tonnelli (RESSOL) Source File           *
* (C) 2007-2008 Falko Strenzke, FlexSecure GmbH  *
* (C) 2008 Jack Lloyd                            *
*************************************************/

#include <botan/numthry.h>
#include <botan/reducer.h>

#include <iostream>

namespace Botan {

/*************************************************
* Shanks-Tonnelli algorithm                      *
*************************************************/
BigInt ressol(const BigInt& a, const BigInt& p)
   {
   if(a < 0)
      throw Invalid_Argument("ressol(): a to solve for must be positive");
   if(p <= 1)
      throw Invalid_Argument("ressol(): prime must be > 1");

   if(a == 0)
      return 0;
   if(p == 2)
      return a;

   if(jacobi(a, p) != 1) // not a quadratic residue
      return -1;

   if(p % 4 == 3)
      return power_mod(a, ((p+1) >> 2), p);

   u32bit s = low_zero_bits(p - 1);
   BigInt q = p >> s;

   q -= 1;
   q >>= 1;

   Modular_Reducer mod_p(p);

   BigInt r = power_mod(a, q, p);
   BigInt n = mod_p.multiply(a, mod_p.square(r));
   r = mod_p.multiply(r, a);

   if(n == 1)
      return r;

   // find random non quadratic residue z
   BigInt z = 2;
   while(jacobi(z, p) == 1) // while z quadratic residue
      ++z;

   BigInt c = power_mod(z, (q << 1) + 1, p);

   while(n > 1)
      {
      q = n;

      u32bit i = 0;
      while(q != 1)
         {
         q = mod_p.square(q);
         ++i;
         }
      u32bit t = s;

      if(t <= i)
         return -1;

      c = power_mod(c, BigInt(BigInt::Power2, t-i-1), p);
      r = mod_p.multiply(r, c);
      c = mod_p.square(c);
      n = mod_p.multiply(n, c);
      s = i;
      }

   return r;
   }

}
<commit_msg>Fix return values for ressol(), saying BigInt x = -1 does something unexpected (see ticket #23, http://bugs.randombit.net/show_bug.cgi?id=23)<commit_after>/*************************************************
* Shanks-Tonnelli (RESSOL) Source File           *
* (C) 2007-2008 Falko Strenzke, FlexSecure GmbH  *
* (C) 2008 Jack Lloyd                            *
*************************************************/

#include <botan/numthry.h>
#include <botan/reducer.h>

#include <iostream>

namespace Botan {

/*************************************************
* Shanks-Tonnelli algorithm                      *
*************************************************/
BigInt ressol(const BigInt& a, const BigInt& p)
   {
   if(a < 0)
      throw Invalid_Argument("ressol(): a to solve for must be positive");
   if(p <= 1)
      throw Invalid_Argument("ressol(): prime must be > 1");

   if(a == 0)
      return 0;
   if(p == 2)
      return a;

   if(jacobi(a, p) != 1) // not a quadratic residue
      return BigInt("-1");

   if(p % 4 == 3)
      return power_mod(a, ((p+1) >> 2), p);

   u32bit s = low_zero_bits(p - 1);
   BigInt q = p >> s;

   q -= 1;
   q >>= 1;

   Modular_Reducer mod_p(p);

   BigInt r = power_mod(a, q, p);
   BigInt n = mod_p.multiply(a, mod_p.square(r));
   r = mod_p.multiply(r, a);

   if(n == 1)
      return r;

   // find random non quadratic residue z
   BigInt z = 2;
   while(jacobi(z, p) == 1) // while z quadratic residue
      ++z;

   BigInt c = power_mod(z, (q << 1) + 1, p);

   while(n > 1)
      {
      q = n;

      u32bit i = 0;
      while(q != 1)
         {
         q = mod_p.square(q);
         ++i;
         }
      u32bit t = s;

      if(t <= i)
         return BigInt("-1");

      c = power_mod(c, BigInt(BigInt::Power2, t-i-1), p);
      r = mod_p.multiply(r, c);
      c = mod_p.square(c);
      n = mod_p.multiply(n, c);
      s = i;
      }

   return r;
   }

}
<|endoftext|>


<commit_before>#include <node.h>
#include <nan.h>
#include <v8.h>
#include <vector>
#include "mouse.h"
#include "deadbeef_rand.h"
#include "keypress.h"
#include "screen.h"
#include "screengrab.h"
#include "MMBitmap.h"

using namespace v8;

/*
 __  __
|  \/  | ___  _   _ ___  ___
| |\/| |/ _ \| | | / __|/ _ \
| |  | | (_) | |_| \__ \  __/
|_|  |_|\___/ \__,_|___/\___|

*/

NAN_METHOD(moveMouse)
{
	NanScope();
	if (args.Length() < 2)
	{
		return NanThrowError("Invalid number of arguments.");
	}
	size_t x = args[0]->Int32Value();
	size_t y = args[1]->Int32Value();

	MMPoint point;
	point = MMPointMake(x, y);
	moveMouse(point);
	NanReturnValue(NanNew("1"));
}

NAN_METHOD(moveMouseSmooth)
{
	NanScope();
	if (args.Length() < 2)
	{
		return NanThrowError("Invalid number of arguments.");
	}
	size_t x = args[0]->Int32Value();
	size_t y = args[1]->Int32Value();

	MMPoint point;
	point = MMPointMake(x, y);
	smoothlyMoveMouse(point);
	NanReturnValue(NanNew("1"));
}

NAN_METHOD(getMousePos)
{
	NanScope();

	MMPoint pos = getMousePos();

 	//Return object with .x and .y.
	Local<Object> obj = NanNew<Object>();
	obj->Set(NanNew<String>("x"), NanNew<Number>(pos.x));
	obj->Set(NanNew<String>("y"), NanNew<Number>(pos.y));
	NanReturnValue(obj);
}

NAN_METHOD(mouseClick)
{
	NanScope();

	MMMouseButton button = LEFT_BUTTON;

	if (args.Length() == 1)
	{
		char *b = (*v8::String::Utf8Value(args[0]->ToString()));

		if (strcmp(b, "left") == 0)
		{
			button = LEFT_BUTTON;
		}
		else if (strcmp(b, "right") == 0)
		{
			button = RIGHT_BUTTON;
		}
		else if (strcmp(b, "middle") == 0)
		{
			button = CENTER_BUTTON;
		}
		else
		{
			return NanThrowError("Invalid mouse button specified.");
		}
	}
	else if (args.Length() > 1)
	{
		return NanThrowError("Invalid number of arguments.");
	}

	clickMouse(button);

	NanReturnValue(NanNew("1"));
}

NAN_METHOD(mouseToggle)
{
	NanScope();

	MMMouseButton button = LEFT_BUTTON;
	bool down;

	if (args.Length() > 0)
	{
		const char *d = (*v8::String::Utf8Value(args[0]->ToString()));

		if (strcmp(d, "down") == 0)
		{
			down = true;;
		}
		else if (strcmp(d, "up") == 0)
		{
			down = false;
		}
		else
		{
			return NanThrowError("Invalid mouse button state specified.");
		}
	}

	if (args.Length() == 2)
	{
		char *b = (*v8::String::Utf8Value(args[1]->ToString()));

		if (strcmp(b, "left") == 0)
		{
			button = LEFT_BUTTON;
		}
		else if (strcmp(b, "right") == 0)
		{
			button = RIGHT_BUTTON;
		}
		else if (strcmp(b, "middle") == 0)
		{
			button = CENTER_BUTTON;
		}
		else
		{
			return NanThrowError("Invalid mouse button specified.");
		}
	}
	else if (args.Length() > 2)
	{
		return NanThrowError("Invalid number of arguments.");
	}

	toggleMouse(down, button);

	NanReturnValue(NanNew("1"));
}

/*
 _  __          _                         _
| |/ /___ _   _| |__   ___   __ _ _ __ __| |
| ' // _ \ | | | '_ \ / _ \ / _` | '__/ _` |
| . \  __/ |_| | |_) | (_) | (_| | | | (_| |
|_|\_\___|\__, |_.__/ \___/ \__,_|_|  \__,_|
          |___/
*/

NAN_METHOD(keyTap)
{
	NanScope();

	if (args.Length() != 1)
	{
		return NanThrowError("Invalid number of arguments.");
	}

	MMKeyFlags flags = MOD_NONE;
	MMKeyCode key;

	char *k = (*v8::String::Utf8Value(args[0]->ToString()));

	//There's a better way to do this, I just want to get it working.
	if (strcmp(k, "backspace") == 0)
	{
		key = K_BACKSPACE;
	}
	else if (strcmp(k, "enter") == 0)
	{
		key = K_RETURN;
	}
	else if (strcmp(k, "tab") == 0)
	{
		key = K_TAB;
	}
	else if (strcmp(k, "up") == 0)
	{
		key = K_UP;
	}
	else if (strcmp(k, "down") == 0)
	{
		key = K_DOWN;
	}
	else if (strcmp(k, "left") == 0)
	{
		key = K_LEFT;
	}
	else if (strcmp(k, "right") == 0)
	{
		key = K_RIGHT;
	}
	else if (strcmp(k, "escape") == 0)
	{
		key = K_ESCAPE;
	}
	else if (strcmp(k, "delete") == 0)
	{
		key = K_DELETE;
	}
	else if (strcmp(k, "home") == 0)
	{
		key = K_HOME;
	}
	else if (strcmp(k, "end") == 0)
	{
		key = K_END;
	}
	else if (strcmp(k, "pageup") == 0)
	{
		key = K_PAGEUP;
	}
	else if (strcmp(k, "pagedown") == 0)
	{
		key = K_PAGEDOWN;
	}
	else
	{
		return NanThrowError("Invalid key specified.");
	}

	tapKeyCode(key, flags);

	NanReturnValue(NanNew("1"));
}

NAN_METHOD(typeString)
{
	NanScope();

	char *str;
	NanUtf8String string(args[0]);

	str = *string;

	typeString(str);

	NanReturnValue(NanNew("1"));
}

/*
  ____
 / ___|  ___ _ __ ___  ___ _ __
 \___ \ / __| '__/ _ \/ _ \ '_ \
  ___) | (__| | |  __/  __/ | | |
 |____/ \___|_|  \___|\___|_| |_|

*/

NAN_METHOD(getPixelColor)
{
	NanScope();

	MMBitmapRef bitmap;
	MMRGBHex color;

	size_t x = args[0]->Int32Value();
	size_t y = args[1]->Int32Value();

	bitmap = copyMMBitmapFromDisplayInRect(MMRectMake(x, y, 1, 1));

	color = MMRGBHexAtPoint(bitmap, 0, 0);

	char hex [6];

	//Length needs to be 7 because snprintf includes a terminating null.
	//Use %06x to pad hex value with leading 0s.
	snprintf(hex, 7, "%06x", color);

	destroyMMBitmap(bitmap);

	NanReturnValue(NanNew(hex));
}

void init(Handle<Object> target)
{

	target->Set(NanNew<String>("moveMouse"),
		NanNew<FunctionTemplate>(moveMouse)->GetFunction());

	target->Set(NanNew<String>("moveMouseSmooth"),
		NanNew<FunctionTemplate>(moveMouseSmooth)->GetFunction());

	target->Set(NanNew<String>("getMousePos"),
		NanNew<FunctionTemplate>(getMousePos)->GetFunction());

	target->Set(NanNew<String>("mouseClick"),
		NanNew<FunctionTemplate>(mouseClick)->GetFunction());

	target->Set(NanNew<String>("mouseToggle"),
		NanNew<FunctionTemplate>(mouseToggle)->GetFunction());

	target->Set(NanNew<String>("keyTap"),
		NanNew<FunctionTemplate>(keyTap)->GetFunction());

	target->Set(NanNew<String>("typeString"),
		NanNew<FunctionTemplate>(typeString)->GetFunction());

	target->Set(NanNew<String>("getPixelColor"),
		NanNew<FunctionTemplate>(getPixelColor)->GetFunction());

}

NODE_MODULE(robotjs, init)
<commit_msg>Added getScreenSize, closes #25.<commit_after>#include <node.h>
#include <nan.h>
#include <v8.h>
#include <vector>
#include "mouse.h"
#include "deadbeef_rand.h"
#include "keypress.h"
#include "screen.h"
#include "screengrab.h"
#include "MMBitmap.h"

using namespace v8;

/*
 __  __
|  \/  | ___  _   _ ___  ___
| |\/| |/ _ \| | | / __|/ _ \
| |  | | (_) | |_| \__ \  __/
|_|  |_|\___/ \__,_|___/\___|

*/

NAN_METHOD(moveMouse)
{
	NanScope();
	if (args.Length() < 2)
	{
		return NanThrowError("Invalid number of arguments.");
	}
	size_t x = args[0]->Int32Value();
	size_t y = args[1]->Int32Value();

	MMPoint point;
	point = MMPointMake(x, y);
	moveMouse(point);
	NanReturnValue(NanNew("1"));
}

NAN_METHOD(moveMouseSmooth)
{
	NanScope();
	if (args.Length() < 2)
	{
		return NanThrowError("Invalid number of arguments.");
	}
	size_t x = args[0]->Int32Value();
	size_t y = args[1]->Int32Value();

	MMPoint point;
	point = MMPointMake(x, y);
	smoothlyMoveMouse(point);
	NanReturnValue(NanNew("1"));
}

NAN_METHOD(getMousePos)
{
	NanScope();

	MMPoint pos = getMousePos();

 	//Return object with .x and .y.
	Local<Object> obj = NanNew<Object>();
	obj->Set(NanNew<String>("x"), NanNew<Number>(pos.x));
	obj->Set(NanNew<String>("y"), NanNew<Number>(pos.y));
	NanReturnValue(obj);
}

NAN_METHOD(mouseClick)
{
	NanScope();

	MMMouseButton button = LEFT_BUTTON;

	if (args.Length() == 1)
	{
		char *b = (*v8::String::Utf8Value(args[0]->ToString()));

		if (strcmp(b, "left") == 0)
		{
			button = LEFT_BUTTON;
		}
		else if (strcmp(b, "right") == 0)
		{
			button = RIGHT_BUTTON;
		}
		else if (strcmp(b, "middle") == 0)
		{
			button = CENTER_BUTTON;
		}
		else
		{
			return NanThrowError("Invalid mouse button specified.");
		}
	}
	else if (args.Length() > 1)
	{
		return NanThrowError("Invalid number of arguments.");
	}

	clickMouse(button);

	NanReturnValue(NanNew("1"));
}

NAN_METHOD(mouseToggle)
{
	NanScope();

	MMMouseButton button = LEFT_BUTTON;
	bool down;

	if (args.Length() > 0)
	{
		const char *d = (*v8::String::Utf8Value(args[0]->ToString()));

		if (strcmp(d, "down") == 0)
		{
			down = true;;
		}
		else if (strcmp(d, "up") == 0)
		{
			down = false;
		}
		else
		{
			return NanThrowError("Invalid mouse button state specified.");
		}
	}

	if (args.Length() == 2)
	{
		char *b = (*v8::String::Utf8Value(args[1]->ToString()));

		if (strcmp(b, "left") == 0)
		{
			button = LEFT_BUTTON;
		}
		else if (strcmp(b, "right") == 0)
		{
			button = RIGHT_BUTTON;
		}
		else if (strcmp(b, "middle") == 0)
		{
			button = CENTER_BUTTON;
		}
		else
		{
			return NanThrowError("Invalid mouse button specified.");
		}
	}
	else if (args.Length() > 2)
	{
		return NanThrowError("Invalid number of arguments.");
	}

	toggleMouse(down, button);

	NanReturnValue(NanNew("1"));
}

/*
 _  __          _                         _
| |/ /___ _   _| |__   ___   __ _ _ __ __| |
| ' // _ \ | | | '_ \ / _ \ / _` | '__/ _` |
| . \  __/ |_| | |_) | (_) | (_| | | | (_| |
|_|\_\___|\__, |_.__/ \___/ \__,_|_|  \__,_|
          |___/
*/

NAN_METHOD(keyTap)
{
	NanScope();

	if (args.Length() != 1)
	{
		return NanThrowError("Invalid number of arguments.");
	}

	MMKeyFlags flags = MOD_NONE;
	MMKeyCode key;

	char *k = (*v8::String::Utf8Value(args[0]->ToString()));

	//There's a better way to do this, I just want to get it working.
	if (strcmp(k, "backspace") == 0)
	{
		key = K_BACKSPACE;
	}
	else if (strcmp(k, "enter") == 0)
	{
		key = K_RETURN;
	}
	else if (strcmp(k, "tab") == 0)
	{
		key = K_TAB;
	}
	else if (strcmp(k, "up") == 0)
	{
		key = K_UP;
	}
	else if (strcmp(k, "down") == 0)
	{
		key = K_DOWN;
	}
	else if (strcmp(k, "left") == 0)
	{
		key = K_LEFT;
	}
	else if (strcmp(k, "right") == 0)
	{
		key = K_RIGHT;
	}
	else if (strcmp(k, "escape") == 0)
	{
		key = K_ESCAPE;
	}
	else if (strcmp(k, "delete") == 0)
	{
		key = K_DELETE;
	}
	else if (strcmp(k, "home") == 0)
	{
		key = K_HOME;
	}
	else if (strcmp(k, "end") == 0)
	{
		key = K_END;
	}
	else if (strcmp(k, "pageup") == 0)
	{
		key = K_PAGEUP;
	}
	else if (strcmp(k, "pagedown") == 0)
	{
		key = K_PAGEDOWN;
	}
	else
	{
		return NanThrowError("Invalid key specified.");
	}

	tapKeyCode(key, flags);

	NanReturnValue(NanNew("1"));
}

NAN_METHOD(typeString)
{
	NanScope();

	char *str;
	NanUtf8String string(args[0]);

	str = *string;

	typeString(str);

	NanReturnValue(NanNew("1"));
}

/*
  ____
 / ___|  ___ _ __ ___  ___ _ __
 \___ \ / __| '__/ _ \/ _ \ '_ \
  ___) | (__| | |  __/  __/ | | |
 |____/ \___|_|  \___|\___|_| |_|

*/

NAN_METHOD(getPixelColor)
{
	NanScope();

	MMBitmapRef bitmap;
	MMRGBHex color;

	size_t x = args[0]->Int32Value();
	size_t y = args[1]->Int32Value();

	bitmap = copyMMBitmapFromDisplayInRect(MMRectMake(x, y, 1, 1));

	color = MMRGBHexAtPoint(bitmap, 0, 0);

	char hex [6];

	//Length needs to be 7 because snprintf includes a terminating null.
	//Use %06x to pad hex value with leading 0s.
	snprintf(hex, 7, "%06x", color);

	destroyMMBitmap(bitmap);

	NanReturnValue(NanNew(hex));
}

NAN_METHOD(getScreenSize)
{
	NanScope();

	//Get display size.
	MMSize displaySize = getMainDisplaySize();

	//Create our return object.
	Local<Object> obj = NanNew<Object>();
	obj->Set(NanNew<String>("width"), NanNew<Number>(displaySize.width));
	obj->Set(NanNew<String>("height"), NanNew<Number>(displaySize.height));

	//Return our object with .width and .height.
	NanReturnValue(obj);
}

void init(Handle<Object> target)
{

	target->Set(NanNew<String>("moveMouse"),
		NanNew<FunctionTemplate>(moveMouse)->GetFunction());

	target->Set(NanNew<String>("moveMouseSmooth"),
		NanNew<FunctionTemplate>(moveMouseSmooth)->GetFunction());

	target->Set(NanNew<String>("getMousePos"),
		NanNew<FunctionTemplate>(getMousePos)->GetFunction());

	target->Set(NanNew<String>("mouseClick"),
		NanNew<FunctionTemplate>(mouseClick)->GetFunction());

	target->Set(NanNew<String>("mouseToggle"),
		NanNew<FunctionTemplate>(mouseToggle)->GetFunction());

	target->Set(NanNew<String>("keyTap"),
		NanNew<FunctionTemplate>(keyTap)->GetFunction());

	target->Set(NanNew<String>("typeString"),
		NanNew<FunctionTemplate>(typeString)->GetFunction());

	target->Set(NanNew<String>("getPixelColor"),
		NanNew<FunctionTemplate>(getPixelColor)->GetFunction());

	target->Set(NanNew<String>("getScreenSize"),
		NanNew<FunctionTemplate>(getScreenSize)->GetFunction());

}

NODE_MODULE(robotjs, init)
<|endoftext|>