<commit_before>/*=========================================================================

  Program:   Visualization Library
  Module:    Collect.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

This file is part of the Visualization Library. No part of this file or its
contents may be copied, reproduced or altered in any way without the express
written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
#include <stdlib.h>
#include <iostream.h>
#include <math.h>

#include "Collect.hh"

vlCollection::vlCollection()
{
  this->NumberOfItems = 0;
  this->Top = NULL;
  this->Bottom = NULL;
}

void vlCollection::AddItem(vlObject *a)
{
  vlCollectionElement *elem;

  elem = new vlCollectionElement;

  if (!this->Top)
    {
    this->Top = elem;
    }
  else
    {
    this->Bottom->Next = elem;
    }
  this->Bottom = elem;

  elem->Item = a;
  elem->Next = NULL;

  this->NumberOfItems++;
}

void vlCollection::RemoveItem(vlObject *a)
{
  int i;
  vlCollectionElement *elem,*prev;

  if (!this->Top) return;

  elem = this->Top;
  prev = NULL;
  for (i = 0; i < this->NumberOfItems; i++)
    {
    if (elem->Item == a)
      {
      if (prev)
	{
	prev->Next = elem->Next;
	}
      else
	{
	this->Top = elem->Next;
	}
      if (!elem->Next)
	{
	this->Bottom = prev;
	}

      delete elem;
      this->NumberOfItems--;
      return;
      }
    else
      {
      prev = elem;
      elem = elem->Next;
      }
    }
}

int vlCollection::IsItemPresent(vlObject *a)
{
  int i;
  vlCollectionElement *elem;

  if (!this->Top) return 0;

  elem = this->Top;
  for (i = 0; i < this->NumberOfItems; i++)
    {
    if (elem->Item == a)
      {
      return i + 1;
      }
    else
      {
      elem = elem->Next;
      }
    }
}

int vlCollection::GetNumberOfItems()
{
  return this->NumberOfItems;
}

vlObject *vlCollection::GetItem(int num)
{
  int i;
  vlCollectionElement *elem;

  if ((num < 1) || (num > this->NumberOfItems))
    {
    vlErrorMacro(<< ": Requesting illegal index\n");
    return this->Top->Item;
    }

  elem = this->Top;
  for (i = 1; i < num; i++)
    {
    elem = elem->Next;
    }

  return (elem->Item);
}

void vlCollection::PrintSelf(ostream& os, vlIndent indent)
{
  if (this->ShouldIPrint(vlCollection::GetClassName()))
    {
    vlObject::PrintSelf(os,indent);

    os << indent << "Number Of Items: " << this->NumberOfItems << "\n";
    }
}

<commit_msg>ERR: Fixed bug in return value.<commit_after>/*=========================================================================

  Program:   Visualization Library
  Module:    Collect.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

This file is part of the Visualization Library. No part of this file or its
contents may be copied, reproduced or altered in any way without the express
written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
#include <stdlib.h>
#include <iostream.h>
#include <math.h>

#include "Collect.hh"

vlCollection::vlCollection()
{
  this->NumberOfItems = 0;
  this->Top = NULL;
  this->Bottom = NULL;
}

void vlCollection::AddItem(vlObject *a)
{
  vlCollectionElement *elem;

  elem = new vlCollectionElement;

  if (!this->Top)
    {
    this->Top = elem;
    }
  else
    {
    this->Bottom->Next = elem;
    }
  this->Bottom = elem;

  elem->Item = a;
  elem->Next = NULL;

  this->NumberOfItems++;
}

void vlCollection::RemoveItem(vlObject *a)
{
  int i;
  vlCollectionElement *elem,*prev;

  if (!this->Top) return;

  elem = this->Top;
  prev = NULL;
  for (i = 0; i < this->NumberOfItems; i++)
    {
    if (elem->Item == a)
      {
      if (prev)
	{
	prev->Next = elem->Next;
	}
      else
	{
	this->Top = elem->Next;
	}
      if (!elem->Next)
	{
	this->Bottom = prev;
	}

      delete elem;
      this->NumberOfItems--;
      return;
      }
    else
      {
      prev = elem;
      elem = elem->Next;
      }
    }
}

int vlCollection::IsItemPresent(vlObject *a)
{
  int i;
  vlCollectionElement *elem;

  if (!this->Top) return 0;

  elem = this->Top;
  for (i = 0; i < this->NumberOfItems; i++)
    {
    if (elem->Item == a)
      {
      return i + 1;
      }
    else
      {
      elem = elem->Next;
      }
    }

  return 0;
}

int vlCollection::GetNumberOfItems()
{
  return this->NumberOfItems;
}

vlObject *vlCollection::GetItem(int num)
{
  int i;
  vlCollectionElement *elem;

  if ((num < 1) || (num > this->NumberOfItems))
    {
    vlErrorMacro(<< ": Requesting illegal index\n");
    return this->Top->Item;
    }

  elem = this->Top;
  for (i = 1; i < num; i++)
    {
    elem = elem->Next;
    }

  return (elem->Item);
}

void vlCollection::PrintSelf(ostream& os, vlIndent indent)
{
  if (this->ShouldIPrint(vlCollection::GetClassName()))
    {
    vlObject::PrintSelf(os,indent);

    os << indent << "Number Of Items: " << this->NumberOfItems << "\n";
    }
}

<|endoftext|>


<commit_before>/*
 * File:   RotatorMPMCQueue.hpp
 * Author: Barath Kannan
 *
 * Created on 25 September 2016, 12:04 AM
 */

#ifndef CONQ_ROTATORMPMCQUEUE_HPP
#define CONQ_ROTATORMPMCQUEUE_HPP

#include "CONQ/MPMCQueue.hpp"
#include <thread>

namespace CONQ{

template <typename T, size_t SUBQUEUES>
class RotatorMPMCQueue{
public:
    RotatorMPMCQueue(){}

    void mpEnqueue(const T& input){
        thread_local static size_t indx{acquireEnqueueIndx()};
        q[indx].mpEnqueue(input);
    }

    bool mcDequeue(T& output){
        thread_local static size_t indx{acquireDequeueIndx()};
        for (size_t i=0; i<SUBQUEUES; ++i){
            if (q[(indx+i)%SUBQUEUES].mcDequeue(output)) return true;
        }
        return false;
    }

private:
    size_t acquireEnqueueIndx(){
        size_t tmp = enqueueIndx.load(std::memory_order_relaxed);
        while(!enqueueIndx.compare_exchange_weak(tmp, (tmp+1)%SUBQUEUES));
        return tmp;
    }

    size_t acquireDequeueIndx(){
        size_t tmp = dequeueIndx.load(std::memory_order_relaxed);
        while(!dequeueIndx.compare_exchange_weak(tmp, (tmp+1)%SUBQUEUES));
        return tmp;
    }

    std::atomic<size_t> enqueueIndx{0};
    std::atomic<size_t> dequeueIndx{0};
    std::array<MPMCQueue<T>, SUBQUEUES> q;

    RotatorMPMCQueue(const RotatorMPMCQueue&){};
    void operator=(const RotatorMPMCQueue&){};
};

}

#endif /* CONQ_ROTATORMPMCQUEUE_HPP */

<commit_msg>rotator queue now adapts to hotspots in subqueues<commit_after>/*
 * File:   RotatorMPMCQueue.hpp
 * Author: Barath Kannan
 * Array of unbounded MPMC Queues. Enqueue operations are assigned a subqueue,
 * which is used for all enqueue operations occuring from that thread. The deque
 * operation maintains a list of subqueues on which a "hit" has occured - pertaining
 * to the subqueues from which a successful dequeue operation has occured. On a
 * successful dequeue operation, the queue that is used is pushed to the front of the
 * list. The "hit lists" allow the queue to adapt fairly well to different usage contexts,
 * including when there are more readers than writers, more writers than readers,
 * and high contention. This queue only performs worse in single-reader single-writer
 * contexts.
 * Created on 25 September 2016, 12:04 AM
 */

#ifndef CONQ_ROTATORMPMCQUEUE_HPP
#define CONQ_ROTATORMPMCQUEUE_HPP

#include "CONQ/MPMCQueue.hpp"
#include <thread>
#include <queue>

namespace CONQ{

template <typename T, size_t SUBQUEUES>
class RotatorMPMCQueue{
public:
    RotatorMPMCQueue(){
    }

    void mpEnqueue(const T& input){
        thread_local static size_t indx{acquireEnqueueIndx()};
        q[indx].mpEnqueue(input);
    }

    bool mcDequeue(T& output){
        thread_local static size_t indx{acquireDequeueIndx()};
        thread_local static std::deque<size_t> hitList;
        thread_local static std::deque<size_t> noHitList;
        if (noHitList.empty() && hitList.empty()){
            for (size_t i=0; i<SUBQUEUES; ++i){
                noHitList.push_back((i+indx)%SUBQUEUES);
            }
        }
        for (auto it = hitList.begin(); it != hitList.end(); ++it){
            size_t current = *it;
            if (q[current].mcDequeue(output)){
                if (it != hitList.begin()){
                    hitList.erase(it);
                    hitList.push_front(current);
                }
                return true;
            }
        }
        for (size_t i=0; i<noHitList.size(); ++i){
            size_t front = noHitList.front();
            if (q[front].mcDequeue(output)){
                hitList.push_back(front);
                noHitList.pop_front();
                return true;
            }
            noHitList.pop_front();
            noHitList.push_back(front);
        }
        return false;
    }

private:
    size_t acquireEnqueueIndx(){
        size_t tmp = enqueueIndx.load(std::memory_order_relaxed);
        while(!enqueueIndx.compare_exchange_weak(tmp, (tmp+1)%SUBQUEUES));
        return tmp;
    }

    size_t acquireDequeueIndx(){
        size_t tmp = dequeueIndx.load(std::memory_order_relaxed);
        while(!dequeueIndx.compare_exchange_weak(tmp, (tmp+1)%SUBQUEUES));
        return tmp;
    }

    std::atomic<size_t> enqueueIndx{0};
    std::atomic<size_t> dequeueIndx{0};
    std::array<MPMCQueue<T>, SUBQUEUES> q;

    RotatorMPMCQueue(const RotatorMPMCQueue&){};
    void operator=(const RotatorMPMCQueue&){};
};

}

#endif /* CONQ_ROTATORMPMCQUEUE_HPP */

<|endoftext|>


<commit_before>#ifndef ENGINE_SPRITENODE_HPP
#define ENGINE_SPRITENODE_HPP

#include "Node.hpp"
#include "SFML/Graphics/Texture.hpp"
#include <functional>

namespace engine {

	class Animation {
	protected:
		std::vector<sf::IntRect> m_frames;
		bool m_looping;
		float m_speed;
		float m_currentTime;
		size_t m_currentFrame;
	public:
		Animation();

		void SetLooping(bool looping);

		bool IsLooping() const;

		std::vector<sf::IntRect>& GetFrames();

		void SetSpeed(float speed);

		float GetSpeed() const;

		void AddFrame(const sf::IntRect& frame);

		void Reset();

		void Update(float delta);

