<commit_before>#include "history.h"

History::History(const std::string& fileName):
   _mem(fileName)
{
   if (_mem.size()==0)
   {
      _mem.reserve(_emptyLen);
      _mem.allocate(_header);
      _mem.allocate(_info);
      _header.head() = _info.addr();
      _header.dataHead() = FileMem::nullPtr;
      _mem.sync(_header,FileSync::write);
      _info.timeStamp() = 0;
      _info.fileNamePtr() = FileMem::nullPtr;
      _info.fileNameSize() = 0;
      _info.objectPtr() = FileMem::nullPtr;
      _info.objectSize() = 0;
      _info.commandPtr() = FileMem::nullPtr;
      _info.commandSize() = 0;
      _info.childHead() = FileMem::nullPtr;
      _info.next() = FileMem::nullPtr;
      _mem.sync(_info,FileSync::write);
   }
   else
   {
      bool cond = _mem.size()>=_emptyLen;
      assert<InvalidFile>(cond,__FILE__,__LINE__);
      _header = _mem.head();
      _mem.sync(_header,FileSync::read);
      cond = true;
      for (int i=0;i<_idLen;++i)
      {
         if (_header.ident()[i]!=_identString[i])
         {
            cond = false;
         }
      }
      assert<InvalidFile>(cond,__FILE__,__LINE__);
      _info = _header.head();
      _mem.sync(_info,FileSync::read);
   }
}

void History::set_timestamp(int64_t tStamp)
{
   _info.timeStamp() = tStamp;
   _mem.sync(_info,FileSync::write);
}

void History::set_filename(const std::string& name)
{
   bool cond = _info.fileNamePtr()==FileMem::nullPtr;
   assert<AlreadySet>(cond,__FILE__,__LINE__);
   _info.fileNamePtr() = write_string(name);
   _info.fileNameSize() = name.size();
   _mem.sync(_info,FileSync::write);
}

void History::set_object(const std::string& object)
{
   bool cond = _info.objectPtr()==FileMem::nullPtr;
   assert<AlreadySet>(cond,__FILE__,__LINE__);
   _info.objectPtr() = write_string(object);
   _info.objectSize() = object.size();
   _mem.sync(_info,FileSync::write);
}

void History::set_command(const std::string& command)
{
   bool cond = _info.commandPtr()==FileMem::nullPtr;
   assert<AlreadySet>(cond,__FILE__,__LINE__);
   _info.commandPtr() = write_string(command);
   _info.commandSize() = command.size();
   _mem.sync(_info,FileSync::write);
}

void History::add_child(History& child)
{
   if (_info.childHead()==FileMem::nullPtr)
   {
      _info.childHead() = rec_add_child(child.begin());
      _mem.sync(_info,FileSync::write);
   }
   else
   {
      Node i = _info.childHead();
      _mem.sync(i,FileSync::read);
      while (i.next()!=FileMem::nullPtr)
      {
         i = i.next();
         _mem.sync(i,FileSync::read);
      }
      i.next() = rec_add_child(child.begin());
      _mem.sync(i,FileSync::write);
   }
}

History::Iterator History::begin()
{
   return {_info.childHead(),_mem};
}

History::Iterator History::end()
{
   return {FileMem::nullPtr,_mem};
}

FileMem::Ptr History::write_string(const std::string& str)
{
   int rLen = str.size() + 1;
   if (_mem.capacity()<rLen)
   {
      _mem.reserve(rLen - _mem.capacity());
   }
   String string(rLen);
   memcpy(string.c_str(),str.c_str(),rLen);
   _mem.allocate(string);
   _mem.sync(string,FileSync::write);
}

FileMem::Ptr History::rec_add_child(Iterator i)
{
   if (i!=end())
   {
      Node child = *i;
      _mem.allocate(child);
      copy_child(child,i);
      child.childHead() = rec_add_child(i.childHead());
      child.next() = rec_add_child(++i);
      _mem.sync(child,FileSync::write);
      return child.addr();
   }
   else
   {
      return FileMem::nullPtr;
   }
}

void History::copy_child(Node& child, Iterator& i)
{
   bool cond = child.fileNamePtr()!=FileMem::nullPtr&&
               child.objectPtr()!=FileMem::nullPtr&&
               child.commandPtr()!=FileMem::nullPtr;
   assert<NotSet>(cond,__FILE__,__LINE__);
   String fileName(child.fileNameSize());
   String object(child.objectSize());
   String command(child.commandSize());
   memcpy(fileName.c_str(),i.filename().c_str(),child.fileNameSize());
   memcpy(object.c_str(),i.object().c_str(),child.objectSize());
   memcpy(command.c_str(),i.command().c_str(),child.commandSize());
   _mem.allocate(fileName);
   _mem.allocate(object);
   _mem.allocate(command);
   _mem.sync(fileName,FileSync::write);
   _mem.sync(object,FileSync::write);
   _mem.sync(command,FileSync::write);
}

int64_t History::Iterator::timestamp()
{
   return _info.timeStamp();
}

std::string History::Iterator::filename()
{
   std::string ret;
   if (_ptr!=FileMem::nullPtr&&_info.fileNamePtr()!=FileMem::nullPtr)
   {
      String string(_info.fileNameSize(),_info.fileNamePtr());
      _mem.sync(string,FileSync::read);
      ret = string.c_str();
   }
   return ret;
}

std::string History::Iterator::object()
{
   std::string ret;
   if (_ptr!=FileMem::nullPtr&&_info.objectPtr()!=FileMem::nullPtr)
   {
      String string(_info.objectSize(),_info.objectPtr());
      _mem.sync(string,FileSync::read);
      ret = string.c_str();
   }
   return ret;
}

std::string History::Iterator::command()
{
   std::string ret;
   if (_ptr!=FileMem::nullPtr&&_info.commandPtr()!=FileMem::nullPtr)
   {
      String string(_info.commandSize(),_info.commandPtr());
      _mem.sync(string,FileSync::read);
      ret = string.c_str();
   }
   return ret;
}

History::Iterator History::Iterator::childHead()
{
   return {_info.childHead(),_mem};
}

History::Iterator& History::Iterator::operator++()
{
   _ptr = _info.next();
   if (_ptr!=FileMem::nullPtr)
   {
      _info = _ptr;
      _mem.sync(_info,FileSync::read);
   }
   return *this;
}

bool History::Iterator::operator!=(const Iterator& cmp)
{
   return _ptr!=cmp._ptr;
}

History::Iterator::Iterator(FileMem::Ptr ptr, FileMem& mem):
   _ptr(ptr),
   _mem(mem)
{
   _info.next() = FileMem::nullPtr;
   if (_ptr!=FileMem::nullPtr)
   {
      _mem.sync(_info,FileSync::read);
   }
}

History::Node& History::Iterator::operator*()
{
   return _info;
}
<commit_msg>Trimmed history class.<commit_after>#include "history.h"

History::History(const std::string& fileName):
   _mem(fileName)
{
   if (_mem.size()==0)
   {
      _mem.reserve(_emptyLen);
      _mem.allocate(_header);
      _mem.allocate(_info);
      _header.head() = _info.addr();
      _header.dataHead() = FileMem::nullPtr;
      _mem.sync(_header,FileSync::write);
      _info.timeStamp() = 0;
      _info.fileNamePtr() = FileMem::nullPtr;
      _info.fileNameSize() = 0;
      _info.objectPtr() = FileMem::nullPtr;
      _info.objectSize() = 0;
      _info.commandPtr() = FileMem::nullPtr;
      _info.commandSize() = 0;
      _info.childHead() = FileMem::nullPtr;
      _info.next() = FileMem::nullPtr;
      _mem.sync(_info,FileSync::write);
   }
   else
   {
      bool cond = _mem.size()>=_emptyLen;
      assert<InvalidFile>(cond,__FILE__,__LINE__);
      _header = _mem.head();
      _mem.sync(_header,FileSync::read);
      cond = true;
      for (int i=0;i<_idLen;++i)
      {
         if (_header.ident()[i]!=_identString[i])
         {
            cond = false;
         }
      }
      assert<InvalidFile>(cond,__FILE__,__LINE__);
      _info = _header.head();
      _mem.sync(_info,FileSync::read);
   }
}

void History::set_timestamp(int64_t tStamp)
{
   _info.timeStamp() = tStamp;
   _mem.sync(_info,FileSync::write);
}

void History::set_filename(const std::string& name)
{
   bool cond = _info.fileNamePtr()==FileMem::nullPtr;
   assert<AlreadySet>(cond,__FILE__,__LINE__);
   _info.fileNamePtr() = write_string(name);
   _info.fileNameSize() = name.size();
   _mem.sync(_info,FileSync::write);
}

void History::set_object(const std::string& object)
{
   bool cond = _info.objectPtr()==FileMem::nullPtr;
   assert<AlreadySet>(cond,__FILE__,__LINE__);
   _info.objectPtr() = write_string(object);
   _info.objectSize() = object.size();
   _mem.sync(_info,FileSync::write);
}

void History::set_command(const std::string& command)
{
   bool cond = _info.commandPtr()==FileMem::nullPtr;
   assert<AlreadySet>(cond,__FILE__,__LINE__);
   _info.commandPtr() = write_string(command);
   _info.commandSize() = command.size();
   _mem.sync(_info,FileSync::write);
}

void History::add_child(History& child)
{
   if (_info.childHead()==FileMem::nullPtr)
   {
      _info.childHead() = rec_add_child(child.begin());
      _mem.sync(_info,FileSync::write);
   }
   else
   {
      Node i = _info.childHead();
      _mem.sync(i,FileSync::read);
      while (i.next()!=FileMem::nullPtr)
      {
         i = i.next();
         _mem.sync(i,FileSync::read);
      }
      i.next() = rec_add_child(child.begin());
      _mem.sync(i,FileSync::write);
   }
}

History::Iterator History::begin()
{
   return {_info.childHead(),_mem};
}

History::Iterator History::end()
{
   return {FileMem::nullPtr,_mem};
}

FileMem::Ptr History::write_string(const std::string& str)
{
   int rLen = str.size() + 1;
   if (_mem.capacity()<rLen)
   {
      _mem.reserve(rLen - _mem.capacity());
   }
   String string(rLen);
   memcpy(string.c_str(),str.c_str(),rLen);
   _mem.allocate(string);
   _mem.sync(string,FileSync::write);
}

FileMem::Ptr History::rec_add_child(Iterator i)
{
   if (i!=end())
   {
      Node child = *i;
      _mem.allocate(child);
      copy_child(child,i);
      child.childHead() = rec_add_child(i.childHead());
      child.next() = rec_add_child(++i);
      _mem.sync(child,FileSync::write);
      return child.addr();
   }
   else
   {
      return FileMem::nullPtr;
   }
}

void History::copy_child(Node& child, Iterator& i)
{
   bool cond = child.fileNamePtr()!=FileMem::nullPtr&&
               child.objectPtr()!=FileMem::nullPtr&&
               child.commandPtr()!=FileMem::nullPtr;
   assert<NotSet>(cond,__FILE__,__LINE__);
   child.fileNamePtr() = write_string(i.filename());
   child.objectPtr() = write_string(i.object());
   child.commandPtr() = write_string(i.command());
}

int64_t History::Iterator::timestamp()
{
   return _info.timeStamp();
}

std::string History::Iterator::filename()
{
   std::string ret;
   if (_ptr!=FileMem::nullPtr&&_info.fileNamePtr()!=FileMem::nullPtr)
   {
      String string(_info.fileNameSize(),_info.fileNamePtr());
      _mem.sync(string,FileSync::read);
      ret = string.c_str();
   }
   return ret;
}

std::string History::Iterator::object()
{
   std::string ret;
   if (_ptr!=FileMem::nullPtr&&_info.objectPtr()!=FileMem::nullPtr)
   {
      String string(_info.objectSize(),_info.objectPtr());
      _mem.sync(string,FileSync::read);
      ret = string.c_str();
   }
   return ret;
}

std::string History::Iterator::command()
{
   std::string ret;
   if (_ptr!=FileMem::nullPtr&&_info.commandPtr()!=FileMem::nullPtr)
   {
      String string(_info.commandSize(),_info.commandPtr());
      _mem.sync(string,FileSync::read);
      ret = string.c_str();
   }
   return ret;
}

History::Iterator History::Iterator::childHead()
{
   return {_info.childHead(),_mem};
}

