<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2011.  All rights reserved
 */
#include	"../../../StroikaPreComp.h"

#if		qHasFeature_libcurl
#include	<curl/curl.h>
#endif

#include	"../../../Characters/Format.h"
#include	"../../../Execution/Exceptions.h"

#include	"Client_libcurl.h"

using	namespace	Stroika::Foundation;
using	namespace	Stroika::Foundation::Characters;
using	namespace	Stroika::Foundation::IO;
using	namespace	Stroika::Foundation::IO::Network;
using	namespace	Stroika::Foundation::IO::Network::Transfer;

#if		qHasFeature_libcurl
namespace	{
	struct	ModuleInit_ {
		ModuleInit_ ()
		{
			curl_global_init (CURL_GLOBAL_ALL);
		}
	};
}
#endif

#if		qHasFeature_libcurl
namespace	{
	wstring	mkExceptMsg_ (LibCurlException::CURLcode ccode)
		{
			return String::FromUTF8 (curl_easy_strerror (static_cast<CURLcode> (ccode))).As<wstring> ();
		}
}

/*
 ********************************************************************************
 ************************ Transfer::LibCurlException ****************************
 ********************************************************************************
 */
LibCurlException::LibCurlException (CURLcode ccode)
	: StringException (mkExceptMsg_ (ccode))
	, fCurlCode_ (ccode)
{
}

void	LibCurlException::DoThrowIfError (CURLcode status)
{
	if (status != CURLE_OK) {
		Execution::DoThrow (LibCurlException (status));
	}
}
#endif

#if		qHasFeature_libcurl
/*
 ********************************************************************************
 ********************* Transfer::IConnection_LibCurl ****************************
 ********************************************************************************
 */
IConnection_LibCurl::IConnection_LibCurl ()
	: fCurlHandle_ (curl_easy_init ())
	, fCURLCache_URL_ ()
	, fResponseData_ ()
	, fSavedHeaders_ (nullptr)
{
}

IConnection_LibCurl::~IConnection_LibCurl ()
{
	if (fCurlHandle_ != nullptr) {
		curl_easy_cleanup (fCurlHandle_);
	}
	if (fSavedHeaders_ != nullptr) {
		curl_slist_free_all (fSavedHeaders_);
		fSavedHeaders_ = nullptr;
	}
}

URL		IConnection_LibCurl::GetURL () const override
{
	// needs work... - not sure this is safe - may need to cache orig... instead of reparsing...
	return URL (String::FromUTF8 (fCURLCache_URL_).As<wstring> ());
}

void	IConnection_LibCurl::SetURL (const URL& url) override
{
	MakeHandleIfNeeded_ ();
	fCURLCache_URL_ = String (url.GetURL ()).AsUTF8 ();
	LibCurlException::DoThrowIfError (::curl_easy_setopt (fCurlHandle_, CURLOPT_URL, fCURLCache_URL_.c_str ()));
}

void	IConnection_LibCurl::Close ()	override
{
	if (fCurlHandle_ != nullptr) {
		::curl_easy_cleanup (fCurlHandle_);
		fCurlHandle_ = nullptr;
	}
}

size_t	IConnection_LibCurl::ResponseWriteHandler_ (void* ptr, size_t size, size_t nmemb, void* userP)
{
	return reinterpret_cast<IConnection_LibCurl*> (userP)->ResponseWriteHandler_ (reinterpret_cast<const Byte*> (ptr), size * nmemb);
}

size_t	IConnection_LibCurl::ResponseWriteHandler_ (const Byte* ptr, size_t nBytes)
{
	fResponseData_.insert (fResponseData_.end (), ptr, ptr + nBytes);
	return nBytes;
}

size_t	IConnection_LibCurl::ResponseHeaderWriteHandler_ (void* ptr, size_t size, size_t nmemb, void* userP)
{
	return reinterpret_cast<IConnection_LibCurl*> (userP)->ResponseHeaderWriteHandler_ (reinterpret_cast<const Byte*> (ptr), size * nmemb);
}

size_t	IConnection_LibCurl::ResponseHeaderWriteHandler_ (const Byte* ptr, size_t nBytes)
{
	string tmp (reinterpret_cast<const char*> (ptr), nBytes);
	string::size_type i = tmp.find (':');
	String	from;
	String	to;
	if (i == string::npos) {
		from = String::FromUTF8 (tmp);
	}
	else {
		from = String::FromUTF8 (tmp.substr (0, i));
		to = String::FromUTF8 (tmp.substr (i+1));
	}
	from = from.Trim ();
	to = to.Trim ();
	fResponseHeaders_[from] = to;
	return nBytes;
}

Response	IConnection_LibCurl::SendAndRequest (const Request& request)	override
{
	MakeHandleIfNeeded_ ();
	fResponseData_.clear ();
	fResponseHeaders_.clear ();

	//grab useragent from request headers...
	//curl_easy_setopt (fCurlHandle_, CURLOPT_USERAGENT, "libcurl-agent/1.0");

	// grab initial headers and do POST/etc based on args in request...
	curl_slist*	tmpH	=	curl_slist_append (nullptr, "Expect: ");	//tmphack - really iterate over requst headers - with a few exceptions...
	LibCurlException::DoThrowIfError (::curl_easy_setopt (fCurlHandle_, CURLOPT_HTTPHEADER, tmpH));
	if (fSavedHeaders_ != nullptr) {
		curl_slist_free_all (fSavedHeaders_);
		fSavedHeaders_ = nullptr;
	}
	fSavedHeaders_ = tmpH;

	LibCurlException::DoThrowIfError (:: curl_easy_perform (fCurlHandle_));

	Response	response;
	response.fData = fResponseData_;

	long	resultCode	=	0;
	LibCurlException::DoThrowIfError (::curl_easy_getinfo (fCurlHandle_, CURLINFO_RESPONSE_CODE, &resultCode));
	response.fStatus = resultCode;
	response.fHeaders = fResponseHeaders_;
	response.fData = fResponseData_;
	return response;
}

void	IConnection_LibCurl::MakeHandleIfNeeded_ ()
{
	if (fCurlHandle_ == nullptr) {
		fCurlHandle_  = curl_easy_init ();
		LibCurlException::DoThrowIfError (::curl_easy_setopt (fCurlHandle_, CURLOPT_URL, fCURLCache_URL_.c_str ()));
	}
}
#endif

#if		qHasFeature_libcurl
/*
 ********************************************************************************
 ********************* Transfer::IConnection_LibCurl ****************************
 ********************************************************************************
 */
LibCurlConnection::LibCurlConnection ()
	: Connection (Memory::SharedPtr<IConnection> (new IConnection_LibCurl ()))
{
}
#endif<commit_msg>minor tweeks to Client_libcurl<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2011.  All rights reserved
 */
#include	"../../../StroikaPreComp.h"

#if		qHasFeature_libcurl
#include	<curl/curl.h>
#endif

#include	"../../../Characters/Format.h"
#include	"../../../Execution/Exceptions.h"

#include	"Client_libcurl.h"

using	namespace	Stroika::Foundation;
using	namespace	Stroika::Foundation::Characters;
using	namespace	Stroika::Foundation::IO;
using	namespace	Stroika::Foundation::IO::Network;
using	namespace	Stroika::Foundation::IO::Network::Transfer;

#if		qHasFeature_libcurl
namespace	{
	struct	ModuleInit_ {
		ModuleInit_ ()
		{
			curl_global_init (CURL_GLOBAL_ALL);
		}
	};
}
#endif

#if		qHasFeature_libcurl
namespace	{
	wstring	mkExceptMsg_ (LibCurlException::CURLcode ccode)
		{
			return String::FromUTF8 (curl_easy_strerror (static_cast<CURLcode> (ccode))).As<wstring> ();
		}
}

/*
 ********************************************************************************
 ************************ Transfer::LibCurlException ****************************
 ********************************************************************************
 */
LibCurlException::LibCurlException (CURLcode ccode)
	: StringException (mkExceptMsg_ (ccode))
	, fCurlCode_ (ccode)
{
}

void	LibCurlException::DoThrowIfError (CURLcode status)
{
	if (status != CURLE_OK) {
		Execution::DoThrow (LibCurlException (status));
	}
}
#endif

#if		qHasFeature_libcurl
/*
 ********************************************************************************
 ********************* Transfer::IConnection_LibCurl ****************************
 ********************************************************************************
 */
IConnection_LibCurl::IConnection_LibCurl ()
	: fCurlHandle_ (nullptr)
	, fCURLCache_URL_ ()
	, fResponseData_ ()
	, fSavedHeaders_ (nullptr)
{
}

IConnection_LibCurl::~IConnection_LibCurl ()
{
	if (fCurlHandle_ != nullptr) {
		curl_easy_cleanup (fCurlHandle_);
	}
	if (fSavedHeaders_ != nullptr) {
		curl_slist_free_all (fSavedHeaders_);
		fSavedHeaders_ = nullptr;
	}
}

URL		IConnection_LibCurl::GetURL () const override
{
	// needs work... - not sure this is safe - may need to cache orig... instead of reparsing...
	return URL (String::FromUTF8 (fCURLCache_URL_).As<wstring> ());
}

void	IConnection_LibCurl::SetURL (const URL& url) override
{
	MakeHandleIfNeeded_ ();
	fCURLCache_URL_ = String (url.GetURL ()).AsUTF8 ();
	LibCurlException::DoThrowIfError (::curl_easy_setopt (fCurlHandle_, CURLOPT_URL, fCURLCache_URL_.c_str ()));
}

void	IConnection_LibCurl::Close ()	override
{
	if (fCurlHandle_ != nullptr) {
		::curl_easy_cleanup (fCurlHandle_);
		fCurlHandle_ = nullptr;
	}
}

size_t	IConnection_LibCurl::ResponseWriteHandler_ (void* ptr, size_t size, size_t nmemb, void* userP)
{
	return reinterpret_cast<IConnection_LibCurl*> (userP)->ResponseWriteHandler_ (reinterpret_cast<const Byte*> (ptr), size * nmemb);
}

size_t	IConnection_LibCurl::ResponseWriteHandler_ (const Byte* ptr, size_t nBytes)
{
	fResponseData_.insert (fResponseData_.end (), ptr, ptr + nBytes);
	return nBytes;
}

size_t	IConnection_LibCurl::ResponseHeaderWriteHandler_ (void* ptr, size_t size, size_t nmemb, void* userP)
{
	return reinterpret_cast<IConnection_LibCurl*> (userP)->ResponseHeaderWriteHandler_ (reinterpret_cast<const Byte*> (ptr), size * nmemb);
}

size_t	IConnection_LibCurl::ResponseHeaderWriteHandler_ (const Byte* ptr, size_t nBytes)
{
	string tmp (reinterpret_cast<const char*> (ptr), nBytes);
	string::size_type i = tmp.find (':');
	String	from;
	String	to;
	if (i == string::npos) {
		from = String::FromUTF8 (tmp);
	}
	else {
		from = String::FromUTF8 (tmp.substr (0, i));
		to = String::FromUTF8 (tmp.substr (i+1));
	}
	from = from.Trim ();
	to = to.Trim ();
	fResponseHeaders_[from] = to;
	return nBytes;
}