		const sf::IntRect& GetCurrentTexture();

		bool IsOver();

		std::function<void(void)> OnOver;
	};

	class SpriteNode : public Node {
	protected:
		const sf::Texture* m_texture;
		sf::Vertex m_vertices[4];
		sf::IntRect m_textureRect;
		std::map<std::string, Animation*> m_animations;
		std::string m_currentAnimation;
		bool m_animated;
		std::string m_animationWhenDone;
		bool m_vFlipped;
	public:
		SpriteNode(Scene* scene);

		virtual ~SpriteNode();

		void SetTexture(std::string path, const sf::IntRect* rect = nullptr);

		void SetTexture(sf::Texture* texture, const sf::IntRect* rect = nullptr);

		virtual bool initialize(Json::Value& root);

		virtual uint8_t GetType() const;

		void PlayAnimation(std::string name, std::string after = "");

		Animation* GetAnimation();

		virtual void SetFlipped(bool flipped);

		virtual void SetVFlipped(bool flipped);

		virtual void SetSize(sf::Vector2f size);

		std::string GetAnimationName() const {
			return m_currentAnimation;
		}

		sf::IntRect& GetTextureRect() {
			return m_textureRect;
		}

		bool IsVFlipped() const {
			return m_vFlipped;
		}

		void SetColor(const sf::Color& color) {
			m_vertices[0].color = color;
			m_vertices[1].color = color;
			m_vertices[2].color = color;
			m_vertices[3].color = color;
		}

	protected:
		void UpdatePosition();

		void UpdateTexCoords();

	protected:
		virtual void OnDraw(sf::RenderTarget& target, sf::RenderStates states, float delta);
	};
}
#endif

<commit_msg>Add Animation::GetCurrentFrame<commit_after>#ifndef ENGINE_SPRITENODE_HPP
#define ENGINE_SPRITENODE_HPP

#include "Node.hpp"
#include "SFML/Graphics/Texture.hpp"
#include <functional>

namespace engine {

	class Animation {
	protected:
		std::vector<sf::IntRect> m_frames;
		bool m_looping;
		float m_speed;
		float m_currentTime;
		size_t m_currentFrame;
	public:
		Animation();

		void SetLooping(bool looping);

		bool IsLooping() const;

		std::vector<sf::IntRect>& GetFrames();

		void SetSpeed(float speed);

		float GetSpeed() const;

		void AddFrame(const sf::IntRect& frame);

		void Reset();

		void Update(float delta);

		const sf::IntRect& GetCurrentTexture();

		bool IsOver();

		std::function<void(void)> OnOver;

		size_t GetCurrentFrame() {
			return m_currentFrame;
		}
	};

	class SpriteNode : public Node {
	protected:
		const sf::Texture* m_texture;
		sf::Vertex m_vertices[4];
		sf::IntRect m_textureRect;
		std::map<std::string, Animation*> m_animations;
		std::string m_currentAnimation;
		bool m_animated;
		std::string m_animationWhenDone;
		bool m_vFlipped;
	public:
		SpriteNode(Scene* scene);

		virtual ~SpriteNode();

		void SetTexture(std::string path, const sf::IntRect* rect = nullptr);

		void SetTexture(sf::Texture* texture, const sf::IntRect* rect = nullptr);

		virtual bool initialize(Json::Value& root);

		virtual uint8_t GetType() const;

		void PlayAnimation(std::string name, std::string after = "");

		Animation* GetAnimation();

		virtual void SetFlipped(bool flipped);

		virtual void SetVFlipped(bool flipped);

		virtual void SetSize(sf::Vector2f size);

		std::string GetAnimationName() const {
			return m_currentAnimation;
		}

		sf::IntRect& GetTextureRect() {
			return m_textureRect;
		}

		bool IsVFlipped() const {
			return m_vFlipped;
		}

		void SetColor(const sf::Color& color) {
			m_vertices[0].color = color;
			m_vertices[1].color = color;
			m_vertices[2].color = color;
			m_vertices[3].color = color;
		}

	protected:
		void UpdatePosition();

		void UpdateTexCoords();

	protected:
		virtual void OnDraw(sf::RenderTarget& target, sf::RenderStates states, float delta);
	};
}
#endif

<|endoftext|>


<commit_before>#include "SkEndian.h"
#include "SkFontHost.h"
#include "SkStream.h"

struct SkSFNTHeader {
    uint32_t    fVersion;
    uint16_t    fNumTables;
    uint16_t    fSearchRange;
    uint16_t    fEntrySelector;
    uint16_t    fRangeShift;
};

struct SkTTCFHeader {
    uint32_t    fTag;
    uint32_t    fVersion;
    uint32_t    fNumOffsets;
    uint32_t    fOffset0;   // the first of N (fNumOffsets)
};

union SkSharedTTHeader {
    SkSFNTHeader    fSingle;
    SkTTCFHeader    fCollection;
};

struct SkSFNTDirEntry {
    uint32_t    fTag;
    uint32_t    fChecksum;
    uint32_t    fOffset;
    uint32_t    fLength;
};

static int count_tables(SkStream* stream, size_t* offsetToDir = NULL) {
    SkSharedTTHeader shared;
    if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) {
        return 0;
    }

    uint32_t tag = SkEndian_SwapBE32(shared.fCollection.fTag);
    if (SkSetFourByteTag('t', 't', 'c', 'f') == tag) {
        if (shared.fCollection.fNumOffsets == 0) {
            return 0;
        }
        size_t offset = SkEndian_SwapBE32(shared.fCollection.fOffset0);
        stream->rewind();
        if (stream->skip(offset) != offset) {
            return 0;
        }
        if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) {
            return 0;
        }
        if (offsetToDir) {
            *offsetToDir = offset;
        }
    }
    return SkEndian_SwapBE16(shared.fSingle.fNumTables);
}

///////////////////////////////////////////////////////////////////////////////

struct SfntHeader {
    SfntHeader() : fCount(0), fDir(NULL) {}
    ~SfntHeader() { sk_free(fDir); }

    bool init(SkStream* stream) {
        size_t offsetToDir;
        fCount = count_tables(stream, &offsetToDir);
        if (0 == fCount) {
            return false;
        }

        stream->rewind();
        if (stream->skip(offsetToDir) != offsetToDir) {
            return false;
        }

        size_t size = fCount * sizeof(SkSFNTDirEntry);
        fDir = reinterpret_cast<SkSFNTDirEntry*>(sk_malloc_throw(size));
        return stream->read(fDir, size) == size;
    }

    int             fCount;
    SkSFNTDirEntry* fDir;
};

///////////////////////////////////////////////////////////////////////////////

int SkFontHost::CountTables(SkFontID fontID) {
    SkStream* stream = SkFontHost::OpenStream(fontID);
    if (NULL == stream) {
        return 0;
    }

    SkAutoUnref au(stream);
    return count_tables(stream);
}

int SkFontHost::GetTableTags(SkFontID fontID, SkFontTableTag tags[]) {
    SkStream* stream = SkFontHost::OpenStream(fontID);
    if (NULL == stream) {
        return 0;
    }

    SkAutoUnref au(stream);
    SfntHeader  header;
    if (!header.init(stream)) {
        return 0;
    }

    for (int i = 0; i < header.fCount; i++) {
        tags[i] = SkEndian_SwapBE32(header.fDir[i].fTag);
    }
    return header.fCount;
}

size_t SkFontHost::GetTableSize(SkFontID fontID, SkFontTableTag tag) {
    SkStream* stream = SkFontHost::OpenStream(fontID);
    if (NULL == stream) {
        return 0;
    }

    SkAutoUnref au(stream);
    SfntHeader  header;
    if (!header.init(stream)) {
        return 0;
    }

    for (int i = 0; i < header.fCount; i++) {
        if (SkEndian_SwapBE32(header.fDir[i].fTag) == tag) {
            return SkEndian_SwapBE32(header.fDir[i].fLength);
        }
    }
    return 0;
}

size_t SkFontHost::GetTableData(SkFontID fontID, SkFontTableTag tag,
                                size_t offset, size_t length, void* data) {
    SkStream* stream = SkFontHost::OpenStream(fontID);
    if (NULL == stream) {
        return 0;
    }

    SkAutoUnref au(stream);
    SfntHeader  header;
    if (!header.init(stream)) {
        return 0;
    }

    for (int i = 0; i < header.fCount; i++) {
        if (SkEndian_SwapBE32(header.fDir[i].fTag) == tag) {
            size_t realOffset = SkEndian_SwapBE32(header.fDir[i].fOffset);
            size_t realLength = SkEndian_SwapBE32(header.fDir[i].fLength);
            // now sanity check the caller's offset/length
            if (offset >= realLength) {
                return 0;
            }
            if (offset + length > realLength) {
                length = realLength - offset;
            }
            // skip the stream to the part of the table we want to copy from
            stream->rewind();
            size_t bytesToSkip = realOffset + offset;
            if (stream->skip(bytesToSkip) != bytesToSkip) {
                return 0;
            }
            if (stream->read(data, length) != length) {
                return 0;
            }
            return length;
        }
    }
    return 0;
}

<commit_msg>SkFontHost_tables: fix minor bugs<commit_after>#include "SkEndian.h"
#include "SkFontHost.h"
#include "SkStream.h"

struct SkSFNTHeader {
    uint32_t    fVersion;
    uint16_t    fNumTables;
    uint16_t    fSearchRange;
    uint16_t    fEntrySelector;
    uint16_t    fRangeShift;
};

struct SkTTCFHeader {
    uint32_t    fTag;
    uint32_t    fVersion;
    uint32_t    fNumOffsets;
    uint32_t    fOffset0;   // the first of N (fNumOffsets)
};

union SkSharedTTHeader {
    SkSFNTHeader    fSingle;
    SkTTCFHeader    fCollection;
};

struct SkSFNTDirEntry {
    uint32_t    fTag;
    uint32_t    fChecksum;
    uint32_t    fOffset;
    uint32_t    fLength;
};

static int count_tables(SkStream* stream, size_t* offsetToDir = NULL) {
    SkSharedTTHeader shared;
    if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) {
        return 0;
    }

    uint32_t tag = SkEndian_SwapBE32(shared.fCollection.fTag);
    if (SkSetFourByteTag('t', 't', 'c', 'f') == tag) {
        if (shared.fCollection.fNumOffsets == 0) {
            return 0;
        }
        size_t offset = SkEndian_SwapBE32(shared.fCollection.fOffset0);
        stream->rewind();
        if (stream->skip(offset) != offset) {
            return 0;
        }
        if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) {
            return 0;
        }
        if (offsetToDir) {
            *offsetToDir = offset;
        }
    } else {
        *offsetToDir = 0;
    }

    return SkEndian_SwapBE16(shared.fSingle.fNumTables);
}

///////////////////////////////////////////////////////////////////////////////

struct SfntHeader {
    SfntHeader() : fCount(0), fDir(NULL) {}
    ~SfntHeader() { sk_free(fDir); }

