<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osgGA/GUIEventAdapter>

using namespace osgGA;

GUIEventAdapter::GUIEventAdapter():
    _eventType(NONE),
    _time(0.0),
    _key(0),
    _button(0),
    _Xmin(0.0),
    _Xmax(1.0),
    _Ymin(0.0),
    _Ymax(1.0),
    _mx(0.5),
    _my(0.5),
    _pressure(0.0),
    _buttonMask(0),
    _modKeyMask(0),
    _scrollingMotion(SCROLL_NONE),
    _scrollingDeltaX(0),
    _scrollingDeltaY(0),
    _mouseYOrientation(Y_INCREASING_DOWNWARDS),
    _tabletPointerType(UNKNOWN)
{}

GUIEventAdapter::GUIEventAdapter(const GUIEventAdapter& rhs):
    Referenced(),
    _eventType(rhs._eventType),
    _time(rhs._time),
    _key(rhs._key),
    _button(rhs._button),
    _Xmin(rhs._Xmin),
    _Xmax(rhs._Xmax),
    _Ymin(rhs._Ymin),
    _Ymax(rhs._Ymax),
    _mx(rhs._mx),
    _my(rhs._my),
    _pressure(rhs._pressure),
    _buttonMask(rhs._buttonMask),
    _modKeyMask(rhs._modKeyMask),
    _scrollingMotion(rhs._scrollingMotion),
    _scrollingDeltaX(rhs._scrollingDeltaX),
    _scrollingDeltaY(rhs._scrollingDeltaY),
    _mouseYOrientation(rhs._mouseYOrientation),
    _tabletPointerType(rhs._tabletPointerType)
{}

GUIEventAdapter::~GUIEventAdapter()
{
}

void GUIEventAdapter::setWindowSize(float Xmin, float Ymin, float Xmax, float Ymax)
{
    _Xmin = Xmin;
    _Ymin = Ymin;
    _Xmax = Xmax;
    _Ymax = Ymax;
}
<commit_msg>Added osg:: to Referenced() to fix IRIX build.<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osgGA/GUIEventAdapter>

using namespace osgGA;

GUIEventAdapter::GUIEventAdapter():
    _eventType(NONE),
    _time(0.0),
    _key(0),
    _button(0),
    _Xmin(0.0),
    _Xmax(1.0),
    _Ymin(0.0),
    _Ymax(1.0),
    _mx(0.5),
    _my(0.5),
    _pressure(0.0),
    _buttonMask(0),
    _modKeyMask(0),
    _scrollingMotion(SCROLL_NONE),
    _scrollingDeltaX(0),
    _scrollingDeltaY(0),
    _mouseYOrientation(Y_INCREASING_DOWNWARDS),
    _tabletPointerType(UNKNOWN)
{}

GUIEventAdapter::GUIEventAdapter(const GUIEventAdapter& rhs):
    osg::Referenced(),
    _eventType(rhs._eventType),
    _time(rhs._time),
    _key(rhs._key),
    _button(rhs._button),
    _Xmin(rhs._Xmin),
    _Xmax(rhs._Xmax),
    _Ymin(rhs._Ymin),
    _Ymax(rhs._Ymax),
    _mx(rhs._mx),
    _my(rhs._my),
    _pressure(rhs._pressure),
    _buttonMask(rhs._buttonMask),
    _modKeyMask(rhs._modKeyMask),
    _scrollingMotion(rhs._scrollingMotion),
    _scrollingDeltaX(rhs._scrollingDeltaX),
    _scrollingDeltaY(rhs._scrollingDeltaY),
    _mouseYOrientation(rhs._mouseYOrientation),
    _tabletPointerType(rhs._tabletPointerType)
{}

GUIEventAdapter::~GUIEventAdapter()
{
}