History::Iterator& History::Iterator::operator++()
{
   _ptr = _info.next();
   if (_ptr!=FileMem::nullPtr)
   {
      _info = _ptr;
      _mem.sync(_info,FileSync::read);
   }
   return *this;
}

bool History::Iterator::operator!=(const Iterator& cmp)
{
   return _ptr!=cmp._ptr;
}

History::Iterator::Iterator(FileMem::Ptr ptr, FileMem& mem):
   _ptr(ptr),
   _mem(mem)
{
   _info.next() = FileMem::nullPtr;
   if (_ptr!=FileMem::nullPtr)
   {
      _mem.sync(_info,FileSync::read);
   }
}

History::Node& History::Iterator::operator*()
{
   return _info;
}
<|endoftext|>


<commit_before>// Copyright (c) Arduino. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include <time.h>
#include <sys/time.h>

#include "sdk/httpapi.h"
#include "sdk/iot_logging.h"

#include "util/HTTPSClient.h"
#include "util/NTPClient.h"

#define POOL_SIZE 1

HTTPSClient httpsClients[POOL_SIZE];

HTTPAPI_RESULT HTTPAPI_Init(void)
{
    time_t epochTime = (time_t)-1;
    NTPClient ntpClient;

    ntpClient.begin();
    while (true) {
        epochTime = ntpClient.getEpochTime("0.pool.ntp.org");

        if (epochTime == (time_t)-1) {
            LogError("Fetching NTP epoch time failed!\n");
            delay(5000);
        } else {
            LogInfo("Fetched NTP epoch time is: %lu\n", epochTime);
            break;
        }
    }
    ntpClient.end();

    struct timeval tv;
    tv.tv_sec = epochTime;
    tv.tv_usec = 0;

    settimeofday(&tv, NULL);

    for (int i = 0; i < POOL_SIZE; i++) {
        httpsClients[i] = HTTPSClient();
    }
    return HTTPAPI_OK;
}

void HTTPAPI_Deinit(void)
{
}

HTTP_HANDLE HTTPAPI_CreateConnection(const char* hostName)
{
    HTTPSClient* client = NULL;

    // find an available client to use
    for (int i = 0; i < POOL_SIZE; i++) {
        if (!httpsClients[i].connected()) {
            client = &httpsClients[i];
            break;
        }
    }

    if (client) {
        if (!client->begin(hostName)) {
            // connection failed
            LogError("HTTPS connection to %s failed\n", hostName);
            client = NULL;
        }
    } else {
        // no clients available
        LogError("No HTTPS clients available\n");
    }

    return ((HTTP_HANDLE)client);
}

void HTTPAPI_CloseConnection(HTTP_HANDLE handle)
{
    HTTPSClient* client = (HTTPSClient*)handle;

    client->end();
}

static const char* HTTPRequestTypes[] = {
    "GET",
    "POST",
    "PUT",
    "DELETE",
    "PATCH"
};

HTTPAPI_RESULT HTTPAPI_ExecuteRequest(HTTP_HANDLE handle,
        HTTPAPI_REQUEST_TYPE requestType, const char* relativePath,
        HTTP_HEADERS_HANDLE httpHeadersHandle, const unsigned char* content,
        size_t contentLength, unsigned int* statusCode,
        HTTP_HEADERS_HANDLE responseHeadersHandle,
        BUFFER_HANDLE responseContent)
{
    int result;
    size_t headersCount;
    char* header;

    HTTPSClient* client = (HTTPSClient*)handle;

    if (!client->connected()) {
        // client not connected
        LogError("HTTPS request failed, client not connected\n");
        return HTTPAPI_OPEN_REQUEST_FAILED;
    }

    result = client->sendRequest(HTTPRequestTypes[requestType], relativePath);
    if (!result) {
        LogError("HTTPS send request failed\n");
        return HTTPAPI_SEND_REQUEST_FAILED;
    }

    HTTPHeaders_GetHeaderCount(httpHeadersHandle, &headersCount);

    for (size_t i = 0; i < headersCount && result; i++) {
        HTTPHeaders_GetHeader(httpHeadersHandle, i, &header);
        result = client->sendHeader(header);
        free(header);
    }

    if (!result) {
        LogError("HTTPS send header failed\n");
        return HTTPAPI_SEND_REQUEST_FAILED;
    }

    result = client->sendBody(content, contentLength);
    if (!result) {
        LogError("HTTPS send body failed\n");
        return HTTPAPI_SEND_REQUEST_FAILED;
    }

    result = client->readStatus();
    if (result == -1) {
        return HTTPAPI_STRING_PROCESSING_ERROR;
    }
    *statusCode = result;

    while (result > 0) {
        String headerName;
        String headerValue;

        result = client->readHeader(headerName, headerValue);
        HTTPHeaders_AddHeaderNameValuePair(responseHeadersHandle, headerName.c_str(), headerValue.c_str());
    }

    if (result == -1) {
        LogError("HTTPS header parsing failed\n");
        return HTTPAPI_HTTP_HEADERS_FAILED;
    }

    contentLength = client->contentLength();
    if (contentLength) {
        BUFFER_pre_build(responseContent, contentLength);
        client->readBody(BUFFER_u_char(responseContent), contentLength);
    }

    return HTTPAPI_OK;
}

HTTPAPI_RESULT HTTPAPI_SetOption(HTTP_HANDLE handle, const char* optionName,
        const void* value)
{
    HTTPSClient* client = (HTTPSClient*)handle;
    HTTPAPI_RESULT result = HTTPAPI_INVALID_ARG;

    if (strcmp("timeout", optionName) == 0) {
        client->setTimeout(*(const unsigned int*)value);

        result = HTTPAPI_OK;
    }

    return result;
}

HTTPAPI_RESULT HTTPAPI_CloneOption(const char* optionName, const void* value,
        const void** savedValue)
{
    HTTPAPI_RESULT result = HTTPAPI_INVALID_ARG;

    if (strcmp("timeout", optionName) == 0) {
        unsigned int* timeout = (unsigned int*)malloc(sizeof(unsigned int));

        *timeout = *(const unsigned int*)value;

        *savedValue = &timeout;

        result = HTTPAPI_OK;
    }

    return result;
}
<commit_msg>Set initial HTTPS client timeout to 10s<commit_after>// Copyright (c) Arduino. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include <time.h>
#include <sys/time.h>

#include "sdk/httpapi.h"
#include "sdk/iot_logging.h"

#include "util/HTTPSClient.h"
#include "util/NTPClient.h"

#define POOL_SIZE 1

HTTPSClient httpsClients[POOL_SIZE];

HTTPAPI_RESULT HTTPAPI_Init(void)
{
    time_t epochTime = (time_t)-1;
    NTPClient ntpClient;

    ntpClient.begin();
    while (true) {
        epochTime = ntpClient.getEpochTime("0.pool.ntp.org");

        if (epochTime == (time_t)-1) {
            LogError("Fetching NTP epoch time failed!\n");
            delay(5000);
        } else {
            LogInfo("Fetched NTP epoch time is: %lu\n", epochTime);
            break;
        }
    }
    ntpClient.end();

    struct timeval tv;
    tv.tv_sec = epochTime;
    tv.tv_usec = 0;

    settimeofday(&tv, NULL);

    for (int i = 0; i < POOL_SIZE; i++) {
        httpsClients[i] = HTTPSClient();
        httpsClients[i].setTimeout(10000);
    }
    return HTTPAPI_OK;
}

void HTTPAPI_Deinit(void)
{
}

HTTP_HANDLE HTTPAPI_CreateConnection(const char* hostName)
{
    HTTPSClient* client = NULL;

    // find an available client to use
    for (int i = 0; i < POOL_SIZE; i++) {
        if (!httpsClients[i].connected()) {
            client = &httpsClients[i];
            break;
        }
    }

    if (client) {
        if (!client->begin(hostName)) {
            // connection failed
            LogError("HTTPS connection to %s failed\n", hostName);
            client = NULL;
        }
    } else {
        // no clients available
        LogError("No HTTPS clients available\n");
    }

    return ((HTTP_HANDLE)client);
}

void HTTPAPI_CloseConnection(HTTP_HANDLE handle)
{
    HTTPSClient* client = (HTTPSClient*)handle;

    client->end();
}

static const char* HTTPRequestTypes[] = {
    "GET",
    "POST",
    "PUT",
    "DELETE",
    "PATCH"
};

HTTPAPI_RESULT HTTPAPI_ExecuteRequest(HTTP_HANDLE handle,
        HTTPAPI_REQUEST_TYPE requestType, const char* relativePath,
        HTTP_HEADERS_HANDLE httpHeadersHandle, const unsigned char* content,
        size_t contentLength, unsigned int* statusCode,
        HTTP_HEADERS_HANDLE responseHeadersHandle,
        BUFFER_HANDLE responseContent)
{
    int result;
    size_t headersCount;
    char* header;

    HTTPSClient* client = (HTTPSClient*)handle;

    if (!client->connected()) {
        // client not connected
        LogError("HTTPS request failed, client not connected\n");
        return HTTPAPI_OPEN_REQUEST_FAILED;
    }

    result = client->sendRequest(HTTPRequestTypes[requestType], relativePath);
    if (!result) {
        LogError("HTTPS send request failed\n");
        return HTTPAPI_SEND_REQUEST_FAILED;
    }

    HTTPHeaders_GetHeaderCount(httpHeadersHandle, &headersCount);

    for (size_t i = 0; i < headersCount && result; i++) {
        HTTPHeaders_GetHeader(httpHeadersHandle, i, &header);
        result = client->sendHeader(header);
        free(header);
    }

    if (!result) {
        LogError("HTTPS send header failed\n");
        return HTTPAPI_SEND_REQUEST_FAILED;
    }

    result = client->sendBody(content, contentLength);
    if (!result) {
        LogError("HTTPS send body failed\n");
        return HTTPAPI_SEND_REQUEST_FAILED;
    }

    result = client->readStatus();
    if (result == -1) {
        return HTTPAPI_STRING_PROCESSING_ERROR;
    }
    *statusCode = result;

    while (result > 0) {
        String headerName;
        String headerValue;

        result = client->readHeader(headerName, headerValue);
        HTTPHeaders_AddHeaderNameValuePair(responseHeadersHandle, headerName.c_str(), headerValue.c_str());
    }

    if (result == -1) {
        LogError("HTTPS header parsing failed\n");
        return HTTPAPI_HTTP_HEADERS_FAILED;
    }

    contentLength = client->contentLength();
    if (contentLength) {
        BUFFER_pre_build(responseContent, contentLength);
        client->readBody(BUFFER_u_char(responseContent), contentLength);
    }

    return HTTPAPI_OK;
}

HTTPAPI_RESULT HTTPAPI_SetOption(HTTP_HANDLE handle, const char* optionName,
        const void* value)
{
    HTTPSClient* client = (HTTPSClient*)handle;
    HTTPAPI_RESULT result = HTTPAPI_INVALID_ARG;

    if (strcmp("timeout", optionName) == 0) {
        client->setTimeout(*(const unsigned int*)value);

        result = HTTPAPI_OK;
    }

    return result;
}

HTTPAPI_RESULT HTTPAPI_CloneOption(const char* optionName, const void* value,
        const void** savedValue)
{
    HTTPAPI_RESULT result = HTTPAPI_INVALID_ARG;

    if (strcmp("timeout", optionName) == 0) {
        unsigned int* timeout = (unsigned int*)malloc(sizeof(unsigned int));

        *timeout = *(const unsigned int*)value;

        *savedValue = &timeout;

        result = HTTPAPI_OK;
    }

    return result;
}
<|endoftext|>


<commit_before>#include "libtorrent/session.hpp"
#include "libtorrent/hasher.hpp"
#include <fstream>
#include <boost/thread.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/convenience.hpp>

#include "test.hpp"

using boost::filesystem::remove_all;
using boost::filesystem::create_directory;

void test_sleep(int millisec)
{
	boost::xtime xt;
	boost::xtime_get(&xt, boost::TIME_UTC);
	boost::uint64_t nanosec = (millisec % 1000) * 1000000 + xt.nsec;
	int sec = millisec / 1000;
	if (nanosec > 1000000000)
	{
		nanosec -= 1000000000;
		sec++;
	}
	xt.nsec = nanosec;
	xt.sec += sec;
	boost::thread::sleep(xt);
}

using namespace libtorrent;