    bool init(SkStream* stream) {
        size_t offsetToDir;
        fCount = count_tables(stream, &offsetToDir);
        if (0 == fCount) {
            return false;
        }

        stream->rewind();
        const size_t tableRecordOffset = offsetToDir + sizeof(SkSFNTHeader);
        if (stream->skip(tableRecordOffset) != tableRecordOffset) {
            return false;
        }

        size_t size = fCount * sizeof(SkSFNTDirEntry);
        fDir = reinterpret_cast<SkSFNTDirEntry*>(sk_malloc_throw(size));
        return stream->read(fDir, size) == size;
    }

    int             fCount;
    SkSFNTDirEntry* fDir;
};

///////////////////////////////////////////////////////////////////////////////

int SkFontHost::CountTables(SkFontID fontID) {
    SkStream* stream = SkFontHost::OpenStream(fontID);
    if (NULL == stream) {
        return 0;
    }

    SkAutoUnref au(stream);
    return count_tables(stream);
}

int SkFontHost::GetTableTags(SkFontID fontID, SkFontTableTag tags[]) {
    SkStream* stream = SkFontHost::OpenStream(fontID);
    if (NULL == stream) {
        return 0;
    }

    SkAutoUnref au(stream);
    SfntHeader  header;
    if (!header.init(stream)) {
        return 0;
    }

    for (int i = 0; i < header.fCount; i++) {
        tags[i] = SkEndian_SwapBE32(header.fDir[i].fTag);
    }
    return header.fCount;
}

size_t SkFontHost::GetTableSize(SkFontID fontID, SkFontTableTag tag) {
    SkStream* stream = SkFontHost::OpenStream(fontID);
    if (NULL == stream) {
        return 0;
    }

    SkAutoUnref au(stream);
    SfntHeader  header;
    if (!header.init(stream)) {
        return 0;
    }

    for (int i = 0; i < header.fCount; i++) {
        if (SkEndian_SwapBE32(header.fDir[i].fTag) == tag) {
            return SkEndian_SwapBE32(header.fDir[i].fLength);
        }
    }
    return 0;
}

size_t SkFontHost::GetTableData(SkFontID fontID, SkFontTableTag tag,
                                size_t offset, size_t length, void* data) {
    SkStream* stream = SkFontHost::OpenStream(fontID);
    if (NULL == stream) {
        return 0;
    }

    SkAutoUnref au(stream);
    SfntHeader  header;
    if (!header.init(stream)) {
        return 0;
    }

    for (int i = 0; i < header.fCount; i++) {
        if (SkEndian_SwapBE32(header.fDir[i].fTag) == tag) {
            size_t realOffset = SkEndian_SwapBE32(header.fDir[i].fOffset);
            size_t realLength = SkEndian_SwapBE32(header.fDir[i].fLength);
            // now sanity check the caller's offset/length
            if (offset >= realLength) {
                return 0;
            }
            // if the caller is trusting the length from the file, then a
            // hostile file might choose a value which would overflow offset +
            // length.
            if (offset + length < offset) {
                return 0;
            }
            if (offset + length > realLength) {
                length = realLength - offset;
            }
            // skip the stream to the part of the table we want to copy from
            stream->rewind();
            size_t bytesToSkip = realOffset + offset;
            if (stream->skip(bytesToSkip) != bytesToSkip) {
                return 0;
            }
            if (stream->read(data, length) != length) {
                return 0;
            }
            return length;
        }
    }
    return 0;
}

<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip>
#include <chrono>
#include <arm_neon.h>
#include <stdlib.h>
#include <inttypes.h>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <signal.h>

std::mutex m ;
std::condition_variable cv ;
std::chrono::high_resolution_clock::time_point mid ;
std::chrono::high_resolution_clock::time_point reset ;

int32x4_t va;
std::int32_t a ;
std::int32_t * ptr;
std::int32_t n = 2500;
std::int64_t size = sizeof(a)*n;
std::int32_t limit = n-4;
std::int32_t data_bit[] = {1, 0, 0, 1};

void inline sig_handler(int sign) {
    free(ptr);
    std::cout << "\nReceived signal. aborting." << std::endl ;
    exit(-1);
}

void inline boost_song() {
    using namespace std::chrono ;

    int i{0} ;
    while( true ) {
        std::unique_lock<std::mutex> lk{m} ;
        cv.wait( lk ) ;

        while( high_resolution_clock::now() < end ) {
            int32_t var[4] = { *(ptr + i), *(ptr + i + 2), *(ptr + i + 3), *(ptr + i + 4) };
            va = vld1q_s32(var);
            i++;
            if(i==limit) i=0;
        }

        std::this_thread::sleep_until( reset ) ;
    }
}

int init_memory(void) {
    ptr = (int32_t *)malloc(size);
    if( ptr == NULL ){
        std::cout << "Malloc Error" << std::endl;
        return -1;
    }
    for(int i=0; i<=n; i++){
        ptr[i] = i;
    }
    return 0;
}

void square_am_signal(float time) {
    using namespace std::chrono ;

    seconds const sec{1} ;
    nanoseconds const nsec{ sec } ;
    using rep = nanoseconds::rep ;
    auto nsec_per_sec = nsec.count() ;

    auto start = high_resolution_clock::now() ;
    auto const end = start + nanoseconds( static_cast<rep>(0.1 * nsec_per_sec) ) ;

    while (high_resolution_clock::now() < end) {
        cv.notify_all() ;
        std::this_thread::sleep_until( end ) ;
        start = reset;
    }
}

int main(){
    signal(SIGINT, sig_handler);

    init_memory();
    for ( unsigned i = 0 ; i < std::thread::hardware_concurrency() ; ++i ) {
        std::thread t( boost_song ) ;
        t.detach() ;
    }
    square_am_signal(0.05);
    free(ptr);
    return 0;
}
<commit_msg>add send_data func<commit_after>#include <iostream>
#include <iomanip>
#include <chrono>
#include <arm_neon.h>
#include <stdlib.h>
#include <inttypes.h>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <signal.h>

std::mutex m ;
std::condition_variable cv ;
std::chrono::high_resolution_clock::time_point mid ;
std::chrono::high_resolution_clock::time_point reset ;

int32x4_t va;
std::int32_t a ;
std::int32_t * ptr;
std::int32_t n = 2500;
std::int64_t size = sizeof(a)*n;
std::int32_t limit = n-4;
std::int32_t data_bit[] = {1, 0, 0, 1};

void inline sig_handler(int sign) {
    free(ptr);
    std::cout << "\nReceived signal. aborting." << std::endl ;
    exit(-1);
}

void inline boost_song() {
    using namespace std::chrono ;

    int i{0} ;
    while( true ) {
        std::unique_lock<std::mutex> lk{m} ;
        cv.wait( lk ) ;

        while( high_resolution_clock::now() < end ) {
            int32_t var[4] = { *(ptr + i), *(ptr + i + 2), *(ptr + i + 3), *(ptr + i + 4) };
            va = vld1q_s32(var);
            i++;
            if(i==limit) i=0;
        }

        std::this_thread::sleep_until( reset ) ;
    }
}

int init_memory(void) {
    ptr = (int32_t *)malloc(size);
    if( ptr == NULL ){
        std::cout << "Malloc Error" << std::endl;
        return -1;
    }
    for(int i=0; i<=n; i++){
        ptr[i] = i;
    }
    return 0;
}

void send_data(float time) {
    using namespace std::chrono ;

    seconds const sec{1} ;
    nanoseconds const nsec{ sec } ;
    using rep = nanoseconds::rep ;
    auto nsec_per_sec = nsec.count() ;

    for(int32_t d : data_bit){
        auto start = high_resolution_clock::now() ;
        auto const end = start + nanoseconds( static_cast<rep>(time * nsec_per_sec) ) ;
        if( d == 1 ){
            std::cout << "Detected 1 bit" << std::endl;
            while (high_resolution_clock::now() < end) {
                cv.notify_all() ;
                std::this_thread::sleep_until( end ) ;
                start = reset;
            }
        }
        else{
            std::this_thread::sleep_until( end ) ;
        }
    }
}

int main(){
    signal(SIGINT, sig_handler);

    init_memory();
    for ( unsigned i = 0 ; i < std::thread::hardware_concurrency() ; ++i ) {
        std::thread t( boost_song ) ;
        t.detach() ;
    }
    send_data(0.05);
    free(ptr);
    return 0;
}
<|endoftext|>


<commit_before>#include "DSVSCA.h"