void GUIEventAdapter::setWindowSize(float Xmin, float Ymin, float Xmax, float Ymax)
{
    _Xmin = Xmin;
    _Ymin = Ymin;
    _Xmax = Xmax;
    _Ymax = Ymax;
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 Samplecount S.L.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef METHCLA_MEMORY_HPP_INCLUDED
#define METHCLA_MEMORY_HPP_INCLUDED

#include "Methcla/Utility/Macros.h"

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>

#if !defined(METHCLA_USE_BOOST_SHARED_PTR)
#  if defined(__native_client__)
#    define METHCLA_USE_BOOST_SHARED_PTR 1
# else
#    define METHCLA_USE_BOOST_SHARED_PTR 0
# endif
#endif

#if METHCLA_USE_BOOST_SHARED_PTR
METHCLA_WITHOUT_WARNINGS_BEGIN
#  include <boost/shared_ptr.hpp>
#  include <boost/make_shared.hpp>
METHCLA_WITHOUT_WARNINGS_END
#else
#  include <memory>
#endif

namespace Methcla { namespace Memory {

class Alignment
{
public:
    Alignment(size_t alignment)
        : m_alignment(std::max(alignment, sizeof(void*)))
    {
        assert( (m_alignment & (m_alignment - 1)) == 0 /* Alignment must be a power of two */ );
    }
    Alignment(const Alignment&) = default;

    operator size_t () const
    {
        return m_alignment;
    }

    template <typename T> bool isAligned(T size) const
    {
        return isAligned(m_alignment, size);
    }

    template <typename T> T align(T size) const
    {
        return align(m_alignment, size);
    }

    template <typename T> size_t padding(T size) const
    {
        return padding(m_alignment, size);
    }

    // Aligning pointers
    template <typename T> bool isAligned(T* ptr) const
    {
        return isAligned(reinterpret_cast<uintptr_t>(ptr));
    }

    template <typename T> T* align(T* ptr) const
    {
        return reinterpret_cast<T*>(align(reinterpret_cast<uintptr_t>(ptr)));
    }

    template <typename T> size_t padding(T* ptr) const
    {
        return padding(reinterpret_cast<uintptr_t>(ptr));
    }

    // Static alignment functions
    template <typename T> static bool isAligned(size_t alignment, T n)
    {
        return (n & ~(alignment-1)) == n;
    }

    template <typename T> static T align(size_t alignment, T n)
    {
        return (n + alignment) & ~(alignment-1);
    }

    template <typename T> static size_t padding(size_t alignment, T n)
    {
        return align(alignment, n) - n;
    }

private:
    size_t m_alignment;
};

//* Alignment needed for data accessed by SIMD instructions.
static const Alignment kSIMDAlignment(16);

//* Allocate memory of `size` bytes.
//
// @throw std::invalid_argument
// @throw std::bad_alloc
void* alloc(size_t size);

//* Allocate aligned memory of `size` bytes.
//
// @throw std::invalid_argument
// @throw std::bad_alloc
void* allocAligned(Alignment align, size_t size);

//* Free memory allocated by this allocator.
void free(void* ptr) noexcept;

//* Allocate memory for `n` elements of type `T`.
//
// @throw std::invalid_argument
// @throw std::bad_alloc
template <typename T> T* allocOf(size_t n=1)
{
    return static_cast<T*>(alloc(n * sizeof(T)));
}

//* Allocate aligned memory for `n` elements of type `T`.
//
// @throw std::invalid_argument
// @throw std::bad_alloc
template <typename T> T* allocAlignedOf(Alignment align, size_t n=1)
{
    return static_cast<T*>(allocAligned(align, n * sizeof(T)));
}

#if METHCLA_USE_BOOST_SHARED_PTR
using boost::shared_ptr;
using boost::make_shared;
using boost::allocate_shared;
#else
using std::shared_ptr;
using std::make_shared;
using std::allocate_shared;
#endif
} }

#endif // METHCLA_MEMORY_HPP_INCLUDED
<commit_msg>Throw std::invalid_argument instead of using assert<commit_after>// Copyright 2012-2013 Samplecount S.L.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef METHCLA_MEMORY_HPP_INCLUDED
#define METHCLA_MEMORY_HPP_INCLUDED

#include "Methcla/Utility/Macros.h"

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <stdexcept>

#if !defined(METHCLA_USE_BOOST_SHARED_PTR)
#  if defined(__native_client__)
#    define METHCLA_USE_BOOST_SHARED_PTR 1
# else
#    define METHCLA_USE_BOOST_SHARED_PTR 0
# endif
#endif

#if METHCLA_USE_BOOST_SHARED_PTR
METHCLA_WITHOUT_WARNINGS_BEGIN
#  include <boost/shared_ptr.hpp>
#  include <boost/make_shared.hpp>
METHCLA_WITHOUT_WARNINGS_END
#else
#  include <memory>
#endif

namespace Methcla { namespace Memory {

class Alignment
{
public:
    Alignment(size_t alignment)
        : m_alignment(std::max(alignment, sizeof(void*)))
    {
        if ((m_alignment & (m_alignment - 1)) != 0)
            // Alignment must be a power of two
            throw std::invalid_argument("Alignment must be a power of two");
    }

    Alignment(const Alignment&) = default;

    operator size_t () const
    {
        return m_alignment;
    }

    template <typename T> bool isAligned(T size) const
    {
        return isAligned(m_alignment, size);
    }

    template <typename T> T align(T size) const
    {
        return align(m_alignment, size);
    }

    template <typename T> size_t padding(T size) const
    {
        return padding(m_alignment, size);
    }

    // Aligning pointers
    template <typename T> bool isAligned(T* ptr) const
    {
        return isAligned(reinterpret_cast<uintptr_t>(ptr));
    }

    template <typename T> T* align(T* ptr) const
    {
        return reinterpret_cast<T*>(align(reinterpret_cast<uintptr_t>(ptr)));
    }

    template <typename T> size_t padding(T* ptr) const
    {
        return padding(reinterpret_cast<uintptr_t>(ptr));
    }

    // Static alignment functions
    template <typename T> static bool isAligned(size_t alignment, T n)
    {
        return (n & ~(alignment-1)) == n;
    }

    template <typename T> static T align(size_t alignment, T n)
    {
        return (n + alignment) & ~(alignment-1);
    }

    template <typename T> static size_t padding(size_t alignment, T n)
    {
        return align(alignment, n) - n;
    }

private:
    size_t m_alignment;
};

//* Alignment needed for data accessed by SIMD instructions.
static const Alignment kSIMDAlignment(16);

//* Allocate memory of `size` bytes.
//
// @throw std::invalid_argument
// @throw std::bad_alloc
void* alloc(size_t size);

//* Allocate aligned memory of `size` bytes.
//
// @throw std::invalid_argument
// @throw std::bad_alloc
void* allocAligned(Alignment align, size_t size);

//* Free memory allocated by this allocator.
void free(void* ptr) noexcept;

//* Allocate memory for `n` elements of type `T`.
//
// @throw std::invalid_argument
// @throw std::bad_alloc
template <typename T> T* allocOf(size_t n=1)
{
    return static_cast<T*>(alloc(n * sizeof(T)));
}

//* Allocate aligned memory for `n` elements of type `T`.
//
// @throw std::invalid_argument
// @throw std::bad_alloc
template <typename T> T* allocAlignedOf(Alignment align, size_t n=1)
{
    return static_cast<T*>(allocAligned(align, n * sizeof(T)));
}

#if METHCLA_USE_BOOST_SHARED_PTR
using boost::shared_ptr;
using boost::make_shared;
using boost::allocate_shared;
#else
using std::shared_ptr;
using std::make_shared;
using std::allocate_shared;
#endif
} }

#endif // METHCLA_MEMORY_HPP_INCLUDED
<|endoftext|>


<commit_before>
#include "ComputeProcessor.h"

#include <cassert>
#include <string>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
std::string GetExecutableFullPath()
{
	char buffer[512];
	GetModuleFileName(NULL, buffer, sizeof(buffer) - 1);
	return buffer;
}
#endif

// List of all registered transform descriptions
static std::vector<TransformDescBase*> g_TransformDescs;

Arguments::Arguments(int argc, const char* argv[])
{
	// Copy from the command-line into local storage
	m_Arguments.resize(argc);
	for (size_t i = 0; i < m_Arguments.size(); i++)
		m_Arguments[i] = argv[i];

	// Override first argument with complete path to executable
	m_Arguments[0] = GetExecutableFullPath();
}

size_t Arguments::GetIndexOf(const std::string& arg, int occurrence) const
{
	// Linear search for a matching argument
	int found = 0;
	for (size_t i = 0; i < m_Arguments.size(); i++)
	{
		if (m_Arguments[i] == arg)
		{
			if (found++ == occurrence)
				return i;
		}
	}

	return -1;
}

bool Arguments::Have(const std::string& arg) const
{
	// Does the specific argument exist?
	return GetIndexOf(arg) != -1;
}

std::string Arguments::GetProperty(const std::string& arg, int occurrence) const
{
	// Does the arg exist and does it have a value
	size_t index = GetIndexOf(arg, occurrence);
	if (index == -1 || index + 1 >= m_Arguments.size())
		return "";

	return m_Arguments[index + 1];
}

size_t Arguments::Count() const
{
	return m_Arguments.size();
}

const std::string& Arguments::operator [] (int index) const
{
	return m_Arguments[index];
}

TokenList::TokenList()
	: first(0)
	, last(0)
	, error(cmpError_CreateOK())
{
}

TokenList::TokenList(cmpToken* first_token, cmpToken* last_token)
	: first(first_token)
	, last(last_token)
	, error(cmpError_CreateOK())
{
}

cmpToken* TokenList::Add(cmpToken *token)
{
	cmpToken_AddToList(&first, &last, token);
	return token;
}

cmpToken* TokenList::Add(enum cmpTokenType type, const char* start, cmpU32 length, cmpU32 line)
{
	cmpToken* token;
	error = cmpToken_Create(&token, type, start, length, line);
	if (!cmpError_OK(&error))
		throw error;
	return Add(token);
}

cmpToken* TokenList::Add(enum cmpTokenType type, cmpU32 line)
{
	// Ensure this is a single character token
	assert(type != cmpToken_None);
	assert(type < cmpToken_InvalidSeparator);

	// Construnct a single character string out of its character code
	const char* text;
	switch (type)
	{
		case cmpToken_LBrace: text = "{"; break;
		case cmpToken_RBrace: text = "}"; break;
		case cmpToken_Comma: text = ","; break;
		case cmpToken_LBracket: text = "("; break;
		case cmpToken_RBracket: text = ")"; break;
		case cmpToken_LSqBracket: text = "["; break;
		case cmpToken_RSqBracket: text = "]"; break;
		case cmpToken_Colon: text = ":"; break;
		case cmpToken_SemiColon: text = ";"; break;
		case cmpToken_Period: text = "."; break;
		case cmpToken_Question: text = "?"; break;
		case cmpToken_Tilde: text = "~"; break;
		case cmpToken_LAngle: text = "<"; break;
		case cmpToken_RAngle: text = ">"; break;
		case cmpToken_Plus: text = "+"; break;
		case cmpToken_Minus: text = "-"; break;
		case cmpToken_Asterisk: text = "*"; break;
		case cmpToken_Divide: text = "/"; break;
		case cmpToken_Modulo: text = "%%"; break;
		case cmpToken_Equals: text = "="; break;
		case cmpToken_And: text = "&"; break;
		case cmpToken_Or: text = "|"; break;
		case cmpToken_Xor: text = "^"; break;
		case cmpToken_Not: text = "!"; break;
		case cmpToken_Hash: text = "#"; break;
		default:
			assert(false);
	}

	return Add(type, text, 1, line);
}

cmpToken* TokenList::Add(const HashString& string, cmpU32 line)
{
	// Create a symbol token using globally persistent HashString text
	cmpToken* token = Add(cmpToken_Symbol, string.text, string.length, line);
	token->hash = string.hash;
	return token;
}

cmpToken* TokenList::Add(const String& string, cmpU32 line)
{
	cmpToken* token = Add(cmpToken_String, string.text, string.length, line);
	token->hash = cmpHash(string.text, string.length);
	return token;
}

void TokenList::DeleteAll()
{
	// Move one beyond last for while comparison delete to be inclusive
	if (last != 0)
		last = last->next;

	while (first != last)
	{
		cmpToken* next = first->next;
		cmpToken_Destroy(first);
		first = next;
	}

	first = 0;
	last = 0;
}

ComputeProcessor::ComputeProcessor(const ::Arguments& arguments)
	: m_Arguments(arguments)
	, m_InputFilename(arguments[1])
	, m_MemoryFile(0)
	, m_LexerCursor(0)
	, m_ParserCursor(0)
	, m_RootNode(0)
{
	// Parse the executable path looking for its directory
	m_ExecutableDirectory = m_Arguments[0];
	size_t sep = m_ExecutableDirectory.rfind('\\');
	if (sep == -1)
		sep = m_ExecutableDirectory.rfind('/');
	if (sep != -1)
		m_ExecutableDirectory = m_ExecutableDirectory.substr(0, sep);
}

ComputeProcessor::~ComputeProcessor()
{
	// Destroy all transforms, assuming transform description list and allocate transforms lists are in sync
	for (size_t i = 0; i < m_Transforms.size(); i++)
	{
		const TransformDescBase* desc = g_TransformDescs[i];
		assert(desc != 0);
		assert(desc->delete_func != 0);
		desc->delete_func(m_Transforms[i]);
	}

	// Destroy all tokens
	m_Tokens.DeleteAll();

	// Destroy all nodes
	if (m_RootNode != 0)
		cmpNode_Destroy(m_RootNode);

	// Destroy all parser objects
	if (m_ParserCursor != 0)
		cmpParserCursor_Destroy(m_ParserCursor);
	if (m_LexerCursor != 0)
		cmpLexerCursor_Destroy(m_LexerCursor);
	if (m_MemoryFile != 0)
		cmpMemoryFile_Destroy(m_MemoryFile);
}

bool ComputeProcessor::ParseFile()
{
	const char* filename = m_InputFilename.c_str();
	bool verbose = m_Arguments.Have("-verbose");

	// Open the input file
	if (cmpError error = cmpMemoryFile_Create(&m_MemoryFile, filename))
	{
		printf("Error opening input file: %s\n\n", cmpError_Text(&error));
		return false;
	}

	// Build a list of tokens
	if (cmpError error = cmpLexerCursor_Create(&m_LexerCursor, cmpMemoryFile_Data(m_MemoryFile), cmpMemoryFile_Size(m_MemoryFile), verbose))
	{
		printf("Error creating lexer cursor: %s\n\n", cmpError_Text(&error));
		return false;
	}
	while (cmpToken* token = cmpLexer_ConsumeToken(m_LexerCursor))
	{
		m_Tokens.Add(token);
		if (verbose)
			printf("[0x%2x] %s %d\n", token->type, cmpTokenType_Name(token->type), token->length);
	}

	// Print any lexer errors
	if (cmpError error = cmpLexerCursor_Error(m_LexerCursor))
	{
		printf("%s(%d): %s\n", filename, cmpLexerCursor_Line(m_LexerCursor), cmpError_Text(&error));
		return false;
	}

	cmpError error = cmpNode_CreateEmpty(&m_RootNode);
	if (!cmpError_OK(&error))
	{
		printf("Error: %s\n", error.text);
		return false;
	}

	// Build a list of parser nodes
	if (cmpError error = cmpParserCursor_Create(&m_ParserCursor, m_Tokens.first, verbose))
	{
		printf("Error creating parser cursor: %s\n\n", cmpError_Text(&error));
		return false;
	}
	while (cmpNode* node = cmpParser_ConsumeNode(m_ParserCursor))
		cmpNode_AddChild(m_RootNode, node);

	if (verbose)
		cmpParser_LogNodes(m_RootNode, 0);

	// Print any parser errors
	if (cmpError error = cmpParserCursor_Error(m_ParserCursor))
	{
		printf("%s(%d): %s\n",filename, cmpParserCursor_Line(m_ParserCursor), cmpError_Text(&error));
		return false;
	}

	return true;
}

namespace
{
	bool VisitNode(const ComputeProcessor& processor, cmpNode* node, INodeVisitor* visitor)
	{
		assert(visitor != 0);
		assert(node != 0);
		if (!visitor->Visit(processor, *node))
			return false;

		for (cmpNode* child = node->first_child; child != 0; child = child->next_sibling)
		{
			if (!VisitNode(processor, child, visitor))
				return false;
		}

		return true;
	}
}

bool ComputeProcessor::VisitNodes(INodeVisitor* visitor)
{
	assert(visitor != 0);
	return VisitNode(*this, m_RootNode, visitor);
}

cmpError ComputeProcessor::ApplyTransforms()
{
	if (m_Transforms.empty())
	{
		// Create all transforms for the processor the first time this function is called
		for (size_t i = 0; i < g_TransformDescs.size(); i++)
		{
			const TransformDescBase* desc = g_TransformDescs[i];
			assert(desc != 0);
			assert(desc->new_func != 0);
			ITransform* transform = desc->new_func();
			assert(transform != 0);
			m_Transforms.push_back(transform);
		}
	}

	// Apply all transforms in the (indeterminate) order they are registered
	for (size_t i = 0; i < m_Transforms.size(); i++)
	{
		ITransform* transform = m_Transforms[i];
		assert(transform != 0);
		cmpError error = transform->Apply(*this);
		if (!cmpError_OK(&error))
			return error;
	}

	return cmpError_CreateOK();
}

TokenIterator::TokenIterator(cmpNode& node)
	: first_token(node.first_token)
	, last_token(node.last_token ? node.last_token->next : 0)
	, token(first_token)
{
}

cmpToken* TokenIterator::SkipWhitespace()
{
	// Skip all whitespace/EOL tokens
	while (
		token != last_token &&
		(token->type == cmpToken_Whitespace ||
		 token->type == cmpToken_EOL))
		token = token->next;

	// Return NULL if skipped over all tokens
	return token == last_token ? token : 0;
}

TokenIterator::operator bool () const
{
	return token != last_token;
}

TokenIterator& TokenIterator::operator ++ ()
{
	if (token != last_token)
		token = token->next;
	else
		token = 0;

	return *this;
}

String::String()
	: text(0)
	, length(0)
{
}

String::String(const char *source, size_t src_length)
	: text(0)
	, length(0)
{
	Set(source, src_length);
}

String::String(const std::string& source)
	: text(0)
	, length(0)
{
	Set(source.c_str(), source.length());
}

String::String(const String& rhs)
	: text(rhs.text)
	, length(rhs.length)
{
	// Take ownership
	rhs.text = 0;
}

String::~String()
{
	if (text != 0)
		delete [] text;
}

void String::Set(const char *source, size_t src_length)
{
	// Copy and null terminate
	assert(text == 0);
	length = src_length;
	text = new char[length + 1];
	memcpy(text, source, length);
	text[length] = 0;
}

String& String::operator = (const String& rhs)
{
	// Take ownership
	assert(text == 0);
	text = rhs.text;
	length = rhs.length;
	rhs.text = 0;
	return *this;
}

TransformDescBase::TransformDescBase(NewFunc new_func, DeleteFunc delete_func)
	: new_func(new_func)
	, delete_func(delete_func)
{
	// Register transform description
	g_TransformDescs.push_back(this);
}
<commit_msg>ComputeBridge: Add cmpToken_Whitespace and cmpToken_EOL as single character emitters for TokenList.<commit_after>
#include "ComputeProcessor.h"

#include <cassert>
#include <string>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
std::string GetExecutableFullPath()
{
	char buffer[512];
	GetModuleFileName(NULL, buffer, sizeof(buffer) - 1);
	return buffer;
}
#endif

// List of all registered transform descriptions
static std::vector<TransformDescBase*> g_TransformDescs;

Arguments::Arguments(int argc, const char* argv[])
{
	// Copy from the command-line into local storage
	m_Arguments.resize(argc);
	for (size_t i = 0; i < m_Arguments.size(); i++)
		m_Arguments[i] = argv[i];

	// Override first argument with complete path to executable
	m_Arguments[0] = GetExecutableFullPath();
}

size_t Arguments::GetIndexOf(const std::string& arg, int occurrence) const
{
	// Linear search for a matching argument
	int found = 0;
	for (size_t i = 0; i < m_Arguments.size(); i++)
	{
		if (m_Arguments[i] == arg)
		{
			if (found++ == occurrence)
				return i;
		}
	}

	return -1;
}

bool Arguments::Have(const std::string& arg) const
{
	// Does the specific argument exist?
	return GetIndexOf(arg) != -1;
}

std::string Arguments::GetProperty(const std::string& arg, int occurrence) const
{
	// Does the arg exist and does it have a value
	size_t index = GetIndexOf(arg, occurrence);
	if (index == -1 || index + 1 >= m_Arguments.size())
		return "";

	return m_Arguments[index + 1];
}

size_t Arguments::Count() const
{
	return m_Arguments.size();
}

const std::string& Arguments::operator [] (int index) const
{
	return m_Arguments[index];
}

TokenList::TokenList()
	: first(0)
	, last(0)
	, error(cmpError_CreateOK())
{
}

TokenList::TokenList(cmpToken* first_token, cmpToken* last_token)
	: first(first_token)
	, last(last_token)
	, error(cmpError_CreateOK())
{
}

cmpToken* TokenList::Add(cmpToken *token)
{
	cmpToken_AddToList(&first, &last, token);
	return token;
}

cmpToken* TokenList::Add(enum cmpTokenType type, const char* start, cmpU32 length, cmpU32 line)
{
	cmpToken* token;
	error = cmpToken_Create(&token, type, start, length, line);
	if (!cmpError_OK(&error))
		throw error;
	return Add(token);
}

cmpToken* TokenList::Add(enum cmpTokenType type, cmpU32 line)
{
	// Ensure this is a single character token
	assert(type != cmpToken_None);
	assert(type == cmpToken_Whitespace || type == cmpToken_EOL || type < cmpToken_InvalidSeparator);

	// Construnct a single character string out of its character code
	const char* text;
	switch (type)
	{
		case cmpToken_LBrace: text = "{"; break;
		case cmpToken_RBrace: text = "}"; break;
		case cmpToken_Comma: text = ","; break;
		case cmpToken_LBracket: text = "("; break;
		case cmpToken_RBracket: text = ")"; break;
		case cmpToken_LSqBracket: text = "["; break;
		case cmpToken_RSqBracket: text = "]"; break;
		case cmpToken_Colon: text = ":"; break;
		case cmpToken_SemiColon: text = ";"; break;
		case cmpToken_Period: text = "."; break;
		case cmpToken_Question: text = "?"; break;
		case cmpToken_Tilde: text = "~"; break;
		case cmpToken_LAngle: text = "<"; break;
		case cmpToken_RAngle: text = ">"; break;
		case cmpToken_Plus: text = "+"; break;
		case cmpToken_Minus: text = "-"; break;
		case cmpToken_Asterisk: text = "*"; break;
		case cmpToken_Divide: text = "/"; break;
		case cmpToken_Modulo: text = "%%"; break;
		case cmpToken_Equals: text = "="; break;
		case cmpToken_And: text = "&"; break;
		case cmpToken_Or: text = "|"; break;
		case cmpToken_Xor: text = "^"; break;
		case cmpToken_Not: text = "!"; break;
		case cmpToken_Hash: text = "#"; break;

		// Single character tokens for writing to file but not necessarily as input
		case cmpToken_Whitespace: text = " "; break;
		case cmpToken_EOL: text = "\n"; break;

		default:
			assert(false);
	}

	return Add(type, text, 1, line);
}

cmpToken* TokenList::Add(const HashString& string, cmpU32 line)
{
	// Create a symbol token using globally persistent HashString text
	cmpToken* token = Add(cmpToken_Symbol, string.text, string.length, line);
	token->hash = string.hash;
	return token;
}

cmpToken* TokenList::Add(const String& string, cmpU32 line)
{
	cmpToken* token = Add(cmpToken_String, string.text, string.length, line);
	token->hash = cmpHash(string.text, string.length);
	return token;
}

void TokenList::DeleteAll()
{
	// Move one beyond last for while comparison delete to be inclusive
	if (last != 0)
		last = last->next;

	while (first != last)
	{
		cmpToken* next = first->next;
		cmpToken_Destroy(first);
		first = next;
	}

	first = 0;
	last = 0;
}

ComputeProcessor::ComputeProcessor(const ::Arguments& arguments)
	: m_Arguments(arguments)
	, m_InputFilename(arguments[1])
	, m_MemoryFile(0)
	, m_LexerCursor(0)
	, m_ParserCursor(0)
	, m_RootNode(0)
{
	// Parse the executable path looking for its directory
	m_ExecutableDirectory = m_Arguments[0];
	size_t sep = m_ExecutableDirectory.rfind('\\');
	if (sep == -1)
		sep = m_ExecutableDirectory.rfind('/');
	if (sep != -1)
		m_ExecutableDirectory = m_ExecutableDirectory.substr(0, sep);
}

ComputeProcessor::~ComputeProcessor()
{
	// Destroy all transforms, assuming transform description list and allocate transforms lists are in sync
	for (size_t i = 0; i < m_Transforms.size(); i++)
	{
		const TransformDescBase* desc = g_TransformDescs[i];
		assert(desc != 0);
		assert(desc->delete_func != 0);
		desc->delete_func(m_Transforms[i]);
	}

	// Destroy all tokens
	m_Tokens.DeleteAll();

	// Destroy all nodes
	if (m_RootNode != 0)
		cmpNode_Destroy(m_RootNode);

	// Destroy all parser objects
	if (m_ParserCursor != 0)
		cmpParserCursor_Destroy(m_ParserCursor);
	if (m_LexerCursor != 0)
		cmpLexerCursor_Destroy(m_LexerCursor);
	if (m_MemoryFile != 0)
		cmpMemoryFile_Destroy(m_MemoryFile);
}

bool ComputeProcessor::ParseFile()
{
	const char* filename = m_InputFilename.c_str();
	bool verbose = m_Arguments.Have("-verbose");

	// Open the input file
	if (cmpError error = cmpMemoryFile_Create(&m_MemoryFile, filename))
	{
		printf("Error opening input file: %s\n\n", cmpError_Text(&error));
		return false;
	}

	// Build a list of tokens
	if (cmpError error = cmpLexerCursor_Create(&m_LexerCursor, cmpMemoryFile_Data(m_MemoryFile), cmpMemoryFile_Size(m_MemoryFile), verbose))
	{
		printf("Error creating lexer cursor: %s\n\n", cmpError_Text(&error));
		return false;
	}
	while (cmpToken* token = cmpLexer_ConsumeToken(m_LexerCursor))
	{
		m_Tokens.Add(token);
		if (verbose)
			printf("[0x%2x] %s %d\n", token->type, cmpTokenType_Name(token->type), token->length);
	}

	// Print any lexer errors
	if (cmpError error = cmpLexerCursor_Error(m_LexerCursor))
	{
		printf("%s(%d): %s\n", filename, cmpLexerCursor_Line(m_LexerCursor), cmpError_Text(&error));
		return false;
	}

	cmpError error = cmpNode_CreateEmpty(&m_RootNode);
	if (!cmpError_OK(&error))
	{
		printf("Error: %s\n", error.text);
		return false;
	}

	// Build a list of parser nodes
	if (cmpError error = cmpParserCursor_Create(&m_ParserCursor, m_Tokens.first, verbose))
	{
		printf("Error creating parser cursor: %s\n\n", cmpError_Text(&error));
		return false;
	}
	while (cmpNode* node = cmpParser_ConsumeNode(m_ParserCursor))
		cmpNode_AddChild(m_RootNode, node);

	if (verbose)
		cmpParser_LogNodes(m_RootNode, 0);

	// Print any parser errors
	if (cmpError error = cmpParserCursor_Error(m_ParserCursor))
	{
		printf("%s(%d): %s\n",filename, cmpParserCursor_Line(m_ParserCursor), cmpError_Text(&error));
		return false;
	}

	return true;
}

namespace
{
	bool VisitNode(const ComputeProcessor& processor, cmpNode* node, INodeVisitor* visitor)
	{
		assert(visitor != 0);
		assert(node != 0);
		if (!visitor->Visit(processor, *node))
			return false;

		for (cmpNode* child = node->first_child; child != 0; child = child->next_sibling)
		{
			if (!VisitNode(processor, child, visitor))
				return false;
		}

		return true;
	}
}

bool ComputeProcessor::VisitNodes(INodeVisitor* visitor)
{
	assert(visitor != 0);
	return VisitNode(*this, m_RootNode, visitor);
}

cmpError ComputeProcessor::ApplyTransforms()
{
	if (m_Transforms.empty())
	{
		// Create all transforms for the processor the first time this function is called
		for (size_t i = 0; i < g_TransformDescs.size(); i++)
		{
			const TransformDescBase* desc = g_TransformDescs[i];
			assert(desc != 0);
			assert(desc->new_func != 0);
			ITransform* transform = desc->new_func();
			assert(transform != 0);
			m_Transforms.push_back(transform);
		}
	}

	// Apply all transforms in the (indeterminate) order they are registered
	for (size_t i = 0; i < m_Transforms.size(); i++)
	{
		ITransform* transform = m_Transforms[i];
		assert(transform != 0);
		cmpError error = transform->Apply(*this);
		if (!cmpError_OK(&error))
			return error;
	}

	return cmpError_CreateOK();
}

TokenIterator::TokenIterator(cmpNode& node)
	: first_token(node.first_token)
	, last_token(node.last_token ? node.last_token->next : 0)
	, token(first_token)
{
}

cmpToken* TokenIterator::SkipWhitespace()
{
	// Skip all whitespace/EOL tokens
	while (
		token != last_token &&
		(token->type == cmpToken_Whitespace ||
		 token->type == cmpToken_EOL))
		token = token->next;

	// Return NULL if skipped over all tokens
	return token == last_token ? token : 0;
}

TokenIterator::operator bool () const
{
	return token != last_token;
}

TokenIterator& TokenIterator::operator ++ ()
{
	if (token != last_token)
		token = token->next;
	else
		token = 0;

	return *this;
}

String::String()
	: text(0)
	, length(0)
{
}

String::String(const char *source, size_t src_length)
	: text(0)
	, length(0)
{
	Set(source, src_length);
}

String::String(const std::string& source)
	: text(0)
	, length(0)
{
	Set(source.c_str(), source.length());
}

String::String(const String& rhs)
	: text(rhs.text)
	, length(rhs.length)
{
	// Take ownership
	rhs.text = 0;
}

String::~String()
{
	if (text != 0)
		delete [] text;
}

void String::Set(const char *source, size_t src_length)
{
	// Copy and null terminate
	assert(text == 0);
	length = src_length;
	text = new char[length + 1];
	memcpy(text, source, length);
	text[length] = 0;
}

String& String::operator = (const String& rhs)
{
	// Take ownership
	assert(text == 0);
	text = rhs.text;
	length = rhs.length;
	rhs.text = 0;
	return *this;
}

TransformDescBase::TransformDescBase(NewFunc new_func, DeleteFunc delete_func)
	: new_func(new_func)
	, delete_func(delete_func)
{
	// Register transform description
	g_TransformDescs.push_back(this);
}
<|endoftext|>


<commit_before>#include "is_valid_char.hxx"
#include "../../Positive_Matrix_With_Prefactor_State.hxx"

#include <algorithm>
#include <iterator>
#include <string>

using namespace std::literals;

inline void check_iterator(const char character,
                           const std::vector<char>::const_iterator &begin,
                           const std::vector<char>::const_iterator &iterator,
                           const std::vector<char>::const_iterator &end)
{
  if(iterator == end)
    {
      throw std::runtime_error("Invalid polynomial string after '"s + character + "': "
                               + std::string(begin,end));
    }
}

std::vector<char>::const_iterator
parse_polynomial(const std::vector<char>::const_iterator &begin,
                 const std::vector<char>::const_iterator &end,
                 Polynomial &polynomial)
{
  const std::vector<char> delimiters({',', '}'});
  const auto delimiter(
    std::find_first_of(begin, end, delimiters.begin(), delimiters.end()));
  if(delimiter == end)
    {
      throw std::runtime_error("Missing '}' at end of array of polynomials");
    }

  std::string mantissa;
  for(auto c(begin); c < delimiter; ++c)
    {
      if(*c == '`')
        {
          do
            {
              ++c;
            }
          while(c != delimiter
                && (std::isdigit(*c) || *c == '.' || !is_valid_char(*c)
                    || *c == '`'));
        }
      if(*c == '*')
        {
          do
            {
              ++c;
              check_iterator('*',begin, c, delimiter);
            }
          while(!is_valid_char(*c));

          std::string exponent;
          if(*c == '^')
            {
              exponent = "E";
              ++c;
              check_iterator('^', begin, c, delimiter);
              while(c!=delimiter && (exponent.size() == 1 && (*c == '-' || *c == '+'))
                    || std::isdigit(*c) || !is_valid_char(*c))
                {
                  if(is_valid_char(*c))
                    {
                      exponent.push_back(*c);
                    }
                  ++c;
                }
              while(c != delimiter && (!is_valid_char(*c) || *c == '*'))
                {
                  ++c;
                }
            }

          size_t degree(0);
          // Hard code the polynomial to be in 'x' since that is what
          // SDPB.m uses.
          if(*c == 'x')
            {
              ++c;
              while(!is_valid_char(*c))
                {
                  ++c;
                  check_iterator('x', begin, c, delimiter);
                }
              if(*c != '^')
                {
                  degree = 1;
                }
              else
                {
                  ++c;
                  std::string degree_string;
                  while((degree_string.empty() && (*c == '-' || *c == '+'))
                        || std::isdigit(*c) || !is_valid_char(*c))
                    {
                      if(is_valid_char(*c) && *c != '+')
                        {
                          degree_string.push_back(*c);
                        }
                      ++c;
                    }
                  degree = std::stoull(degree_string);
                }
            }

          if(polynomial.coefficients.size() < degree + 1)
            {
              polynomial.coefficients.resize(degree + 1);
            }
          polynomial.coefficients.at(degree)
            = El::BigFloat(mantissa + exponent);
          mantissa.clear();
        }
      else if(!mantissa.empty() && (*c == '-' || *c == '+' || c == delimiter))
        {
          if(polynomial.coefficients.size() < 1)
            {
              polynomial.coefficients.resize(1);
            }
          polynomial.coefficients.at(0) = El::BigFloat(mantissa);
          mantissa.clear();
        }
      if(is_valid_char(*c) && *c != '+')
        {
          mantissa.push_back(*c);
        }
    }
  return delimiter;
}
<commit_msg>Fix logic when parsing exponents<commit_after>#include "is_valid_char.hxx"
#include "../../Positive_Matrix_With_Prefactor_State.hxx"

#include <algorithm>
#include <iterator>
#include <string>

using namespace std::literals;

inline void check_iterator(const char character,
                           const std::vector<char>::const_iterator &begin,
                           const std::vector<char>::const_iterator &iterator,
                           const std::vector<char>::const_iterator &end)
{
  if(iterator == end)
    {
      throw std::runtime_error("Invalid polynomial string after '"s + character + "': "
                               + std::string(begin,end));
    }
}

std::vector<char>::const_iterator
parse_polynomial(const std::vector<char>::const_iterator &begin,
                 const std::vector<char>::const_iterator &end,
                 Polynomial &polynomial)
{
  const std::vector<char> delimiters({',', '}'});
  const auto delimiter(
    std::find_first_of(begin, end, delimiters.begin(), delimiters.end()));
  if(delimiter == end)
    {
      throw std::runtime_error("Missing '}' at end of array of polynomials");
    }

  std::string mantissa;
  for(auto c(begin); c < delimiter; ++c)
    {
      if(*c == '`')
        {
          do
            {
              ++c;
            }
          while(c != delimiter
                && (std::isdigit(*c) || *c == '.' || !is_valid_char(*c)
                    || *c == '`'));
        }
      if(*c == '*')
        {
          do
            {
              ++c;
              check_iterator('*',begin, c, delimiter);
            }
          while(!is_valid_char(*c));

          std::string exponent;
          if(*c == '^')
            {
              exponent = "E";
              ++c;
              check_iterator('^', begin, c, delimiter);
              while(c != delimiter
                    && ((exponent.size() == 1 && (*c == '-' || *c == '+'))
                        || std::isdigit(*c) || !is_valid_char(*c)))
                {
                  if(is_valid_char(*c))
                    {
                      exponent.push_back(*c);
                    }
                  ++c;
                }
              while(c != delimiter && (!is_valid_char(*c) || *c == '*'))
                {
                  ++c;
                }
            }

          size_t degree(0);
          // Hard code the polynomial to be in 'x' since that is what
          // SDPB.m uses.
          if(*c == 'x')
            {
              ++c;
              while(!is_valid_char(*c))
                {
                  ++c;
                  check_iterator('x', begin, c, delimiter);
                }
              if(*c != '^')
                {
                  degree = 1;
                }
              else
                {
                  ++c;
                  std::string degree_string;
                  while((degree_string.empty() && (*c == '-' || *c == '+'))
                        || std::isdigit(*c) || !is_valid_char(*c))
                    {
                      if(is_valid_char(*c) && *c != '+')
                        {
                          degree_string.push_back(*c);
                        }
                      ++c;
                    }
                  degree = std::stoull(degree_string);
                }
            }

          if(polynomial.coefficients.size() < degree + 1)
            {
              polynomial.coefficients.resize(degree + 1);
            }
          polynomial.coefficients.at(degree)
            = El::BigFloat(mantissa + exponent);
          mantissa.clear();
        }
      else if(!mantissa.empty() && (*c == '-' || *c == '+' || c == delimiter))
        {
          if(polynomial.coefficients.size() < 1)
            {
              polynomial.coefficients.resize(1);
            }
          polynomial.coefficients.at(0) = El::BigFloat(mantissa);
          mantissa.clear();
        }
      if(is_valid_char(*c) && *c != '+')
        {
          mantissa.push_back(*c);
        }
    }
  return delimiter;
}
<|endoftext|>


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

#include "chrome/test/nacl/nacl_test.h"

#include "base/file_util.h"
#include "base/path_service.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/automation/tab_proxy.h"
#include "native_client/src/trusted/platform_qualify/nacl_os_qualify.h"
#include "net/base/escape.h"
#include "net/base/net_util.h"

namespace {

const char kTestCompleteCookie[] = "status";
const char kTestCompleteSuccess[] = "OK";

const FilePath::CharType kBaseUrl[] =
    FILE_PATH_LITERAL("http://localhost:5103/tests/prebuilt");

const FilePath::CharType kSrpcHwHtmlFileName[] =
    FILE_PATH_LITERAL("srpc_hw.html");

const FilePath::CharType kSrpcBasicHtmlFileName[] =
    FILE_PATH_LITERAL("srpc_basic.html");

const FilePath::CharType kSrpcSockAddrHtmlFileName[] =
    FILE_PATH_LITERAL("srpc_sockaddr.html");

const FilePath::CharType kSrpcShmHtmlFileName[] =
    FILE_PATH_LITERAL("srpc_shm.html");

const FilePath::CharType kSrpcPluginHtmlFileName[] =
    FILE_PATH_LITERAL("srpc_plugin.html");

const FilePath::CharType kSrpcNrdXferHtmlFileName[] =
    FILE_PATH_LITERAL("srpc_nrd_xfer.html");

const FilePath::CharType kServerHtmlFileName[] =
    FILE_PATH_LITERAL("server_test.html");

const FilePath::CharType kNpapiHwHtmlFileName[] =
    FILE_PATH_LITERAL("npapi_hw.html");
}  // anonymous namespace

NaClTest::NaClTest()
    : UITest(), use_x64_nexes_(false) {
  launch_arguments_.AppendSwitch(switches::kEnableNaCl);

  // Currently we disable some of the sandboxes.  See:
  // Make NaCl work in Chromium's Linux seccomp sandbox and the Mac sandbox
  // http://code.google.com/p/nativeclient/issues/detail?id=344
#if defined(OS_LINUX) && defined(USE_SECCOMP_SANDBOX)
  launch_arguments_.AppendSwitch(switches::kDisableSeccompSandbox);
#endif
  launch_arguments_.AppendSwitchWithValue(switches::kLoggingLevel, "0");
}

NaClTest::~NaClTest() {}

FilePath NaClTest::GetTestRootDir() {
  FilePath path;
  PathService::Get(base::DIR_SOURCE_ROOT, &path);
  path = path.AppendASCII("native_client");
  return path;
}

GURL NaClTest::GetTestUrl(const FilePath& filename) {
  FilePath path(kBaseUrl);
  if (use_x64_nexes_)
    path = path.AppendASCII("x64");
  else
    path = path.AppendASCII("x86");
  path = path.Append(filename);
  return GURL(path.value());
}

void NaClTest::WaitForFinish(const FilePath& filename,
                             int wait_time) {
  GURL url = GetTestUrl(filename);
  scoped_refptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab.get());
  bool test_result = WaitUntilCookieValue(tab.get(),
                                          url,
                                          kTestCompleteCookie,
                                          wait_time,
                                          kTestCompleteSuccess);
  EXPECT_TRUE(test_result);
}