boost::tuple<torrent_handle, torrent_handle, torrent_handle>
setup_transfer(session* ses1, session* ses2, session* ses3
	, bool clear_files, bool use_metadata_transfer)
{
	using namespace boost::filesystem;

	assert(ses1);
	assert(ses2);

	assert(ses1->id() != ses2->id());
	if (ses3)
		assert(ses3->id() != ses2->id());

	char const* tracker_url = "http://non-existent-name.com/announce";

	torrent_info t;
	int total_size = 2 * 1024 * 1024;
	t.add_file(path("temporary"), total_size);
	t.set_piece_size(16 * 1024);
	t.add_tracker(tracker_url);

	std::vector<char> piece(16 * 1024);
	for (int i = 0; i < int(piece.size()); ++i)
		piece[i] = (i % 26) + 'A';

	// calculate the hash for all pieces
	int num = t.num_pieces();
	sha1_hash ph = hasher(&piece[0], piece.size()).final();
	for (int i = 0; i < num; ++i)
		t.set_hash(i, ph);

	create_directory("./tmp1");
	std::ofstream file("./tmp1/temporary");
	while (total_size > 0)
	{
		file.write(&piece[0], (std::min)(int(piece.size()), total_size));
		total_size -= piece.size();
	}
	file.close();
	if (clear_files) remove_all("./tmp2/temporary");

	t.create_torrent();
	std::cerr << "generated torrent: " << t.info_hash() << std::endl;

	ses1->set_severity_level(alert::debug);
	ses2->set_severity_level(alert::debug);

	// they should not use the same save dir, because the
	// file pool will complain if two torrents are trying to
	// use the same files
	sha1_hash info_hash = t.info_hash();
	torrent_handle tor1 = ses1->add_torrent(t, "./tmp1");
	torrent_handle tor2;
	torrent_handle tor3;
	if (ses3) tor3 = ses3->add_torrent(t, "./tmp3");

  	if (use_metadata_transfer)
		tor2 = ses2->add_torrent(tracker_url
		, t.info_hash(), 0, "./tmp2");
	else
		tor2 = ses2->add_torrent(t, "./tmp2");

	assert(ses1->get_torrents().size() == 1);
	assert(ses2->get_torrents().size() == 1);

	test_sleep(100);

	std::cerr << "connecting peer\n";
	tor1.connect_peer(tcp::endpoint(address::from_string("127.0.0.1")
		, ses2->listen_port()));

	if (ses3)
	{
		// give the other peers some time to get an initial
		// set of pieces before they start sharing with each-other
		tor3.connect_peer(tcp::endpoint(
			address::from_string("127.0.0.1")
			, ses2->listen_port()));
		tor3.connect_peer(tcp::endpoint(
			address::from_string("127.0.0.1")
			, ses1->listen_port()));
	}

	return boost::make_tuple(tor1, tor2, tor3);
}

<commit_msg>test fix<commit_after>#include "libtorrent/session.hpp"
#include "libtorrent/hasher.hpp"
#include <fstream>
#include <boost/thread.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/convenience.hpp>

#include "test.hpp"

using boost::filesystem::remove_all;
using boost::filesystem::create_directory;

void test_sleep(int millisec)
{
	boost::xtime xt;
	boost::xtime_get(&xt, boost::TIME_UTC);
	boost::uint64_t nanosec = (millisec % 1000) * 1000000 + xt.nsec;
	int sec = millisec / 1000;
	if (nanosec > 1000000000)
	{
		nanosec -= 1000000000;
		sec++;
	}
	xt.nsec = nanosec;
	xt.sec += sec;
	boost::thread::sleep(xt);
}

using namespace libtorrent;

template <class T>
boost::intrusive_ptr<T> clone_ptr(boost::intrusive_ptr<T> const& ptr)
{
	return boost::intrusive_ptr<T>(new T(*ptr));
}

boost::tuple<torrent_handle, torrent_handle, torrent_handle>
setup_transfer(session* ses1, session* ses2, session* ses3
	, bool clear_files, bool use_metadata_transfer)
{
	using namespace boost::filesystem;

	assert(ses1);
	assert(ses2);

	assert(ses1->id() != ses2->id());
	if (ses3)
		assert(ses3->id() != ses2->id());

	char const* tracker_url = "http://non-existent-name.com/announce";

	boost::intrusive_ptr<torrent_info> t(new torrent_info);
	int total_size = 2 * 1024 * 1024;
	t->add_file(path("temporary"), total_size);
	t->set_piece_size(16 * 1024);
	t->add_tracker(tracker_url);

	std::vector<char> piece(16 * 1024);
	for (int i = 0; i < int(piece.size()); ++i)
		piece[i] = (i % 26) + 'A';

	// calculate the hash for all pieces
	int num = t->num_pieces();
	sha1_hash ph = hasher(&piece[0], piece.size()).final();
	for (int i = 0; i < num; ++i)
		t->set_hash(i, ph);

	create_directory("./tmp1");
	std::ofstream file("./tmp1/temporary");
	while (total_size > 0)
	{
		file.write(&piece[0], (std::min)(int(piece.size()), total_size));
		total_size -= piece.size();
	}
	file.close();
	if (clear_files) remove_all("./tmp2/temporary");

	t->create_torrent();
	std::cerr << "generated torrent: " << t->info_hash() << std::endl;

	ses1->set_severity_level(alert::debug);
	ses2->set_severity_level(alert::debug);

	// they should not use the same save dir, because the
	// file pool will complain if two torrents are trying to
	// use the same files
	sha1_hash info_hash = t->info_hash();
	torrent_handle tor1 = ses1->add_torrent(t, "./tmp1");
	torrent_handle tor2;
	torrent_handle tor3;
	if (ses3) tor3 = ses3->add_torrent(clone_ptr(t), "./tmp3");

  	if (use_metadata_transfer)
		tor2 = ses2->add_torrent(tracker_url
		, t->info_hash(), 0, "./tmp2");
	else
		tor2 = ses2->add_torrent(clone_ptr(t), "./tmp2");

	assert(ses1->get_torrents().size() == 1);
	assert(ses2->get_torrents().size() == 1);

	test_sleep(100);

	std::cerr << "connecting peer\n";
	tor1.connect_peer(tcp::endpoint(address::from_string("127.0.0.1")
		, ses2->listen_port()));

	if (ses3)
	{
		// give the other peers some time to get an initial
		// set of pieces before they start sharing with each-other
		tor3.connect_peer(tcp::endpoint(
			address::from_string("127.0.0.1")
			, ses2->listen_port()));
		tor3.connect_peer(tcp::endpoint(
			address::from_string("127.0.0.1")
			, ses1->listen_port()));
	}

	return boost::make_tuple(tor1, tor2, tor3);
}

<|endoftext|>


<commit_before>#include "splitruns.h"
#include "pvalue.h"
#include "gtest/gtest.h"
#include <gsl/gsl_cdf.h>

TEST(splitruns, split)
{
    constexpr double Tobs = 15.5;
    constexpr unsigned N = 12;
    constexpr unsigned n = 2;

    const double F = runs_cumulative(Tobs, N);
    const double approx = F*F / (1.0 + Delta(Tobs, N));

    EXPECT_NEAR(approx, runs_split_cumulative(Tobs, N, n), 1e-16);
}

TEST(splitruns, approx)
{
    // compare with full results
    constexpr unsigned N = 25;
    constexpr unsigned n = 2;

    // check for absolute difference here but relative error would be
    // more interesting. Not implemented in gtest
    for (auto i = 1; i < 20; ++i) {
        const double Tobs = 20 + 2*i;
        EXPECT_NEAR(runs_split_cumulative(Tobs, N, n), runs_cumulative(Tobs, n*N), 2e-7)
            << " at Tobs = " << Tobs;
    }
}

TEST(splitruns, hH)
{
    constexpr double Tobs = 15.5;
    constexpr double x = 3.3;
    constexpr unsigned N = 12;

    // compare to mathematica
    EXPECT_NEAR(h(Tobs, N), 0.000373964, 1e-8);
    EXPECT_NEAR(H(Tobs-x, Tobs, N), 0.00245352, 1e-8);
    EXPECT_NEAR(Delta(Tobs, N), 0.00175994, 1e-8);
}

TEST(splitruns, cdf)
{
    EXPECT_NEAR(gsl_cdf_chisq_P(15.5, 12), 0.784775, 1e-6);
}
<commit_msg>[splitruns] Fix splittest<commit_after>#include "splitruns.h"
#include "pvalue.h"
#include "gtest/gtest.h"
#include <gsl/gsl_cdf.h>

TEST(splitruns, split)
{
    constexpr double Tobs = 15.5;
    constexpr unsigned N = 12;
    constexpr unsigned n = 2;

    const double F = runs_cumulative(Tobs, N);
    const double approx = F*F / (1.0 + Delta(Tobs, N));

    EXPECT_NEAR(approx, runs_split_cumulative(Tobs, N, n), 1e-15);
}

TEST(splitruns, approx)
{
    // compare with full results
    constexpr unsigned N = 25;
    constexpr unsigned n = 2;

    // check for absolute difference here but relative error would be
    // more interesting. Not implemented in gtest
    for (auto i = 1; i < 20; ++i) {
        const double Tobs = 20 + 2*i;
        EXPECT_NEAR(runs_split_cumulative(Tobs, N, n), runs_cumulative(Tobs, n*N), 2e-7)
            << " at Tobs = " << Tobs;
    }
}

TEST(splitruns, hH)
{
    constexpr double Tobs = 15.5;
    constexpr double x = 3.3;
    constexpr unsigned N = 12;

    // compare to mathematica
    EXPECT_NEAR(h(Tobs, N), 0.000373964, 1e-8);
    EXPECT_NEAR(H(Tobs-x, Tobs, N), 0.00245352, 1e-8);
    EXPECT_NEAR(Delta(Tobs, N), 0.00175994, 1e-8);
}

TEST(splitruns, cdf)
{
    EXPECT_NEAR(gsl_cdf_chisq_P(15.5, 12), 0.784775, 1e-6);
}
<|endoftext|>


<commit_before><commit_msg>Rearrange the code to avoid a memory leak as suggested by coverity.<commit_after><|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <mnc.h>
#include <iostream>

#ifdef MNC_V8
#include "v8/test-v8-common.h"
#define OBJECT_CONTEXT_TEST_SUITE V8ObjectContext
#endif

#ifdef MNC_JSC
#include "jsc/test-jsc-common.h"
#define OBJECT_CONTEXT_TEST_SUITE JSCObjectContext
#endif

using namespace mnc;

static mnc::Value* result = mnc::Value::Null;

MNC_FUNC(CollectMyResult) {
  result = ctx->GetArgument(0);
}

MNC_OBJ(Child) {
  ctx->Export("collect", CollectMyResult);
}

MNC_OBJ(Wrapper) {
  ctx->Export("child", Child);
}

static JSCObjectContext* new_object_ctx;

static JSValueRef GetObject(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef *exception) {
  return new_object_ctx->object_ref_;
}

TEST(OBJECT_CONTEXT_TEST_SUITE, FillObject) {

  JSStaticValue staticValue;

  staticValue.name = "wrapper";
  staticValue.getProperty = GetObject;

  JSStaticValue staticValues[] = {
    staticValue,
    { 0, 0, 0, 0 }
  };

  JSStaticFunction staticFunctions[] = {
      { 0, 0, 0 }
  };

  JSClassDefinition globalsDefinition = {
      0, kJSClassAttributeNone, "globals", 0, staticValues, staticFunctions,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  };

  JSClassRef globals = JSClassCreate(&globalsDefinition);
  JSContextRef ctx = JSGlobalContextCreate(globals);

  new_object_ctx = new JSCObjectContext(ctx);
  Wrapper(new_object_ctx);

  new_object_ctx->Build("wrapper");

  JSStringRef script = JSStringCreateWithUTF8CString("wrapper.child.collect(42)");
  JSValueRef exception = NULL;
  JSEvaluateScript(ctx, script, NULL, NULL, 1, &exception);

  EXPECT_EQ(42, result->NumberValue());
}<commit_msg>feed global object using setproperty<commit_after>#include <gtest/gtest.h>
#include <mnc.h>
#include <iostream>

#ifdef MNC_V8
#include "v8/test-v8-common.h"
#define OBJECT_CONTEXT_TEST_SUITE V8ObjectContext
#endif