Response	IConnection_LibCurl::SendAndRequest (const Request& request)	override
{
	MakeHandleIfNeeded_ ();
	fResponseData_.clear ();
	fResponseHeaders_.clear ();

	//grab useragent from request headers...
	//curl_easy_setopt (fCurlHandle_, CURLOPT_USERAGENT, "libcurl-agent/1.0");

	// grab initial headers and do POST/etc based on args in request...
	curl_slist*	tmpH	=	nullptr;
	for (map<String,String>::const_iterator i = request.fOverrideHeaders.begin (); i != request.fOverrideHeaders.end (); ++i) {
		tmpH = curl_slist_append (tmpH, (i->first + L": " + i->second).c_str ());
	}
	AssertNotNull (fCurlHandle_);
	LibCurlException::DoThrowIfError (::curl_easy_setopt (fCurlHandle_, CURLOPT_HTTPHEADER, tmpH));
	if (fSavedHeaders_ != nullptr) {
		curl_slist_free_all (fSavedHeaders_);
		fSavedHeaders_ = nullptr;
	}
	fSavedHeaders_ = tmpH;

	LibCurlException::DoThrowIfError (:: curl_easy_perform (fCurlHandle_));

	Response	response;
	response.fData = fResponseData_;

	long	resultCode	=	0;
	LibCurlException::DoThrowIfError (::curl_easy_getinfo (fCurlHandle_, CURLINFO_RESPONSE_CODE, &resultCode));
	response.fStatus = resultCode;
	response.fHeaders = fResponseHeaders_;
	response.fData = fResponseData_;
	return response;
}

void	IConnection_LibCurl::MakeHandleIfNeeded_ ()
{
	if (fCurlHandle_ == nullptr) {
		ThrowIfNull (fCurlHandle_ = ::curl_easy_init ());

		/*
		 * Now setup COMMON options we ALWAYS set.
		 */
		LibCurlException::DoThrowIfError (::curl_easy_setopt (fCurlHandle_, CURLOPT_URL, fCURLCache_URL_.c_str ()));

		LibCurlException::DoThrowIfError (::curl_easy_setopt (fCurlHandle_, CURLOPT_WRITEFUNCTION, ResponseWriteHandler_));
		LibCurlException::DoThrowIfError (::curl_easy_setopt (fCurlHandle_, CURLOPT_WRITEDATA, this));
		LibCurlException::DoThrowIfError (::curl_easy_setopt (fCurlHandle_, CURLOPT_HEADERFUNCTION, ResponseHeaderWriteHandler_));
		LibCurlException::DoThrowIfError (::curl_easy_setopt (fCurlHandle_, CURLOPT_WRITEHEADER, this));
	}
}
#endif

#if		qHasFeature_libcurl
/*
 ********************************************************************************
 ********************* Transfer::IConnection_LibCurl ****************************
 ********************************************************************************
 */
LibCurlConnection::LibCurlConnection ()
	: Connection (Memory::SharedPtr<IConnection> (new IConnection_LibCurl ()))
{
}
#endif<|endoftext|>


<commit_before><commit_msg>Added a forgotten VPackBuilder.close() in Traversalnode to VPack. This caused the query planner to fail at certain cases<commit_after><|endoftext|>


<commit_before>#include "VirtualHIDManager.hpp"

#define super IOService
OSDefineMetaClassAndStructors(org_pqrs_driver_VirtualHIDManager, IOService);

bool org_pqrs_driver_VirtualHIDManager::init(OSDictionary* dict) {
  if (!super::init(dict)) {
    return false;
  }

  attachedClientCount_ = 0;
  virtualHIDPointing_ = nullptr;

  if (auto serialNumber = OSString::withCString("org.pqrs.driver.VirtualHIDManager")) {
    setProperty(kIOHIDSerialNumberKey, serialNumber);
    serialNumber->release();
  }

  return true;
}

void org_pqrs_driver_VirtualHIDManager::free(void) {
  super::free();
}

bool org_pqrs_driver_VirtualHIDManager::start(IOService* provider) {
  if (!super::start(provider)) {
    return false;
  }

  // Publish ourselves so clients can find us
  //
  // Note:
  // IOHIDDevice (VirtualHIDPointing, etc) cannot create custom UserClient directly.
  // Therefore, we provide IOHIDManager for UserClient.
  registerService();

  return true;
}

void org_pqrs_driver_VirtualHIDManager::stop(IOService* provider) {
}

void org_pqrs_driver_VirtualHIDManager::attachClient(void) {
  ++attachedClientCount_;

  IOLog("org_pqrs_driver_VirtualHIDManager::attachClient attachedClientCount_ = %d\n", static_cast<int>(attachedClientCount_));

  createVirtualHIDPointing();
}

void org_pqrs_driver_VirtualHIDManager::detachClient(void) {
  if (attachedClientCount_ > 0) {
    --attachedClientCount_;
  }

  IOLog("org_pqrs_driver_VirtualHIDManager::detachClient attachedClientCount_ = %d\n", static_cast<int>(attachedClientCount_));

  if (attachedClientCount_ == 0 && virtualHIDPointing_) {
    terminateVirtualHIDPointing();
  }
}

void org_pqrs_driver_VirtualHIDManager::createVirtualHIDPointing(void) {
  if (virtualHIDPointing_) {
    return;
  }

  // See IOHIDResourceDeviceUserClient::createAndStartDevice
  virtualHIDPointing_ = OSTypeAlloc(org_pqrs_driver_VirtualHIDPointing);
  if (!virtualHIDPointing_) {
    return;
  }

  if (!virtualHIDPointing_->init(nullptr)) {
    goto error;
  }

  if (!virtualHIDPointing_->attach(this)) {
    goto error;
  }

  if (!virtualHIDPointing_->start(this)) {
    virtualHIDPointing_->detach(this);
    goto error;
  }

  return;

error:
  if (virtualHIDPointing_) {
    virtualHIDPointing_->release();
    virtualHIDPointing_ = nullptr;
  }
}

void org_pqrs_driver_VirtualHIDManager::terminateVirtualHIDPointing(void) {
  if (!virtualHIDPointing_) {
    return;
  }

  virtualHIDPointing_->terminate();
  virtualHIDPointing_->release();
  virtualHIDPointing_ = nullptr;
}

IOReturn org_pqrs_driver_VirtualHIDManager::handleHIDPointingReport(IOMemoryDescriptor* report) {
  if (virtualHIDPointing_) {
    return virtualHIDPointing_->handleReport(report, kIOHIDReportTypeInput, kIOHIDOptionsTypeNone);
  }
  return kIOReturnError;
}
<commit_msg>call terminateVirtualHIDPointing in stop<commit_after>#include "VirtualHIDManager.hpp"

#define super IOService
OSDefineMetaClassAndStructors(org_pqrs_driver_VirtualHIDManager, IOService);

bool org_pqrs_driver_VirtualHIDManager::init(OSDictionary* dict) {
  IOLog("org_pqrs_driver_VirtualHIDManager::init\n");

  if (!super::init(dict)) {
    return false;
  }

  attachedClientCount_ = 0;
  virtualHIDPointing_ = nullptr;

  if (auto serialNumber = OSString::withCString("org.pqrs.driver.VirtualHIDManager")) {
    setProperty(kIOHIDSerialNumberKey, serialNumber);
    serialNumber->release();
  }

  return true;
}

void org_pqrs_driver_VirtualHIDManager::free(void) {
  IOLog("org_pqrs_driver_VirtualHIDManager::free\n");

  super::free();
}

bool org_pqrs_driver_VirtualHIDManager::start(IOService* provider) {
  IOLog("org_pqrs_driver_VirtualHIDManager::start\n");

  if (!super::start(provider)) {
    return false;
  }

  // Publish ourselves so clients can find us
  //
  // Note:
  // IOHIDDevice (VirtualHIDPointing, etc) cannot create custom UserClient directly.
  // Therefore, we provide IOHIDManager for UserClient.
  registerService();

  return true;
}

void org_pqrs_driver_VirtualHIDManager::stop(IOService* provider) {
  IOLog("org_pqrs_driver_VirtualHIDManager::stop\n");

  terminateVirtualHIDPointing();

  super::stop(provider);
}

void org_pqrs_driver_VirtualHIDManager::attachClient(void) {
  ++attachedClientCount_;

  IOLog("org_pqrs_driver_VirtualHIDManager::attachClient attachedClientCount_ = %d\n", static_cast<int>(attachedClientCount_));

  createVirtualHIDPointing();
}

void org_pqrs_driver_VirtualHIDManager::detachClient(void) {
  if (attachedClientCount_ > 0) {
    --attachedClientCount_;
  }

  IOLog("org_pqrs_driver_VirtualHIDManager::detachClient attachedClientCount_ = %d\n", static_cast<int>(attachedClientCount_));

  if (attachedClientCount_ == 0 && virtualHIDPointing_) {
    terminateVirtualHIDPointing();
  }
}

void org_pqrs_driver_VirtualHIDManager::createVirtualHIDPointing(void) {
  if (virtualHIDPointing_) {
    return;
  }

  // See IOHIDResourceDeviceUserClient::createAndStartDevice
  virtualHIDPointing_ = OSTypeAlloc(org_pqrs_driver_VirtualHIDPointing);
  if (!virtualHIDPointing_) {
    return;
  }

  if (!virtualHIDPointing_->init(nullptr)) {
    goto error;
  }

  if (!virtualHIDPointing_->attach(this)) {
    goto error;
  }

  if (!virtualHIDPointing_->start(this)) {
    virtualHIDPointing_->detach(this);
    goto error;
  }

  return;

error:
  if (virtualHIDPointing_) {
    virtualHIDPointing_->release();
    virtualHIDPointing_ = nullptr;
  }
}

void org_pqrs_driver_VirtualHIDManager::terminateVirtualHIDPointing(void) {
  if (!virtualHIDPointing_) {
    return;
  }

  virtualHIDPointing_->terminate();
  virtualHIDPointing_->release();
  virtualHIDPointing_ = nullptr;
}

IOReturn org_pqrs_driver_VirtualHIDManager::handleHIDPointingReport(IOMemoryDescriptor* report) {
  if (!virtualHIDPointing_) {
    return kIOReturnError;
  }

  return virtualHIDPointing_->handleReport(report, kIOHIDReportTypeInput, kIOHIDOptionsTypeNone);
}
<|endoftext|>


<commit_before>// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include "TestFixtures/Decoration.hpp"
#include <autowiring/AutoPacketFactory.h>
#include <autowiring/AutoPacketGraph.h>
#include CHRONO_HEADER
#include THREAD_HEADER

class AutoPacketGraphTest:
  public testing::Test
{};

class APReceiver1 {
public:
  APReceiver1(void) {}
  void AutoFilter(Decoration<0> d0) { }
};

class APReceiver2 {
public:
  APReceiver2(void) {}
  void AutoFilter(Decoration<0> d0, Decoration<1>& d1) { }
};

class APReceiver3 {
public:
  APReceiver3(void) {}
  void AutoFilter(Decoration<0> d0, Decoration<1> d1) { }
};

class APReceiver4 {
public:
  APReceiver4(void) {}
  void AutoFilter(Decoration<0> d0, Decoration<2> d2) { }
};

TEST_F(AutoPacketGraphTest, VerifyEmptyGraphBeforeCtxtInit) {
  AutoCreateContext ctxt;
  CurrentContextPusher pshr(ctxt);

  AutoRequired<AutoPacketGraph> graph;
  ASSERT_TRUE(graph->GetEdgeCounts().empty())
    << "Graph did not start out empty before context initiation";

  ctxt->Initiate();

  ASSERT_TRUE(graph->GetEdgeCounts().empty())
    << "Graph did not stay empty after context initiation";

  ctxt->SignalShutdown();
}

TEST_F(AutoPacketGraphTest, VerifyEmptyGraphAfterCtxtInit) {
  AutoCreateContext ctxt;
  CurrentContextPusher pshr(ctxt);

  ctxt->Initiate();

  AutoRequired<AutoPacketGraph> graph;
  ASSERT_TRUE(graph->GetEdgeCounts().empty())
    << "Graph did not start out empty";

  ctxt->SignalShutdown();
}