void NaClTest::RunTest(const FilePath& filename, int timeout) {
  GURL url = GetTestUrl(filename);
  NavigateToURL(url);
  WaitForFinish(filename, timeout);
}

void NaClTest::SetUp() {
  FilePath nacl_test_dir = GetTestRootDir();
#if defined(OS_WIN)
  if (NaClOsIs64BitWindows())
    use_x64_nexes_ = true;
#elif defined(OS_LINUX) && defined(__LP64__)
  use_x64_nexes_ = true;
#endif

  UITest::SetUp();

  StartHttpServerWithPort(nacl_test_dir, L"5103");
}

void NaClTest::TearDown() {
  StopHttpServer();
  UITest::TearDown();
}

TEST_F(NaClTest, ServerTest) {
  FilePath test_file(kServerHtmlFileName);
  RunTest(test_file, action_max_timeout_ms());
}

TEST_F(NaClTest, SrpcHelloWorld) {
  FilePath test_file(kSrpcHwHtmlFileName);
  RunTest(test_file, action_max_timeout_ms());
}

TEST_F(NaClTest, SrpcBasicTest) {
  FilePath test_file(kSrpcBasicHtmlFileName);
  RunTest(test_file, action_max_timeout_ms());
}

TEST_F(NaClTest, SrpcSockAddrTest) {
  FilePath test_file(kSrpcSockAddrHtmlFileName);
  RunTest(test_file, action_max_timeout_ms());
}