#ifdef MNC_JSC
#include "jsc/test-jsc-common.h"
#define OBJECT_CONTEXT_TEST_SUITE JSCObjectContext
#endif

using namespace mnc;

static mnc::Value* result = mnc::Value::Null;

MNC_FUNC(CollectMyResult) {
  result = ctx->GetArgument(0);
}

MNC_OBJ(Child) {
  ctx->Export("collect", CollectMyResult);
}

MNC_OBJ(Wrapper) {
  ctx->Export("child", Child);
}

TEST(OBJECT_CONTEXT_TEST_SUITE, FillObject) {

  JSStaticValue staticValues[] = {
    { 0, 0, 0, 0 }
  };

  JSStaticFunction staticFunctions[] = {
      { 0, 0, 0 }
  };

  JSClassDefinition globalsDefinition = {
      0, kJSClassAttributeNone, "globals", 0, staticValues, staticFunctions,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  };

  JSClassRef globals = JSClassCreate(&globalsDefinition);
  JSContextRef ctx = JSGlobalContextCreate(globals);

  JSCObjectContext* new_object_ctx = new JSCObjectContext(ctx);
  Wrapper(new_object_ctx);

  new_object_ctx->Build("wrapper");

  JSObjectRef global_object = JSContextGetGlobalObject(ctx);
  JSObjectSetProperty(ctx, global_object, JSStringCreateWithUTF8CString("wrapper"), new_object_ctx->object_ref_, NULL, 0);

  JSStringRef script = JSStringCreateWithUTF8CString("wrapper.child.collect(42)");
  JSValueRef exception = NULL;
  JSEvaluateScript(ctx, script, NULL, NULL, 1, &exception);

  EXPECT_EQ(42, result->NumberValue());
}<|endoftext|>


<commit_before>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/bencode.hpp"
#include "libtorrent/lazy_entry.hpp"
#include <boost/lexical_cast.hpp>
#include <iostream>

#include "test.hpp"

using namespace libtorrent;

// test vectors from bittorrent protocol description
// http://www.bittorrent.com/protocol.html

std::string encode(entry const& e)
{
	std::string ret;
	bencode(std::back_inserter(ret), e);
	return ret;
}

entry decode(std::string const& str)
{
	return bdecode(str.begin(), str.end());
}

int test_main()
{
	using namespace libtorrent;

	// ** strings **
	{
		entry e("spam");
		TEST_CHECK(encode(e) == "4:spam");
		TEST_CHECK(decode(encode(e)) == e);
	}

	// ** integers **
	{
		entry e(3);
		TEST_CHECK(encode(e) == "i3e");
		TEST_CHECK(decode(encode(e)) == e);
	}

	{
		entry e(-3);
		TEST_CHECK(encode(e) == "i-3e");
		TEST_CHECK(decode(encode(e)) == e);
	}

	{
		entry e(int(0));
		TEST_CHECK(encode(e) == "i0e");
		TEST_CHECK(decode(encode(e)) == e);
	}

	// ** lists **
	{
		entry::list_type l;
		l.push_back(entry("spam"));
		l.push_back(entry("eggs"));
		entry e(l);
		TEST_CHECK(encode(e) == "l4:spam4:eggse");
		TEST_CHECK(decode(encode(e)) == e);
	}

	// ** dictionaries **
	{
		entry e(entry::dictionary_t);
		e["spam"] = entry("eggs");
		e["cow"] = entry("moo");
		TEST_CHECK(encode(e) == "d3:cow3:moo4:spam4:eggse");
		TEST_CHECK(decode(encode(e)) == e);
	}

	{
		char b[] = "i12453e";
		lazy_entry e;
		int ret = lazy_bdecode(b, b + sizeof(b)-1, e);
		TORRENT_ASSERT(ret == 0);
		std::cout << e << std::endl;
		std::pair<const char*, int> section = e.data_section();
		TORRENT_ASSERT(memcmp(b, section.first, section.second) == 0);
		TORRENT_ASSERT(section.second == sizeof(b) - 1);
		TORRENT_ASSERT(e.type() == lazy_entry::int_t);
		TORRENT_ASSERT(e.int_value() == 12453);
	}

	{
		char b[] = "26:abcdefghijklmnopqrstuvwxyz";
		lazy_entry e;
		int ret = lazy_bdecode(b, b + sizeof(b)-1, e);
		TORRENT_ASSERT(ret == 0);
		std::cout << e << std::endl;
		std::pair<const char*, int> section = e.data_section();
		TORRENT_ASSERT(memcmp(b, section.first, section.second) == 0);
		TORRENT_ASSERT(section.second == sizeof(b) - 1);
		TORRENT_ASSERT(e.type() == lazy_entry::string_t);
		TORRENT_ASSERT(e.string_value() == std::string("abcdefghijklmnopqrstuvwxyz"));
		TORRENT_ASSERT(e.string_length() == 26);
	}

	{
		char b[] = "li12453e3:aaae";
		lazy_entry e;
		int ret = lazy_bdecode(b, b + sizeof(b)-1, e);
		TORRENT_ASSERT(ret == 0);
		std::cout << e << std::endl;
		std::pair<const char*, int> section = e.data_section();
		TORRENT_ASSERT(memcmp(b, section.first, section.second) == 0);
		TORRENT_ASSERT(section.second == sizeof(b) - 1);
		TORRENT_ASSERT(e.type() == lazy_entry::list_t);
		TORRENT_ASSERT(e.list_size() == 2);
		TORRENT_ASSERT(e.list_at(0)->type() == lazy_entry::int_t);
		TORRENT_ASSERT(e.list_at(1)->type() == lazy_entry::string_t);
		TORRENT_ASSERT(e.list_at(0)->int_value() == 12453);
		TORRENT_ASSERT(e.list_at(1)->string_value() == std::string("aaa"));
		TORRENT_ASSERT(e.list_at(1)->string_length() == 3);
		section = e.list_at(1)->data_section();
		TORRENT_ASSERT(memcmp("3:aaa", section.first, section.second) == 0);
		TORRENT_ASSERT(section.second == 5);
	}

	{
		char b[] = "d1:ai12453e1:b3:aaa1:c3:bbb1:X10:0123456789e";
		lazy_entry e;
		int ret = lazy_bdecode(b, b + sizeof(b)-1, e);
		TORRENT_ASSERT(ret == 0);
		std::cout << e << std::endl;
		std::pair<const char*, int> section = e.data_section();
		TORRENT_ASSERT(memcmp(b, section.first, section.second) == 0);
		TORRENT_ASSERT(section.second == sizeof(b) - 1);
		TORRENT_ASSERT(e.type() == lazy_entry::dict_t);
		TORRENT_ASSERT(e.dict_size() == 4);
		TORRENT_ASSERT(e.dict_find("a")->type() == lazy_entry::int_t);
		TORRENT_ASSERT(e.dict_find("a")->int_value() == 12453);
		TORRENT_ASSERT(e.dict_find("b")->type() == lazy_entry::string_t);
		TORRENT_ASSERT(e.dict_find("b")->string_value() == std::string("aaa"));
		TORRENT_ASSERT(e.dict_find("b")->string_length() == 3);
		TORRENT_ASSERT(e.dict_find("c")->type() == lazy_entry::string_t);
		TORRENT_ASSERT(e.dict_find("c")->string_value() == std::string("bbb"));
		TORRENT_ASSERT(e.dict_find("c")->string_length() == 3);
		TORRENT_ASSERT(e.dict_find_string_value("X") == "0123456789");
	}
	return 0;
}

<commit_msg>fixed compile problem in test_bencoding.cpp related to std namespace<commit_after>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/bencode.hpp"
#include "libtorrent/lazy_entry.hpp"
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <cstring>

#include "test.hpp"

using namespace libtorrent;

// test vectors from bittorrent protocol description
// http://www.bittorrent.com/protocol.html

std::string encode(entry const& e)
{
	std::string ret;
	bencode(std::back_inserter(ret), e);
	return ret;
}

entry decode(std::string const& str)
{
	return bdecode(str.begin(), str.end());
}

int test_main()
{
	using namespace libtorrent;

	// ** strings **
	{
		entry e("spam");
		TEST_CHECK(encode(e) == "4:spam");
		TEST_CHECK(decode(encode(e)) == e);
	}

	// ** integers **
	{
		entry e(3);
		TEST_CHECK(encode(e) == "i3e");
		TEST_CHECK(decode(encode(e)) == e);
	}

	{
		entry e(-3);
		TEST_CHECK(encode(e) == "i-3e");
		TEST_CHECK(decode(encode(e)) == e);
	}

	{
		entry e(int(0));
		TEST_CHECK(encode(e) == "i0e");
		TEST_CHECK(decode(encode(e)) == e);
	}

	// ** lists **
	{
		entry::list_type l;
		l.push_back(entry("spam"));
		l.push_back(entry("eggs"));
		entry e(l);
		TEST_CHECK(encode(e) == "l4:spam4:eggse");
		TEST_CHECK(decode(encode(e)) == e);
	}

	// ** dictionaries **
	{
		entry e(entry::dictionary_t);
		e["spam"] = entry("eggs");
		e["cow"] = entry("moo");
		TEST_CHECK(encode(e) == "d3:cow3:moo4:spam4:eggse");
		TEST_CHECK(decode(encode(e)) == e);
	}

	{
		char b[] = "i12453e";
		lazy_entry e;
		int ret = lazy_bdecode(b, b + sizeof(b)-1, e);
		TORRENT_ASSERT(ret == 0);
		std::cout << e << std::endl;
		std::pair<const char*, int> section = e.data_section();
		TORRENT_ASSERT(std::memcmp(b, section.first, section.second) == 0);
		TORRENT_ASSERT(section.second == sizeof(b) - 1);
		TORRENT_ASSERT(e.type() == lazy_entry::int_t);
		TORRENT_ASSERT(e.int_value() == 12453);
	}

	{
		char b[] = "26:abcdefghijklmnopqrstuvwxyz";
		lazy_entry e;
		int ret = lazy_bdecode(b, b + sizeof(b)-1, e);
		TORRENT_ASSERT(ret == 0);
		std::cout << e << std::endl;
		std::pair<const char*, int> section = e.data_section();
		TORRENT_ASSERT(std::memcmp(b, section.first, section.second) == 0);
		TORRENT_ASSERT(section.second == sizeof(b) - 1);
		TORRENT_ASSERT(e.type() == lazy_entry::string_t);
		TORRENT_ASSERT(e.string_value() == std::string("abcdefghijklmnopqrstuvwxyz"));
		TORRENT_ASSERT(e.string_length() == 26);
	}

	{
		char b[] = "li12453e3:aaae";
		lazy_entry e;
		int ret = lazy_bdecode(b, b + sizeof(b)-1, e);
		TORRENT_ASSERT(ret == 0);
		std::cout << e << std::endl;
		std::pair<const char*, int> section = e.data_section();
		TORRENT_ASSERT(std::memcmp(b, section.first, section.second) == 0);
		TORRENT_ASSERT(section.second == sizeof(b) - 1);
		TORRENT_ASSERT(e.type() == lazy_entry::list_t);
		TORRENT_ASSERT(e.list_size() == 2);
		TORRENT_ASSERT(e.list_at(0)->type() == lazy_entry::int_t);
		TORRENT_ASSERT(e.list_at(1)->type() == lazy_entry::string_t);
		TORRENT_ASSERT(e.list_at(0)->int_value() == 12453);
		TORRENT_ASSERT(e.list_at(1)->string_value() == std::string("aaa"));
		TORRENT_ASSERT(e.list_at(1)->string_length() == 3);
		section = e.list_at(1)->data_section();
		TORRENT_ASSERT(std::memcmp("3:aaa", section.first, section.second) == 0);
		TORRENT_ASSERT(section.second == 5);
	}

	{
		char b[] = "d1:ai12453e1:b3:aaa1:c3:bbb1:X10:0123456789e";
		lazy_entry e;
		int ret = lazy_bdecode(b, b + sizeof(b)-1, e);
		TORRENT_ASSERT(ret == 0);
		std::cout << e << std::endl;
		std::pair<const char*, int> section = e.data_section();
		TORRENT_ASSERT(std::memcmp(b, section.first, section.second) == 0);
		TORRENT_ASSERT(section.second == sizeof(b) - 1);
		TORRENT_ASSERT(e.type() == lazy_entry::dict_t);
		TORRENT_ASSERT(e.dict_size() == 4);
		TORRENT_ASSERT(e.dict_find("a")->type() == lazy_entry::int_t);
		TORRENT_ASSERT(e.dict_find("a")->int_value() == 12453);
		TORRENT_ASSERT(e.dict_find("b")->type() == lazy_entry::string_t);
		TORRENT_ASSERT(e.dict_find("b")->string_value() == std::string("aaa"));
		TORRENT_ASSERT(e.dict_find("b")->string_length() == 3);
		TORRENT_ASSERT(e.dict_find("c")->type() == lazy_entry::string_t);
		TORRENT_ASSERT(e.dict_find("c")->string_value() == std::string("bbb"));
		TORRENT_ASSERT(e.dict_find("c")->string_length() == 3);
		TORRENT_ASSERT(e.dict_find_string_value("X") == "0123456789");
	}
	return 0;
}