TEST_F(AutoPacketGraphTest, VerifySimpleEdgeFromObjectBeforeInit) {
  AutoCreateContext ctxt;
  CurrentContextPusher pshr(ctxt);

  AutoRequired<AutoPacketGraph> graph;
  AutoRequired<APReceiver1> receiver1;

  ASSERT_TRUE(graph->GetEdgeCounts().empty())
    << "Graph should still be empty before context is initialized";

  ctxt->Initiate();

  ASSERT_EQ(1UL, graph->GetEdgeCounts().size())
    << "Graph did not detect AutoFilter from object after being initiated";

  ctxt->SignalShutdown();
}

TEST_F(AutoPacketGraphTest, VerifySimpleInputFilter) {
  // TODO
}

TEST_F(AutoPacketGraphTest, VerifySimpleOutputFilter) {
  // TODO
}

TEST_F(AutoPacketGraphTest, VerifyPacketDecorationIncrementingCount) {
  // TODO
}

TEST_F(AutoPacketGraphTest, VerifyLoadAutoFilterSystem) {
  AutoCreateContext ctxt;
  CurrentContextPusher pshr(ctxt);

  AutoRequired<AutoPacketFactory> factory(ctxt);
  AutoRequired<AutoPacketGraph> graph;

  ctxt->Initiate();

  AutoRequired<APReceiver1> receiver1;
  AutoRequired<APReceiver2> receiver2;
  AutoRequired<APReceiver3> receiver3;
  AutoRequired<APReceiver4> receiver4;

  AutoPacketGraph::t_deliveryEdges edges = graph->GetEdgeCounts();

  ASSERT_EQ(7UL, edges.size())
    << "Graph could not load the edges from new objects";

  for (auto& itr : edges) {
    ASSERT_EQ(0UL, itr.second)
      << "Coutn should be 0 since packets have not been delivered yet";
  }
}

<commit_msg>adding 2 quick tests<commit_after>// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include "TestFixtures/Decoration.hpp"
#include <autowiring/AutoPacketFactory.h>
#include <autowiring/AutoPacketGraph.h>
#include CHRONO_HEADER
#include THREAD_HEADER

class AutoPacketGraphTest:
  public testing::Test
{};

class APReceiver1 {
public:
  APReceiver1(void) {}
  void AutoFilter(Decoration<0> d0) { }
};

class APReceiver2 {
public:
  APReceiver2(void) {}
  void AutoFilter(Decoration<0> d0, Decoration<1>& d1) { }
};

class APReceiver3 {
public:
  APReceiver3(void) {}
  void AutoFilter(Decoration<0> d0, Decoration<1> d1) { }
};

class APReceiver4 {
public:
  APReceiver4(void) {}
  void AutoFilter(Decoration<0> d0, Decoration<2> d2) { }
};

TEST_F(AutoPacketGraphTest, VerifyEmptyGraphBeforeCtxtInit) {
  AutoCreateContext ctxt;
  CurrentContextPusher pshr(ctxt);

  AutoRequired<AutoPacketGraph> graph;
  ASSERT_TRUE(graph->GetEdgeCounts().empty())
    << "Graph did not start out empty before context initiation";

  ctxt->Initiate();

  ASSERT_TRUE(graph->GetEdgeCounts().empty())
    << "Graph did not stay empty after context initiation";

  ctxt->SignalShutdown();
}

TEST_F(AutoPacketGraphTest, VerifyEmptyGraphAfterCtxtInit) {
  AutoCreateContext ctxt;
  CurrentContextPusher pshr(ctxt);

  ctxt->Initiate();

  AutoRequired<AutoPacketGraph> graph;
  ASSERT_TRUE(graph->GetEdgeCounts().empty())
    << "Graph did not start out empty";

  ctxt->SignalShutdown();
}

TEST_F(AutoPacketGraphTest, VerifySimpleEdgeFromObjectBeforeInit) {
  AutoCreateContext ctxt;
  CurrentContextPusher pshr(ctxt);

  AutoRequired<AutoPacketGraph> graph;
  AutoRequired<APReceiver1> receiver1;

  ASSERT_TRUE(graph->GetEdgeCounts().empty())
    << "Graph should still be empty before context is initialized";

  ctxt->Initiate();

  ASSERT_EQ(1UL, graph->GetEdgeCounts().size())
    << "Graph did not detect AutoFilter from object after being initiated";

  ctxt->SignalShutdown();
}

TEST_F(AutoPacketGraphTest, VerifySimpleEdgeFromNewObject) {
  AutoCreateContext ctxt;
  CurrentContextPusher pshr(ctxt);

  AutoRequired<AutoPacketGraph> graph;

  ctxt->Initiate();

  ASSERT_TRUE(graph->GetEdgeCounts().empty())
    << "Graph should still be empty before context is initialized";

  AutoRequired<APReceiver1> receiver1;

  ASSERT_EQ(1UL, graph->GetEdgeCounts().size())
    << "Graph did not detect AutoFilter from object after being initiated";

  ctxt->SignalShutdown();
}

TEST_F(AutoPacketGraphTest, VerifyLoadGraphAfterInitAndObject) {
  AutoCreateContext ctxt;
  CurrentContextPusher pshr(ctxt);

  AutoRequired<APReceiver1> receiver1;

  ctxt->Initiate();

  AutoRequired<AutoPacketGraph> graph;

  ASSERT_EQ(1UL, graph->GetEdgeCounts().size())
    << "Graph did not detect AutoFilter from object after being initiated";

  ctxt->SignalShutdown();
}

TEST_F(AutoPacketGraphTest, VerifySimpleInputFilter) {
  // TODO
}

TEST_F(AutoPacketGraphTest, VerifySimpleOutputFilter) {
  // TODO
}

TEST_F(AutoPacketGraphTest, VerifyPacketDecorationIncrementingCount) {
  // TODO
}

TEST_F(AutoPacketGraphTest, VerifyLoadAutoFilterSystem) {
  AutoCreateContext ctxt;
  CurrentContextPusher pshr(ctxt);

  AutoRequired<AutoPacketFactory> factory(ctxt);
  AutoRequired<AutoPacketGraph> graph;

  ctxt->Initiate();

  AutoRequired<APReceiver1> receiver1;
  AutoRequired<APReceiver2> receiver2;
  AutoRequired<APReceiver3> receiver3;
  AutoRequired<APReceiver4> receiver4;

  AutoPacketGraph::t_deliveryEdges edges = graph->GetEdgeCounts();

  {
    auto packet = factory->NewPacket();
    packet->Decorate(Decoration<0>(0));
    packet->Decorate(Decoration<2>(2));
  }

  ASSERT_EQ(7UL, edges.size())
    << "Graph could not load the edges from new objects";

  for (auto& itr : edges) {
    ASSERT_EQ(0UL, itr.second)
      << "Coutn should be 0 since packets have not been delivered yet";
  }

  ctxt->SignalShutdown();
}

<|endoftext|>


<commit_before>#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <cstdlib>

void assertTrue(bool actual)
{
    std::cout << "Test " << (actual ? "Pass" : "FAIL") << std::endl;
}

void assertFalse(bool actual)
{
    std::cout << "Test " << (!actual ? "Pass" : "FAIL") << std::endl;
}

// Binary search using a recursive algorithm.
bool
binary_search_recursive(const std::vector<int>::iterator begin,
                 const std::vector<int>::iterator end,
                 int target)
{
    if(begin == end)
        return false;

    std::vector<int>::iterator mid = begin + std::distance(begin, end)/2;
    if(*mid == target) {
        return true;
    } else if(target < *mid) {
        return binary_search_recursive(begin, mid, target);
    } else {
        return binary_search_recursive(mid, end, target);
    }

    return false;
}

// Binary search using an iterative algorithm.
bool
binary_search_iterative(const std::vector<int>::iterator begin,
                        const std::vector<int>::iterator end,
                        int target)
{
    std::vector<int>::iterator sub_range_begin = begin;
    std::vector<int>::iterator sub_range_end = end;

    while(sub_range_begin != sub_range_end)
    {
        std::vector<int>::iterator mid = sub_range_begin +
        std::distance(sub_range_begin, sub_range_end)/2;

        if(*mid == target) {
            return true;
        } else if(target < *mid) {
            sub_range_end = mid;
        } else {
            sub_range_begin = mid;
        }
    }

    return false;
}

int main()
{
    const int data_size = 100;

    // Fill a vector with some random values
    std::vector<int> data(data_size);
    std::generate(data.begin(), data.end(), std::rand);

    // Remember the last element in the data set.
    // This will be the target value to search for.
    int val = data.back();

    // Sort the vector
    std::sort(data.begin(), data.end());

    // Search for the target value in each algorithm implementation
    assertTrue(std::binary_search(data.begin(), data.end(), val));
    assertTrue(binary_search_recursive(data.begin(), data.end(), val));
    assertTrue(binary_search_iterative(data.begin(), data.end(), val));

    return 0;
}

<commit_msg>Changing to a sequential data sequence and testing negative test cases<commit_after>#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <cstdlib>

void assertTrue(bool actual)
{
    std::cout << "Test " << (actual ? "Pass" : "FAIL") << std::endl;
}

void assertFalse(bool actual)
{
    std::cout << "Test " << (!actual ? "Pass" : "FAIL") << std::endl;
}

class IncrementingSequence
{
public:
    // Constructor
    IncrementingSequence(): i_(0) {}
    // Return an incrementing counter
    int operator() () { return i_++; }
private:
    int i_;
};

// Binary search using a recursive algorithm.
bool
binary_search_recursive(const std::vector<int>::iterator begin,
                 const std::vector<int>::iterator end,
                 int target)
{
    if(begin == end)
        return false;

    std::vector<int>::iterator mid = begin + std::distance(begin, end)/2;
    if(*mid == target) {
        return true;
    } else if(target < *mid) {
        return binary_search_recursive(begin, mid, target);
    } else {
        return binary_search_recursive(mid, end, target);
    }

    return false;
}

// Binary search using an iterative algorithm.
bool
binary_search_iterative(const std::vector<int>::iterator begin,
                        const std::vector<int>::iterator end,
                        int target)
{
    std::vector<int>::iterator sub_range_begin = begin;
    std::vector<int>::iterator sub_range_end = end;

    while(sub_range_begin != sub_range_end)
    {
        std::vector<int>::iterator mid = sub_range_begin +
        std::distance(sub_range_begin, sub_range_end)/2;

        if(*mid == target) {
            return true;
        } else if(target < *mid) {
            sub_range_end = mid;
        } else {
            sub_range_begin = mid;
        }
    }

    return false;
}

int main()
{
    const int data_size = 100;

    // Fill a vector with some values
    std::vector<int> data(data_size);
    std::generate(data.begin(), data.end(), IncrementingSequence());

    // Search for values in each algorithm implementation
    assertTrue(std::binary_search(data.begin(), data.end(), 25));
    assertFalse(std::binary_search(data.begin(), data.end(), -1));

    assertTrue(binary_search_recursive(data.begin(), data.end(), 25));
    assertFalse(binary_search_recursive(data.begin(), data.end(), -1));

    assertTrue(binary_search_iterative(data.begin(), data.end(), 25));
    assertFalse(binary_search_iterative(data.begin(), data.end(), -1));

    return 0;
}

<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/
#include "modules/common/adapters/adapter_gflags.h"
#include "modules/common/log.h"
#include "modules/perception/proto/perception_obstacle.pb.h"
#include "modules/perception/traffic_light/base/image_lights.h"
#include "ros/ros.h"
#include "sensor_msgs/Image.h"

using apollo::perception::traffic_light::Image;
using apollo::perception::traffic_light::CameraId;
using apollo::perception::PerceptionObstacles;