TEST_F(NaClTest, SrpcShmTest) {
  FilePath test_file(kSrpcShmHtmlFileName);
  RunTest(test_file, action_max_timeout_ms());
}

TEST_F(NaClTest, SrpcPluginTest) {
  FilePath test_file(kSrpcPluginHtmlFileName);
  RunTest(test_file, action_max_timeout_ms());
}

TEST_F(NaClTest, SrpcNrdXferTest) {
  FilePath test_file(kSrpcNrdXferHtmlFileName);
  RunTest(test_file, action_max_timeout_ms());
}

TEST_F(NaClTest, NpapiHwTest) {
  FilePath test_file(kNpapiHwHtmlFileName);
  RunTest(test_file, action_max_timeout_ms());
}
<commit_msg>Mark SrpcPluginTest as flaky.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/test/nacl/nacl_test.h"

#include "base/file_util.h"
#include "base/path_service.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/automation/tab_proxy.h"
#include "native_client/src/trusted/platform_qualify/nacl_os_qualify.h"
#include "net/base/escape.h"
#include "net/base/net_util.h"

namespace {

const char kTestCompleteCookie[] = "status";
const char kTestCompleteSuccess[] = "OK";

const FilePath::CharType kBaseUrl[] =
    FILE_PATH_LITERAL("http://localhost:5103/tests/prebuilt");

const FilePath::CharType kSrpcHwHtmlFileName[] =
    FILE_PATH_LITERAL("srpc_hw.html");

const FilePath::CharType kSrpcBasicHtmlFileName[] =
    FILE_PATH_LITERAL("srpc_basic.html");

const FilePath::CharType kSrpcSockAddrHtmlFileName[] =
    FILE_PATH_LITERAL("srpc_sockaddr.html");

const FilePath::CharType kSrpcShmHtmlFileName[] =
    FILE_PATH_LITERAL("srpc_shm.html");

const FilePath::CharType kSrpcPluginHtmlFileName[] =
    FILE_PATH_LITERAL("srpc_plugin.html");

const FilePath::CharType kSrpcNrdXferHtmlFileName[] =
    FILE_PATH_LITERAL("srpc_nrd_xfer.html");

const FilePath::CharType kServerHtmlFileName[] =
    FILE_PATH_LITERAL("server_test.html");

const FilePath::CharType kNpapiHwHtmlFileName[] =
    FILE_PATH_LITERAL("npapi_hw.html");
}  // anonymous namespace