<|endoftext|>


<commit_before>#include "blob_mock.hpp"
#include "dlsys_mock.hpp"
#include "fs.hpp"
#include "manager_mock.hpp"
#include "utils.hpp"

#include <filesystem>
#include <memory>
#include <string>
#include <vector>

#include <gtest/gtest.h>

namespace fs = std::filesystem;

namespace blobs
{
using ::testing::_;
using ::testing::Return;
using ::testing::StrEq;
using ::testing::StrictMock;

std::vector<std::string>* returnList = nullptr;

std::vector<std::string> getLibraryList(const std::string& path,
                                        PathMatcher check)
{
    return (returnList) ? *returnList : std::vector<std::string>();
}

std::unique_ptr<GenericBlobInterface> factoryReturn;

std::unique_ptr<GenericBlobInterface> fakeFactory()
{
    return std::move(factoryReturn);
}

TEST(UtilLoadLibraryTest, NoFilesFound)
{
    /* Verify nothing special happens when there are no files found. */

    StrictMock<internal::InternalDlSysMock> dlsys;
    StrictMock<ManagerMock> manager;

    loadLibraries(&manager, "", &dlsys);
}

TEST(UtilLoadLibraryTest, OneFileFoundIsLibrary)
{
    /* Verify if it finds a library, and everything works, it'll regsiter it.
     */

    std::vector<std::string> files = {"this.fake"};
    returnList = &files;

    StrictMock<internal::InternalDlSysMock> dlsys;
    StrictMock<ManagerMock> manager;
    void* handle = reinterpret_cast<void*>(0x01);
    auto blobMock = std::make_unique<BlobMock>();

    factoryReturn = std::move(blobMock);

    EXPECT_CALL(dlsys, dlopen(_, _)).WillOnce(Return(handle));

    EXPECT_CALL(dlsys, dlerror()).Times(2).WillRepeatedly(Return(nullptr));

    EXPECT_CALL(dlsys, dlsym(handle, StrEq("createHandler")))
        .WillOnce(Return(reinterpret_cast<void*>(fakeFactory)));

    EXPECT_CALL(manager, registerHandler(_));

    loadLibraries(&manager, "", &dlsys);
}

TEST(UtilLibraryMatchTest, TestAll)
{
    struct LibraryMatch
    {
        std::string name;
        bool expectation;
    };

    std::vector<LibraryMatch> tests = {
        {"libblobcmds.0.0.1", false}, {"libblobcmds.0.0", false},
        {"libblobcmds.0", false},     {"libblobcmds.10", false},
        {"libblobcmds.a", false},     {"libcmds.so.so.0", true},
        {"libcmds.so.0", true},       {"libcmds.so.0.0", false},
        {"libcmds.so.0.0.10", false}, {"libblobs.so.1000", true}};

    for (const auto& test : tests)
    {
        EXPECT_EQ(test.expectation, matchBlobHandler(test.name));
    }
}

} // namespace blobs
<commit_msg>test/utils: stop using local variable with global return<commit_after>#include "blob_mock.hpp"
#include "dlsys_mock.hpp"
#include "fs.hpp"
#include "manager_mock.hpp"
#include "utils.hpp"

#include <filesystem>
#include <memory>
#include <string>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

namespace fs = std::filesystem;

namespace blobs
{
using ::testing::_;
using ::testing::Return;
using ::testing::StrEq;
using ::testing::StrictMock;

std::vector<std::string> returnList;

std::vector<std::string> getLibraryList(const std::string& path,
                                        PathMatcher check)
{
    return returnList;
}

std::unique_ptr<GenericBlobInterface> factoryReturn;

std::unique_ptr<GenericBlobInterface> fakeFactory()
{
    return std::move(factoryReturn);
}

class UtilLoadLibraryTest : public ::testing::Test
{
  protected:
    UtilLoadLibraryTest()
    {
        returnList = {};
    }
};

TEST_F(UtilLoadLibraryTest, NoFilesFound)
{
    /* Verify nothing special happens when there are no files found. */

    StrictMock<internal::InternalDlSysMock> dlsys;
    StrictMock<ManagerMock> manager;

    loadLibraries(&manager, "", &dlsys);
}

TEST_F(UtilLoadLibraryTest, OneFileFoundIsLibrary)
{
    /* Verify if it finds a library, and everything works, it'll regsiter it.
     */

    returnList = {"this.fake"};

    StrictMock<internal::InternalDlSysMock> dlsys;
    StrictMock<ManagerMock> manager;
    void* handle = reinterpret_cast<void*>(0x01);
    auto blobMock = std::make_unique<BlobMock>();

    factoryReturn = std::move(blobMock);

    EXPECT_CALL(dlsys, dlopen(_, _)).WillOnce(Return(handle));

    EXPECT_CALL(dlsys, dlerror()).Times(2).WillRepeatedly(Return(nullptr));

    EXPECT_CALL(dlsys, dlsym(handle, StrEq("createHandler")))
        .WillOnce(Return(reinterpret_cast<void*>(fakeFactory)));

    EXPECT_CALL(manager, registerHandler(_));

    loadLibraries(&manager, "", &dlsys);
}

TEST(UtilLibraryMatchTest, TestAll)
{
    struct LibraryMatch
    {
        std::string name;
        bool expectation;
    };

    std::vector<LibraryMatch> tests = {
        {"libblobcmds.0.0.1", false}, {"libblobcmds.0.0", false},
        {"libblobcmds.0", false},     {"libblobcmds.10", false},
        {"libblobcmds.a", false},     {"libcmds.so.so.0", true},
        {"libcmds.so.0", true},       {"libcmds.so.0.0", false},
        {"libcmds.so.0.0.10", false}, {"libblobs.so.1000", true}};

    for (const auto& test : tests)
    {
        EXPECT_EQ(test.expectation, matchBlobHandler(test.name));
    }
}

} // namespace blobs
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <string>

#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
#include "test/md5_helper.h"
#if CONFIG_WEBM_IO
#include "test/webm_video_source.h"
#endif
#include "vp9/decoder/vp9_thread.h"

namespace {

using std::string;

class VP9WorkerThreadTest : public ::testing::TestWithParam<bool> {
 protected:
  virtual ~VP9WorkerThreadTest() {}
  virtual void SetUp() {
    vp9_worker_init(&worker_);
  }

  virtual void TearDown() {
    vp9_worker_end(&worker_);
  }

  VP9Worker worker_;
};

int ThreadHook(void* data, void* return_value) {
  int* const hook_data = reinterpret_cast<int*>(data);
  *hook_data = 5;
  return *reinterpret_cast<int*>(return_value);
}

TEST_P(VP9WorkerThreadTest, HookSuccess) {
  EXPECT_NE(vp9_worker_sync(&worker_), 0);  // should be a no-op.

  for (int i = 0; i < 2; ++i) {
    EXPECT_NE(vp9_worker_reset(&worker_), 0);

    int hook_data = 0;
    int return_value = 1;  // return successfully from the hook
    worker_.hook = ThreadHook;
    worker_.data1 = &hook_data;
    worker_.data2 = &return_value;

    const bool synchronous = GetParam();
    if (synchronous) {
      vp9_worker_execute(&worker_);
    } else {
      vp9_worker_launch(&worker_);
    }
    EXPECT_NE(vp9_worker_sync(&worker_), 0);
    EXPECT_FALSE(worker_.had_error);
    EXPECT_EQ(5, hook_data);

    EXPECT_NE(vp9_worker_sync(&worker_), 0);  // should be a no-op.
  }
}

TEST_P(VP9WorkerThreadTest, HookFailure) {
  EXPECT_NE(vp9_worker_reset(&worker_), 0);

  int hook_data = 0;
  int return_value = 0;  // return failure from the hook
  worker_.hook = ThreadHook;
  worker_.data1 = &hook_data;
  worker_.data2 = &return_value;

  const bool synchronous = GetParam();
  if (synchronous) {
    vp9_worker_execute(&worker_);
  } else {
    vp9_worker_launch(&worker_);
  }
  EXPECT_FALSE(vp9_worker_sync(&worker_));
  EXPECT_EQ(1, worker_.had_error);

  // Ensure _reset() clears the error and _launch() can be called again.
  return_value = 1;
  EXPECT_NE(vp9_worker_reset(&worker_), 0);
  EXPECT_FALSE(worker_.had_error);
  vp9_worker_launch(&worker_);
  EXPECT_NE(vp9_worker_sync(&worker_), 0);
  EXPECT_FALSE(worker_.had_error);
}

// -----------------------------------------------------------------------------
// Multi-threaded decode tests

#if CONFIG_WEBM_IO
struct FileList {
  const char *name;
  const char *expected_md5;
};

// Decodes |filename| with |num_threads|. Returns the md5 of the decoded frames.
string DecodeFile(const string& filename, int num_threads) {
  libvpx_test::WebMVideoSource video(filename);
  video.Init();

  vpx_codec_dec_cfg_t cfg = {0};
  cfg.threads = num_threads;
  libvpx_test::VP9Decoder decoder(cfg, 0);

  libvpx_test::MD5 md5;
  for (video.Begin(); video.cxdata(); video.Next()) {
    const vpx_codec_err_t res =
        decoder.DecodeFrame(video.cxdata(), video.frame_size());
    if (res != VPX_CODEC_OK) {
      EXPECT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError();
      break;
    }

    libvpx_test::DxDataIterator dec_iter = decoder.GetDxData();
    const vpx_image_t *img = NULL;

    // Get decompressed data
    while ((img = dec_iter.Next())) {
      md5.Add(img);
    }
  }
  return string(md5.Get());
}

void DecodeFiles(const FileList files[]) {
  for (const FileList *iter = files; iter->name != NULL; ++iter) {
    SCOPED_TRACE(iter->name);
    for (int t = 2; t <= 8; ++t) {
      EXPECT_STREQ(iter->expected_md5, DecodeFile(iter->name, t).c_str())
          << "threads = " << t;
    }
  }
}

TEST(VP9DecodeMultiThreadedTest, Decode) {
  // no tiles or frame parallel; this exercises loop filter threading.
  EXPECT_STREQ("b35a1b707b28e82be025d960aba039bc",
               DecodeFile("vp90-2-03-size-226x226.webm", 2).c_str());
}

TEST(VP9DecodeMultiThreadedTest, Decode2) {
  static const FileList files[] = {
    { "vp90-2-08-tile_1x2_frame_parallel.webm",
      "68ede6abd66bae0a2edf2eb9232241b6" },
    { "vp90-2-08-tile_1x4_frame_parallel.webm",
      "368ebc6ebf3a5e478d85b2c3149b2848" },
    { "vp90-2-08-tile_1x8_frame_parallel.webm",
      "17e439da2388aff3a0f69cb22579c6c1" },
    { NULL, NULL }
  };

  DecodeFiles(files);
}

// Test tile quantity changes within one file.
TEST(VP9DecodeMultiThreadedTest, Decode3) {
  static const FileList files[] = {
    { "vp90-2-14-resize-fp-tiles-1-16.webm",
      "0cd5e632c326297e975f38949c31ea94" },
    { "vp90-2-14-resize-fp-tiles-1-2-4-8-16.webm",
      "5c78a96a42e7f4a4f6b2edcdb791e44c" },
    { "vp90-2-14-resize-fp-tiles-1-2.webm",
      "e030450ae85c3277be2a418769df98e2" },
    { "vp90-2-14-resize-fp-tiles-1-4.webm",
      "312eed4e2b64eb7a4e7f18916606a430" },
    { "vp90-2-14-resize-fp-tiles-16-1.webm",
      "1755c16d8af16a9cb3fe7338d90abe52" },
    { "vp90-2-14-resize-fp-tiles-16-2.webm",
      "500300592d3fcb6f12fab25e48aaf4df" },
    { "vp90-2-14-resize-fp-tiles-16-4.webm",
      "47c48379fa6331215d91c67648e1af6e" },
    { "vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm",
      "eecf17290739bc708506fa4827665989" },
    { "vp90-2-14-resize-fp-tiles-16-8.webm",
      "29b6bb54e4c26b5ca85d5de5fed94e76" },
    { "vp90-2-14-resize-fp-tiles-1-8.webm",
      "1b6f175e08cd82cf84bb800ac6d1caa3" },
    { "vp90-2-14-resize-fp-tiles-2-16.webm",
      "ca3b03e4197995d8d5444ede7a6c0804" },
    { "vp90-2-14-resize-fp-tiles-2-1.webm",
      "99aec065369d70bbb78ccdff65afed3f" },
    { "vp90-2-14-resize-fp-tiles-2-4.webm",
      "22d0ebdb49b87d2920a85aea32e1afd5" },
    { "vp90-2-14-resize-fp-tiles-2-8.webm",
      "c2115cf051c62e0f7db1d4a783831541" },
    { "vp90-2-14-resize-fp-tiles-4-16.webm",
      "c690d7e1719b31367564cac0af0939cb" },
    { "vp90-2-14-resize-fp-tiles-4-1.webm",
      "a926020b2cc3e15ad4cc271853a0ff26" },
    { "vp90-2-14-resize-fp-tiles-4-2.webm",
      "42699063d9e581f1993d0cf890c2be78" },
    { "vp90-2-14-resize-fp-tiles-4-8.webm",
      "7f76d96036382f45121e3d5aa6f8ec52" },
    { "vp90-2-14-resize-fp-tiles-8-16.webm",
      "76a43fcdd7e658542913ea43216ec55d" },
    { "vp90-2-14-resize-fp-tiles-8-1.webm",
      "8e3fbe89486ca60a59299dea9da91378" },
    { "vp90-2-14-resize-fp-tiles-8-2.webm",
      "ae96f21f21b6370cc0125621b441fc52" },
    { "vp90-2-14-resize-fp-tiles-8-4.webm",
      "3eb4f24f10640d42218f7fd7b9fd30d4" },
    { NULL, NULL }
  };

  DecodeFiles(files);
}
#endif  // CONFIG_WEBM_IO

INSTANTIATE_TEST_CASE_P(Synchronous, VP9WorkerThreadTest, ::testing::Bool());

}  // namespace
<commit_msg>vp9_thread_test: remove unnecessary c_str()'s<commit_after>/*
 *  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <string>