std::map<std::string, cv::Scalar> kColorTable = {
    {std::string("red_light_box"), cv::Scalar(0, 0, 255)},
    {std::string("green_light_box"), cv::Scalar(0, 255, 0)},
    {std::string("yellow_light_box"), cv::Scalar(0, 255, 255)},
    {std::string("black_light_box"), cv::Scalar(255, 90, 199)},
    {std::string("unknown_light_box"), cv::Scalar(0, 76, 153)},
    {std::string("projection_roi"), cv::Scalar(255, 255, 0)},
    {std::string("crop_roi"), cv::Scalar(0, 255, 255)},
    {std::string("debug_roi"), cv::Scalar(255, 169, 255)}};

std::vector<std::shared_ptr<Image>> g_cached_images;
const int kMaxCachedImageNum = 100;

void OnPerception(const PerceptionObstacles &);
void OnImageShort(const sensor_msgs::ImagePtr &);
void OnImageLong(const sensor_msgs::ImagePtr &);

int main(int argc, char **argv) {
  ros::init(argc, argv, "camera_visualizer");
  ros::NodeHandle n;

  ros::Subscriber sub_perception_debug =
      n.subscribe(FLAGS_perception_obstacle_topic, 1000, OnPerception);
  ros::Subscriber sub_tl_image_long =
      n.subscribe(FLAGS_image_long_topic, 1000, OnImageLong);
  ros::Subscriber sub_tl_image_short =
      n.subscribe(FLAGS_image_short_topic, 1000, OnImageShort);

  ros::spin();
  return 0;
}

void OnPerception(const PerceptionObstacles &obstacles) {
  // TODO(all): add debug into perception debug pb and draw on image.
  g_cached_images.back()->GenerateMat();
  cv::Mat img = g_cached_images.back()->mat();

  cv::resize(img, img, cv::Size(960, 540));
  cv::imshow("camera_debug_image", img);
  cv::waitKey(10);
}

void OnImage(CameraId camera_id, const sensor_msgs::ImagePtr &msg) {
  boost::shared_ptr<sensor_msgs::Image> img(new sensor_msgs::Image);
  *img = *msg;
  boost::shared_ptr<const sensor_msgs::Image> img_msg(img);
  std::shared_ptr<Image> image(new Image);
  if (!image->Init(img_msg->header.stamp.toSec(), camera_id, img_msg)) {
    std::cerr << "tl_visualizer load image failed.";
  }
  g_cached_images.push_back(image);

  while (g_cached_images.size() > kMaxCachedImageNum) {
    g_cached_images.erase(g_cached_images.begin());
  }
}
void OnImageLong(const sensor_msgs::ImagePtr &msg) {
  OnImage(CameraId::LONG_FOCUS, msg);
}

void OnImageShort(const sensor_msgs::ImagePtr &msg) {
  OnImage(CameraId::SHORT_FOCUS, msg);
}
<commit_msg>perception: only show short camera in camera visualizer.<commit_after>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/
#include "modules/common/adapters/adapter_gflags.h"
#include "modules/common/log.h"
#include "modules/perception/proto/perception_obstacle.pb.h"
#include "modules/perception/traffic_light/base/image_lights.h"
#include "ros/ros.h"
#include "sensor_msgs/Image.h"

using apollo::perception::traffic_light::Image;
using apollo::perception::traffic_light::CameraId;
using apollo::perception::PerceptionObstacles;

std::map<std::string, cv::Scalar> kColorTable = {
    {std::string("red_light_box"), cv::Scalar(0, 0, 255)},
    {std::string("green_light_box"), cv::Scalar(0, 255, 0)},
    {std::string("yellow_light_box"), cv::Scalar(0, 255, 255)},
    {std::string("black_light_box"), cv::Scalar(255, 90, 199)},
    {std::string("unknown_light_box"), cv::Scalar(0, 76, 153)},
    {std::string("projection_roi"), cv::Scalar(255, 255, 0)},
    {std::string("crop_roi"), cv::Scalar(0, 255, 255)},
    {std::string("debug_roi"), cv::Scalar(255, 169, 255)}};

std::vector<std::shared_ptr<Image>> g_cached_images;
const int kMaxCachedImageNum = 10;

void OnPerception(const PerceptionObstacles &);
void OnImageShort(const sensor_msgs::ImagePtr &);

int main(int argc, char **argv) {
  ros::init(argc, argv, "camera_visualizer");
  ros::NodeHandle n;

  ros::Subscriber sub_perception_debug =
      n.subscribe(FLAGS_perception_obstacle_topic, 1000, OnPerception);
  ros::Subscriber sub_tl_image_short =
      n.subscribe(FLAGS_image_short_topic, 1000, OnImageShort);

  ros::spin();
  return 0;
}

void OnPerception(const PerceptionObstacles &obstacles) {
  // TODO(all): add debug into perception debug pb and draw on image.
  g_cached_images.back()->GenerateMat();
  cv::Mat img = g_cached_images.back()->mat();

  cv::resize(img, img, cv::Size(960, 540));
  cv::imshow("camera_debug_image", img);
  cv::waitKey(10);
}

void OnImage(CameraId camera_id, const sensor_msgs::ImagePtr &msg) {
  boost::shared_ptr<sensor_msgs::Image> img(new sensor_msgs::Image);
  *img = *msg;
  boost::shared_ptr<const sensor_msgs::Image> img_msg(img);
  std::shared_ptr<Image> image(new Image);
  if (!image->Init(img_msg->header.stamp.toSec(), camera_id, img_msg)) {
    std::cerr << "tl_visualizer load image failed.";
  }
  g_cached_images.push_back(image);

  while (g_cached_images.size() > kMaxCachedImageNum) {
    g_cached_images.erase(g_cached_images.begin());
  }
}

void OnImageShort(const sensor_msgs::ImagePtr &msg) {
  OnImage(CameraId::SHORT_FOCUS, msg);
}
<|endoftext|>


<commit_before>#include "../../util/token.h"
#include "../../util/tokenreader.h"
#include <exception>
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string>
#include <math.h>

using namespace std;

class Failure: public exception{
public:
    Failure(int num):
    num(num){
    }

    int num;
};

static void test1_write(const string & name){
    ofstream out(name.c_str());
    out << "(foo)";
    out.close();
}

static string randomFile(){
    static char temp[64];
    sprintf(temp, "/tmp/tokenXXXXXX");
    return string(mktemp(temp));
}

static void test1(){
    try{
        string file = randomFile();
        test1_write(file);
        TokenReader reader(file);
        reader.readToken();
    } catch (...){
        throw Failure(1);
    }
}

static void test2_write(string name){
    ofstream out(name.c_str());
    out << "(foo";
    out.close();
}

static void test2(){
    try{
        string file = randomFile();
        test2_write(file);
        TokenReader reader(file);
        reader.readToken();
        throw Failure(2);
    } catch (const TokenException & e){
        /* good */
    }
}

static void test3_write(string file){
    ofstream out(file.c_str());
    out << "(foo1 (foo2 (foo3)) (foo2 (foo3)))";
    out.close();
}

static void test3(){
    string file = randomFile();
    test3_write(file);
    TokenReader reader(file);
    Token * head = reader.readToken();
    vector<const Token*> tokens = head->findTokens("foo1/foo2/foo3");
    if (tokens.size() != 2){
        throw Failure(3);
    }
}

static void test4_write(string file){
    ofstream out(file.c_str());
    out << "(foo (bar cheese))";
    out.close();
}

static void test4(){
    string file = randomFile();
    test4_write(file);
    TokenReader reader(file);
    Token * head = reader.readToken();
    string words;
    head->match("foo/bar", words);
    if (words != "cheese"){
        throw Failure(4);
    }
}

static void test5_write(string file){
    ofstream out(file.c_str());
    out << "(relative-position -.5 -.5)";
    out.close();
}

static void test5(){
    string file = randomFile();
    test5_write(file);
    TokenReader reader(file);
    Token * head = reader.readToken();
    double n1 = 0, n2 = 0;
    double epsilon = 0.00000001;
    if (*head != "relative-position"){
        throw Failure(5);
    }
    head->view() >> n1 >> n2;
    if (fabs(n1 - (-0.5)) > epsilon){
        throw Failure(5);
    }
    if (fabs(n2 - (-0.5)) > epsilon){
        throw Failure(5);
    }
}

static void test6(){
    string data = "(foo1 (foo2 (foo3)) (foo2 (foo3)))";
    TokenReader reader;
    Token * head = reader.readTokenFromString(data);
    vector<const Token*> tokens = head->findTokens("foo1/foo2/foo3");
    if (tokens.size() != 2){
        throw Failure(6);
    }
}

int main(){
    try{
        test1();
        test2();
        test3();
        test4();
        test5();
        test6();
        cout << "All tests passed!" << endl;
        return 0;
    } catch (const Failure & f){
        cout << "Test case " << f.num << " failed" << endl;
        return 1;
    }
}
<commit_msg>recognize more values for true/false in tokens<commit_after>#include "../../util/token.h"
#include "../../util/tokenreader.h"
#include <exception>
#include <iostream>
#include <sstream>
#include <fstream>
#include <stdlib.h>
#include <string>
#include <math.h>

using namespace std;

class Failure: public exception{
public:
    Failure(int num):
    num(num){
    }

    int num;
};

static void test1_write(const string & name){
    ofstream out(name.c_str());
    out << "(foo)";
    out.close();
}

static string randomFile(){
    static char temp[64];
    sprintf(temp, "/tmp/tokenXXXXXX");
    return string(mktemp(temp));
}

static void test1(){
    try{
        string file = randomFile();
        test1_write(file);
        TokenReader reader(file);
        reader.readToken();
    } catch (...){
        throw Failure(1);
    }
}

static void test2_write(string name){
    ofstream out(name.c_str());
    out << "(foo";
    out.close();
}

static void test2(){
    try{
        string file = randomFile();
        test2_write(file);
        TokenReader reader(file);
        reader.readToken();
        throw Failure(2);
    } catch (const TokenException & e){
        /* good */
    }
}

static void test3_write(string file){
    ofstream out(file.c_str());
    out << "(foo1 (foo2 (foo3)) (foo2 (foo3)))";
    out.close();
}

static void test3(){
    string file = randomFile();
    test3_write(file);
    TokenReader reader(file);
    Token * head = reader.readToken();
    vector<const Token*> tokens = head->findTokens("foo1/foo2/foo3");
    if (tokens.size() != 2){
        throw Failure(3);
    }
}

static void test4_write(string file){
    ofstream out(file.c_str());
    out << "(foo (bar cheese))";
    out.close();
}

static void test4(){
    string file = randomFile();
    test4_write(file);
    TokenReader reader(file);
    Token * head = reader.readToken();
    string words;
    head->match("foo/bar", words);
    if (words != "cheese"){
        throw Failure(4);
    }
}

static void test5_write(string file){
    ofstream out(file.c_str());
    out << "(relative-position -.5 -.5)";
    out.close();
}

static void test5(){
    string file = randomFile();
    test5_write(file);
    TokenReader reader(file);
    Token * head = reader.readToken();
    double n1 = 0, n2 = 0;
    double epsilon = 0.00000001;
    if (*head != "relative-position"){
        throw Failure(5);
    }
    head->view() >> n1 >> n2;
    if (fabs(n1 - (-0.5)) > epsilon){
        throw Failure(5);
    }
    if (fabs(n2 - (-0.5)) > epsilon){
        throw Failure(5);
    }
}

static void test6(){
    string data = "(foo1 (foo2 (foo3)) (foo2 (foo3)))";
    TokenReader reader;
    Token * head = reader.readTokenFromString(data);
    vector<const Token*> tokens = head->findTokens("foo1/foo2/foo3");
    if (tokens.size() != 2){
        throw Failure(6);
    }
}

static void test7_helper(string on, string off){
    std::ostringstream out;
    out << "(foo " << on << " " << off << ")";
    TokenReader reader;
    Token * head = reader.readTokenFromString(out.str());
    bool xtrue = false;
    bool xfalse = true;
    head->match("foo", xtrue, xfalse);
    if (!xtrue || xfalse){
        throw Failure(7);
    }
}