int DSVSCA::process_filter_graph(process_info info) {
    AVPacket packet, packet0;
    AVFrame *frame = av_frame_alloc();
    AVFrame *filt_frame = av_frame_alloc();
    AVFrame *comb_virt_frame = av_frame_alloc();
    int got_frame;

    std::unordered_map<Filter::Channel, Virtualizer*, std::hash<int>> c2v_;
    complete_sofa sofa_;

    AVPacket packet_out;
    AVPacket comb_packet_out;
    int got_output;

    Encoder *encoder = new Encoder(AV_CODEC_ID_AC3,
            info.format->decoder_ctx->bit_rate, AV_SAMPLE_FMT_FLTP);

    SJoin  *sjoin  = new SJoin(encoder);

    long total_duration = info.format->format_ctx->duration / (long)AV_TIME_BASE;
    uint64_t total_sample_count = 0;
    uint64_t samples_completed = 0;

    int ret = 0;

    AVOutputFormat *ofmt = NULL;
    AVFormatContext *ofmt_ctx = NULL;

    size_t index_of_ext = info.video_file_name.find_last_of('.');
    std::string out_filename_str;
    if (index_of_ext == std::string::npos) out_filename_str = info.video_file_name + "-virtualized";
    else out_filename_str = info.video_file_name.substr(0, index_of_ext) + "-virtualized" + info.video_file_name.substr(index_of_ext);
    const char *out_filename = out_filename_str.c_str();

    avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
    if(!ofmt_ctx) {
        av_log(NULL, AV_LOG_ERROR, "Could not create output context!\n");
        exit(1);
    }

    ofmt = ofmt_ctx->oformat;

    for(int i = 0; i < info.format->format_ctx->nb_streams; i++) {
        AVStream *in_stream = info.format->format_ctx->streams[i];
        AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
        if(!out_stream) {
            av_log(NULL, AV_LOG_ERROR, "Failed to allocate output stream!\n");
            exit(1);
        }

        ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
        out_stream->codec->codec_tag = 0;
        if(ret < 0) {
            av_log(NULL, AV_LOG_ERROR, "Failed to copy context from input to output stream codec context\n");
            exit(1);
        }

        if(ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
            out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
    }

    av_dump_format(ofmt_ctx, 0, out_filename, 1);

    if(!(ofmt->flags & AVFMT_NOFILE)) {
        ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
        if(ret < 0) {
            av_log(NULL, AV_LOG_ERROR, "Unable to open output file\n");
            exit(1);
        }
    }

    ret = avformat_write_header(ofmt_ctx, NULL);
    if(ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Error opening file to write header\n");
        exit(1);
    }

    /* Read all of the packets */
    packet0.data = NULL;
    packet.data = NULL;
    while(1) {
        if(!packet0.data) {
            ret = av_read_frame(info.format->format_ctx, &packet);
            if(ret < 0) break;
            packet0 = packet;
        }

        //in_stream = ifmt_ctx->streams[packet.stream_index];
        //out_stream = ofmt_ctx->streams[packet.stream_index];

        if(packet.stream_index == 0) {
            ret = av_interleaved_write_frame(ofmt_ctx, &packet0);
            if(ret < 0) {
                av_log(NULL, AV_LOG_ERROR, "Error muxing video packet\n");
            }
        }

        if(packet.stream_index == info.format->audio_stream_index) {
            got_frame = 0;
            ret = avcodec_decode_audio4(info.format->decoder_ctx, frame, &got_frame, &packet);

            if(ret < 0) {
                av_log(NULL, AV_LOG_ERROR, "Error decoding audio\n");
                continue;
            }

            packet.size -= ret;
            packet.data += ret;

            if(got_frame) {

                /* push audio from decoded frame through filter graph */
                if(av_buffersrc_add_frame_flags(info.filter->abuffer_ctx, frame, 0) < 0) {
                    av_log(NULL, AV_LOG_ERROR, "Error feeding into filter graph\n");
                    break;
                }

                int i ;
                int frame_sample_count = 0;

                while(ret >= 0) {
                    // This is where you will work with each processed frame.

                    i = 0;

                    for (auto it = info.filter->abuffersink_ctx_map.begin();
                            it != info.filter->abuffersink_ctx_map.end(); it++) {
                        ret = av_buffersink_get_frame(it->second, filt_frame);
                        if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) break;

                        int sample_count = filt_frame->nb_samples;
                        int sample_rate = filt_frame->sample_rate;
                        if (total_sample_count == 0) total_sample_count = total_duration * sample_rate;
                        if (frame_sample_count == 0) frame_sample_count = sample_count;

                        if (c2v_.count(it->first) == 0) {
                            float x_y_z[3];
                            if (info.coords.count(it->first) == 0) Filter::get_coords(it->first, &x_y_z[0], &x_y_z[1], &x_y_z[2]);
                            else {
                                x_y_z[0] = info.coords.at(it->first).x;
                                x_y_z[1] = info.coords.at(it->first).y;
                                x_y_z[2] = info.coords.at(it->first).z;

                                if (info.coord_type == Filter::Spherical) mysofa_s2c(x_y_z);
                            }

                            if (sofa_.hrtf == NULL) {
                                Virtualizer * virt = new Virtualizer(info.sofa_file_name.c_str(),
                                        sample_rate, x_y_z[0], x_y_z[1], x_y_z[2], info.block_size);
                                c2v_.insert(std::make_pair(it->first, virt));
                                sofa_ = virt->get_hrtf();
                            }
                            else {
                                Virtualizer * virt = new Virtualizer(sofa_, sample_rate,
                                        x_y_z[0], x_y_z[1], x_y_z[2], info.block_size);
                                c2v_.insert(std::make_pair(it->first, virt));
                            }
                        }

                        float * samples = Virtualizer::get_float_samples(filt_frame->extended_data[0],
                                info.format->decoder_ctx->sample_fmt, sample_count);

                        float ** float_results = c2v_[it->first]->process(samples, sample_count);

                        uint8_t * result_l = Virtualizer::get_short_samples(float_results[0],
                                info.format->decoder_ctx->sample_fmt, sample_count);

                        uint8_t * result_r = Virtualizer::get_short_samples(float_results[1],
                                info.format->decoder_ctx->sample_fmt, sample_count);

                        delete[] float_results[0];
                        delete[] float_results[1];
                        delete[] float_results;
                        delete[] samples;

                        AVFrame *virt_frame = encoder->new_frame(encoder->codec_ctx, result_r,
                                result_l);

                        virt_frame->format = AV_SAMPLE_FMT_FLTP;
                        virt_frame->sample_rate = 48000;
                        virt_frame->channel_layout = 3;

                        //av_log(NULL, AV_LOG_INFO, "%d ", i);

                        if(av_buffersrc_add_frame_flags(sjoin->abuffers_ctx[i], virt_frame, 0) < 0)
                            av_log(NULL, AV_LOG_ERROR, "Error feeding into filtergraph\n");

                        av_frame_unref(filt_frame);
                        i++;
                    }

                    if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) break;
                    ret = av_buffersink_get_frame(sjoin->abuffersink_ctx, comb_virt_frame);

                    if(ret < 0) {
                        av_log(NULL, AV_LOG_ERROR, "No virtualization frame %d\n", ret);
                        continue;
                    }
                    av_init_packet(&comb_packet_out);
                    comb_packet_out.data = NULL;
                    comb_packet_out.size = 0;

                    ret = avcodec_encode_audio2(encoder->codec_ctx, &comb_packet_out,
                            comb_virt_frame, &got_output);
                    if(ret < 0) {
                        av_log(NULL, AV_LOG_ERROR, "Error encoding comb frame %d\n", ret);
                        exit(1);
                    }

                    uint8_t* data = comb_packet_out.data;

                    av_copy_packet(&comb_packet_out, &packet0);

                    comb_packet_out.data = data;
                    ret = av_interleaved_write_frame(ofmt_ctx, &comb_packet_out);
                    if(ret < 0) {
                        av_log(NULL, AV_LOG_ERROR, "Error muxing video packet\n");
                    }
                    av_free_packet(&comb_packet_out);
                    av_frame_unref(comb_virt_frame);

                }

                samples_completed += frame_sample_count;
            }
            if(packet.size <= 0) av_free_packet(&packet0);
        } else {
            av_free_packet(&packet0);
        }

        if (total_sample_count != 0) {
            int completion = (100 * samples_completed) / total_sample_count;
            if (completion > 100) completion = 100;
            info.progress->store(completion);
        }
    }

    for (auto it = c2v_.begin(); it != c2v_.end(); it++) delete it->second;

    av_write_trailer(ofmt_ctx);
    avformat_close_input(&info.format->format_ctx);
    if(ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
        avio_close(ofmt_ctx->pb);
    avformat_free_context(ofmt_ctx);
    av_frame_free(&frame);
    av_frame_free(&filt_frame);
    av_frame_free(&comb_virt_frame);

    if(ret < 0 && ret != AVERROR_EOF) {
        av_log(NULL, AV_LOG_ERROR, "Error occured while closing out: %d\n", ret);
        return ret;
    }
}
<commit_msg>Stopped virtualizing the bass.<commit_after>#include "DSVSCA.h"

int DSVSCA::process_filter_graph(process_info info) {
    AVPacket packet, packet0;
    AVFrame *frame = av_frame_alloc();
    AVFrame *filt_frame = av_frame_alloc();
    AVFrame *comb_virt_frame = av_frame_alloc();
    int got_frame;

    std::unordered_map<Filter::Channel, Virtualizer*, std::hash<int>> c2v_;
    complete_sofa sofa_;

    AVPacket packet_out;
    AVPacket comb_packet_out;
    int got_output;

    Encoder *encoder = new Encoder(AV_CODEC_ID_AC3,
            info.format->decoder_ctx->bit_rate, AV_SAMPLE_FMT_FLTP);

    SJoin  *sjoin  = new SJoin(encoder);

    long total_duration = info.format->format_ctx->duration / (long)AV_TIME_BASE;
    uint64_t total_sample_count = 0;
    uint64_t samples_completed = 0;

    int ret = 0;

    AVOutputFormat *ofmt = NULL;
    AVFormatContext *ofmt_ctx = NULL;

    size_t index_of_ext = info.video_file_name.find_last_of('.');
    std::string out_filename_str;
    if (index_of_ext == std::string::npos) out_filename_str = info.video_file_name + "-virtualized";
    else out_filename_str = info.video_file_name.substr(0, index_of_ext) + "-virtualized" + info.video_file_name.substr(index_of_ext);
    const char *out_filename = out_filename_str.c_str();

    avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
    if(!ofmt_ctx) {
        av_log(NULL, AV_LOG_ERROR, "Could not create output context!\n");
        exit(1);
    }

    ofmt = ofmt_ctx->oformat;

    for(int i = 0; i < info.format->format_ctx->nb_streams; i++) {
        AVStream *in_stream = info.format->format_ctx->streams[i];
        AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
        if(!out_stream) {
            av_log(NULL, AV_LOG_ERROR, "Failed to allocate output stream!\n");
            exit(1);
        }

        ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
        out_stream->codec->codec_tag = 0;
        if(ret < 0) {
            av_log(NULL, AV_LOG_ERROR, "Failed to copy context from input to output stream codec context\n");
            exit(1);
        }

        if(ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
            out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
    }

    av_dump_format(ofmt_ctx, 0, out_filename, 1);

    if(!(ofmt->flags & AVFMT_NOFILE)) {
        ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
        if(ret < 0) {
            av_log(NULL, AV_LOG_ERROR, "Unable to open output file\n");
            exit(1);
        }
    }

    ret = avformat_write_header(ofmt_ctx, NULL);
    if(ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Error opening file to write header\n");
        exit(1);
    }

    /* Read all of the packets */
    packet0.data = NULL;
    packet.data = NULL;
    while(1) {
        if(!packet0.data) {
            ret = av_read_frame(info.format->format_ctx, &packet);
            if(ret < 0) break;
            packet0 = packet;
        }

        //in_stream = ifmt_ctx->streams[packet.stream_index];
        //out_stream = ofmt_ctx->streams[packet.stream_index];

        if(packet.stream_index == 0) {
            ret = av_interleaved_write_frame(ofmt_ctx, &packet0);
            if(ret < 0) {
                av_log(NULL, AV_LOG_ERROR, "Error muxing video packet\n");
            }
        }

        if(packet.stream_index == info.format->audio_stream_index) {
            got_frame = 0;
            ret = avcodec_decode_audio4(info.format->decoder_ctx, frame, &got_frame, &packet);

            if(ret < 0) {
                av_log(NULL, AV_LOG_ERROR, "Error decoding audio\n");
                continue;
            }

            packet.size -= ret;
            packet.data += ret;

            if(got_frame) {

                /* push audio from decoded frame through filter graph */
                if(av_buffersrc_add_frame_flags(info.filter->abuffer_ctx, frame, 0) < 0) {
                    av_log(NULL, AV_LOG_ERROR, "Error feeding into filter graph\n");
                    break;
                }

                int i ;
                int frame_sample_count = 0;

                while(ret >= 0) {
                    // This is where you will work with each processed frame.

                    i = 0;

                    for (auto it = info.filter->abuffersink_ctx_map.begin();
                            it != info.filter->abuffersink_ctx_map.end(); it++) {
                        ret = av_buffersink_get_frame(it->second, filt_frame);
                        if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) break;

                        uint8_t * result_l, * result_r;

                        if (it->first != Filter::LFE) {
                            int sample_count = filt_frame->nb_samples;
                            int sample_rate = filt_frame->sample_rate;
                            if (total_sample_count == 0) total_sample_count = total_duration * sample_rate;
                            if (frame_sample_count == 0) frame_sample_count = sample_count;

                            if (c2v_.count(it->first) == 0) {
                                float x_y_z[3];
                                if (info.coords.count(it->first) == 0) Filter::get_coords(it->first, &x_y_z[0], &x_y_z[1], &x_y_z[2]);
                                else {
                                    x_y_z[0] = info.coords.at(it->first).x;
                                    x_y_z[1] = info.coords.at(it->first).y;
                                    x_y_z[2] = info.coords.at(it->first).z;

                                    if (info.coord_type == Filter::Spherical) mysofa_s2c(x_y_z);
                                }

                                if (sofa_.hrtf == NULL) {
                                    Virtualizer * virt = new Virtualizer(info.sofa_file_name.c_str(),
                                            sample_rate, x_y_z[0], x_y_z[1], x_y_z[2], info.block_size);
                                    c2v_.insert(std::make_pair(it->first, virt));
                                    sofa_ = virt->get_hrtf();
                                }
                                else {
                                    Virtualizer * virt = new Virtualizer(sofa_, sample_rate,
                                            x_y_z[0], x_y_z[1], x_y_z[2], info.block_size);
                                    c2v_.insert(std::make_pair(it->first, virt));
                                }
                            }

                            float * samples = Virtualizer::get_float_samples(filt_frame->extended_data[0],
                                    info.format->decoder_ctx->sample_fmt, sample_count);

                            float ** float_results = c2v_[it->first]->process(samples, sample_count);

                            result_l = Virtualizer::get_short_samples(float_results[0],
                                    info.format->decoder_ctx->sample_fmt, sample_count);

                            result_r = Virtualizer::get_short_samples(float_results[1],
                                    info.format->decoder_ctx->sample_fmt, sample_count);

                            delete[] float_results[0];
                            delete[] float_results[1];
                            delete[] float_results;
                            delete[] samples;
                        }
                        else {
                            result_l = result_r = filt_frame->extended_data[0];
                        }

                        AVFrame *virt_frame = encoder->new_frame(encoder->codec_ctx, result_r,
                                result_l);

                        virt_frame->format = AV_SAMPLE_FMT_FLTP;
                        virt_frame->sample_rate = 48000;
                        virt_frame->channel_layout = 3;

                        //av_log(NULL, AV_LOG_INFO, "%d ", i);

                        if(av_buffersrc_add_frame_flags(sjoin->abuffers_ctx[i], virt_frame, 0) < 0)
                            av_log(NULL, AV_LOG_ERROR, "Error feeding into filtergraph\n");

                        av_frame_unref(filt_frame);
                        i++;
                    }

                    if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) break;
                    ret = av_buffersink_get_frame(sjoin->abuffersink_ctx, comb_virt_frame);

                    if(ret < 0) {
                        av_log(NULL, AV_LOG_ERROR, "No virtualization frame %d\n", ret);
                        continue;
                    }
                    av_init_packet(&comb_packet_out);
                    comb_packet_out.data = NULL;
                    comb_packet_out.size = 0;

                    ret = avcodec_encode_audio2(encoder->codec_ctx, &comb_packet_out,
                            comb_virt_frame, &got_output);
                    if(ret < 0) {
                        av_log(NULL, AV_LOG_ERROR, "Error encoding comb frame %d\n", ret);
                        exit(1);
                    }

                    uint8_t* data = comb_packet_out.data;

                    av_copy_packet(&comb_packet_out, &packet0);

                    comb_packet_out.data = data;
                    ret = av_interleaved_write_frame(ofmt_ctx, &comb_packet_out);
                    if(ret < 0) {
                        av_log(NULL, AV_LOG_ERROR, "Error muxing video packet\n");
                    }
                    av_free_packet(&comb_packet_out);
                    av_frame_unref(comb_virt_frame);

                }

                samples_completed += frame_sample_count;
            }
            if(packet.size <= 0) av_free_packet(&packet0);
        } else {
            av_free_packet(&packet0);
        }

        if (total_sample_count != 0) {
            int completion = (100 * samples_completed) / total_sample_count;
            if (completion > 100) completion = 100;
            info.progress->store(completion);
        }
    }

    for (auto it = c2v_.begin(); it != c2v_.end(); it++) delete it->second;

    av_write_trailer(ofmt_ctx);
    avformat_close_input(&info.format->format_ctx);
    if(ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
        avio_close(ofmt_ctx->pb);
    avformat_free_context(ofmt_ctx);
    av_frame_free(&frame);
    av_frame_free(&filt_frame);
    av_frame_free(&comb_virt_frame);

    if(ret < 0 && ret != AVERROR_EOF) {
        av_log(NULL, AV_LOG_ERROR, "Error occured while closing out: %d\n", ret);
        return ret;
    }
}
<|endoftext|>