NaClTest::NaClTest()
    : UITest(), use_x64_nexes_(false) {
  launch_arguments_.AppendSwitch(switches::kEnableNaCl);

  // Currently we disable some of the sandboxes.  See:
  // Make NaCl work in Chromium's Linux seccomp sandbox and the Mac sandbox
  // http://code.google.com/p/nativeclient/issues/detail?id=344
#if defined(OS_LINUX) && defined(USE_SECCOMP_SANDBOX)
  launch_arguments_.AppendSwitch(switches::kDisableSeccompSandbox);
#endif
  launch_arguments_.AppendSwitchWithValue(switches::kLoggingLevel, "0");
}

NaClTest::~NaClTest() {}

FilePath NaClTest::GetTestRootDir() {
  FilePath path;
  PathService::Get(base::DIR_SOURCE_ROOT, &path);
  path = path.AppendASCII("native_client");
  return path;
}

GURL NaClTest::GetTestUrl(const FilePath& filename) {
  FilePath path(kBaseUrl);
  if (use_x64_nexes_)
    path = path.AppendASCII("x64");
  else
    path = path.AppendASCII("x86");
  path = path.Append(filename);
  return GURL(path.value());
}

void NaClTest::WaitForFinish(const FilePath& filename,
                             int wait_time) {
  GURL url = GetTestUrl(filename);
  scoped_refptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab.get());
  bool test_result = WaitUntilCookieValue(tab.get(),
                                          url,
                                          kTestCompleteCookie,
                                          wait_time,
                                          kTestCompleteSuccess);
  EXPECT_TRUE(test_result);
}

void NaClTest::RunTest(const FilePath& filename, int timeout) {
  GURL url = GetTestUrl(filename);
  NavigateToURL(url);
  WaitForFinish(filename, timeout);
}

void NaClTest::SetUp() {
  FilePath nacl_test_dir = GetTestRootDir();
#if defined(OS_WIN)
  if (NaClOsIs64BitWindows())
    use_x64_nexes_ = true;
#elif defined(OS_LINUX) && defined(__LP64__)
  use_x64_nexes_ = true;
#endif

  UITest::SetUp();

  StartHttpServerWithPort(nacl_test_dir, L"5103");
}

void NaClTest::TearDown() {
  StopHttpServer();
  UITest::TearDown();
}

TEST_F(NaClTest, ServerTest) {
  FilePath test_file(kServerHtmlFileName);
  RunTest(test_file, action_max_timeout_ms());
}

TEST_F(NaClTest, SrpcHelloWorld) {
  FilePath test_file(kSrpcHwHtmlFileName);
  RunTest(test_file, action_max_timeout_ms());
}

TEST_F(NaClTest, SrpcBasicTest) {
  FilePath test_file(kSrpcBasicHtmlFileName);
  RunTest(test_file, action_max_timeout_ms());
}

TEST_F(NaClTest, SrpcSockAddrTest) {
  FilePath test_file(kSrpcSockAddrHtmlFileName);
  RunTest(test_file, action_max_timeout_ms());
}

TEST_F(NaClTest, SrpcShmTest) {
  FilePath test_file(kSrpcShmHtmlFileName);
  RunTest(test_file, action_max_timeout_ms());
}

TEST_F(NaClTest, FLAKY_SrpcPluginTest) {
  FilePath test_file(kSrpcPluginHtmlFileName);
  RunTest(test_file, action_max_timeout_ms());
}

TEST_F(NaClTest, SrpcNrdXferTest) {
  FilePath test_file(kSrpcNrdXferHtmlFileName);
  RunTest(test_file, action_max_timeout_ms());
}

TEST_F(NaClTest, NpapiHwTest) {
  FilePath test_file(kNpapiHwHtmlFileName);
  RunTest(test_file, action_max_timeout_ms());
}
<|endoftext|>


<commit_before>//============================================================================
// Name        : sandpile1.cpp
// Author      : Aldo Guzmán-Sáenz
// Version     :
// Copyright   :
// Description : This program simulates an abelian sandpile's evolution.
//============================================================================

#include <iostream>
#include <stack>
#include <vector>
#include <stdlib.h>
#include <fstream>

using namespace std;

#define CRITICAL 4								// Value at which points become unstable

stack< pair<int,int> > unstable1, unstable2; 	// Stacks used to store the current unstable cells in the grid
vector< pair<int,int> > initialunstable;		// Vector used to store the initial unstable cells in the grid
int n;											// Size of a size of the grid
vector<int> grid;								// Our sandpile, stored as an integer grid, the size is specified in main()

pair<int,int> operator+(						// Function to add pairs using the operator +
		const pair<int, int>& x,
		const pair<int, int>& y)
{
    return make_pair(x.first+y.first, x.second+y.second);
}

int ih(pair<int,int> index) 					// Index Helper function to convert from pairs of indices to a single index
{
	return index.first*n + index.second;
}

pair<int,int> ih(int index)						// Overload of ih to convert from an index to a pair of indices
{
	return make_pair(index/n,index%n);
}

vector< pair<int,int> > adjacent(const pair<int,int>& current) // Returns the positions of the 4 adjacent cells in our grid
{
	vector< pair<int,int> > result;
	result.push_back(current+make_pair(-1,0));
	result.push_back(current+make_pair(0,1));
	result.push_back(current+make_pair(1,0));
	result.push_back(current+make_pair(0,-1));
	return result;
}

bool issink(const pair<int, int>& index) 	// Determines if the cell at index is a sink (not affected by toppling)
{											// In our case, only cells at the boundary are sinks
	return (index.first>=n || index.first<0 || index.second>=n || index.second<0);
}

void relax()				// Main relaxation function (uses two stacks to keep track of unstable cells in our grid)
{
	vector< pair<int,int> > neighbors(CRITICAL);
	unsigned int i;
	pair<int,int> current;
	while(!unstable1.empty() || !unstable2.empty())
	{
		while(!unstable1.empty())
		{
			current=unstable1.top();
			while (grid[ih(current)] >= CRITICAL)
			{
				grid[ih(current)] -= CRITICAL;
				neighbors = adjacent(current);
				for(i=0;i<neighbors.size();++i)
					if (issink(neighbors[i])==false)
					{
						grid[ih(neighbors[i])]+=1;
						if (grid[ih(neighbors[i])] >= CRITICAL)
							unstable2.push(neighbors[i]);
					}
			}
			unstable1.pop();
		}
		while(!unstable2.empty())
		{
			current=unstable2.top();
			while (grid[ih(current)] >= CRITICAL)
			{
				grid[ih(current)] -= CRITICAL;
				neighbors = adjacent(current);
				for(i=0;i<neighbors.size();++i)
					if (issink(neighbors[i])==false)
					{
						grid[ih(neighbors[i])]+=1;
						if (grid[ih(neighbors[i])] >= CRITICAL)
							unstable1.push(neighbors[i]);
					}
			}
			unstable2.pop();
		}
	}
}

//============================================================================
// TODO: Implement parameter parsing
// Parameters:
// --size N 			size of the grid
// --numberofgrains		number of initial unstable cells (at random positions)
//============================================================================
int main(int argc, char **argv) {
	string path("./grid.dat");
	ofstream output(path.c_str(), ios::out | ofstream::binary);
	n=100;											// Default grid size
	//n=atoi(argv[1]);								// Read grid size from command line if available
	int nunstable=150;
	grid.resize(n*n,3);								// Fill our grid with 3's
	srand(2);
	initialunstable.resize(nunstable);
	for(unsigned int i=0; i< initialunstable.size();++i)
	{
		initialunstable[i].first=rand()%n;
		initialunstable[i].second=rand()%n;
	}
	for(unsigned int i=0; i< initialunstable.size();++i)
	{
		grid[ih(initialunstable[i])]=4;
		unstable1.push(initialunstable[i]);
	}
	relax();
	output.write(reinterpret_cast<const char *>(&n), sizeof(n));
	output.write(reinterpret_cast<const char *>(&nunstable), sizeof(nunstable));
	for (unsigned int i=0;i<grid.size();++i)
	{
		output.write(reinterpret_cast<const char *>(&grid[i]),sizeof(grid[i]));
	}
	for (unsigned int i=0;i<initialunstable.size();++i)
	{
		output.write(reinterpret_cast<const char *>(&initialunstable[i].first),sizeof(initialunstable[i].first));
		output.write(reinterpret_cast<const char *>(&initialunstable[i].second),sizeof(initialunstable[i].second));
	}
	return 0;
}
<commit_msg>Delete sandpile1.cpp<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: saltimer.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2003-05-28 12:35:28 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SVWIN_H
#include <tools/svwin.h>
#endif

#define _SV_SALTIMER_CXX

#ifndef _SV_SALDATA_HXX
#include <saldata.hxx>
#endif
#ifndef _SV_SALTIMER_HXX
#include <saltimer.hxx>
#endif

// =======================================================================

// Maximale Periode
#define MAX_SYSPERIOD     65533

// =======================================================================

void ImplSalStartTimer( ULONG nMS, BOOL bMutex )
{
    SalData* pSalData = GetSalData();

    // Remenber the time of the timer
    pSalData->mnTimerMS = nMS;
    if ( !bMutex )
        pSalData->mnTimerOrgMS = nMS;

    // Periode darf nicht zu gross sein, da Windows mit USHORT arbeitet
    if ( nMS > MAX_SYSPERIOD )
        nMS = MAX_SYSPERIOD;

    // Gibt es einen Timer, dann zerstoren
    if ( pSalData->mnTimerId )
        KillTimer( 0, pSalData->mnTimerId );

    // Make a new timer with new period
    pSalData->mnTimerId = SetTimer( 0, 0, (UINT)nMS, SalTimerProc );
}

// -----------------------------------------------------------------------

void SalTimer::Stop()
{
    SalData* pSalData = GetSalData();

    // If we have a timer, than
    if ( pSalData->mnTimerId )
    {
        KillTimer( 0, pSalData->mnTimerId );
        pSalData->mnTimerId = 0;
    }
}

// -----------------------------------------------------------------------

void SalTimer::SetCallback( SALTIMERPROC pProc )
{
    SalData* pSalData = GetSalData();
    pSalData->mpTimerProc = pProc;
}

// -----------------------------------------------------------------------

void CALLBACK SalTimerProc( HWND, UINT, UINT, DWORD )
{
    SalData* pSalData = GetSalData();

    // Test for MouseLeave
    SalTestMouseLeave();

    if ( pSalData->mpTimerProc )
    {
        // Try to aquire the mutex. If we don't get the mutex then we
        // try this a short time later again.
        if ( ImplSalYieldMutexTryToAcquire() )
        {
            pSalData->mbInTimerProc = TRUE;
            pSalData->mpTimerProc();
            pSalData->mbInTimerProc = FALSE;
            ImplSalYieldMutexRelease();

            // Run the timer in the correct time, if we start this
            // with a small timeout, because we don't get the mutex
            if ( pSalData->mnTimerId &&
                 (pSalData->mnTimerMS != pSalData->mnTimerOrgMS) )
                ImplSalStartTimer( pSalData->mnTimerOrgMS, FALSE );
        }
        else
            ImplSalStartTimer( 10, TRUE );
    }
}
<commit_msg>INTEGRATION: CWS vclplug (1.2.134); FILE MERGED 2003/10/29 18:29:28 pl 1.2.134.2: #i21232# timer must run in main thread 2003/10/24 13:35:12 pl 1.2.134.1: #21232# win port of virtualiing sal part<commit_after>/*************************************************************************
 *
 *  $RCSfile: saltimer.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2003-11-18 14:51:01 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SVWIN_H
#include <tools/svwin.h>
#endif

#define _SV_SALTIMER_CXX

#ifndef _SV_SALDATA_HXX
#include <saldata.hxx>
#endif
#ifndef _SV_SALTIMER_H
#include <saltimer.h>
#endif
#ifndef _SV_SALINST_H
#include <salinst.h>
#endif