static void test7(){
    test7_helper("on", "off");
    test7_helper("1", "0");
    test7_helper("true", "false");
    test7_helper("enable", "disable");
}

int main(){
    try{
        test1();
        test2();
        test3();
        test4();
        test5();
        test6();
        test7();
        cout << "All tests passed!" << endl;
        return 0;
    } catch (const Failure & f){
        cout << "Test case " << f.num << " failed" << endl;
        return 1;
    }
}
<|endoftext|>


<commit_before>/*
 * This file is part of the bitcoin-classic project
 * Copyright (C) 2017 Tom Zander <tomz@freedommail.ch>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "transaction_utils.h"
#include "test/test_bitcoin.h"

#include <boost/test/auto_unit_test.hpp>
#include <Application.h>
#include <BlocksDB.h>
#include <chain.h>
#include <chainparams.h>
#include <primitives/transaction.h>
#include <main.h>
#include <consensus/validation.h>

#include <vector>

class MyTestingFixture : public TestingSetup
{
public:
    MyTestingFixture() : TestingSetup(CBaseChainParams::REGTEST, BlocksDbOnDisk) {}
};

static CBlockIndex *createBlockIndex(CBlockIndex *prev, int height, int time, uint256 *hash)
{
    assert(hash);
    CBlockIndex *index = new CBlockIndex();
    index->nHeight = height;
    index->nTime = time;
    index->pprev = prev;
    *hash = CDiskBlockIndex(index).GetBlockHash();
    index->phashBlock = hash;
    index->BuildSkip();
    Blocks::DB::instance()->appendBlock(index, 0);
    Blocks::indexMap.insert(std::make_pair(*hash, index));
    Blocks::DB::instance()->appendHeader(index);
    return index;
}

static CBlock createBlock(CBlockIndex *parent, const std::vector<CTransaction>& txns)
{
    CMutableTransaction coinbase;
    coinbase.vin.resize(1);
    coinbase.vout.resize(1);
    coinbase.vin[0].scriptSig = CScript() << (parent->nHeight + 1) << OP_0;
    coinbase.vout[0].nValue = 50 * COIN;

    CBlock block;
    block.vtx.push_back(coinbase);
    block.nVersion = 4;
    block.hashPrevBlock = *parent->phashBlock;
    block.nTime = parent->GetMedianTimePast() + 20;
    block.nBits = 0x207fffff;
    block.nNonce = 0;

    block.vtx.reserve(txns.size() + 1);
    for (const CTransaction &tx : txns) {
        block.vtx.push_back(tx);
    }

    return block;
}

BOOST_FIXTURE_TEST_SUITE(UAHF, MyTestingFixture)

BOOST_AUTO_TEST_CASE(Test_Enabling)
{
    mapArgs["-uahfstarttime"] = "0";
    MockApplication::doInit();
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFDisabled);
    BOOST_CHECK_EQUAL(Application::uahfStartTime(), 0);

    mapArgs["-uahfstarttime"] = "-1";
    MockApplication::doInit();
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFDisabled);
    BOOST_CHECK_EQUAL(Application::uahfStartTime(), 0);

    mapArgs["-uahfstarttime"] = "1";
    MockApplication::doInit();
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFWaiting);
    BOOST_CHECK_EQUAL(Application::uahfStartTime(), 1);

    mapArgs["-uahfstarttime"] = "12352";
    MockApplication::doInit();
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFWaiting);
    BOOST_CHECK_EQUAL(Application::uahfStartTime(), 12352);

    BOOST_CHECK(Blocks::DB::instance()->uahfForkBlock() == uint256());
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFWaiting);

    // we use the MTP, which uses 11 blocks, so make sure we actually have those
    // and they say exactly what we want them to say.
    std::vector<uint256> hashes;
    hashes.resize(12);
    // create 20 block-indexes.
    CBlockIndex *tip = Blocks::indexMap.begin()->second;
    for (int i = 0; i < 12; ++i) {
        tip = createBlockIndex(tip, i + 1, 20000 + i * 100, &hashes[i]);
    }
    chainActive.SetTip(tip);
    // tip GMTP is 20600, the one before 20500

    Blocks::DB::instance()->setUahfForkBlock(hashes[11]);
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFActive);

    mapArgs["-uahfstarttime"] = "0";
    MockApplication::doInit();
    Blocks::DB::createInstance(0, false);
    BOOST_CHECK(Blocks::DB::instance()->uahfForkBlock() == uint256());
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFDisabled);

    mapArgs["-uahfstarttime"] = "12352";
    MockApplication::doInit();
    Blocks::DB::createInstance(0, false);
    Blocks::DB::instance()->CacheAllBlockInfos();
    BOOST_CHECK(Blocks::DB::instance()->uahfForkBlock() == hashes[11]);
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFActive);

    mapArgs["-uahfstarttime"] = "20500";
    MockApplication::doInit();
    Blocks::DB::createInstance(0, false);
    Blocks::DB::instance()->CacheAllBlockInfos();
    BOOST_CHECK(Blocks::DB::instance()->uahfForkBlock() == hashes[11]);
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFActive);

    mapArgs["-uahfstarttime"] = "20600";
    MockApplication::doInit();
    Blocks::DB::createInstance(0, false);
    Blocks::DB::instance()->CacheAllBlockInfos();
    BOOST_CHECK(Blocks::DB::instance()->uahfForkBlock() == hashes[11]);
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFRulesActive);

    mapArgs["-uahfstarttime"] = "20601";
    MockApplication::doInit();
    Blocks::DB::createInstance(0, false);
    Blocks::DB::instance()->CacheAllBlockInfos();
    BOOST_CHECK(Blocks::DB::instance()->uahfForkBlock() == hashes[11]);
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFWaiting);
}

BOOST_AUTO_TEST_CASE(Test_BlockValidation)
{
    std::vector<uint256> hashes;
    hashes.resize(21);

    // create 20 block-indexes.
    CBlockIndex *tip = Blocks::indexMap.begin()->second;
    for (int i = 0; i < 20; ++i) {
        tip = createBlockIndex(tip, i + 1, i * 100, &hashes[i]);
    }

    // Create block with block index.
    std::vector<CTransaction> transactions;
    CBlock block = createBlock(tip, transactions);
    uint256 hash;
    mapArgs["-uahfstarttime"] = "1400"; // that makes our upcoming block the first on the new chain
    MockApplication::doInit();

    CValidationState state;
    bool accepted = ContextualCheckBlock(block, state, tip);
    BOOST_CHECK(!accepted);
    BOOST_CHECK_EQUAL(state.GetRejectReason(), "bad-blk-too-small");

    transactions = TxUtils::transactionsForBlock(1000000);
    block = createBlock(tip, transactions);
    BOOST_CHECK(::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > 1000000);

    accepted = ContextualCheckBlock(block, state, tip);
    BOOST_CHECK(accepted);
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFWaiting);

    // Accept it so we can create small blocks again.
    tip = createBlockIndex(tip, 20, 2500, &hashes[20]);

    // Base transaction is valid before the fork.
    mapArgs["-uahfstarttime"] = "2000";
    MockApplication::doInit();
    transactions.clear();
    CMutableTransaction tx;
    TxUtils::RandomTransaction(tx, TxUtils::SingleOutput);
    transactions.push_back(tx);
    block = createBlock(tip, transactions);
    BOOST_CHECK(ContextualCheckBlock(block, state, tip));

    // Base transaction is still valid after sunset.
    mapArgs["-uahfstarttime"] = "1400";
    MockApplication::doInit();
    BOOST_CHECK(ContextualCheckBlock(block, state, tip));

    // Wrong commitment, still valid.
    tx.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_0;
    transactions[0] = tx;
    block = createBlock(tip, transactions);
    BOOST_CHECK(ContextualCheckBlock(block, state, tip));

    const Consensus::Params &params = Params().GetConsensus();
    // Anti replay commitment, not valid anymore.
    tx.vout[0].scriptPubKey = CScript() << OP_RETURN << params.antiReplayOpReturnCommitment;
    transactions[0] = tx;
    block = createBlock(tip, transactions);
    BOOST_CHECK_EQUAL(ContextualCheckBlock(block, state, tip), false);

    // Anti replay commitment, **At** sunset.
    tip->nHeight = Params().GetConsensus().antiReplayOpReturnSunsetHeight - 1; // (remember, tip is pindexPREV)
    BOOST_CHECK_EQUAL(ContextualCheckBlock(block, state, tip), false);

    // Anti replay commitment, disabled after sunset.
    logDebug() << "sunset" << Params().GetConsensus().antiReplayOpReturnSunsetHeight;
    tip->nHeight = Params().GetConsensus().antiReplayOpReturnSunsetHeight;
    BOOST_CHECK(ContextualCheckBlock(block, state, tip));

    // Anti replay commitment, disabled before start time.
    mapArgs["-uahfstarttime"] = "3000";
    MockApplication::doInit();
    BOOST_CHECK(ContextualCheckBlock(block, state, tip));
}

BOOST_AUTO_TEST_CASE(Test_isCommitment) {
    std::vector<unsigned char> data{};

    // Empty commitment.
    auto s = CScript() << OP_RETURN << data;
    BOOST_CHECK(s.isCommitment(data));

    // Commitment to a value of the wrong size.
    data.push_back(42);
    BOOST_CHECK(!s.isCommitment(data));

    // Not a commitment.
    s = CScript() << data;
    BOOST_CHECK(!s.isCommitment(data));

    // Non empty commitment.
    s = CScript() << OP_RETURN << data;
    BOOST_CHECK(s.isCommitment(data));

    // Commitment to the wrong value.
    data[0] = 0x42;
    BOOST_CHECK(!s.isCommitment(data));

    // Commitment to a larger value.
    std::string str = "Bitcoin: A peer-to-peer Electronic Cash System";
    data = std::vector<unsigned char>(str.begin(), str.end());
    BOOST_CHECK(!s.isCommitment(data));

    s = CScript() << OP_RETURN << data;
    BOOST_CHECK(s.isCommitment(data));

    // 64 bytes commitment, still valid.
    data.resize(64);
    s = CScript() << OP_RETURN << data;
    BOOST_CHECK(s.isCommitment(data));

    // Commitment is too large.
    data.push_back(23);
    s = CScript() << OP_RETURN << data;
    BOOST_CHECK(!s.isCommitment(data));

    // Check with the actual replay commitment we are going to use.
    SelectParams(CBaseChainParams::MAIN);
    const Consensus::Params &params = Params().GetConsensus();
    s = CScript() << OP_RETURN << params.antiReplayOpReturnCommitment;
    BOOST_CHECK(s.isCommitment(params.antiReplayOpReturnCommitment));
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Add some comments<commit_after>/*
 * This file is part of the bitcoin-classic project
 * Copyright (C) 2017 Tom Zander <tomz@freedommail.ch>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "transaction_utils.h"
#include "test/test_bitcoin.h"

#include <boost/test/auto_unit_test.hpp>
#include <Application.h>
#include <BlocksDB.h>
#include <chain.h>
#include <chainparams.h>
#include <primitives/transaction.h>
#include <main.h>
#include <consensus/validation.h>

#include <vector>

class MyTestingFixture : public TestingSetup
{
public:
    MyTestingFixture() : TestingSetup(CBaseChainParams::REGTEST, BlocksDbOnDisk) {}
};

static CBlockIndex *createBlockIndex(CBlockIndex *prev, int height, int time, uint256 *hash)
{
    assert(hash);
    CBlockIndex *index = new CBlockIndex();
    index->nHeight = height;
    index->nTime = time;
    index->pprev = prev;
    *hash = CDiskBlockIndex(index).GetBlockHash();
    index->phashBlock = hash;
    index->BuildSkip();
    Blocks::DB::instance()->appendBlock(index, 0);
    Blocks::indexMap.insert(std::make_pair(*hash, index));
    Blocks::DB::instance()->appendHeader(index);
    return index;
}

static CBlock createBlock(CBlockIndex *parent, const std::vector<CTransaction>& txns)
{
    CMutableTransaction coinbase;
    coinbase.vin.resize(1);
    coinbase.vout.resize(1);
    coinbase.vin[0].scriptSig = CScript() << (parent->nHeight + 1) << OP_0;
    coinbase.vout[0].nValue = 50 * COIN;

    CBlock block;
    block.vtx.push_back(coinbase);
    block.nVersion = 4;
    block.hashPrevBlock = *parent->phashBlock;
    block.nTime = parent->GetMedianTimePast() + 20;
    block.nBits = 0x207fffff;
    block.nNonce = 0;

    block.vtx.reserve(txns.size() + 1);
    for (const CTransaction &tx : txns) {
        block.vtx.push_back(tx);
    }

    return block;
}

BOOST_FIXTURE_TEST_SUITE(UAHF, MyTestingFixture)

BOOST_AUTO_TEST_CASE(Test_Enabling)
{
    mapArgs["-uahfstarttime"] = "0";
    MockApplication::doInit();
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFDisabled);
    BOOST_CHECK_EQUAL(Application::uahfStartTime(), 0);

    mapArgs["-uahfstarttime"] = "-1";
    MockApplication::doInit();
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFDisabled);
    BOOST_CHECK_EQUAL(Application::uahfStartTime(), 0);

    mapArgs["-uahfstarttime"] = "1";
    MockApplication::doInit();
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFWaiting);
    BOOST_CHECK_EQUAL(Application::uahfStartTime(), 1);

    mapArgs["-uahfstarttime"] = "12352";
    MockApplication::doInit();
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFWaiting);
    BOOST_CHECK_EQUAL(Application::uahfStartTime(), 12352);

    BOOST_CHECK(Blocks::DB::instance()->uahfForkBlock() == uint256());
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFWaiting);

    // we use the MTP, which uses 11 blocks, so make sure we actually have those
    // and they say exactly what we want them to say.
    std::vector<uint256> hashes;
    hashes.resize(12);
    // create 20 block-indexes.
    CBlockIndex *tip = Blocks::indexMap.begin()->second;
    for (int i = 0; i < 12; ++i) {
        tip = createBlockIndex(tip, i + 1, 20000 + i * 100, &hashes[i]);
    }
    chainActive.SetTip(tip);
    // tip GMTP is 20600, the one before 20500

    Blocks::DB::instance()->setUahfForkBlock(hashes[11]);
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFActive);

    mapArgs["-uahfstarttime"] = "0";
    MockApplication::doInit();
    Blocks::DB::createInstance(0, false);
    BOOST_CHECK(Blocks::DB::instance()->uahfForkBlock() == uint256());
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFDisabled);

    mapArgs["-uahfstarttime"] = "12352";
    MockApplication::doInit();
    Blocks::DB::createInstance(0, false);
    Blocks::DB::instance()->CacheAllBlockInfos();
    BOOST_CHECK(Blocks::DB::instance()->uahfForkBlock() == hashes[11]);
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFActive);

    /* UAHF spec states;
     * "activation time": once the MTP of the chain tip is equal to or greater
     * than this time, the next block must be a valid fork block. The fork block
     * and subsequent blocks built on it must satisfy the new consensus rules.
     *
     * "fork block": the first block built on top of a chain tip whose MTP is
     * greater than or equal to the activation time.
     */

    // Defining UAHF starts at 20500 means the tip (being 20600) is our fork-block.
    mapArgs["-uahfstarttime"] = "20500";
    MockApplication::doInit();
    Blocks::DB::createInstance(0, false);
    Blocks::DB::instance()->CacheAllBlockInfos();
    BOOST_CHECK(Blocks::DB::instance()->uahfForkBlock() == hashes[11]);
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFActive);

    // Defining UAHF starts at 20600 means the tip is the last one before the fork block.
    mapArgs["-uahfstarttime"] = "20600";
    MockApplication::doInit();
    Blocks::DB::createInstance(0, false);
    Blocks::DB::instance()->CacheAllBlockInfos();
    BOOST_CHECK(Blocks::DB::instance()->uahfForkBlock() == hashes[11]);
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFRulesActive);

    // Check for off-by-one sec
    mapArgs["-uahfstarttime"] = "20601";
    MockApplication::doInit();
    Blocks::DB::createInstance(0, false);
    Blocks::DB::instance()->CacheAllBlockInfos();
    BOOST_CHECK(Blocks::DB::instance()->uahfForkBlock() == hashes[11]);
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFWaiting);
}