<commit_before>#ifndef DURATION_H
#define DURATION_H

#include <string>

namespace sys
{

class Duration
{
public:
    Duration();

    Duration(const Duration &duration);

    Duration & operator = (const Duration &duration);

    unsigned long elapsed() const;

private:
    unsigned long _start;
};

}

#endif // DURATION_H
<commit_msg>removing unused include directive<commit_after>#ifndef DURATION_H
#define DURATION_H

namespace sys
{

class Duration
{
public:
    Duration();

    Duration(const Duration &duration);

    Duration & operator = (const Duration &duration);

    unsigned long elapsed() const;

private:
    unsigned long _start;
};

}

#endif // DURATION_H
<|endoftext|>


<commit_before>// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Core/Flags.hpp>
#include <Nazara/Core/Debug.hpp>

namespace Nz
{
	/*!
	* \ingroup core
	* \class Nz::Flags
	* \brief Core class used to combine enumeration values into flags bitfield
	*/

	/*!
	* \brief Constructs a Flags object using a bitfield
	*
	* \param value Bitfield to be used
	*
	* Uses a bitfield to builds the flag value. (e.g. if bit 0 is active, then Enum value 0 will be set as active).
	*/
	template<typename E>
	constexpr Flags<E>::Flags(BitField value) :
	m_value(value)
	{
	}

	/*!
	* \brief Constructs a Flags object using an Enum value
	*
	* \param enumVal enumVal
	*
	* Setup a Flags object with only one flag active (corresponding to the enum value passed as argument).
	*/
	template<typename E>
	constexpr Flags<E>::Flags(E enumVal) :
	Flags(GetFlagValue(enumVal))
	{
	}

	/*!
	* \brief Clear all flags
	*
	* \see Test
	*/
	template<typename E>
	void Flags<E>::Clear()
	{
		m_value = 0;
	}

	/*!
	* \brief Clear some flags
	*
	* \param flags Flags to be cleared
	*
	* \see Test
	*/
	template<typename E>
	void Flags<E>::Clear(const Flags& flags)
	{
		m_value &= ~flags;
	}

	/*!
	* \brief Enable some flags
	*
	* \param flags Flags to be enabled
	*
	* \see Clear
	* \see Test
	*/
	template<typename E>
	void Flags<E>::Set(const Flags& flags)
	{
		m_value |= flags;
	}

	/*!
	* \brief Tests if all flags from a Flags object are enabled
	* \return True if all tested flags are enabled.
	*
	* \see Clear
	*/
	template<typename E>
	constexpr bool Flags<E>::Test(const Flags& flags) const
	{
		return (m_value & flags.m_value) == flags.m_value;
	}

	/*!
	* \brief Tests any flag
	* \return True if any flag is enabled.
	*
	* This will convert to a boolean value allowing to check if any flag is set.
	*/
	template<typename E>
	constexpr Flags<E>::operator bool() const
	{
		return m_value != 0;
	}

	/*!
	* \brief Converts to an integer
	* \return Enabled flags as a integer
	*
	* This will only works if the integer type is large enough to store all flags states
	*/
	template<typename E>
	template<typename T, typename>
	constexpr Flags<E>::operator T() const
	{
		return m_value;
	}

	/*!
	* \brief Reverse flag states
	* \return Opposite enabled flags
	*
	* This will returns a copy of the Flags object with reversed flags states.
	*/
	template<typename E>
	constexpr Flags<E> Flags<E>::operator~() const
	{
		return Flags((~m_value) & ValueMask);
	}

	/*!
	* \brief Compare flag states
	* \return Shared flags
	*
	* \param rhs Flags to compare with.
	*
	* This will returns a copy of the Flags object with only enabled flags in common with the parameter
	*/
	template<typename E>
	constexpr Flags<E> Flags<E>::operator&(const Flags& rhs) const
	{
		return Flags(m_value & rhs.m_value);
	}

	/*!
	* \brief Combine flag states
	* \return Combined flags
	*
	* This will returns a copy of the Flags object with combined flags from the parameter.
	*
	* \param rhs Flags to combine with.
	*/
	template<typename E>
	constexpr Flags<E> Flags<E>::operator|(const Flags& rhs) const
	{
		return Flags(m_value | rhs.m_value);
	}

	/*!
	* \brief XOR flag states
	* \return XORed flags.
	*
	* \param rhs Flags to XOR with.
	*
	* This performs a XOR (Exclusive OR) on a copy of the flag object.
	* This will returns a copy of the object with disabled common flags and enabled unique ones.
	*/
	template<typename E>
	constexpr Flags<E> Flags<E>::operator^(const Flags& rhs) const
	{
		return Flags((m_value ^ rhs.m_value) & ValueMask);
	}

	/*!
	* \brief Check equality with flag object
	* \return True if both flags objects have the same states.
	*
	* \param rhs Flags to compare with.
	*
	* Compare two Flags object and returns true if the flag states are identical.
	*/
	template<typename E>
	constexpr bool Flags<E>::operator==(const Flags& rhs) const
	{
		return m_value == rhs.m_value;
	}

	/*!
	* \brief Check inequality with flag object
	* \return True if both flags objects have different states.
	*
	* \param rhs Flags to compare with.
	*
	* Compare two Flags object and returns true if the flag states are identical.
	*/
	template<typename E>
	constexpr bool Flags<E>::operator!=(const Flags& rhs) const
	{
		return !operator==(rhs);
	}

	/*!
	* \brief Combine flag states
	* \return A reference to the object.
	*
	* \param rhs Flags to combine with.
	*
	* This will enable flags which are enabled in parameter object and not in Flag object.
	*/
	template<typename E>
	/*constexpr*/ Flags<E>& Flags<E>::operator|=(const Flags& rhs)
	{
		m_value |= rhs.m_value;

		return *this;
	}

	/*!
	* \brief Compare flag states
	* \return A reference to the object.
	*
	* \param rhs Flags to compare with.
	*
	* This will disable flags which are disabled in parameter object and enabled in Flag object (and vice-versa).
	*/
	template<typename E>
	/*constexpr*/ Flags<E>& Flags<E>::operator&=(const Flags& rhs)
	{
		m_value &= rhs.m_value;

		return *this;
	}

	/*!
	* \brief XOR flag states
	* \return A reference to the object.
	*
	* \param rhs Flags to XOR with.
	*
	* This performs a XOR (Exclusive OR) on the flag object.
	* This will disable flags enabled in both Flags objects and enable those enabled in only one of the Flags objects.
	*/
	template<typename E>
	/*constexpr*/ Flags<E>& Flags<E>::operator^=(const Flags& rhs)
	{
		m_value ^= rhs.m_value;
		m_value &= ValueMask;

		return *this;
	}