// =======================================================================

// Maximale Periode
#define MAX_SYSPERIOD     65533

// =======================================================================

void ImplSalStartTimer( ULONG nMS, BOOL bMutex )
{
    SalData* pSalData = GetSalData();

    // Remenber the time of the timer
    pSalData->mnTimerMS = nMS;
    if ( !bMutex )
        pSalData->mnTimerOrgMS = nMS;

    // Periode darf nicht zu gross sein, da Windows mit USHORT arbeitet
    if ( nMS > MAX_SYSPERIOD )
        nMS = MAX_SYSPERIOD;

    // Gibt es einen Timer, dann zerstoren
    if ( pSalData->mnTimerId )
        KillTimer( 0, pSalData->mnTimerId );

    // Make a new timer with new period
    pSalData->mnTimerId = SetTimer( 0, 0, (UINT)nMS, SalTimerProc );
}

// -----------------------------------------------------------------------

WinSalTimer::~WinSalTimer()
{
}

void WinSalTimer::Start( ULONG nMS )
{
    // switch to main thread
    SalData* pSalData = GetSalData();
    if ( pSalData->mpFirstInstance )
    {
        if ( pSalData->mnAppThreadId != GetCurrentThreadId() )
            ImplPostMessage( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS );
        else
            ImplSendMessage( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS );
    }
    else
        ImplSalStartTimer( nMS, FALSE );
}

void WinSalTimer::Stop()
{
    SalData* pSalData = GetSalData();

    // If we have a timer, than
    if ( pSalData->mnTimerId )
    {
        KillTimer( 0, pSalData->mnTimerId );
        pSalData->mnTimerId = 0;
    }
}

// -----------------------------------------------------------------------

void CALLBACK SalTimerProc( HWND, UINT, UINT, DWORD )
{
    SalData* pSalData = GetSalData();
    ImplSVData* pSVData = ImplGetSVData();

    // Test for MouseLeave
    SalTestMouseLeave();

    if ( pSVData->mpSalTimer )
    {
        // Try to aquire the mutex. If we don't get the mutex then we
        // try this a short time later again.
        if ( ImplSalYieldMutexTryToAcquire() )
        {
            pSalData->mbInTimerProc = TRUE;
            pSVData->mpSalTimer->CallCallback();
            pSalData->mbInTimerProc = FALSE;
            ImplSalYieldMutexRelease();

            // Run the timer in the correct time, if we start this
            // with a small timeout, because we don't get the mutex
            if ( pSalData->mnTimerId &&
                 (pSalData->mnTimerMS != pSalData->mnTimerOrgMS) )
                ImplSalStartTimer( pSalData->mnTimerOrgMS, FALSE );
        }
        else
            ImplSalStartTimer( 10, TRUE );
    }
}
<|endoftext|>


<commit_before>//
//  scan.cpp
//  See the file "LICENSE.md" for the full license governing this code.
//

#include "compile.h"
#if COMPILE_DMZ

#include "scan.h"
#include "expiry_categorize.h"
#include "expiry_seg.h"

#define SCAN_FOREVER 0  // useful for performance profiling
#define EXTRA_TIME_FOR_EXPIRY_IN_MICROSECONDS 1000 // once the card number has been successfully identified, allow a bit more time to figure out the expiry

#define kDecayFactor 0.8f
#define kMinStability 0.7f

void scanner_initialize(ScannerState *state) {
  scanner_reset(state);
}

void scanner_reset(ScannerState *state) {
  state->count15 = 0;
  state->count16 = 0;
  state->aggregated15 = NumberScores::Zero();
  state->aggregated16 = NumberScores::Zero();
  scan_analytics_init(&state->session_analytics);
  state->timeOfCardNumberCompletionInMilliseconds = 0;
  state->collect_expiry = false;
  state->expiry_month = 0;
  state->expiry_year = 0;
  state->expiry_groups.clear();
  state->name_groups.clear();
}

void scanner_add_frame(ScannerState *state, IplImage *y, bool collect_expiry, FrameScanResult *result) {

  bool still_need_to_collect_card_number = (state->timeOfCardNumberCompletionInMilliseconds == 0);
  bool still_need_to_collect_expiry = collect_expiry && (state->expiry_month == 0 || state->expiry_year == 0);

  // Don't bother with a bunch of assertions about y here,
  // since the frame reader will make them anyway.
  scan_card_image(y, still_need_to_collect_card_number, still_need_to_collect_expiry, result);
  if (result->upside_down) {
    return;
  }

  scan_analytics_record_frame(&state->session_analytics, result);

  // TODO: Scene change detection?

  if (!result->usable) {
    return;
  }

  if (still_need_to_collect_expiry) {
    state->collect_expiry = true;
    expiry_extract(y, state->expiry_groups, result->expiry_groups, &state->expiry_month, &state->expiry_year);
    state->name_groups = result->name_groups;  // for now, for the debugging display
  }

  if (still_need_to_collect_card_number) {
    if(result->hseg.n_offsets == 15) {
      state->aggregated15 *= kDecayFactor;
      state->aggregated15 += result->scores * (1 - kDecayFactor);
      state->count15++;
    } else if(result->hseg.n_offsets == 16) {
      state->aggregated16 *= kDecayFactor;
      state->aggregated16 += result->scores * (1 - kDecayFactor);
      state->count16++;
    } else {
      assert(false);
    }
  }
}