BOOST_AUTO_TEST_CASE(Test_BlockValidation)
{
    std::vector<uint256> hashes;
    hashes.resize(21);

    // create 20 block-indexes.
    CBlockIndex *tip = Blocks::indexMap.begin()->second;
    for (int i = 0; i < 20; ++i) {
        tip = createBlockIndex(tip, i + 1, i * 100, &hashes[i]);
    }

    // Create block with block index.
    std::vector<CTransaction> transactions;
    CBlock block = createBlock(tip, transactions);
    uint256 hash;
    mapArgs["-uahfstarttime"] = "1400"; // that makes our upcoming block the first on the new chain
    MockApplication::doInit();

    CValidationState state;
    bool accepted = ContextualCheckBlock(block, state, tip);
    BOOST_CHECK(!accepted);
    BOOST_CHECK_EQUAL(state.GetRejectReason(), "bad-blk-too-small");

    transactions = TxUtils::transactionsForBlock(1000000);
    block = createBlock(tip, transactions);
    BOOST_CHECK(::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > 1000000);

    accepted = ContextualCheckBlock(block, state, tip);
    BOOST_CHECK(accepted);
    BOOST_CHECK_EQUAL(Application::uahfChainState(), Application::UAHFWaiting);

    // Accept it so we can create small blocks again.
    tip = createBlockIndex(tip, 20, 2500, &hashes[20]);

    // Base transaction is valid before the fork.
    mapArgs["-uahfstarttime"] = "2000";
    MockApplication::doInit();
    transactions.clear();
    CMutableTransaction tx;
    TxUtils::RandomTransaction(tx, TxUtils::SingleOutput);
    transactions.push_back(tx);
    block = createBlock(tip, transactions);
    BOOST_CHECK(ContextualCheckBlock(block, state, tip));

    // Base transaction is still valid after sunset.
    mapArgs["-uahfstarttime"] = "1400";
    MockApplication::doInit();
    BOOST_CHECK(ContextualCheckBlock(block, state, tip));

    // Wrong commitment, still valid.
    tx.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_0;
    transactions[0] = tx;
    block = createBlock(tip, transactions);
    BOOST_CHECK(ContextualCheckBlock(block, state, tip));

    const Consensus::Params &params = Params().GetConsensus();
    // Anti replay commitment, not valid anymore.
    tx.vout[0].scriptPubKey = CScript() << OP_RETURN << params.antiReplayOpReturnCommitment;
    transactions[0] = tx;
    block = createBlock(tip, transactions);
    BOOST_CHECK_EQUAL(ContextualCheckBlock(block, state, tip), false);

    // Anti replay commitment, **At** sunset.
    tip->nHeight = Params().GetConsensus().antiReplayOpReturnSunsetHeight - 1; // (remember, tip is pindexPREV)
    BOOST_CHECK_EQUAL(ContextualCheckBlock(block, state, tip), false);

    // Anti replay commitment, disabled after sunset.
    logDebug() << "sunset" << Params().GetConsensus().antiReplayOpReturnSunsetHeight;
    tip->nHeight = Params().GetConsensus().antiReplayOpReturnSunsetHeight;
    BOOST_CHECK(ContextualCheckBlock(block, state, tip));

    // Anti replay commitment, disabled before start time.
    mapArgs["-uahfstarttime"] = "3000";
    MockApplication::doInit();
    BOOST_CHECK(ContextualCheckBlock(block, state, tip));
}

BOOST_AUTO_TEST_CASE(Test_isCommitment) {
    std::vector<unsigned char> data{};

    // Empty commitment.
    auto s = CScript() << OP_RETURN << data;
    BOOST_CHECK(s.isCommitment(data));

    // Commitment to a value of the wrong size.
    data.push_back(42);
    BOOST_CHECK(!s.isCommitment(data));

    // Not a commitment.
    s = CScript() << data;
    BOOST_CHECK(!s.isCommitment(data));

    // Non empty commitment.
    s = CScript() << OP_RETURN << data;
    BOOST_CHECK(s.isCommitment(data));

    // Commitment to the wrong value.
    data[0] = 0x42;
    BOOST_CHECK(!s.isCommitment(data));

    // Commitment to a larger value.
    std::string str = "Bitcoin: A peer-to-peer Electronic Cash System";
    data = std::vector<unsigned char>(str.begin(), str.end());
    BOOST_CHECK(!s.isCommitment(data));

    s = CScript() << OP_RETURN << data;
    BOOST_CHECK(s.isCommitment(data));

    // 64 bytes commitment, still valid.
    data.resize(64);
    s = CScript() << OP_RETURN << data;
    BOOST_CHECK(s.isCommitment(data));

    // Commitment is too large.
    data.push_back(23);
    s = CScript() << OP_RETURN << data;
    BOOST_CHECK(!s.isCommitment(data));

    // Check with the actual replay commitment we are going to use.
    SelectParams(CBaseChainParams::MAIN);
    const Consensus::Params &params = Params().GetConsensus();
    s = CScript() << OP_RETURN << params.antiReplayOpReturnCommitment;
    BOOST_CHECK(s.isCommitment(params.antiReplayOpReturnCommitment));
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>/*
* (C) 2017 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "tests.h"

#if defined(BOTAN_HAS_ASN1)
   #include <botan/der_enc.h>
   #include <botan/ber_dec.h>
   #include <botan/asn1_print.h>
#endif

namespace Botan_Tests {

#if defined(BOTAN_HAS_ASN1)

namespace {

Test::Result test_ber_stack_recursion()
   {
   Test::Result result("BER stack recursion");

   // OSS-Fuzz #813 GitHub #989

   try
      {
      const std::vector<uint8_t> in(10000000, 0);
      Botan::DataSource_Memory input(in.data(), in.size());
      Botan::BER_Decoder dec(input);

      while(dec.more_items())
         {
         Botan::BER_Object obj;
         dec.get_next(obj);
         }
      }
   catch(Botan::Decoding_Error&)
      {
      }

   result.test_success("No crash");

   return result;
   }

Test::Result test_ber_eoc_decoding_limits()
   {
   Test::Result result("BER nested indefinite length");

   // OSS-Fuzz #4353

   Botan::ASN1_Pretty_Printer printer;

   size_t max_eoc_allowed = 0;

   for(size_t len = 1; len < 1024; ++len)
      {
      std::vector<uint8_t> buf(4*len);

      /*
      This constructs a len deep sequence of SEQUENCES each with
      an indefinite length
      */
      for(size_t i = 0; i != 2*len; i += 2)
         {
         buf[i  ] = 0x30;
         buf[i+1] = 0x80;
         }
      // remainder of values left as zeros (EOC markers)

      try
         {
         printer.print(buf);
         }
      catch(Botan::BER_Decoding_Error&)
         {
         max_eoc_allowed = len - 1;
         break;
         }
      }

   result.test_eq("EOC limited to prevent stack exhaustion", max_eoc_allowed, 16);

   return result;
   }