#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
#include "test/md5_helper.h"
#if CONFIG_WEBM_IO
#include "test/webm_video_source.h"
#endif
#include "vp9/decoder/vp9_thread.h"

namespace {

using std::string;

class VP9WorkerThreadTest : public ::testing::TestWithParam<bool> {
 protected:
  virtual ~VP9WorkerThreadTest() {}
  virtual void SetUp() {
    vp9_worker_init(&worker_);
  }

  virtual void TearDown() {
    vp9_worker_end(&worker_);
  }

  VP9Worker worker_;
};

int ThreadHook(void* data, void* return_value) {
  int* const hook_data = reinterpret_cast<int*>(data);
  *hook_data = 5;
  return *reinterpret_cast<int*>(return_value);
}

TEST_P(VP9WorkerThreadTest, HookSuccess) {
  EXPECT_NE(vp9_worker_sync(&worker_), 0);  // should be a no-op.

  for (int i = 0; i < 2; ++i) {
    EXPECT_NE(vp9_worker_reset(&worker_), 0);

    int hook_data = 0;
    int return_value = 1;  // return successfully from the hook
    worker_.hook = ThreadHook;
    worker_.data1 = &hook_data;
    worker_.data2 = &return_value;

    const bool synchronous = GetParam();
    if (synchronous) {
      vp9_worker_execute(&worker_);
    } else {
      vp9_worker_launch(&worker_);
    }
    EXPECT_NE(vp9_worker_sync(&worker_), 0);
    EXPECT_FALSE(worker_.had_error);
    EXPECT_EQ(5, hook_data);

    EXPECT_NE(vp9_worker_sync(&worker_), 0);  // should be a no-op.
  }
}

TEST_P(VP9WorkerThreadTest, HookFailure) {
  EXPECT_NE(vp9_worker_reset(&worker_), 0);

  int hook_data = 0;
  int return_value = 0;  // return failure from the hook
  worker_.hook = ThreadHook;
  worker_.data1 = &hook_data;
  worker_.data2 = &return_value;

  const bool synchronous = GetParam();
  if (synchronous) {
    vp9_worker_execute(&worker_);
  } else {
    vp9_worker_launch(&worker_);
  }
  EXPECT_FALSE(vp9_worker_sync(&worker_));
  EXPECT_EQ(1, worker_.had_error);

  // Ensure _reset() clears the error and _launch() can be called again.
  return_value = 1;
  EXPECT_NE(vp9_worker_reset(&worker_), 0);
  EXPECT_FALSE(worker_.had_error);
  vp9_worker_launch(&worker_);
  EXPECT_NE(vp9_worker_sync(&worker_), 0);
  EXPECT_FALSE(worker_.had_error);
}

// -----------------------------------------------------------------------------
// Multi-threaded decode tests

#if CONFIG_WEBM_IO
struct FileList {
  const char *name;
  const char *expected_md5;
};

// Decodes |filename| with |num_threads|. Returns the md5 of the decoded frames.
string DecodeFile(const string& filename, int num_threads) {
  libvpx_test::WebMVideoSource video(filename);
  video.Init();

  vpx_codec_dec_cfg_t cfg = {0};
  cfg.threads = num_threads;
  libvpx_test::VP9Decoder decoder(cfg, 0);

  libvpx_test::MD5 md5;
  for (video.Begin(); video.cxdata(); video.Next()) {
    const vpx_codec_err_t res =
        decoder.DecodeFrame(video.cxdata(), video.frame_size());
    if (res != VPX_CODEC_OK) {
      EXPECT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError();
      break;
    }

    libvpx_test::DxDataIterator dec_iter = decoder.GetDxData();
    const vpx_image_t *img = NULL;

    // Get decompressed data
    while ((img = dec_iter.Next())) {
      md5.Add(img);
    }
  }
  return string(md5.Get());
}

void DecodeFiles(const FileList files[]) {
  for (const FileList *iter = files; iter->name != NULL; ++iter) {
    SCOPED_TRACE(iter->name);
    for (int t = 2; t <= 8; ++t) {
      EXPECT_EQ(iter->expected_md5, DecodeFile(iter->name, t))
          << "threads = " << t;
    }
  }
}

TEST(VP9DecodeMultiThreadedTest, Decode) {
  // no tiles or frame parallel; this exercises loop filter threading.
  EXPECT_EQ("b35a1b707b28e82be025d960aba039bc",
            DecodeFile("vp90-2-03-size-226x226.webm", 2));
}

TEST(VP9DecodeMultiThreadedTest, Decode2) {
  static const FileList files[] = {
    { "vp90-2-08-tile_1x2_frame_parallel.webm",
      "68ede6abd66bae0a2edf2eb9232241b6" },
    { "vp90-2-08-tile_1x4_frame_parallel.webm",
      "368ebc6ebf3a5e478d85b2c3149b2848" },
    { "vp90-2-08-tile_1x8_frame_parallel.webm",
      "17e439da2388aff3a0f69cb22579c6c1" },
    { NULL, NULL }
  };

  DecodeFiles(files);
}

// Test tile quantity changes within one file.
TEST(VP9DecodeMultiThreadedTest, Decode3) {
  static const FileList files[] = {
    { "vp90-2-14-resize-fp-tiles-1-16.webm",
      "0cd5e632c326297e975f38949c31ea94" },
    { "vp90-2-14-resize-fp-tiles-1-2-4-8-16.webm",
      "5c78a96a42e7f4a4f6b2edcdb791e44c" },
    { "vp90-2-14-resize-fp-tiles-1-2.webm",
      "e030450ae85c3277be2a418769df98e2" },
    { "vp90-2-14-resize-fp-tiles-1-4.webm",
      "312eed4e2b64eb7a4e7f18916606a430" },
    { "vp90-2-14-resize-fp-tiles-16-1.webm",
      "1755c16d8af16a9cb3fe7338d90abe52" },
    { "vp90-2-14-resize-fp-tiles-16-2.webm",
      "500300592d3fcb6f12fab25e48aaf4df" },
    { "vp90-2-14-resize-fp-tiles-16-4.webm",
      "47c48379fa6331215d91c67648e1af6e" },
    { "vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm",
      "eecf17290739bc708506fa4827665989" },
    { "vp90-2-14-resize-fp-tiles-16-8.webm",
      "29b6bb54e4c26b5ca85d5de5fed94e76" },
    { "vp90-2-14-resize-fp-tiles-1-8.webm",
      "1b6f175e08cd82cf84bb800ac6d1caa3" },
    { "vp90-2-14-resize-fp-tiles-2-16.webm",
      "ca3b03e4197995d8d5444ede7a6c0804" },
    { "vp90-2-14-resize-fp-tiles-2-1.webm",
      "99aec065369d70bbb78ccdff65afed3f" },
    { "vp90-2-14-resize-fp-tiles-2-4.webm",
      "22d0ebdb49b87d2920a85aea32e1afd5" },
    { "vp90-2-14-resize-fp-tiles-2-8.webm",
      "c2115cf051c62e0f7db1d4a783831541" },
    { "vp90-2-14-resize-fp-tiles-4-16.webm",
      "c690d7e1719b31367564cac0af0939cb" },
    { "vp90-2-14-resize-fp-tiles-4-1.webm",
      "a926020b2cc3e15ad4cc271853a0ff26" },
    { "vp90-2-14-resize-fp-tiles-4-2.webm",
      "42699063d9e581f1993d0cf890c2be78" },
    { "vp90-2-14-resize-fp-tiles-4-8.webm",
      "7f76d96036382f45121e3d5aa6f8ec52" },
    { "vp90-2-14-resize-fp-tiles-8-16.webm",
      "76a43fcdd7e658542913ea43216ec55d" },
    { "vp90-2-14-resize-fp-tiles-8-1.webm",
      "8e3fbe89486ca60a59299dea9da91378" },
    { "vp90-2-14-resize-fp-tiles-8-2.webm",
      "ae96f21f21b6370cc0125621b441fc52" },
    { "vp90-2-14-resize-fp-tiles-8-4.webm",
      "3eb4f24f10640d42218f7fd7b9fd30d4" },
    { NULL, NULL }
  };

  DecodeFiles(files);
}
#endif  // CONFIG_WEBM_IO

INSTANTIATE_TEST_CASE_P(Synchronous, VP9WorkerThreadTest, ::testing::Bool());

}  // namespace
<|endoftext|>


<commit_before>//----------------------------------*-C++-*----------------------------------//
/*!
 * \file   utils/HDF5_IO.hh
 * \author Thomas M. Evans
 * \date   Thu Nov 07 21:53:44 2013
 * \brief  HDF5_IO class definition.
 * \note   Copyright (C) 2013 Oak Ridge National Laboratory, UT-Battelle, LLC.
 */
//---------------------------------------------------------------------------//

#ifndef utils_HDF5_IO_hh
#define utils_HDF5_IO_hh

#include <Utils/config.h>
#ifdef USE_HDF5

#include <string>
#include <vector>
#include <hdf5.h>
#include <hdf5_hl.h>

#include "harness/DBC.hh"
#include "utils/Definitions.hh"