	/*!
	* \brief Returns a bitfield corresponding to an enum value.
	* \return Bitfield representation of the enum value
	*
	* \param enumValue Enumeration value to get as a bitfield.
	*
	* Internally, every enum option is turned into a bit, this function allows to get a bitfield with only the bit of the enumeration value enabled.
	*/
	template<typename E>
	constexpr typename Flags<E>::BitField Flags<E>::GetFlagValue(E enumValue)
	{
		return 1U << static_cast<BitField>(enumValue);
	}

	/*!
	* \brief Compare flag states
	* \return Compared flags
	*
	* This will returns a copy of the Flags object compared with the enum state.
	*
	* \param lhs Enum to compare with flags.
	* \param rhs Flags object.
	*/
	template<typename E>
	constexpr Flags<E> operator&(E lhs, Flags<E> rhs)
	{
		return rhs & lhs;
	}

	/*!
	* \brief Combine flag states
	* \return Combined flags
	*
	* This will returns a copy of the Flags object combined with the enum state.
	*
	* \param lhs Enum to combine with flags.
	* \param rhs Flags object.
	*/
	template<typename E>
	constexpr Flags<E> operator|(E lhs, Flags<E> rhs)
	{
		return rhs | lhs;
	}

	/*!
	* \brief XOR flag states
	* \return XORed flags
	*
	* This will returns a copy of the Flags object XORed with the enum state.
	*
	* \param lhs Enum to XOR with flags.
	* \param rhs Flags object.
	*/
	template<typename E>
	constexpr Flags<E> operator^(E lhs, Flags<E> rhs)
	{
		return rhs ^ lhs;
	}

	namespace FlagsOperators
	{
		/*!
		* \brief Override binary NOT operator on enum to turns into a Flags object.
		* \return A Flags object with reversed bits.
		*
		* \param lhs Enumeration value to reverse.
		*
		* Returns a Flags object with all state enabled except for the enum one.
		*/
		template<typename E>
		constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator~(E lhs)
		{
			return ~Flags<E>(lhs);
		}

		/*!
		* \brief Override binary AND operator on enum to turns into a Flags object.
		* \return A Flags object with compare enum states.
		*
		* \param lhs First enumeration value to compare.
		* \param rhs Second enumeration value to compare.
		*
		* Returns a Flags object with compared states from the two enumeration values.
		* In this case, only one flag will be enabled if both enumeration values are the same.
		*/
		template<typename E>
		constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator&(E lhs, E rhs)
		{
			return Flags<E>(lhs) & rhs;
		}

		/*!
		* \brief Override binary OR operator on enum to turns into a Flags object.
		* \return A Flags object with combined enum states.
		*
		* \param lhs First enumeration value to combine.
		* \param rhs Second enumeration value to combine.
		*
		* Returns a Flags object with combined states from the two enumeration values.
		*/
		template<typename E>
		constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator|(E lhs, E rhs)
		{
			return Flags<E>(lhs) | rhs;
		}

		/*!
		* \brief Override binary XOR operator on enum to turns into a Flags object.
		* \return A Flags object with XORed enum states.
		*
		* \param lhs First enumeration value to compare.
		* \param rhs Second enumeration value to compare.
		*
		* Returns a Flags object with XORed states from the two enumeration values.
		* In this case, two flags will be enabled if both the enumeration values are different.
		*/
		template<typename E>
		constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator^(E lhs, E rhs)
		{
			return Flags<E>(lhs) ^ rhs;
		}
	}
}

#include <Nazara/Core/DebugOff.hpp>
<commit_msg>Oopsie<commit_after>// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Core/Flags.hpp>
#include <Nazara/Core/Debug.hpp>

namespace Nz
{
	/*!
	* \ingroup core
	* \class Nz::Flags
	* \brief Core class used to combine enumeration values into flags bitfield
	*/

	/*!
	* \brief Constructs a Flags object using a bitfield
	*
	* \param value Bitfield to be used
	*
	* Uses a bitfield to builds the flag value. (e.g. if bit 0 is active, then Enum value 0 will be set as active).
	*/
	template<typename E>
	constexpr Flags<E>::Flags(BitField value) :
	m_value(value)
	{
	}

	/*!
	* \brief Constructs a Flags object using an Enum value
	*
	* \param enumVal enumVal
	*
	* Setup a Flags object with only one flag active (corresponding to the enum value passed as argument).
	*/
	template<typename E>
	constexpr Flags<E>::Flags(E enumVal) :
	Flags(GetFlagValue(enumVal))
	{
	}

	/*!
	* \brief Clear all flags
	*
	* \see Test
	*/
	template<typename E>
	void Flags<E>::Clear()
	{
		m_value = 0;
	}

	/*!
	* \brief Clear some flags
	*
	* \param flags Flags to be cleared
	*
	* \see Test
	*/
	template<typename E>
	void Flags<E>::Clear(const Flags& flags)
	{
		m_value &= ~flags.m_value;
	}

	/*!
	* \brief Enable some flags
	*
	* \param flags Flags to be enabled
	*
	* \see Clear
	* \see Test
	*/
	template<typename E>
	void Flags<E>::Set(const Flags& flags)
	{
		m_value |= flags.m_value;
	}

	/*!
	* \brief Tests if all flags from a Flags object are enabled
	* \return True if all tested flags are enabled.
	*
	* \see Clear
	*/
	template<typename E>
	constexpr bool Flags<E>::Test(const Flags& flags) const
	{
		return (m_value & flags.m_value) == flags.m_value;
	}

	/*!
	* \brief Tests any flag
	* \return True if any flag is enabled.
	*
	* This will convert to a boolean value allowing to check if any flag is set.
	*/
	template<typename E>
	constexpr Flags<E>::operator bool() const
	{
		return m_value != 0;
	}

	/*!
	* \brief Converts to an integer
	* \return Enabled flags as a integer
	*
	* This will only works if the integer type is large enough to store all flags states
	*/
	template<typename E>
	template<typename T, typename>
	constexpr Flags<E>::operator T() const
	{
		return m_value;
	}

	/*!
	* \brief Reverse flag states
	* \return Opposite enabled flags
	*
	* This will returns a copy of the Flags object with reversed flags states.
	*/
	template<typename E>
	constexpr Flags<E> Flags<E>::operator~() const
	{
		return Flags((~m_value) & ValueMask);
	}

	/*!
	* \brief Compare flag states
	* \return Shared flags
	*
	* \param rhs Flags to compare with.
	*
	* This will returns a copy of the Flags object with only enabled flags in common with the parameter
	*/
	template<typename E>
	constexpr Flags<E> Flags<E>::operator&(const Flags& rhs) const
	{
		return Flags(m_value & rhs.m_value);
	}

	/*!
	* \brief Combine flag states
	* \return Combined flags
	*
	* This will returns a copy of the Flags object with combined flags from the parameter.
	*
	* \param rhs Flags to combine with.
	*/
	template<typename E>
	constexpr Flags<E> Flags<E>::operator|(const Flags& rhs) const
	{
		return Flags(m_value | rhs.m_value);
	}

	/*!
	* \brief XOR flag states
	* \return XORed flags.
	*
	* \param rhs Flags to XOR with.
	*
	* This performs a XOR (Exclusive OR) on a copy of the flag object.
	* This will returns a copy of the object with disabled common flags and enabled unique ones.
	*/
	template<typename E>
	constexpr Flags<E> Flags<E>::operator^(const Flags& rhs) const
	{
		return Flags((m_value ^ rhs.m_value) & ValueMask);
	}

	/*!
	* \brief Check equality with flag object
	* \return True if both flags objects have the same states.
	*
	* \param rhs Flags to compare with.
	*
	* Compare two Flags object and returns true if the flag states are identical.
	*/
	template<typename E>
	constexpr bool Flags<E>::operator==(const Flags& rhs) const
	{
		return m_value == rhs.m_value;
	}

	/*!
	* \brief Check inequality with flag object
	* \return True if both flags objects have different states.
	*
	* \param rhs Flags to compare with.
	*
	* Compare two Flags object and returns true if the flag states are identical.
	*/
	template<typename E>
	constexpr bool Flags<E>::operator!=(const Flags& rhs) const
	{
		return !operator==(rhs);
	}

	/*!
	* \brief Combine flag states
	* \return A reference to the object.
	*
	* \param rhs Flags to combine with.
	*
	* This will enable flags which are enabled in parameter object and not in Flag object.
	*/
	template<typename E>
	/*constexpr*/ Flags<E>& Flags<E>::operator|=(const Flags& rhs)
	{
		m_value |= rhs.m_value;

		return *this;
	}

	/*!
	* \brief Compare flag states
	* \return A reference to the object.
	*
	* \param rhs Flags to compare with.
	*
	* This will disable flags which are disabled in parameter object and enabled in Flag object (and vice-versa).
	*/
	template<typename E>
	/*constexpr*/ Flags<E>& Flags<E>::operator&=(const Flags& rhs)
	{
		m_value &= rhs.m_value;

		return *this;
	}

	/*!
	* \brief XOR flag states
	* \return A reference to the object.
	*
	* \param rhs Flags to XOR with.
	*
	* This performs a XOR (Exclusive OR) on the flag object.
	* This will disable flags enabled in both Flags objects and enable those enabled in only one of the Flags objects.
	*/
	template<typename E>
	/*constexpr*/ Flags<E>& Flags<E>::operator^=(const Flags& rhs)
	{
		m_value ^= rhs.m_value;
		m_value &= ValueMask;

		return *this;
	}

	/*!
	* \brief Returns a bitfield corresponding to an enum value.
	* \return Bitfield representation of the enum value
	*
	* \param enumValue Enumeration value to get as a bitfield.
	*
	* Internally, every enum option is turned into a bit, this function allows to get a bitfield with only the bit of the enumeration value enabled.
	*/
	template<typename E>
	constexpr typename Flags<E>::BitField Flags<E>::GetFlagValue(E enumValue)
	{
		return 1U << static_cast<BitField>(enumValue);
	}

	/*!
	* \brief Compare flag states
	* \return Compared flags
	*
	* This will returns a copy of the Flags object compared with the enum state.
	*
	* \param lhs Enum to compare with flags.
	* \param rhs Flags object.
	*/
	template<typename E>
	constexpr Flags<E> operator&(E lhs, Flags<E> rhs)
	{
		return rhs & lhs;
	}

	/*!
	* \brief Combine flag states
	* \return Combined flags
	*
	* This will returns a copy of the Flags object combined with the enum state.
	*
	* \param lhs Enum to combine with flags.
	* \param rhs Flags object.
	*/
	template<typename E>
	constexpr Flags<E> operator|(E lhs, Flags<E> rhs)
	{
		return rhs | lhs;
	}

	/*!
	* \brief XOR flag states
	* \return XORed flags
	*
	* This will returns a copy of the Flags object XORed with the enum state.
	*
	* \param lhs Enum to XOR with flags.
	* \param rhs Flags object.
	*/
	template<typename E>
	constexpr Flags<E> operator^(E lhs, Flags<E> rhs)
	{
		return rhs ^ lhs;
	}