Test::Result test_asn1_utf8_ascii_parsing()
   {
   Test::Result result("ASN.1 ASCII parsing");

   try
      {
      // \x13 - ASN1 tag for 'printable string'
      // \x06 - 6 characters of payload
      // ...  - UTF-8 encoded (ASCII chars only) word 'Moscow'
      const std::string moscow =
         "\x13\x06\x4D\x6F\x73\x63\x6F\x77";
      const std::string moscow_plain = "Moscow";
      Botan::DataSource_Memory input(moscow.data());
      Botan::BER_Decoder dec(input);

      Botan::ASN1_String str;
      str.decode_from(dec);

      result.test_eq("value()", str.value(), moscow_plain);
      }
   catch(const Botan::Decoding_Error &ex)
      {
      result.test_failure(ex.what());
      }

   return result;
   }

Test::Result test_asn1_utf8_parsing()
   {
   Test::Result result("ASN.1 UTF-8 parsing");

   try
      {
      // \x0C - ASN1 tag for 'UTF8 string'
      // \x0C - 12 characters of payload
      // ...  - UTF-8 encoded russian word for Moscow in cyrillic script
      const std::string moscow =
         "\x0C\x0C\xD0\x9C\xD0\xBE\xD1\x81\xD0\xBA\xD0\xB2\xD0\xB0";
      const std::string moscow_plain =
         "\xD0\x9C\xD0\xBE\xD1\x81\xD0\xBA\xD0\xB2\xD0\xB0";
      Botan::DataSource_Memory input(moscow.data());
      Botan::BER_Decoder dec(input);

      Botan::ASN1_String str;
      str.decode_from(dec);

      result.test_eq("value()", str.value(), moscow_plain);
      }
   catch(const Botan::Decoding_Error &ex)
      {
      result.test_failure(ex.what());
      }

   return result;
   }

Test::Result test_asn1_ucs2_parsing()
   {
   Test::Result result("ASN.1 BMP string (UCS-2) parsing");

   try
      {
      // \x1E     - ASN1 tag for 'BMP (UCS-2) string'
      // \x0C     - 12 characters of payload
      // ...      - UCS-2 encoding for Moscow in cyrillic script
      const std::string moscow =
         "\x1E\x0C\x04\x1C\x04\x3E\x04\x41\x04\x3A\x04\x32\x04\x30";
      const std::string moscow_plain =
         "\xD0\x9C\xD0\xBE\xD1\x81\xD0\xBA\xD0\xB2\xD0\xB0";

      Botan::DataSource_Memory input(moscow.data());
      Botan::BER_Decoder dec(input);

      Botan::ASN1_String str;
      str.decode_from(dec);

      result.test_eq("value()", str.value(), moscow_plain);
      }
   catch(const Botan::Decoding_Error &ex)
      {
         result.test_failure(ex.what());
      }

   return result;
   }

Test::Result test_asn1_ucs4_parsing()
   {
   Test::Result result("ASN.1 universal string (UCS-4) parsing");

   try
      {
      // \x1C - ASN1 tag for 'universal string'
      // \x18 - 24 characters of payload
      // ...  - UCS-4 encoding for Moscow in cyrillic script
      const Botan::byte moscow[] =
         "\x1C\x18\x00\x00\x04\x1C\x00\x00\x04\x3E\x00\x00\x04\x41\x00\x00\x04\x3A\x00\x00\x04\x32\x00\x00\x04\x30";
      const std::string moscow_plain =
         "\xD0\x9C\xD0\xBE\xD1\x81\xD0\xBA\xD0\xB2\xD0\xB0";
      Botan::DataSource_Memory input(moscow, sizeof(moscow));
      Botan::BER_Decoder dec(input);

      Botan::ASN1_String str;
      str.decode_from(dec);

      result.test_eq("value()", str.value(), moscow_plain);
      }
   catch(const Botan::Decoding_Error &ex)
      {
      result.test_failure(ex.what());
      }

   return result;
   }

Test::Result test_asn1_ascii_encoding()
   {
   Test::Result result("ASN.1 ASCII encoding");

   try
      {
      // UTF-8 encoded (ASCII chars only) word 'Moscow'
      const std::string moscow =
         "\x4D\x6F\x73\x63\x6F\x77";
      Botan::ASN1_String str(moscow);

      Botan::DER_Encoder enc;

      str.encode_into(enc);
      auto encodingResult = enc.get_contents();

      // \x13 - ASN1 tag for 'printable string'
      // \x06 - 6 characters of payload
      const auto moscowEncoded = Botan::hex_decode("13064D6F73636F77");
      result.test_eq("encoding result", encodingResult, moscowEncoded);

      result.test_success("No crash");
      }
   catch(const std::exception &ex)
      {
      result.test_failure(ex.what());
      }

   return result;
   }

Test::Result test_asn1_utf8_encoding()
   {
   Test::Result result("ASN.1 UTF-8 encoding");

   try
      {
      // UTF-8 encoded russian word for Moscow in cyrillic script
      const std::string moscow =
         "\xD0\x9C\xD0\xBE\xD1\x81\xD0\xBA\xD0\xB2\xD0\xB0";
      Botan::ASN1_String str(moscow);

      Botan::DER_Encoder enc;

      str.encode_into(enc);
      auto encodingResult = enc.get_contents();

      // \x0C - ASN1 tag for 'UTF8 string'
      // \x0C - 12 characters of payload
      const auto moscowEncoded =
         Botan::hex_decode("0C0CD09CD0BED181D0BAD0B2D0B0");
      result.test_eq("encoding result", encodingResult, moscowEncoded);

      result.test_success("No crash");
      }
   catch(const std::exception &ex)
      {
      result.test_failure(ex.what());
      }

   return result;
   }

}

class ASN1_Tests final : public Test
   {
   public:
      std::vector<Test::Result> run() override
         {
         std::vector<Test::Result> results;

         results.push_back(test_ber_stack_recursion());
         results.push_back(test_ber_eoc_decoding_limits());
         results.push_back(test_asn1_utf8_ascii_parsing());
         results.push_back(test_asn1_utf8_parsing());
         results.push_back(test_asn1_ucs2_parsing());
         results.push_back(test_asn1_ucs4_parsing());
         results.push_back(test_asn1_ascii_encoding());
         results.push_back(test_asn1_utf8_encoding());

         return results;
         }
   };

BOTAN_REGISTER_TEST("asn1", "asn1", ASN1_Tests);

class ASN1_Time_Parsing_Tests final : public Text_Based_Test
   {
   public:
      ASN1_Time_Parsing_Tests() :
         Text_Based_Test("asn1_time.vec", "Tspec") {}

      Test::Result run_one_test(const std::string& tag_str, const VarMap& vars) override
         {
         Test::Result result("ASN.1 date parsing");

         const std::string tspec = vars.get_req_str("Tspec");

         if(tag_str != "UTC" &&
            tag_str != "UTC.invalid" &&
            tag_str != "Generalized" &&
            tag_str != "Generalized.invalid")
            {
            throw Test_Error("Invalid tag value in ASN1 date parsing test");
            }

         const Botan::ASN1_Type tag =
            (tag_str == "UTC" || tag_str == "UTC.invalid") ? Botan::ASN1_Type::UTC_TIME : Botan::ASN1_Type::GENERALIZED_TIME;

         const bool valid = tag_str.find(".invalid") == std::string::npos;

         if(valid)
            {
            Botan::ASN1_Time time(tspec, tag);
            result.test_success("Accepted valid time");
            }
         else
            {
            result.test_throws("Invalid time rejected", [=]() {
               Botan::ASN1_Time time(tspec, tag);
               });
            }

         return result;
         }
   };

BOTAN_REGISTER_TEST("asn1", "asn1_time", ASN1_Time_Parsing_Tests);

class ASN1_Printer_Tests final : public Test
   {
   public:
      std::vector<Test::Result> run() override
         {
         Test::Result result("ASN1_Pretty_Printer");

         Botan::ASN1_Pretty_Printer printer;

         const size_t num_tests = 6;

         for(size_t i = 1; i <= num_tests; ++i)
            {
            std::string i_str = std::to_string(i);
            const std::vector<uint8_t> input1 = Test::read_binary_data_file("asn1_print/input" + i_str + ".der");
            const std::string expected1 = Test::read_data_file("asn1_print/output" + i_str + ".txt");

            result.test_eq("Test " + i_str, printer.print(input1), expected1);
            }

         return {result};
         }
   };

BOTAN_REGISTER_TEST("asn1", "asn1_printer", ASN1_Printer_Tests);

#endif

}

<commit_msg>Test ASN.1 class/type underlying types<commit_after>/*
* (C) 2017 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "tests.h"

#if defined(BOTAN_HAS_ASN1)
   #include <botan/der_enc.h>
   #include <botan/ber_dec.h>
   #include <botan/asn1_print.h>
#endif

namespace Botan_Tests {

#if defined(BOTAN_HAS_ASN1)

namespace {

Test::Result test_ber_stack_recursion()
   {
   Test::Result result("BER stack recursion");

   // OSS-Fuzz #813 GitHub #989

   try
      {
      const std::vector<uint8_t> in(10000000, 0);
      Botan::DataSource_Memory input(in.data(), in.size());
      Botan::BER_Decoder dec(input);

      while(dec.more_items())
         {
         Botan::BER_Object obj;
         dec.get_next(obj);
         }
      }
   catch(Botan::Decoding_Error&)
      {
      }

   result.test_success("No crash");

   return result;
   }

Test::Result test_ber_eoc_decoding_limits()
   {
   Test::Result result("BER nested indefinite length");

   // OSS-Fuzz #4353

   Botan::ASN1_Pretty_Printer printer;

   size_t max_eoc_allowed = 0;

   for(size_t len = 1; len < 1024; ++len)
      {
      std::vector<uint8_t> buf(4*len);

      /*
      This constructs a len deep sequence of SEQUENCES each with
      an indefinite length
      */
      for(size_t i = 0; i != 2*len; i += 2)
         {
         buf[i  ] = 0x30;
         buf[i+1] = 0x80;
         }
      // remainder of values left as zeros (EOC markers)

      try
         {
         printer.print(buf);
         }
      catch(Botan::BER_Decoding_Error&)
         {
         max_eoc_allowed = len - 1;
         break;
         }
      }

   result.test_eq("EOC limited to prevent stack exhaustion", max_eoc_allowed, 16);

   return result;
   }

Test::Result test_asn1_utf8_ascii_parsing()
   {
   Test::Result result("ASN.1 ASCII parsing");

   try
      {
      // \x13 - ASN1 tag for 'printable string'
      // \x06 - 6 characters of payload
      // ...  - UTF-8 encoded (ASCII chars only) word 'Moscow'
      const std::string moscow =
         "\x13\x06\x4D\x6F\x73\x63\x6F\x77";
      const std::string moscow_plain = "Moscow";
      Botan::DataSource_Memory input(moscow.data());
      Botan::BER_Decoder dec(input);

      Botan::ASN1_String str;
      str.decode_from(dec);

      result.test_eq("value()", str.value(), moscow_plain);
      }
   catch(const Botan::Decoding_Error &ex)
      {
      result.test_failure(ex.what());
      }

   return result;
   }

Test::Result test_asn1_utf8_parsing()
   {
   Test::Result result("ASN.1 UTF-8 parsing");

   try
      {
      // \x0C - ASN1 tag for 'UTF8 string'
      // \x0C - 12 characters of payload
      // ...  - UTF-8 encoded russian word for Moscow in cyrillic script
      const std::string moscow =
         "\x0C\x0C\xD0\x9C\xD0\xBE\xD1\x81\xD0\xBA\xD0\xB2\xD0\xB0";
      const std::string moscow_plain =
         "\xD0\x9C\xD0\xBE\xD1\x81\xD0\xBA\xD0\xB2\xD0\xB0";
      Botan::DataSource_Memory input(moscow.data());
      Botan::BER_Decoder dec(input);

      Botan::ASN1_String str;
      str.decode_from(dec);

      result.test_eq("value()", str.value(), moscow_plain);
      }
   catch(const Botan::Decoding_Error &ex)
      {
      result.test_failure(ex.what());
      }

   return result;
   }