namespace denovo
{

//===========================================================================//
/*!
 * \page hdf5_io_page HDF5 IO Services
 *
 * There are 3 basic HDF5 IO classes that can be used to build
 * application-specific HDF5 IO services.  Two classes are used to write files
 * while a single class is used to read files.  HDF5 IO can be classified
 * under two idioms, \e collective and \e independent.  Collective IO occurs
 * when every process writes to a single HDF5 instance (not necessarily at the
 * same time).  Independent IO occurs when each process writes/reads
 * independently of the other processes.  Examples of collective operations
 * are:
 * - writing a distributed field to a single HDF5 dataset
 * - writing multiple datasets to a single HDF5 file concurrently
 * .
 * Independent operational examples are:
 * - writing datasets to multiple files concurrently
 * - writing datasets on a subset of processes non-concurrently
 * .
 * The HDF5 classes that write data are denovo::Parallel_HDF5_Writer and
 * denovo::Serial_HDF5_Writer.  Parallel_HDF5_Writer is designed for
 * collective write operations in which distributed data is written to a
 * single dataset from multiple processes.  Serial_HDF5_Writer is designed for
 * any type of independent writing; although the most common use-cases are
 * a.) writing global data from a specified IO process
 * b.) writing distributed data to multiple files concurrently
 * .
 * We do not currently support the collective operations of writing global
 * data concurrently for multiple processes to a single dataset in
 * Parallel_HDF5_Writer.
 *
 * For reading the class HDF5_Reader is provided.  This class enables \e
 * independent IO reading. The expected use-case is that every process will
 * open the appropriate HDF5 file and read some portion of data.  Because
 * there are no collisions in read operations, it is safe for multiple
 * processes to read from a single file concurrently.  Thus, the notion of
 * collective and independent reads has a different context than writing.
 * This will become clear in the simple examples in
 * test/tstParallel_HDF5_Writer.cc, test/tstSerial_HDF5_Writer.cc, and
 * test/tstHDF5_Reader.cc.
 *
 * All of the read/write classes share a simple interface to add hierarchy to
 * the HDF5 data file.  The following simple example illustrates this:
 * \code
   Parallel_HDF5_Writer w;

   // the 3-dimensional block array holds the local indices of the data-block
   // in (i,j,k) parallel space; for a 5x4x2 decomposition the I has range \c
   // [0,4] the J has range [0,3] and the K has range [0,1]

   // make a decomposition object giving the decomposition of the data field
   // we intend to write
   Parallel_HDF5_Writer::Decomp d(3); // decomposed over a 3-dim mesh

   // the global dimensions of the mesh are 100x100x100
   d.global[I] = 100;
   d.global[J] = 100;
   d.global[K] = 100;

   // the local dimensions are (for a 5x4x2 decomposition)
   d.local[I] = 20;
   d.local[J] = 25;
   d.local[K] = 50;

   // the offset on each domain
   d.offset[I] = d.local[I] * block[I];
   d.offset[J] = d.local[J] * block[J];
   d.offset[K] = d.local[K] * block[K];

   // by default the data is assumed to ordered column-major, but we will
   // explicitly add it (setting d.order = ROW_MAJOR changes the default)
   d.order = Parallel_HDF5_Writer::COLUMN_MAJOR;

   // the data has size (20*25*50) and is ordered ROW_MAJOR
   //   [i + Ni * (j + Nj * (k))

   // open the file for writing (clobbering an existing file)
   w.open("output.h5");

   // we want to put this data in the sub-directory (group) "distributed_data"
   w.begin_group("distributed_data");

   // write the field collectively
   w.write("data_field", d, &data[0]);

   // end this group (returning to "/" in the file hierarchy)
   w.end_group();

   // close the file
   w.close();
 * \endcode
 *
 * To read this file the following code can be used:
 *
 * Both Parallel_HDF5_Writer and Serial_HDF5_Writer will produce HDF5 files
 * that are indistinguishable.  For example, writing a distributed field using
 * the parallel writer will produce identical output to that of the serial
 * writer if the field was manually reduced in memory to a single processor
 * and output from that processor.
 */
/*!
 * \class HDF5_IO
 * \brief Base class for HDF5 read/write classes.
 *
 * This class class provides a base for collective HDF5 IO operations.  HDF5
 * IO semantics define \e collective and \e independent processes.
 *
 * \arg \e collective processes are expected to be called on every domain in a
 * parallel context
 *
 * \arg \e independent processes are not called on every domain; they may or
 * may not be defined in a parallel (MPI) context
 *
 * All of the base functions in this class are potentially \e collective, that
 * is, they are executed on every calling process.  However, they are not
 * mandated as being collective, ie. there are no MPI calling semantics in the
 * functions of this class. The HDF5_IO_Node base class defines a the same
 * member services in an independent context.
 *
 * \sa HDF5_IO_Node, \ref hdf5_io_page
 */
//===========================================================================//

class HDF5_IO
{
  public:
    //@{
    //! Typedefs.
    typedef def::Vec_Dbl         Vec_Dbl;
    typedef def::Vec_Int         Vec_Int;
    typedef def::Vec_Char        Vec_Char;
    typedef std::string          std_string;
    typedef std::vector<hsize_t> Vec_Hsize;
    //@}

    //! Flags specifying how to open/modify file
    enum File_Mode
    {
        READ = 0,       //!< Read-only access
        CLOBBER,        //!< Write access, clobbering existing files
        APPEND,         //!< Write access, appending to existing files
        END_FILE_MODE
    };

    //! Flags indicating order of multi-D field data.
    enum Data_Order
    {
        COLUMN_MAJOR = 0, //!< FORTRAN-STYLE (default)
        ROW_MAJOR         //!< C-STYLE
    };

    //! Decomposition struct for parallel and chunk field input/output.
    struct Decomp
    {
        hsize_t    ndims;
        Vec_Hsize  global;
        Vec_Hsize  local;
        Vec_Hsize  offset;
        Data_Order order;

        explicit Decomp(int n = 0, Data_Order o = COLUMN_MAJOR);
    };

  protected:
    // >>> DATA

    // HDF5 file handle.
    hid_t b_file;

    // Filename.
    std_string b_filename;

    // Nodes.
    int b_node;
    int b_nodes;

    // File access mode
    File_Mode b_mode;

  public:
    // Constructor.
    HDF5_IO();

    // Virtual destructor.
    virtual ~HDF5_IO() = 0;

    // Close output.
    virtual void close();

    // Whether we're closed
    bool closed() const { return b_file == 0; }

    // Whether we're in read-only mode
    bool is_readonly() const { return b_mode == READ; }

    //! Check for existence of a key (alias to query)
    bool exists(const std_string &name) const { return query(name); }

    // Query for a key.
    virtual bool query(const std_string &name) const;

    // >>> HIERARCHY INTERFACE

    // Begin a new group (i.e., a subdirectory)
    virtual void begin_group(const std_string &name);

    // End the current group
    virtual void end_group();

    // Return the absolute path to the current group
    virtual std_string abspath() const;

  protected:
    // >>> IMPLEMENTATION

    // Current location in HDF5 directory hierarchy (defaults to root, '/')
    struct HDF5_Loc
    {
        hid_t      handle;
        std_string group_name;
    };

    // Stack of group locations
    std::vector<HDF5_Loc> b_loc_stack;

    // Access the current location (top of the stack)
    hid_t current_loc() const
    {
        Require(!b_loc_stack.empty());
        return b_loc_stack.back().handle;
    }
};

//===========================================================================//
/*!
 * \class HDF5_IO_Node
 * \brief Base class for HDF5 read/write classes that operate on a single
 * node indepently.
 */
//===========================================================================//

class HDF5_IO_Node : public HDF5_IO
{
    // Base class typedef.
    typedef HDF5_IO Base;

  protected:
    // >>> IMPLEMENTATION

    // Master node where all writes occur.
    int b_master;

  public:
    // Constructor.
    HDF5_IO_Node();

    // Destructor.
    virtual ~HDF5_IO_Node() = 0;

    // Close file after writing.
    void close();

    // Query for a key.
    bool query(const std_string &name) const;

    // >>> HIERARCHY INTERFACE

    // Begin a new group (i.e., a subdirectory)
    void begin_group(const std_string &name);

    // End the current group
    void end_group();

    // Return the absolute path to the current group
    std_string abspath() const;
};

} // end namespace denovo

#endif // USE_HDF5
#endif // utils_HDF5_IO_hh

//---------------------------------------------------------------------------//
//                 end of HDF5_IO.hh
//---------------------------------------------------------------------------//
<commit_msg>Fixed a comment.<commit_after>//----------------------------------*-C++-*----------------------------------//
/*!
 * \file   utils/HDF5_IO.hh
 * \author Thomas M. Evans
 * \date   Thu Nov 07 21:53:44 2013
 * \brief  HDF5_IO class definition.
 * \note   Copyright (C) 2013 Oak Ridge National Laboratory, UT-Battelle, LLC.
 */
//---------------------------------------------------------------------------//

#ifndef utils_HDF5_IO_hh
#define utils_HDF5_IO_hh

#include <Utils/config.h>
#ifdef USE_HDF5

#include <string>
#include <vector>
#include <hdf5.h>
#include <hdf5_hl.h>

#include "harness/DBC.hh"
#include "utils/Definitions.hh"

namespace denovo
{

//===========================================================================//
/*!
 * \page hdf5_io_page HDF5 IO Services
 *
 * There are 3 basic HDF5 IO classes that can be used to build
 * application-specific HDF5 IO services.  Two classes are used to write files
 * while a single class is used to read files.  HDF5 IO can be classified
 * under two idioms, \e collective and \e independent.  Collective IO occurs
 * when every process writes to a single HDF5 instance (not necessarily at the
 * same time).  Independent IO occurs when each process writes/reads
 * independently of the other processes.  Examples of collective operations
 * are:
 * - writing a distributed field to a single HDF5 dataset
 * - writing multiple datasets to a single HDF5 file concurrently
 * .
 * Independent operational examples are:
 * - writing datasets to multiple files concurrently
 * - writing datasets on a subset of processes non-concurrently
 * .
 * The HDF5 classes that write data are denovo::Parallel_HDF5_Writer and
 * denovo::Serial_HDF5_Writer.  Parallel_HDF5_Writer is designed for
 * collective write operations in which distributed data is written to a
 * single dataset from multiple processes.  Serial_HDF5_Writer is designed for
 * any type of independent writing; although the most common use-cases are
 * a.) writing global data from a specified IO process
 * b.) writing distributed data to multiple files concurrently
 * .
 * We do not currently support the collective operations of writing global
 * data concurrently for multiple processes to a single dataset in
 * Parallel_HDF5_Writer.
 *
 * For reading the class HDF5_Reader is provided.  This class enables \e
 * independent IO reading. The expected use-case is that every process will
 * open the appropriate HDF5 file and read some portion of data.  Because
 * there are no collisions in read operations, it is safe for multiple
 * processes to read from a single file concurrently.  Thus, the notion of
 * collective and independent reads has a different context than writing.
 * This will become clear in the simple examples in
 * test/tstParallel_HDF5_Writer.cc, test/tstSerial_HDF5_Writer.cc, and
 * test/tstHDF5_Reader.cc.
 *
 * All of the read/write classes share a simple interface to add hierarchy to
 * the HDF5 data file.  The following simple example illustrates this:
 * \code
   Parallel_HDF5_Writer w;

   // the 3-dimensional block array holds the local indices of the data-block
   // in (i,j,k) parallel space; for a 5x4x2 decomposition the I has range \c
   // [0,4] the J has range [0,3] and the K has range [0,1]

   // make a decomposition object giving the decomposition of the data field
   // we intend to write
   Parallel_HDF5_Writer::Decomp d(3); // decomposed over a 3-dim mesh

   // the global dimensions of the mesh are 100x100x100
   d.global[I] = 100;
   d.global[J] = 100;
   d.global[K] = 100;

   // the local dimensions are (for a 5x4x2 decomposition)
   d.local[I] = 20;
   d.local[J] = 25;
   d.local[K] = 50;

   // the offset on each domain
   d.offset[I] = d.local[I] * block[I];
   d.offset[J] = d.local[J] * block[J];
   d.offset[K] = d.local[K] * block[K];

   // by default the data is assumed to ordered column-major, but we will
   // explicitly add it (setting d.order = ROW_MAJOR changes the default)
   d.order = Parallel_HDF5_Writer::COLUMN_MAJOR;

   // the data has size (20*25*50) and is ordered COLUMN_MAJOR
   //   [i + Ni * (j + Nj * (k))

   // open the file for writing (clobbering an existing file)
   w.open("output.h5");

   // we want to put this data in the sub-directory (group) "distributed_data"
   w.begin_group("distributed_data");

   // write the field collectively
   w.write("data_field", d, &data[0]);

   // end this group (returning to "/" in the file hierarchy)
   w.end_group();

   // close the file
   w.close();
 * \endcode
 *
 * To read this file the following code can be used:
 *
 * Both Parallel_HDF5_Writer and Serial_HDF5_Writer will produce HDF5 files
 * that are indistinguishable.  For example, writing a distributed field using
 * the parallel writer will produce identical output to that of the serial
 * writer if the field was manually reduced in memory to a single processor
 * and output from that processor.
 */
/*!
 * \class HDF5_IO
 * \brief Base class for HDF5 read/write classes.
 *
 * This class class provides a base for collective HDF5 IO operations.  HDF5
 * IO semantics define \e collective and \e independent processes.
 *
 * \arg \e collective processes are expected to be called on every domain in a
 * parallel context
 *
 * \arg \e independent processes are not called on every domain; they may or
 * may not be defined in a parallel (MPI) context
 *
 * All of the base functions in this class are potentially \e collective, that
 * is, they are executed on every calling process.  However, they are not
 * mandated as being collective, ie. there are no MPI calling semantics in the
 * functions of this class. The HDF5_IO_Node base class defines a the same
 * member services in an independent context.
 *
 * \sa HDF5_IO_Node, \ref hdf5_io_page
 */
//===========================================================================//

class HDF5_IO
{
  public:
    //@{
    //! Typedefs.
    typedef def::Vec_Dbl         Vec_Dbl;
    typedef def::Vec_Int         Vec_Int;
    typedef def::Vec_Char        Vec_Char;
    typedef std::string          std_string;
    typedef std::vector<hsize_t> Vec_Hsize;
    //@}