	namespace FlagsOperators
	{
		/*!
		* \brief Override binary NOT operator on enum to turns into a Flags object.
		* \return A Flags object with reversed bits.
		*
		* \param lhs Enumeration value to reverse.
		*
		* Returns a Flags object with all state enabled except for the enum one.
		*/
		template<typename E>
		constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator~(E lhs)
		{
			return ~Flags<E>(lhs);
		}

		/*!
		* \brief Override binary AND operator on enum to turns into a Flags object.
		* \return A Flags object with compare enum states.
		*
		* \param lhs First enumeration value to compare.
		* \param rhs Second enumeration value to compare.
		*
		* Returns a Flags object with compared states from the two enumeration values.
		* In this case, only one flag will be enabled if both enumeration values are the same.
		*/
		template<typename E>
		constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator&(E lhs, E rhs)
		{
			return Flags<E>(lhs) & rhs;
		}

		/*!
		* \brief Override binary OR operator on enum to turns into a Flags object.
		* \return A Flags object with combined enum states.
		*
		* \param lhs First enumeration value to combine.
		* \param rhs Second enumeration value to combine.
		*
		* Returns a Flags object with combined states from the two enumeration values.
		*/
		template<typename E>
		constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator|(E lhs, E rhs)
		{
			return Flags<E>(lhs) | rhs;
		}

		/*!
		* \brief Override binary XOR operator on enum to turns into a Flags object.
		* \return A Flags object with XORed enum states.
		*
		* \param lhs First enumeration value to compare.
		* \param rhs Second enumeration value to compare.
		*
		* Returns a Flags object with XORed states from the two enumeration values.
		* In this case, two flags will be enabled if both the enumeration values are different.
		*/
		template<typename E>
		constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator^(E lhs, E rhs)
		{
			return Flags<E>(lhs) ^ rhs;
		}
	}
}

#include <Nazara/Core/DebugOff.hpp>
<|endoftext|>


<commit_before>#include "client.h"

Client::Client(std::string&& id, std::string&& nick, std::string&& ident, std::string&& gecos, std::string&& pass, std::string&& socktype, const Protocol* mod)
	: User(std::forward<std::string> (id), std::forward<std::string> (nick), std::forward<std::string> (ident), std::forward<std::string> (gecos)),
	password(std::forward<std::string>(pass)), socket(mod->obtainSocket(socktype)), expectingReconnect(true), proto(mod), needRegisterDelay(false), penaltySeconds(0) {}

Client::~Client() {
	if (socket->isConnected())
		socket->closeConnection();
	if (receiveThread.joinable())
		receiveThread.join();
	if (sendThread.joinable())
		sendThread.join();
	if (secondsThread.joinable())
		secondsThread.join();
	if (registerThread.joinable())
		registerThread.join();
}

void Client::connect() {
	proto->connectSocket(socket);
	receiveThread = std::thread (&Client::receiveData, this);
	if (proto->floodThrottleInEffect()) {
		sendThread = std::thread (&Client::sendQueue, this);
		secondsThread = std::thread (&Client::decrementSeconds, this);
	}
	registerThread = std::thread (&Client::delayRegister, this);
	needRegisterDelay = true;
	socket->sendData("CAP LS");
}

void Client::disconnect(const std::string& reason) {
	if (socket->isConnected()) {
		IRCMessage quitMsg ("QUIT");
		quitMsg.setParams(std::vector<std::string> { reason });
		socket->sendData(quitMsg.rawLine());
		socket->closeConnection();
	}
	expectingReconnect = false;
}

bool Client::checkConnection() const {
	if (socket)
		return socket->isConnected();
	return false;
}

bool Client::wantsToReconnect() const {
	return expectingReconnect;
}

void Client::doReconnect() {
	expectingReconnect = true;
	if (receiveThread.joinable())
		receiveThread.join();
	if (sendThread.joinable())
		sendThread.join();
	if (secondsThread.joinable())
		secondsThread.join();
	if (registerThread.joinable())
		registerThread.join();
	connect();
}

void Client::doRegister() {
	if (socket->isConnected()) {
		if (!password.empty()) {
			IRCMessage passMsg ("PASS");
			passMsg.setParams(std::vector<std::string> { password });
			socket->sendData(passMsg.rawLine());
		}
		IRCMessage nickMsg ("NICK");
		nickMsg.setParams(std::vector<std::string> { userNick });
		socket->sendData(nickMsg.rawLine());
		IRCMessage userMsg ("USER");
		userMsg.setParams(std::vector<std::string> { userIdent, "localhost", proto->servName(), userGecos });
		socket->sendData(userMsg.rawLine());
	}
	needRegisterDelay = false;
}

void Client::startFloodThrottle() {
	if (sendThread.joinable() && secondsThread.joinable())
		return;
	if (!sendThread.joinable())
		sendThread = std::thread(&Client::sendQueue, this);
	if (!secondsThread.joinable())
		secondsThread = std::thread(&Client::decrementSeconds, this);
}

void Client::endFloodThrottle() {
	if (sendThread.joinable())
		sendThread.join();
	if (secondsThread.joinable())
		secondsThread.join();
}

std::map<std::string, std::string> Client::modes() const {
	return clientModes;
}

bool Client::modeSet(const std::string& mode) const {
	return clientModes.find(mode) != clientModes.end();
}

std::string Client::modeParam(const std::string& mode) const {
	auto modeIter = clientModes.find(mode);
	if (modeIter == clientModes.end())
		return "";
	return modeIter->second;
}

std::list<std::string> Client::listModeList(const std::string& mode) const {
	auto listModeIter = clientListModes.find(mode);
	if (listModeIter == clientListModes.end())
		return std::list<std::string> ();
	return listModeIter->second;
}

bool Client::itemInList(const std::string& mode, const std::string& param) const {
	auto listModeIter = clientListModes.find(mode);
	if (listModeIter == clientListModes.end())
		return false;
	auto listIter = std::find(listModeIter->second.begin(), listModeIter->second.end(), param);
	return listIter != listModeIter->second.end();
}

void Client::setMode(const std::string& mode) {
	clientModes.insert(std::pair<std::string, std::string> (mode, ""));
}

void Client::setMode(const std::string& mode, const std::string& param) {
	clientModes[mode] = param; // If the mode is already set, we should change its param, but if not, it should be added
}

void Client::unsetMode(const std::string& mode) {
	clientModes.erase(mode);
}

void Client::setListMode(const std::string& mode, const std::string& param) {
	auto listModeIter = clientListModes.find(mode);
	if (listModeIter == clientListModes.end()) {
		clientListModes[mode].push_back(param);
		return;
	}
	auto listIter = std::find(listModeIter->second.begin(), listModeIter->second.end(), param);
	if (listIter == listModeIter->second.end())
		listModeIter->second.push_back(param);
}

void Client::unsetListMode(const std::string& mode, const std::string& param) {
	auto listModeIter = clientListModes.find(mode);
	if (listModeIter == clientListModes.end())
		return;
	listModeIter->second.remove(param);
	if (listModeIter->second.empty())
		clientListModes.erase(listModeIter);
}

void Client::sendLine(const IRCMessage* line) {
	if (proto->floodThrottleInEffect()) {
		std::unique_ptr<IRCMessage> msgCopy (new IRCMessage (line));
		linesToSend.push(msgCopy);
	} else
		socket->sendData(line->rawLine());
}

void Client::receiveData() {
	LogManager* logger = LogManager::getHandle();
	while (socket->isConnected()) {
		std::string newMsg;
		try {
			newMsg = socket->receive();
		} catch (const SocketOperationFailed& ex) {
			logger->log(LOG_DEFAULT, "protocol-client", "Connection failed for client " + userID + " (" + userNick + "!" + userIdent + "@" + userHost + " on server " + proto->servName() + ") during receive.");
			break;
		}
		proto->processIncoming(userID, IRCMessage (newMsg));
		logger->log(LOG_ALL, "protocol-client-recv-" + proto->servName(), newMsg);
	}
}

void Client::sendQueue() {
	LogManager* logger = LogManager::getHandle();
	while (socket->isConnected() && proto->floodThrottleInEffect()) {
		if (linesToSend.empty()) {
			std::this_thread::sleep_for(std::chrono::milliseconds(25));
			continue;
		}
		std::unique_ptr<IRCMessage> sendingLine = linesToSend.front();
		linesToSend.pop();
		unsigned int thisPenalty = 1;
		auto penaltyIter = commandPenalty.find(sendingLine->command());
		if (penaltyIter != commandPenalty.end())
			thisPenalty = penaltyIter->second;
		while (penaltySeconds > 10)
			std::this_thread::sleep_for(std::chrono::seconds(1));
		MutexLocker mutexLock (&sendMutex);
		penaltySeconds += thisPenalty;
		if (socket->isConnected()) { // to make sure the connection didn't get lost during the wait
			std::string lineToSend (sendingLine->rawLine());
			socket->sendData(lineToSend);
			logger->log(LOG_ALL, "protocol-client-send-" + proto->servName(), lineToSend);
		}
		std::stringstream logMsg;
		logMsg << "The command " << sendingLine->command() << " was sent; the penalty has increased by " << thisPenalty << " to " << penaltySeconds << ".";
		logger->log(LOG_ALL, "protocol-client-penalty-" + proto->servName(), logMsg.str());
	}
	if (socket->isConnected()) {
		MutexLocker mutexLock (&sendMutex);
		while (!linesToSend.empty()) {
			std::string lineToSend (linesToSend.front()->rawLine());
			linesToSend.pop();
			socket->sendData(lineToSend);
			logger->log(LOG_ALL, "protocol-client-send-" + proto->servName(), lineToSend);
		}
	}
}

void Client::decrementSeconds() {
	LogManager* logger = LogManager::getHandle();
	while (socket->isConnected() && proto->floodThrottleInEffect()) {
		std::this_thread::sleep_for(std::chrono::seconds(1));
		MutexLocker mutexLock (&sendMutex);
		if (penaltySeconds > 0) {
			penaltySeconds--;
			std::ostringstream logMsg;
			logMsg << "Penalty second count reduced to " << penaltySeconds;
			logger->log(LOG_ALL, "protocol-client-penalty-" + proto->servName(), logMsg.str());
		}
	}
	MutexLocker mutexLock (&sendMutex);
	penaltySeconds = 0;
	logger->log(LOG_DEBUG, "protocol-client-penalty-" + proto->servName(), "Socket disconnected or flood throttling disabled; penalty reset to 0.");
}

void Client::delayRegister() {
	std::this_thread::sleep_for(std::chrono::seconds(5));
	if (!needRegisterDelay)
		return;
	doRegister();
}<commit_msg>Fix constructor arguments<commit_after>#include "client.h"

Client::Client(std::string&& id, std::string&& nick, std::string&& ident, std::string&& gecos, std::string&& pass, std::string&& socktype, const Protocol* mod)
	: User(std::forward<std::string> (id), std::forward<std::string> (nick), std::forward<std::string> (ident), std::forward<std::string> (gecos)),
	password(std::forward<std::string>(pass)), socket(mod->obtainSocket(socktype)), expectingReconnect(true), proto(mod), needRegisterDelay(false), penaltySeconds(0) {}