void scanner_result(ScannerState *state, ScannerResult *result) {
  result->complete = false; // until we change our minds otherwise...avoids having to set this at all the possible early exits

#if SCAN_FOREVER
  return;
#endif

  if (state->timeOfCardNumberCompletionInMilliseconds > 0) {
    *result = state->successfulCardNumberResult;
  }
  else {
    uint16_t max_count = MAX(state->count15, state->count16);
    uint16_t min_count = MIN(state->count15, state->count16);

    // We want a three frame lead at a bare minimum.
    // Also guarantees we have at least three frames, period. :)
    if(max_count - min_count < 3) {
      return;
    }

    // Want a significant opinion about whether visa or amex
    if(min_count * 2 > max_count) {
      return;
    }

    // TODO: Sanity check the scores distributions
    // TODO: Do something else sophisticated here -- look at confidences, distributions, stability, hysteresis, etc.
    NumberScores aggregated;
    if(state->count15 > state->count16) {
      result->n_numbers = 15;
      aggregated = state->aggregated15;
    } else {
      result->n_numbers = 16;
      aggregated = state->aggregated16;
    }

    // Calculate result predictions
    // At the same time, put it in a convenient format for the basic consistency checks
    uint8_t number_as_u8s[16];

    dmz_debug_print("Stability: ");
    for(uint8_t i = 0; i < result->n_numbers; i++) {
      NumberScores::Index r, c;
      float max_score = aggregated.row(i).maxCoeff(&r, &c);
      float sum = aggregated.row(i).sum();
      result->predictions(i, 0) = c;
      number_as_u8s[i] = (uint8_t)c;
      float stability = max_score / sum;
      dmz_debug_print("%d ", (int) ceilf(stability * 100));

      // Bail early if low stability
      if (stability < kMinStability) {
        dmz_debug_print("\n");
        return;
      }
    }
    dmz_debug_print("\n");

    // Don't return a number that fails basic prefix sanity checks
    CardType card_type = dmz_card_info_for_prefix_and_length(number_as_u8s, result->n_numbers, false).card_type;
    if(card_type != CardTypeAmbiguous &&
       card_type != CardTypeUnrecognized &&
       dmz_passes_luhn_checksum(number_as_u8s, result->n_numbers)) {

      dmz_debug_print("CARD NUMBER SCANNED SUCCESSFULLY.\n");
      struct timeval time;
      gettimeofday(&time, NULL);
      state->timeOfCardNumberCompletionInMilliseconds = (long)((time.tv_sec * 1000) + (time.tv_usec / 1000));
      state->successfulCardNumberResult = *result;
    }
  }

  // Once the card number has been successfully scanned, then wait a bit longer for successful expiry scan (if collecting expiry)
  if (state->timeOfCardNumberCompletionInMilliseconds > 0) {
#if SCAN_EXPIRY
    if (state->collect_expiry) {
#else
    if (false) {
#endif
      struct timeval time;
      gettimeofday(&time, NULL);
      long now = (long)((time.tv_sec * 1000) + (time.tv_usec / 1000));

      if ((state->expiry_month > 0 && state->expiry_year > 0) ||
          now - state->timeOfCardNumberCompletionInMilliseconds > EXTRA_TIME_FOR_EXPIRY_IN_MICROSECONDS) {

        result->expiry_month = state->expiry_month;
        result->expiry_year = state->expiry_year;
#if DMZ_DEBUG
        result->expiry_groups = state->expiry_groups;
        result->name_groups = state->name_groups;
#endif
        result->complete = true;

        dmz_debug_print("Extra time for expiry scan: %6.3f seconds\n", ((float)(now - state->timeOfCardNumberCompletionInMilliseconds)) / 1000.0f);
      }
    }
    else {
      result->complete = true;
    }
  }
}

void scanner_destroy(ScannerState *state) {
  // currently a no-op
}

#endif // COMPILE_DMZ
<commit_msg>Expiry: add another `#if SCAN_EXPIRY`<commit_after>//
//  scan.cpp
//  See the file "LICENSE.md" for the full license governing this code.
//

#include "compile.h"
#if COMPILE_DMZ

#include "scan.h"
#include "expiry_categorize.h"
#include "expiry_seg.h"

#define SCAN_FOREVER 0  // useful for performance profiling
#define EXTRA_TIME_FOR_EXPIRY_IN_MICROSECONDS 1000 // once the card number has been successfully identified, allow a bit more time to figure out the expiry

#define kDecayFactor 0.8f
#define kMinStability 0.7f

void scanner_initialize(ScannerState *state) {
  scanner_reset(state);
}

void scanner_reset(ScannerState *state) {
  state->count15 = 0;
  state->count16 = 0;
  state->aggregated15 = NumberScores::Zero();
  state->aggregated16 = NumberScores::Zero();
  scan_analytics_init(&state->session_analytics);
  state->timeOfCardNumberCompletionInMilliseconds = 0;
  state->collect_expiry = false;
  state->expiry_month = 0;
  state->expiry_year = 0;
  state->expiry_groups.clear();
  state->name_groups.clear();
}

void scanner_add_frame(ScannerState *state, IplImage *y, bool collect_expiry, FrameScanResult *result) {

  bool still_need_to_collect_card_number = (state->timeOfCardNumberCompletionInMilliseconds == 0);
  bool still_need_to_collect_expiry = collect_expiry && (state->expiry_month == 0 || state->expiry_year == 0);

  // Don't bother with a bunch of assertions about y here,
  // since the frame reader will make them anyway.
  scan_card_image(y, still_need_to_collect_card_number, still_need_to_collect_expiry, result);
  if (result->upside_down) {
    return;
  }

  scan_analytics_record_frame(&state->session_analytics, result);

  // TODO: Scene change detection?

  if (!result->usable) {
    return;
  }

#if SCAN_EXPIRY
  if (still_need_to_collect_expiry) {
    state->collect_expiry = true;
    expiry_extract(y, state->expiry_groups, result->expiry_groups, &state->expiry_month, &state->expiry_year);
    state->name_groups = result->name_groups;  // for now, for the debugging display
  }
#endif

  if (still_need_to_collect_card_number) {
    if(result->hseg.n_offsets == 15) {
      state->aggregated15 *= kDecayFactor;
      state->aggregated15 += result->scores * (1 - kDecayFactor);
      state->count15++;
    } else if(result->hseg.n_offsets == 16) {
      state->aggregated16 *= kDecayFactor;
      state->aggregated16 += result->scores * (1 - kDecayFactor);
      state->count16++;
    } else {
      assert(false);
    }
  }
}

void scanner_result(ScannerState *state, ScannerResult *result) {
  result->complete = false; // until we change our minds otherwise...avoids having to set this at all the possible early exits

#if SCAN_FOREVER
  return;
#endif

  if (state->timeOfCardNumberCompletionInMilliseconds > 0) {
    *result = state->successfulCardNumberResult;
  }
  else {
    uint16_t max_count = MAX(state->count15, state->count16);
    uint16_t min_count = MIN(state->count15, state->count16);

    // We want a three frame lead at a bare minimum.
    // Also guarantees we have at least three frames, period. :)
    if(max_count - min_count < 3) {
      return;
    }

    // Want a significant opinion about whether visa or amex
    if(min_count * 2 > max_count) {
      return;
    }

    // TODO: Sanity check the scores distributions
    // TODO: Do something else sophisticated here -- look at confidences, distributions, stability, hysteresis, etc.
    NumberScores aggregated;
    if(state->count15 > state->count16) {
      result->n_numbers = 15;
      aggregated = state->aggregated15;
    } else {
      result->n_numbers = 16;
      aggregated = state->aggregated16;
    }

    // Calculate result predictions
    // At the same time, put it in a convenient format for the basic consistency checks
    uint8_t number_as_u8s[16];

    dmz_debug_print("Stability: ");
    for(uint8_t i = 0; i < result->n_numbers; i++) {
      NumberScores::Index r, c;
      float max_score = aggregated.row(i).maxCoeff(&r, &c);
      float sum = aggregated.row(i).sum();
      result->predictions(i, 0) = c;
      number_as_u8s[i] = (uint8_t)c;
      float stability = max_score / sum;
      dmz_debug_print("%d ", (int) ceilf(stability * 100));

      // Bail early if low stability
      if (stability < kMinStability) {
        dmz_debug_print("\n");
        return;
      }
    }
    dmz_debug_print("\n");

    // Don't return a number that fails basic prefix sanity checks
    CardType card_type = dmz_card_info_for_prefix_and_length(number_as_u8s, result->n_numbers, false).card_type;
    if(card_type != CardTypeAmbiguous &&
       card_type != CardTypeUnrecognized &&
       dmz_passes_luhn_checksum(number_as_u8s, result->n_numbers)) {

      dmz_debug_print("CARD NUMBER SCANNED SUCCESSFULLY.\n");
      struct timeval time;
      gettimeofday(&time, NULL);
      state->timeOfCardNumberCompletionInMilliseconds = (long)((time.tv_sec * 1000) + (time.tv_usec / 1000));
      state->successfulCardNumberResult = *result;
    }
  }

  // Once the card number has been successfully scanned, then wait a bit longer for successful expiry scan (if collecting expiry)
  if (state->timeOfCardNumberCompletionInMilliseconds > 0) {
#if SCAN_EXPIRY
    if (state->collect_expiry) {
#else
    if (false) {
#endif
      struct timeval time;
      gettimeofday(&time, NULL);
      long now = (long)((time.tv_sec * 1000) + (time.tv_usec / 1000));

      if ((state->expiry_month > 0 && state->expiry_year > 0) ||
          now - state->timeOfCardNumberCompletionInMilliseconds > EXTRA_TIME_FOR_EXPIRY_IN_MICROSECONDS) {

        result->expiry_month = state->expiry_month;
        result->expiry_year = state->expiry_year;
#if DMZ_DEBUG
        result->expiry_groups = state->expiry_groups;
        result->name_groups = state->name_groups;
#endif
        result->complete = true;

        dmz_debug_print("Extra time for expiry scan: %6.3f seconds\n", ((float)(now - state->timeOfCardNumberCompletionInMilliseconds)) / 1000.0f);
      }
    }
    else {
      result->complete = true;
    }
  }
}

void scanner_destroy(ScannerState *state) {
  // currently a no-op
}

#endif // COMPILE_DMZ
<|endoftext|>


<commit_before>// Virvo - Virtual Reality Volume Rendering
// Copyright (C) 1999-2003 University of Stuttgart, 2004-2005 Brown University
// Contact: Jurgen P. Schulze, jschulze@ucsd.edu
//
// This file is part of Virvo.
//
// Virvo is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library (see license.txt); if not, write to the
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

#include "vvdebugmsg.h"
#include "vvrendercontext.h"

#include <iostream>

#include "vvx11.h"

using namespace std;

struct ContextArchData
{
#ifdef HAVE_X11
  GLXContext glxContext;
  Display* display;
  Drawable drawable;
#endif
};

vvRenderContext::vvRenderContext(const char* displayName)
{
  _archData = new ContextArchData;
  _initialized = false;
  init(displayName);
}

vvRenderContext::~vvRenderContext()
{
  vvDebugMsg::msg(1, "vvRenderContext::~vvRenderContext");

  if (_initialized)
  {
#ifdef HAVE_X11
    glXDestroyContext(_archData->display, _archData->glxContext);
    XCloseDisplay(_archData->display);
#endif
  }
  delete _archData;
}

bool vvRenderContext::makeCurrent() const
{
  if (_initialized)
  {
#ifdef HAVE_X11
    return glXMakeCurrent(_archData->display, _archData->drawable, _archData->glxContext);
#endif
  }
  return false;
}

void vvRenderContext::init(const char* displayName)
{
#ifdef HAVE_X11
  _archData->display = XOpenDisplay(displayName);

  if (_archData->display != NULL)
  {
    const Drawable parent = RootWindow(_archData->display, DefaultScreen(_archData->display));

    int attrList[] = { GLX_RGBA,
                       GLX_RED_SIZE, 8,
                       GLX_GREEN_SIZE, 8,
                       GLX_BLUE_SIZE, 8,
                       GLX_ALPHA_SIZE, 8,
                       GLX_DEPTH_SIZE, 24,
                       None};

    XVisualInfo* vi = glXChooseVisual(_archData->display,
                                      DefaultScreen(_archData->display),
                                      attrList);

    XSetWindowAttributes wa = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    wa.colormap = XCreateColormap(_archData->display, parent, vi->visual, AllocNone);
    wa.background_pixmap = None;
    wa.border_pixel = 0;

    if (vvDebugMsg::getDebugLevel() == 0)
    {
      wa.override_redirect = true;
    }
    else
    {
      wa.override_redirect = false;
    }

    _archData->glxContext = glXCreateContext(_archData->display, vi, NULL, True);

    if (_archData->glxContext != 0)
    {

      int windowWidth = 1;
      int windowHeight = 1;
      if (vvDebugMsg::getDebugLevel() > 0)
      {
        windowWidth = 512;
        windowHeight = 512;
      }

      _archData->drawable = XCreateWindow(_archData->display, parent, 0, 0, windowWidth, windowHeight, 0,
                                          vi->depth, InputOutput, vi->visual,
                                          CWBackPixmap|CWBorderPixel|CWColormap|CWOverrideRedirect, &wa);
      XMapWindow(_archData->display, _archData->drawable);
      XFlush(_archData->display);
      _initialized = true;
    }
    else
    {
      cerr << "Couldn't create OpenGL context" << endl;
      _initialized = false;
    }

    delete vi;
  }
  else
  {
    cerr << "Couldn't open X display" << endl;
    _initialized = false;
  }
#else
  (void)displayName;
#endif
}
// vim: sw=2:expandtab:softtabstop=2:ts=2:cino=\:0g0t0
<commit_msg>remove using namespace std<commit_after>// Virvo - Virtual Reality Volume Rendering
// Copyright (C) 1999-2003 University of Stuttgart, 2004-2005 Brown University
// Contact: Jurgen P. Schulze, jschulze@ucsd.edu
//
// This file is part of Virvo.
//
// Virvo is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library (see license.txt); if not, write to the
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

#include "vvdebugmsg.h"
#include "vvrendercontext.h"

#include <iostream>

#include "vvx11.h"

struct ContextArchData
{
#ifdef HAVE_X11
  GLXContext glxContext;
  Display* display;
  Drawable drawable;
#endif
};

vvRenderContext::vvRenderContext(const char* displayName)
{
  _archData = new ContextArchData;
  _initialized = false;
  init(displayName);
}

vvRenderContext::~vvRenderContext()
{
  vvDebugMsg::msg(1, "vvRenderContext::~vvRenderContext");

  if (_initialized)
  {
#ifdef HAVE_X11
    glXDestroyContext(_archData->display, _archData->glxContext);
    XCloseDisplay(_archData->display);
#endif
  }
  delete _archData;
}

bool vvRenderContext::makeCurrent() const
{
  if (_initialized)
  {
#ifdef HAVE_X11
    return glXMakeCurrent(_archData->display, _archData->drawable, _archData->glxContext);
#endif
  }
  return false;
}

void vvRenderContext::init(const char* displayName)
{
#ifdef HAVE_X11
  _archData->display = XOpenDisplay(displayName);

  if (_archData->display != NULL)
  {
    const Drawable parent = RootWindow(_archData->display, DefaultScreen(_archData->display));

    int attrList[] = { GLX_RGBA,
                       GLX_RED_SIZE, 8,
                       GLX_GREEN_SIZE, 8,
                       GLX_BLUE_SIZE, 8,
                       GLX_ALPHA_SIZE, 8,
                       GLX_DEPTH_SIZE, 24,
                       None};

    XVisualInfo* vi = glXChooseVisual(_archData->display,
                                      DefaultScreen(_archData->display),
                                      attrList);

    XSetWindowAttributes wa = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    wa.colormap = XCreateColormap(_archData->display, parent, vi->visual, AllocNone);
    wa.background_pixmap = None;
    wa.border_pixel = 0;

    if (vvDebugMsg::getDebugLevel() == 0)
    {
      wa.override_redirect = true;
    }
    else
    {
      wa.override_redirect = false;
    }

    _archData->glxContext = glXCreateContext(_archData->display, vi, NULL, True);

    if (_archData->glxContext != 0)
    {

      int windowWidth = 1;
      int windowHeight = 1;
      if (vvDebugMsg::getDebugLevel() > 0)
      {
        windowWidth = 512;
        windowHeight = 512;
      }

      _archData->drawable = XCreateWindow(_archData->display, parent, 0, 0, windowWidth, windowHeight, 0,
                                          vi->depth, InputOutput, vi->visual,
                                          CWBackPixmap|CWBorderPixel|CWColormap|CWOverrideRedirect, &wa);
      XMapWindow(_archData->display, _archData->drawable);
      XFlush(_archData->display);
      _initialized = true;
    }
    else
    {
      std::cerr << "Couldn't create OpenGL context" << std::endl;
      _initialized = false;
    }

    delete vi;
  }
  else
  {
    std::cerr << "Couldn't open X display" << std::endl;
    _initialized = false;
  }
#else
  (void)displayName;
#endif
}
// vim: sw=2:expandtab:softtabstop=2:ts=2:cino=\:0g0t0
<|endoftext|>


<commit_before>/*
  pvsops.c: pvs and other spectral-based opcodes

  Copyright (C) 2017 Victor Lazzarini
  This file is part of Csound.

  The Csound Library is free software; you can redistribute it
  and/or modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  Csound is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with Csound; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  02111-1307 USA
*/
#include <plugin.h>
#include <algorithm>

struct PVTrace : csnd::FPlugin<1, 2> {
  csnd::AuxMem<float> amps;
  static constexpr char const *otypes = "f";
  static constexpr char const *itypes = "fk";

  int init() {
    if (inargs.fsig_data(0).isSliding())
      return csound->init_error(Str("sliding not supported"));

    if (inargs.fsig_data(0).fsig_format() != csnd::fsig_format::pvs &&
        inargs.fsig_data(0).fsig_format() != csnd::fsig_format::polar)
      return csound->init_error(Str("fsig format not supported"));

    amps.allocate(csound, inargs.fsig_data(0).nbins());
    csnd::Fsig &fout = outargs.fsig_data(0);
    fout.init(csound, inargs.fsig_data(0));
    framecount = 0;
    return OK;
  }

  int kperf() {
    csnd::pv_frame &fin = inargs.fsig_data(0);
    csnd::pv_frame &fout = outargs.fsig_data(0);

    if (framecount < fin.count()) {
      int n =  fin.len() - (int) inargs[1];
      float thrsh;
      std::transform(fin.begin(), fin.end(), amps.begin(),
                     [](csnd::pv_bin f){ return f.amp(); });
      std::nth_element(amps.begin(), amps.begin()+n, amps.end());
      thrsh = amps[n];
      std::transform(fin.begin(), fin.end(), fout.begin(),
                     [thrsh](csnd::pv_bin f){
                       return f.amp() >= thrsh ? f : csnd::pv_bin(); });
      framecount = fout.count(fin.count());
    }
    return OK;
  }
};

struct TVConv : csnd::Plugin<1,4> {
  static constexpr char const *otypes = "a";
  static constexpr char const *itypes = "aaii";
  csnd::AuxMem<MYFLT> ir;
  csnd::AuxMem<MYFLT> in;
  csnd::AuxMem<MYFLT> out;
  csnd::AuxMem<MYFLT> saved;
  uint32_t n;
  uint32_t fils;
  uint32_t pars;
  uint32_t ffts;
  uint32_t nparts;
  uint32_t pp;
  csnd::fftp fwd,inv;
  typedef std::complex<MYFLT> cmplx;

  uint32_t rpow2(uint32_t n) {
  uint32_t v = 2;
  while (v <= n)
    v <<= 1;
  if((n - (v >> 1)) < (v - n))
   return v >> 1;
  else return v;
  }

  cmplx *to_cmplx(MYFLT *f) {
    return reinterpret_cast<cmplx*>(f);
  }

  cmplx real_prod(cmplx &a, cmplx &b) {
    return cmplx(a.real()*b.real(),
		 a.imag()*b.imag());
  }

  int init() {
    pars = inargs[2];
    fils = inargs[3];
    if(pars > fils) std::swap(pars,fils);
    if(pars > 1) {
      pars = rpow2(pars);
      fils = rpow2(fils);
      ffts = pars*2;
      fwd = csound->fft_setup(ffts,FFT_FWD);
      inv = csound->fft_setup(ffts,FFT_INV);
      out.allocate(csound, 2*pars);
      saved.allocate(csound, pars);
      ir.allocate(csound, 2*fils);
      in.allocate(csound, 2*fils);
      nparts = fils/pars;
      fils *= 2;
    } else {
      ir.allocate(csound, fils);
      in.allocate(csound, fils);
    }
    n = 0;
    pp = 0;
    return OK;
  }

  int pconv(csnd::AudioSig &outsig,
	    csnd::AudioSig &insig,
	    csnd::AudioSig &irsig){
    auto irp = irsig.begin();
    auto inp = insig.begin();
    for(auto &s: outsig) {
      ir[n+pp] = *irp++;
      in[n+pp] = *inp++;
      in[n+pp+pars] = ir[n+pp+pars] = 0.;
      s  = out[n] + saved[n];
      saved[n] = out[n + pars];
       if(++n == pars) {
	 cmplx *ins,*irs, *ous = to_cmplx(out.data());
	 std::fill(out.begin(), out.end(), 0.);
	 // FFT
         csound->rfft(fwd, ir.data() + pp);
	 csound->rfft(fwd, in.data() + pp);
	 pp += ffts;
	 if(pp == fils) pp = 0;
	 // spectral delay line
         for(uint32_t k = 0, kp = pp; k < nparts; k++, kp+=ffts) {
	   if(kp == fils) kp = 0;
	   ins = to_cmplx(in.data() + kp);
	   irs = to_cmplx(ir.data() + (nparts - k - 1)*ffts);
	   // spectral product
           for(uint i=1; i < pars; i++)
	     ous[i] +=  ins[i] * irs[i];
	   ous[0] += real_prod(ins[0],irs[0]);
	 }
	 // IFFT
	 csound->rfft(inv, out.data());
         n = 0;
       }
    }
    return OK;
  }

  int dconv(csnd::AudioSig &outsig,
	    csnd::AudioSig &insig,
	    csnd::AudioSig &irsig) {
    auto irp = irsig.begin();
    auto inp = insig.begin();
    MYFLT sum = 0.0;
    for(auto &s: outsig) {
     ir[pp] = *irp++;
     in[pp] = *inp++;
     pp = pp != fils - 1 ? pp + 1 : 0;
     for(uint32_t k = 0, kp = pp; k < fils; k++, kp++) {
       if(kp == fils) kp = 0;
       sum += in[kp] * ir[fils - k - 1];
     }
     s = sum;
     sum = 0;
    }
    return OK;
  }

  int aperf() {
    csnd::AudioSig ins(this, inargs(0));
    csnd::AudioSig irs(this, inargs(1));
    csnd::AudioSig outs(this, outargs(0));
    if(pars > 1) return pconv(outs, ins, irs);
    else return dconv(outs, ins, irs);
  }
};

#include <modload.h>
void csnd::on_load(Csound *csound) {
  csnd::plugin<PVTrace>(csound, "pvstrace", csnd::thread::ik);
  csnd::plugin<TVConv>(csound, "tvconv", csnd::thread::ia);
}
<commit_msg>tvconv with freeze params<commit_after>/*
  pvsops.c: pvs and other spectral-based opcodes

  Copyright (C) 2017 Victor Lazzarini
  This file is part of Csound.

  The Csound Library is free software; you can redistribute it
  and/or modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  Csound is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with Csound; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  02111-1307 USA
*/
#include <plugin.h>
#include <algorithm>

struct PVTrace : csnd::FPlugin<1, 2> {
  csnd::AuxMem<float> amps;
  static constexpr char const *otypes = "f";
  static constexpr char const *itypes = "fk";

  int init() {
    if (inargs.fsig_data(0).isSliding())
      return csound->init_error(Str("sliding not supported"));

    if (inargs.fsig_data(0).fsig_format() != csnd::fsig_format::pvs &&
        inargs.fsig_data(0).fsig_format() != csnd::fsig_format::polar)
      return csound->init_error(Str("fsig format not supported"));

    amps.allocate(csound, inargs.fsig_data(0).nbins());
    csnd::Fsig &fout = outargs.fsig_data(0);
    fout.init(csound, inargs.fsig_data(0));
    framecount = 0;
    return OK;
  }

  int kperf() {
    csnd::pv_frame &fin = inargs.fsig_data(0);
    csnd::pv_frame &fout = outargs.fsig_data(0);

    if (framecount < fin.count()) {
      int n =  fin.len() - (int) inargs[1];
      float thrsh;
      std::transform(fin.begin(), fin.end(), amps.begin(),
                     [](csnd::pv_bin f){ return f.amp(); });
      std::nth_element(amps.begin(), amps.begin()+n, amps.end());
      thrsh = amps[n];
      std::transform(fin.begin(), fin.end(), fout.begin(),
                     [thrsh](csnd::pv_bin f){
                       return f.amp() >= thrsh ? f : csnd::pv_bin(); });
      framecount = fout.count(fin.count());
    }
    return OK;
  }
};

struct TVConv : csnd::Plugin<1,6> {
  csnd::AuxMem<MYFLT> ir;
  csnd::AuxMem<MYFLT> in;
    csnd::AuxMem<MYFLT> insp;
    csnd::AuxMem<MYFLT> irsp;
  csnd::AuxMem<MYFLT> out;
  csnd::AuxMem<MYFLT> saved;
  uint32_t n;
  uint32_t fils;
  uint32_t pars;
  uint32_t ffts;
  uint32_t nparts;
  uint32_t pp;
  csnd::fftp fwd,inv;
  typedef std::complex<MYFLT> cmplx;

  uint32_t rpow2(uint32_t n) {
  uint32_t v = 2;
  while (v <= n)
    v <<= 1;
  if((n - (v >> 1)) < (v - n))
   return v >> 1;
  else return v;
  }

  cmplx *to_cmplx(MYFLT *f) {
    return reinterpret_cast<cmplx*>(f);
  }

  cmplx real_prod(cmplx &a, cmplx &b) {
    return cmplx(a.real()*b.real(),
		 a.imag()*b.imag());
  }

  int init() {
    pars = inargs[4];
    fils = inargs[5];
    if(pars > fils) std::swap(pars,fils);
    if(pars > 1) {
      pars = rpow2(pars);
      fils = rpow2(fils);
      ffts = pars*2;
      fwd = csound->fft_setup(ffts,FFT_FWD);
      inv = csound->fft_setup(ffts,FFT_INV);
      out.allocate(csound, 2*pars);
      insp.allocate(csound, 2*fils);
      irsp.allocate(csound, 2*fils);
      saved.allocate(csound, pars);
      ir.allocate(csound, 2*fils);
      in.allocate(csound, 2*fils);
      nparts = fils/pars;
      fils *= 2;
    } else {
      ir.allocate(csound, fils);
      in.allocate(csound, fils);
    }
    n = 0;
    pp = 0;
    return OK;
  }

  int pconv(csnd::AudioSig &outsig,
	    csnd::AudioSig &insig,
	    csnd::AudioSig &irsig){
    auto irp = irsig.begin();
    auto inp = insig.begin();
    MYFLT *frz1 = inargs(2);
    MYFLT *frz2 = inargs(3);
    bool inc1 = csound->is_asig(inargs(2));
    bool inc2 = csound->is_asig(inargs(3));

    for(auto &s: outsig) {
      *frz1 > 0 ? (in[n+pp] = *inp++) : *inp++;
      *frz2 > 0 ? (ir[n+pp] = *irp++) : *irp++;
      frz1 += inc1;
      frz2 += inc2;
      s  = out[n] + saved[n];
      saved[n] = out[n + pars];
       if(++n == pars) {
	 cmplx *ins,*irs, *ous = to_cmplx(out.data());
	 std::copy(in.begin() + pp, in.begin() + pp + ffts,
		   insp.begin() + pp);
	 std::copy(ir.begin() + pp, ir.begin() + pp + ffts,
		   irsp.begin() + pp);
	 std::fill(out.begin(), out.end(), 0.);
	 // FFT
         csound->rfft(fwd, insp.data() + pp);
	 csound->rfft(fwd, irsp.data() + pp);
	 pp += ffts;
	 if(pp == fils) pp = 0;
	 // spectral delay line
         for(uint32_t k = 0, kp = pp; k < nparts; k++, kp+=ffts) {
	   if(kp == fils) kp = 0;
	   ins = to_cmplx(insp.data() + kp);
	   irs = to_cmplx(irsp.data() + (nparts - k - 1)*ffts);
	   // spectral product
           for(uint i=1; i < pars; i++)
	     ous[i] +=  ins[i] * irs[i];
	   ous[0] += real_prod(ins[0],irs[0]);
	 }
	 // IFFT
	 csound->rfft(inv, out.data());
         n = 0;
       }
    }
    return OK;
  }

  int dconv(csnd::AudioSig &outsig,
	    csnd::AudioSig &insig,
	    csnd::AudioSig &irsig) {
    auto irp = irsig.begin();
    auto inp = insig.begin();
    MYFLT *frz1 = inargs(2);
    MYFLT *frz2 = inargs(3);
    bool inc1 = csound->is_asig(inargs(2));
    bool inc2 = csound->is_asig(inargs(3));

    MYFLT sum = 0.0;
    for(auto &s: outsig) {
      *frz1 > 0 ? (in[pp] = *inp++) : *inp++;
      *frz2  >  0 ? (ir[pp] = *irp++) : *irp++;
     pp = pp != fils - 1 ? pp + 1 : 0;
     for(uint32_t k = 0, kp = pp; k < fils; k++, kp++) {
       if(kp == fils) kp = 0;
       sum += in[kp] * ir[fils - k - 1];
     }
     s = sum;
     sum = 0;
     frz1 += inc1;
     frz2 += inc2;
    }
    return OK;
  }

  int aperf() {
    csnd::AudioSig ins(this, inargs(0));
    csnd::AudioSig irs(this, inargs(1));
    csnd::AudioSig outs(this, outargs(0));
    if(pars > 1) return pconv(outs, ins, irs);
    else return dconv(outs, ins, irs);
  }
};

#include <modload.h>
void csnd::on_load(Csound *csound) {
  csnd::plugin<PVTrace>(csound, "pvstrace", csnd::thread::ik);
  csnd::plugin<TVConv>(csound, "tvconv", "a", "aakkii", csnd::thread::ia);
  csnd::plugin<TVConv>(csound, "tvconv", "a", "aaakii", csnd::thread::ia);
  csnd::plugin<TVConv>(csound, "tvconv", "a", "aakaii", csnd::thread::ia);
  csnd::plugin<TVConv>(csound, "tvconv", "a", "aaaaii", csnd::thread::ia);
}
<|endoftext|>