    //! Flags specifying how to open/modify file
    enum File_Mode
    {
        READ = 0,       //!< Read-only access
        CLOBBER,        //!< Write access, clobbering existing files
        APPEND,         //!< Write access, appending to existing files
        END_FILE_MODE
    };

    //! Flags indicating order of multi-D field data.
    enum Data_Order
    {
        COLUMN_MAJOR = 0, //!< FORTRAN-STYLE (default)
        ROW_MAJOR         //!< C-STYLE
    };

    //! Decomposition struct for parallel and chunk field input/output.
    struct Decomp
    {
        hsize_t    ndims;
        Vec_Hsize  global;
        Vec_Hsize  local;
        Vec_Hsize  offset;
        Data_Order order;

        explicit Decomp(int n = 0, Data_Order o = COLUMN_MAJOR);
    };

  protected:
    // >>> DATA

    // HDF5 file handle.
    hid_t b_file;

    // Filename.
    std_string b_filename;

    // Nodes.
    int b_node;
    int b_nodes;

    // File access mode
    File_Mode b_mode;

  public:
    // Constructor.
    HDF5_IO();

    // Virtual destructor.
    virtual ~HDF5_IO() = 0;

    // Close output.
    virtual void close();

    // Whether we're closed
    bool closed() const { return b_file == 0; }

    // Whether we're in read-only mode
    bool is_readonly() const { return b_mode == READ; }

    //! Check for existence of a key (alias to query)
    bool exists(const std_string &name) const { return query(name); }

    // Query for a key.
    virtual bool query(const std_string &name) const;

    // >>> HIERARCHY INTERFACE

    // Begin a new group (i.e., a subdirectory)
    virtual void begin_group(const std_string &name);

    // End the current group
    virtual void end_group();

    // Return the absolute path to the current group
    virtual std_string abspath() const;

  protected:
    // >>> IMPLEMENTATION

    // Current location in HDF5 directory hierarchy (defaults to root, '/')
    struct HDF5_Loc
    {
        hid_t      handle;
        std_string group_name;
    };

    // Stack of group locations
    std::vector<HDF5_Loc> b_loc_stack;

    // Access the current location (top of the stack)
    hid_t current_loc() const
    {
        Require(!b_loc_stack.empty());
        return b_loc_stack.back().handle;
    }
};

//===========================================================================//
/*!
 * \class HDF5_IO_Node
 * \brief Base class for HDF5 read/write classes that operate on a single
 * node indepently.
 */
//===========================================================================//

class HDF5_IO_Node : public HDF5_IO
{
    // Base class typedef.
    typedef HDF5_IO Base;

  protected:
    // >>> IMPLEMENTATION

    // Master node where all writes occur.
    int b_master;

  public:
    // Constructor.
    HDF5_IO_Node();

    // Destructor.
    virtual ~HDF5_IO_Node() = 0;

    // Close file after writing.
    void close();

    // Query for a key.
    bool query(const std_string &name) const;

    // >>> HIERARCHY INTERFACE

    // Begin a new group (i.e., a subdirectory)
    void begin_group(const std_string &name);

    // End the current group
    void end_group();

    // Return the absolute path to the current group
    std_string abspath() const;
};

} // end namespace denovo

#endif // USE_HDF5
#endif // utils_HDF5_IO_hh

//---------------------------------------------------------------------------//
//                 end of HDF5_IO.hh
//---------------------------------------------------------------------------//
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2011-2012 DarkCore <http://www.darkpeninsula.eu/>
 * Copyright (C) 2011-2012 Project SkyFire <http://www.projectskyfire.org/>
 * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
 * Copyright (C) 2005-2012 MaNGOS <http://getmangos.com/>
 * 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"ScriptPCH.h"
#include"baradin_hold.h"

enum Spells
{
    SPELL_BERSERK              = 47008,
    SPELL_CONSUMING_DARKNESS   = 88954,
    SPELL_METEOR_SLASH         = 88942,
    SPELL_FEL_FIRESTORM        = 88972,
};

enum Events
{
    EVENT_BERSERK = 1,
    EVENT_CONSUMING_DARKNESS,
    EVENT_METEOR_SLASH,
};

class boss_argaloth: public CreatureScript
{
    public:
        boss_argaloth() : CreatureScript("boss_argaloth") { }

    struct boss_argalothAI: public BossAI
    {
        boss_argalothAI(Creature* creature) : BossAI(creature, DATA_ARGALOTH) { }

        uint32 fel_firestorm_casted;

        void Reset()
        {
            _Reset();
            me->RemoveAurasDueToSpell(SPELL_BERSERK);
            events.ScheduleEvent(EVENT_BERSERK, 300 *IN_MILLISECONDS);
            events.ScheduleEvent(EVENT_CONSUMING_DARKNESS, 14 *IN_MILLISECONDS);
            events.ScheduleEvent(EVENT_METEOR_SLASH, 10 *IN_MILLISECONDS);
            fel_firestorm_casted = 0;
        }

        void UpdateAI(const uint32 diff)
        {
            if (!UpdateVictim())
                return;

            if (me->GetHealthPct() < 66 && fel_firestorm_casted == 0)
            {
                DoCast(SPELL_FEL_FIRESTORM);
                events.DelayEvents(3 *IN_MILLISECONDS);
                fel_firestorm_casted = 1;
            }
            if (me->GetHealthPct() < 33 && fel_firestorm_casted == 1)
            {
                DoCast(SPELL_FEL_FIRESTORM);
                events.DelayEvents(3 *IN_MILLISECONDS);
                fel_firestorm_casted = 2;
            }

            events.Update(diff);

            if (me->HasUnitState(UNIT_STATE_CASTING))
                    return;

            while (uint32 eventId = events.ExecuteEvent())
            {
                switch (eventId)
                {
                case EVENT_CONSUMING_DARKNESS:
                    DoCast(SPELL_CONSUMING_DARKNESS);
                    events.RescheduleEvent(EVENT_CONSUMING_DARKNESS, 22 *IN_MILLISECONDS);
                    break;
                case EVENT_METEOR_SLASH:
                    DoCast(SPELL_METEOR_SLASH);
                    events.RescheduleEvent(EVENT_METEOR_SLASH, 15 *IN_MILLISECONDS);
                    break;
                case EVENT_BERSERK:
                    DoCast(me, SPELL_BERSERK);
                    break;
                }
            }

            DoMeleeAttackIfReady();
        }
     };

    CreatureAI* GetAI(Creature* creature) const
    {
        return new boss_argalothAI(creature);
    }
};

void AddSC_boss_argaloth()
{
    new boss_argaloth();
}<commit_msg>Fix Meteor Slash Damage INSERT INTO `spell_script_names` (`spell_id` ,`ScriptName`) VALUES ('88942 ', 'spell_meteor_slash'), ('95172 ', 'spell_meteor_slash');<commit_after>/*
 * Copyright (C) 2011-2012 DarkCore <http://www.darkpeninsula.eu/>
 * Copyright (C) 2011-2012 Project SkyFire <http://www.projectskyfire.org/>
 * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
 * Copyright (C) 2005-2012 MaNGOS <http://getmangos.com/>
 * 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"ScriptPCH.h"
#include"baradin_hold.h"

enum Spells
{
    SPELL_BERSERK              = 47008,
    SPELL_CONSUMING_DARKNESS   = 88954,
    SPELL_METEOR_SLASH         = 88942,
    SPELL_FEL_FIRESTORM        = 88972,
};

enum Events
{
    EVENT_BERSERK = 1,
    EVENT_CONSUMING_DARKNESS,
    EVENT_METEOR_SLASH,
};

class boss_argaloth: public CreatureScript
{
    public:
        boss_argaloth() : CreatureScript("boss_argaloth") { }

    struct boss_argalothAI: public BossAI
    {
        boss_argalothAI(Creature* creature) : BossAI(creature, DATA_ARGALOTH) { }

        uint32 fel_firestorm_casted;

        void Reset()
        {
            _Reset();
            me->RemoveAurasDueToSpell(SPELL_BERSERK);
            events.ScheduleEvent(EVENT_BERSERK, 300 *IN_MILLISECONDS);
            events.ScheduleEvent(EVENT_CONSUMING_DARKNESS, 14 *IN_MILLISECONDS);
            events.ScheduleEvent(EVENT_METEOR_SLASH, 10 *IN_MILLISECONDS);
            fel_firestorm_casted = 0;
        }

        void UpdateAI(const uint32 diff)
        {
            if (!UpdateVictim())
                return;

            if (me->GetHealthPct() < 66 && fel_firestorm_casted == 0)
            {
                DoCast(SPELL_FEL_FIRESTORM);
                events.DelayEvents(3 *IN_MILLISECONDS);
                fel_firestorm_casted = 1;
            }
            if (me->GetHealthPct() < 33 && fel_firestorm_casted == 1)
            {
                DoCast(SPELL_FEL_FIRESTORM);
                events.DelayEvents(3 *IN_MILLISECONDS);
                fel_firestorm_casted = 2;
            }

            events.Update(diff);

            if (me->HasUnitState(UNIT_STATE_CASTING))
                    return;

            while (uint32 eventId = events.ExecuteEvent())
            {
                switch (eventId)
                {
                case EVENT_CONSUMING_DARKNESS:
                    DoCast(SPELL_CONSUMING_DARKNESS);
                    events.RescheduleEvent(EVENT_CONSUMING_DARKNESS, 22 *IN_MILLISECONDS);
                    break;
                case EVENT_METEOR_SLASH:
                    DoCast(SPELL_METEOR_SLASH);
                    events.RescheduleEvent(EVENT_METEOR_SLASH, 15 *IN_MILLISECONDS);
                    break;
                case EVENT_BERSERK:
                    DoCast(me, SPELL_BERSERK);
                    break;
                }
            }

            DoMeleeAttackIfReady();
        }
     };

    CreatureAI* GetAI(Creature* creature) const
    {
        return new boss_argalothAI(creature);
    }
};

class spell_meteor_slash : public SpellScriptLoader
{
    public:
        spell_meteor_slash() : SpellScriptLoader("spell_meteor_slash") { }

        class spell_meteor_slash_SpellScript : public SpellScript
        {
            PrepareSpellScript(spell_meteor_slash_SpellScript);

            std::list<Unit*>& targetList;

            void FilterTargets(std::list<Unit*>& unitList)
            {
                targetList = unitList;
            }

            void DamageCaster(SpellEffIndex /*effIndex*/)
            {
                if(!targetList.empty())
                {
                    int32 damage = int32(GetHitDamage() / targetList.size());
                    SetHitDamage(dmg);
                }
            }

            void Register()
            {
                OnUnitTargetSelect += SpellUnitTargetFn(spell_meteor_slash_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CONE_ENEMY_104);
                OnEffectHitTarget += SpellEffectFn(spell_meteor_slash_SpellScript::DamageCaster, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
            }
        };

        SpellScript* GetSpellScript() const
        {
            return new spell_meteor_slash_SpellScript();
        }
};

void AddSC_boss_argaloth()
{
    new boss_argaloth();
    new spell_meteor_slash();
}<|endoftext|>