Client::~Client() {
	if (socket->isConnected())
		socket->closeConnection();
	if (receiveThread.joinable())
		receiveThread.join();
	if (sendThread.joinable())
		sendThread.join();
	if (secondsThread.joinable())
		secondsThread.join();
	if (registerThread.joinable())
		registerThread.join();
}

void Client::connect() {
	proto->connectSocket(socket);
	receiveThread = std::thread (&Client::receiveData, this);
	if (proto->floodThrottleInEffect()) {
		sendThread = std::thread (&Client::sendQueue, this);
		secondsThread = std::thread (&Client::decrementSeconds, this);
	}
	registerThread = std::thread (&Client::delayRegister, this);
	needRegisterDelay = true;
	socket->sendData("CAP LS");
}

void Client::disconnect(const std::string& reason) {
	if (socket->isConnected()) {
		IRCMessage quitMsg ("QUIT");
		quitMsg.setParams(std::vector<std::string> { reason });
		socket->sendData(quitMsg.rawLine());
		socket->closeConnection();
	}
	expectingReconnect = false;
}

bool Client::checkConnection() const {
	if (socket)
		return socket->isConnected();
	return false;
}

bool Client::wantsToReconnect() const {
	return expectingReconnect;
}

void Client::doReconnect() {
	expectingReconnect = true;
	if (receiveThread.joinable())
		receiveThread.join();
	if (sendThread.joinable())
		sendThread.join();
	if (secondsThread.joinable())
		secondsThread.join();
	if (registerThread.joinable())
		registerThread.join();
	connect();
}

void Client::doRegister() {
	if (socket->isConnected()) {
		if (!password.empty()) {
			IRCMessage passMsg ("PASS");
			passMsg.setParams(std::vector<std::string> { password });
			socket->sendData(passMsg.rawLine());
		}
		IRCMessage nickMsg ("NICK");
		nickMsg.setParams(std::vector<std::string> { userNick });
		socket->sendData(nickMsg.rawLine());
		IRCMessage userMsg ("USER");
		userMsg.setParams(std::vector<std::string> { userIdent, "localhost", proto->servName(), userGecos });
		socket->sendData(userMsg.rawLine());
	}
	needRegisterDelay = false;
}

void Client::startFloodThrottle() {
	if (sendThread.joinable() && secondsThread.joinable())
		return;
	if (!sendThread.joinable())
		sendThread = std::thread(&Client::sendQueue, this);
	if (!secondsThread.joinable())
		secondsThread = std::thread(&Client::decrementSeconds, this);
}

void Client::endFloodThrottle() {
	if (sendThread.joinable())
		sendThread.join();
	if (secondsThread.joinable())
		secondsThread.join();
}

std::map<std::string, std::string> Client::modes() const {
	return clientModes;
}

bool Client::modeSet(const std::string& mode) const {
	return clientModes.find(mode) != clientModes.end();
}

std::string Client::modeParam(const std::string& mode) const {
	auto modeIter = clientModes.find(mode);
	if (modeIter == clientModes.end())
		return "";
	return modeIter->second;
}

std::list<std::string> Client::listModeList(const std::string& mode) const {
	auto listModeIter = clientListModes.find(mode);
	if (listModeIter == clientListModes.end())
		return std::list<std::string> ();
	return listModeIter->second;
}

bool Client::itemInList(const std::string& mode, const std::string& param) const {
	auto listModeIter = clientListModes.find(mode);
	if (listModeIter == clientListModes.end())
		return false;
	auto listIter = std::find(listModeIter->second.begin(), listModeIter->second.end(), param);
	return listIter != listModeIter->second.end();
}

void Client::setMode(const std::string& mode) {
	clientModes.insert(std::pair<std::string, std::string> (mode, ""));
}

void Client::setMode(const std::string& mode, const std::string& param) {
	clientModes[mode] = param; // If the mode is already set, we should change its param, but if not, it should be added
}

void Client::unsetMode(const std::string& mode) {
	clientModes.erase(mode);
}

void Client::setListMode(const std::string& mode, const std::string& param) {
	auto listModeIter = clientListModes.find(mode);
	if (listModeIter == clientListModes.end()) {
		clientListModes[mode].push_back(param);
		return;
	}
	auto listIter = std::find(listModeIter->second.begin(), listModeIter->second.end(), param);
	if (listIter == listModeIter->second.end())
		listModeIter->second.push_back(param);
}

void Client::unsetListMode(const std::string& mode, const std::string& param) {
	auto listModeIter = clientListModes.find(mode);
	if (listModeIter == clientListModes.end())
		return;
	listModeIter->second.remove(param);
	if (listModeIter->second.empty())
		clientListModes.erase(listModeIter);
}

void Client::sendLine(const IRCMessage* line) {
	if (proto->floodThrottleInEffect()) {
		std::unique_ptr<IRCMessage> msgCopy (new IRCMessage (*line));
		linesToSend.push(msgCopy);
	} else
		socket->sendData(line->rawLine());
}

void Client::receiveData() {
	LogManager* logger = LogManager::getHandle();
	while (socket->isConnected()) {
		std::string newMsg;
		try {
			newMsg = socket->receive();
		} catch (const SocketOperationFailed& ex) {
			logger->log(LOG_DEFAULT, "protocol-client", "Connection failed for client " + userID + " (" + userNick + "!" + userIdent + "@" + userHost + " on server " + proto->servName() + ") during receive.");
			break;
		}
		proto->processIncoming(userID, IRCMessage (newMsg));
		logger->log(LOG_ALL, "protocol-client-recv-" + proto->servName(), newMsg);
	}
}

void Client::sendQueue() {
	LogManager* logger = LogManager::getHandle();
	while (socket->isConnected() && proto->floodThrottleInEffect()) {
		if (linesToSend.empty()) {
			std::this_thread::sleep_for(std::chrono::milliseconds(25));
			continue;
		}
		std::unique_ptr<IRCMessage> sendingLine = linesToSend.front();
		linesToSend.pop();
		unsigned int thisPenalty = 1;
		auto penaltyIter = commandPenalty.find(sendingLine->command());
		if (penaltyIter != commandPenalty.end())
			thisPenalty = penaltyIter->second;
		while (penaltySeconds > 10)
			std::this_thread::sleep_for(std::chrono::seconds(1));
		MutexLocker mutexLock (&sendMutex);
		penaltySeconds += thisPenalty;
		if (socket->isConnected()) { // to make sure the connection didn't get lost during the wait
			std::string lineToSend (sendingLine->rawLine());
			socket->sendData(lineToSend);
			logger->log(LOG_ALL, "protocol-client-send-" + proto->servName(), lineToSend);
		}
		std::stringstream logMsg;
		logMsg << "The command " << sendingLine->command() << " was sent; the penalty has increased by " << thisPenalty << " to " << penaltySeconds << ".";
		logger->log(LOG_ALL, "protocol-client-penalty-" + proto->servName(), logMsg.str());
	}
	if (socket->isConnected()) {
		MutexLocker mutexLock (&sendMutex);
		while (!linesToSend.empty()) {
			std::string lineToSend (linesToSend.front()->rawLine());
			linesToSend.pop();
			socket->sendData(lineToSend);
			logger->log(LOG_ALL, "protocol-client-send-" + proto->servName(), lineToSend);
		}
	}
}

void Client::decrementSeconds() {
	LogManager* logger = LogManager::getHandle();
	while (socket->isConnected() && proto->floodThrottleInEffect()) {
		std::this_thread::sleep_for(std::chrono::seconds(1));
		MutexLocker mutexLock (&sendMutex);
		if (penaltySeconds > 0) {
			penaltySeconds--;
			std::ostringstream logMsg;
			logMsg << "Penalty second count reduced to " << penaltySeconds;
			logger->log(LOG_ALL, "protocol-client-penalty-" + proto->servName(), logMsg.str());
		}
	}
	MutexLocker mutexLock (&sendMutex);
	penaltySeconds = 0;
	logger->log(LOG_DEBUG, "protocol-client-penalty-" + proto->servName(), "Socket disconnected or flood throttling disabled; penalty reset to 0.");
}

void Client::delayRegister() {
	std::this_thread::sleep_for(std::chrono::seconds(5));
	if (!needRegisterDelay)
		return;
	doRegister();
}<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef AST_VARIABLE_H
#define AST_VARIABLE_H

#include <memory>

#include <boost/intrusive_ptr.hpp>

#include "ast/Deferred.hpp"

namespace eddic {

class Context;
class Variable;

namespace ast {

struct ASTVariableValue {
    std::shared_ptr<Context> context;

    std::string variableName;
    std::shared_ptr<Variable> var;

    mutable long references;
    ASTVariableValue() : references(0) {}
};

typedef Deferred<ASTVariableValue, boost::intrusive_ptr<ASTVariableValue>> VariableValue;

} //end of ast

} //end of eddic

//Adapt the struct for the AST
BOOST_FUSION_ADAPT_STRUCT(
    eddic::ast::VariableValue,
    (std::string, Content->variableName)
)

#endif
<commit_msg>Rename the define guard variable<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef AST_VARIABLE_VALUE_H
#define AST_VARIABLE_VALUE_H

#include <memory>

#include <boost/intrusive_ptr.hpp>

#include "ast/Deferred.hpp"

namespace eddic {

class Context;
class Variable;

namespace ast {

struct ASTVariableValue {
    std::shared_ptr<Context> context;

    std::string variableName;
    std::shared_ptr<Variable> var;

    mutable long references;
    ASTVariableValue() : references(0) {}
};

typedef Deferred<ASTVariableValue, boost::intrusive_ptr<ASTVariableValue>> VariableValue;

} //end of ast

} //end of eddic

//Adapt the struct for the AST
BOOST_FUSION_ADAPT_STRUCT(
    eddic::ast::VariableValue,
    (std::string, Content->variableName)
)

#endif
<|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.

*/

#ifndef TORRENT_ALLOCA

#include "libtorrent/config.hpp"

#ifdef TORRENT_WINDOWS

#include <malloc.h>
#define TORRENT_ALLOCA(t, n) static_cast<t*>(_alloca(sizeof(t) * (n)))

#else

#include <alloca.h>

#define TORRENT_ALLOCA(t, n) static_cast<t*>(alloca(sizeof(t) * (n)))

#endif

#endif

<commit_msg>another FreeBSD fix<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.

*/

#ifndef TORRENT_ALLOCA

#include "libtorrent/config.hpp"

#if defined TORRENT_WINDOWS

#include <malloc.h>
#define TORRENT_ALLOCA(t, n) static_cast<t*>(_alloca(sizeof(t) * (n)))

#elif defined TORRENT_BSD

#include <stdlib.h>
#define TORRENT_ALLOCA(t, n) static_cast<t*>(alloca(sizeof(t) * (n)))

#else

#include <alloca.h>
#define TORRENT_ALLOCA(t, n) static_cast<t*>(alloca(sizeof(t) * (n)))

#endif

#endif

<|endoftext|>