Test::Result test_asn1_ucs2_parsing()
   {
   Test::Result result("ASN.1 BMP string (UCS-2) parsing");

   try
      {
      // \x1E     - ASN1 tag for 'BMP (UCS-2) string'
      // \x0C     - 12 characters of payload
      // ...      - UCS-2 encoding for Moscow in cyrillic script
      const std::string moscow =
         "\x1E\x0C\x04\x1C\x04\x3E\x04\x41\x04\x3A\x04\x32\x04\x30";
      const std::string moscow_plain =
         "\xD0\x9C\xD0\xBE\xD1\x81\xD0\xBA\xD0\xB2\xD0\xB0";

      Botan::DataSource_Memory input(moscow.data());
      Botan::BER_Decoder dec(input);

      Botan::ASN1_String str;
      str.decode_from(dec);

      result.test_eq("value()", str.value(), moscow_plain);
      }
   catch(const Botan::Decoding_Error &ex)
      {
         result.test_failure(ex.what());
      }

   return result;
   }

Test::Result test_asn1_ucs4_parsing()
   {
   Test::Result result("ASN.1 universal string (UCS-4) parsing");

   try
      {
      // \x1C - ASN1 tag for 'universal string'
      // \x18 - 24 characters of payload
      // ...  - UCS-4 encoding for Moscow in cyrillic script
      const Botan::byte moscow[] =
         "\x1C\x18\x00\x00\x04\x1C\x00\x00\x04\x3E\x00\x00\x04\x41\x00\x00\x04\x3A\x00\x00\x04\x32\x00\x00\x04\x30";
      const std::string moscow_plain =
         "\xD0\x9C\xD0\xBE\xD1\x81\xD0\xBA\xD0\xB2\xD0\xB0";
      Botan::DataSource_Memory input(moscow, sizeof(moscow));
      Botan::BER_Decoder dec(input);

      Botan::ASN1_String str;
      str.decode_from(dec);

      result.test_eq("value()", str.value(), moscow_plain);
      }
   catch(const Botan::Decoding_Error &ex)
      {
      result.test_failure(ex.what());
      }

   return result;
   }

Test::Result test_asn1_ascii_encoding()
   {
   Test::Result result("ASN.1 ASCII encoding");

   try
      {
      // UTF-8 encoded (ASCII chars only) word 'Moscow'
      const std::string moscow =
         "\x4D\x6F\x73\x63\x6F\x77";
      Botan::ASN1_String str(moscow);

      Botan::DER_Encoder enc;

      str.encode_into(enc);
      auto encodingResult = enc.get_contents();

      // \x13 - ASN1 tag for 'printable string'
      // \x06 - 6 characters of payload
      const auto moscowEncoded = Botan::hex_decode("13064D6F73636F77");
      result.test_eq("encoding result", encodingResult, moscowEncoded);

      result.test_success("No crash");
      }
   catch(const std::exception &ex)
      {
      result.test_failure(ex.what());
      }

   return result;
   }

Test::Result test_asn1_utf8_encoding()
   {
   Test::Result result("ASN.1 UTF-8 encoding");

   try
      {
      // UTF-8 encoded russian word for Moscow in cyrillic script
      const std::string moscow =
         "\xD0\x9C\xD0\xBE\xD1\x81\xD0\xBA\xD0\xB2\xD0\xB0";
      Botan::ASN1_String str(moscow);

      Botan::DER_Encoder enc;

      str.encode_into(enc);
      auto encodingResult = enc.get_contents();

      // \x0C - ASN1 tag for 'UTF8 string'
      // \x0C - 12 characters of payload
      const auto moscowEncoded =
         Botan::hex_decode("0C0CD09CD0BED181D0BAD0B2D0B0");
      result.test_eq("encoding result", encodingResult, moscowEncoded);

      result.test_success("No crash");
      }
   catch(const std::exception &ex)
      {
      result.test_failure(ex.what());
      }

   return result;
   }

Test::Result test_asn1_tag_underlying_type()
   {
   Test::Result result("ASN.1 class and type underlying type");

   if constexpr(std::is_same_v<std::underlying_type_t<Botan::ASN1_Class>,
                               std::underlying_type_t<Botan::ASN1_Type>>)
   {
      if constexpr(!std::is_same_v<std::underlying_type_t<Botan::ASN1_Class>,
                                   std::invoke_result_t<decltype(&Botan::BER_Object::tagging), Botan::BER_Object>>)
      {
         result.test_failure("Return type of BER_Object::tagging() is different than the underlying type of ASN1_Class");
      }
      else
      {
         result.test_success("Same types");
      }
   }
   else
   {
      result.test_failure("ASN1_Class and ASN1_Type have different underlying types");
   }

   return result;
   }

}

class ASN1_Tests final : public Test
   {
   public:
      std::vector<Test::Result> run() override
         {
         std::vector<Test::Result> results;

         results.push_back(test_ber_stack_recursion());
         results.push_back(test_ber_eoc_decoding_limits());
         results.push_back(test_asn1_utf8_ascii_parsing());
         results.push_back(test_asn1_utf8_parsing());
         results.push_back(test_asn1_ucs2_parsing());
         results.push_back(test_asn1_ucs4_parsing());
         results.push_back(test_asn1_ascii_encoding());
         results.push_back(test_asn1_utf8_encoding());
         results.push_back(test_asn1_tag_underlying_type());

         return results;
         }
   };

BOTAN_REGISTER_TEST("asn1", "asn1", ASN1_Tests);

class ASN1_Time_Parsing_Tests final : public Text_Based_Test
   {
   public:
      ASN1_Time_Parsing_Tests() :
         Text_Based_Test("asn1_time.vec", "Tspec") {}

      Test::Result run_one_test(const std::string& tag_str, const VarMap& vars) override
         {
         Test::Result result("ASN.1 date parsing");

         const std::string tspec = vars.get_req_str("Tspec");

         if(tag_str != "UTC" &&
            tag_str != "UTC.invalid" &&
            tag_str != "Generalized" &&
            tag_str != "Generalized.invalid")
            {
            throw Test_Error("Invalid tag value in ASN1 date parsing test");
            }

         const Botan::ASN1_Type tag =
            (tag_str == "UTC" || tag_str == "UTC.invalid") ? Botan::ASN1_Type::UTC_TIME : Botan::ASN1_Type::GENERALIZED_TIME;

         const bool valid = tag_str.find(".invalid") == std::string::npos;

         if(valid)
            {
            Botan::ASN1_Time time(tspec, tag);
            result.test_success("Accepted valid time");
            }
         else
            {
            result.test_throws("Invalid time rejected", [=]() {
               Botan::ASN1_Time time(tspec, tag);
               });
            }

         return result;
         }
   };

BOTAN_REGISTER_TEST("asn1", "asn1_time", ASN1_Time_Parsing_Tests);

class ASN1_Printer_Tests final : public Test
   {
   public:
      std::vector<Test::Result> run() override
         {
         Test::Result result("ASN1_Pretty_Printer");

         Botan::ASN1_Pretty_Printer printer;

         const size_t num_tests = 6;

         for(size_t i = 1; i <= num_tests; ++i)
            {
            std::string i_str = std::to_string(i);
            const std::vector<uint8_t> input1 = Test::read_binary_data_file("asn1_print/input" + i_str + ".der");
            const std::string expected1 = Test::read_data_file("asn1_print/output" + i_str + ".txt");

            result.test_eq("Test " + i_str, printer.print(input1), expected1);
            }

         return {result};
         }
   };

BOTAN_REGISTER_TEST("asn1", "asn1_printer", ASN1_Printer_Tests);

#endif

}

<|endoftext|>


<commit_before>#include "thread_renderer.h"
#include "audio_nodes.h"
#include "recorder_node.h"

namespace cieq {

ThreadRenderer::ThreadRenderer(AudioNodes& nodes, int frames_per_unit, int fft_size, int viewable_frames)
	: mViewableFrames(viewable_frames)
{
	int num_blocks = (nodes.getBufferRecorderNode()->getNumFrames() / frames_per_unit) + 1;
	mSurfacePool.resize(num_blocks);
	mTexturePool.resize(num_blocks);
	for (auto index = 0; index < num_blocks; ++index)
	{
		mSurfacePool.push_back(std::make_unique<SpectralSurface>(frames_per_unit, fft_size));
		mTexturePool.push_back(ci::gl::Texture::create(*mSurfacePool.back()));
	}

	mFramebuffer = ci::gl::Fbo(viewable_frames, fft_size);
}

void ThreadRenderer::update()
{
	auto index = 0;
	for (SpectralSurfaceRef& surface : mSurfacePool)
	{
		if (*surface && surface->allRowsTouched())
		{
			mTexturePool[index]->update(*surface);
			surface->reset();
		}
		++index;
	}
}

void ThreadRenderer::draw()
{
	auto index = 0;

	ci::gl::SaveFramebufferBinding _bindings;

	//! draw everything to a frame buffer
	mFramebuffer.bindFramebuffer();

	for (SpectralSurfaceRef& surface : mSurfacePool)
	{
		if (*surface)
		{
			//draw surface here.
		}
		else
		{
			//draw mTexturePool[index] here.
		}
		++index;
	}

	mFramebuffer.unbindFramebuffer();
}

SpectralSurface& ThreadRenderer::getSurface(int index)
{
	return *(mSurfacePool[index]);
}

ci::gl::Texture& ThreadRenderer::getTexture(int index)
{
	return *mTexturePool[index].get();
}

} //!cieq<commit_msg>Changed thread_renderer's ctor logic<commit_after>#include "thread_renderer.h"
#include "audio_nodes.h"
#include "recorder_node.h"

namespace cieq {

ThreadRenderer::ThreadRenderer(AudioNodes& nodes, int frames_per_unit, int fft_size, int viewable_frames)
	: mViewableFrames(viewable_frames)
{
	// num_blocks * (hopSize + windowSize) >= numFrames:
	int num_processings = (nodes.getBufferRecorderNode()->getNumFrames() / (nodes.getBufferRecorderNode()->getWindowSize() + nodes.getBufferRecorderNode()->getHopSize()));
	int num_blocks = num_processings / frames_per_unit + 1;
	for (auto index = 0; index < num_blocks; ++index)
	{
		mSurfacePool.push_back(std::make_unique<SpectralSurface>(frames_per_unit, fft_size));
		mTexturePool.push_back(ci::gl::Texture::create(*mSurfacePool.back()));
	}

	mFramebuffer = ci::gl::Fbo(viewable_frames, fft_size);
}

void ThreadRenderer::update()
{
	auto index = 0;
	for (SpectralSurfaceRef& surface : mSurfacePool)
	{
		if (*surface && surface->allRowsTouched())
		{
			mTexturePool[index]->update(*surface);
			surface->reset();
		}
		++index;
	}
}

void ThreadRenderer::draw()
{
	auto index = 0;

	ci::gl::SaveFramebufferBinding _bindings;

	//! draw everything to a frame buffer
	mFramebuffer.bindFramebuffer();

	for (SpectralSurfaceRef& surface : mSurfacePool)
	{
		if (*surface)
		{
			//draw surface here.
		}
		else
		{
			//draw mTexturePool[index] here.
		}
		++index;
	}

	mFramebuffer.unbindFramebuffer();
}

SpectralSurface& ThreadRenderer::getSurface(int index)
{
	return *(mSurfacePool[index]);
}

ci::gl::Texture& ThreadRenderer::getTexture(int index)
{
	return *mTexturePool[index].get();
}

} //!cieq<|endoftext|>