<commit_before>//******************************************************************************
// FILE : field_location.hpp
//
// LAST MODIFIED : 9 August 2006
//
// DESCRIPTION :
// An class hierarchy for specifying locations at which to evaluate fields.
// These are transient objects used internally in Computed_fields and so do not
// access, copy or allocate their members.
//==============================================================================
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is cmgui.
 *
 * The Initial Developer of the Original Code is
 * Auckland Uniservices Ltd, Auckland, New Zealand.
 * Portions created by the Initial Developer are Copyright (C) 2006
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */
#if !defined (__FIELD_LOCATION_HPP__)
#define __FIELD_LOCATION_HPP__

#include "computed_field/computed_field.h"
#include "general/value.h"

struct Cmiss_field;

class Field_location
{
protected:
	FE_value time;
	int number_of_derivatives;

   Field_location(FE_value time = 0.0, int number_of_derivatives = 0) :
		time(time), number_of_derivatives(number_of_derivatives)
	{};

public:

   /* Abstract virtual destructor declaration as we will not make objects of this
		parent class */
	virtual ~Field_location() = 0;

	virtual Field_location *clone() = 0;

	FE_value get_time()
	{
		return time;
	}

	void set_time(FE_value new_time)
	{
		time = new_time;
	}

	int get_number_of_derivatives()
	{
		return number_of_derivatives;
	}

	/** use with care in field evaluation & restore after evaluating with */
	void set_number_of_derivatives(int number_of_derivatives_in)
	{
		number_of_derivatives = number_of_derivatives_in;
	}

	virtual int set_values_for_location(Cmiss_field * /*field*/,
		const FE_value * /*values*/)
	{
		/* Default is that the location can't set the values */
		return 0;
	}
};

class Field_element_xi_location : public Field_location
{
private:
	struct FE_element *element;
	int dimension;
	FE_value xi[MAXIMUM_ELEMENT_XI_DIMENSIONS];
	struct FE_element *top_level_element;

public:
	Field_element_xi_location(struct FE_element *element_in,
			const FE_value *xi_in = NULL, FE_value time_in = 0.0,
			struct FE_element *top_level_element_in = NULL, int number_of_derivatives_in = 0) :
		Field_location(time_in, number_of_derivatives_in),
		element(element_in ? ACCESS(FE_element)(element_in) : 0),
		dimension(element_in ? get_FE_element_dimension(element_in) : 0),
		top_level_element(top_level_element_in ? ACCESS(FE_element)(top_level_element_in) : 0)
	{
		if (xi_in)
		{
			for (int i = 0; i < dimension; i++)
			{
				xi[i] = xi_in[i];
			}
		}
		else
		{
			for (int i = 0; i < dimension; i++)
			{
				xi[i] = 0.0;
			}
		}
	}

	// blank constructor - caller should call set_element_xi & check valid return
	Field_element_xi_location(FE_value time_in = 0.0, int number_of_derivatives_in = 0) :
		Field_location(time_in, number_of_derivatives_in),
		element(0),
		dimension(0),
		top_level_element(0)
	{
	}

   ~Field_element_xi_location()
	{
		DEACCESS(FE_element)(&element);
		if (top_level_element)
			DEACCESS(FE_element)(&top_level_element);
	}

   virtual Field_location *clone()
   {
   	return new Field_element_xi_location(element, xi, time, top_level_element);
   }

	int get_dimension() const
	{
		return dimension;
	}

	struct FE_element *get_element()
	{
		return element;
	}

	const FE_value *get_xi() const
	{
		return xi;
	}

	FE_element *get_top_level_element()
	{
		return top_level_element;
	}

	int set_element_xi(struct FE_element *element_in,
		int number_of_xi_in, const FE_value *xi_in,
		struct FE_element *top_level_element_in = NULL);
};

class Field_node_location : public Field_location
{
private:
	struct FE_node *node;

public:
	Field_node_location(struct FE_node *node,
		FE_value time = 0, int number_of_derivatives = 0):
		Field_location(time, number_of_derivatives),
		node(ACCESS(FE_node)(node))
	{
	}

   ~Field_node_location()
	{
   	DEACCESS(FE_node)(&node);
	}

   virtual Field_location *clone()
   {
   	return new Field_node_location(node, time);
   }

	FE_node *get_node()
	{
		return node;
	}

	void set_node(FE_node *node_in)
	{
		REACCESS(FE_node)(&node, node_in);
	}
};

class Field_time_location : public Field_location
{
public:
	Field_time_location(FE_value time = 0, int number_of_derivatives = 0):
		Field_location(time, number_of_derivatives)
	{
	}

   ~Field_time_location()
	{
	}

   virtual Field_location *clone()
   {
   	return new Field_time_location(time);
   }
};

class Field_coordinate_location : public Field_location
{
private:
	Cmiss_field *reference_field;
	int number_of_values;
	FE_value *values;
	FE_value *derivatives;

public:
	Field_coordinate_location(Cmiss_field *reference_field_in,
		int number_of_values_in, const FE_value* values_in, FE_value time = 0,
		int number_of_derivatives_in = 0, const FE_value* derivatives_in = NULL);

	// blank constructor - caller should call set_field_values & check valid return
	Field_coordinate_location(FE_value time = 0) :
		Field_location(time),
		reference_field(0),
		number_of_values(0),
		values(0),
		derivatives(0)
	{
	}

	~Field_coordinate_location();

   virtual Field_location *clone()
   {
   	return new Field_coordinate_location(reference_field, number_of_values, values, time, number_of_derivatives, derivatives);
   }

	Cmiss_field *get_reference_field()
	{
		return reference_field;
	}

	int get_number_of_values()
	{
		return number_of_values;
	}

	FE_value *get_values()
	{
		return values;
	}

	int set_field_values(Cmiss_field_id reference_field_in,
		int number_of_values_in, const FE_value *values_in);

	int set_values_for_location(Cmiss_field *field,
		const FE_value *values);

};

#endif /* !defined (__FIELD_LOCATION_HPP__) */
<commit_msg>Tidying up spaces for tabs.  https://tracker.physiomeproject.org/show_bug.cgi?id=3535<commit_after>//******************************************************************************
// FILE : field_location.hpp
//
// LAST MODIFIED : 9 August 2006
//
// DESCRIPTION :
// An class hierarchy for specifying locations at which to evaluate fields.
// These are transient objects used internally in Computed_fields and so do not
// access, copy or allocate their members.
//==============================================================================
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is cmgui.
 *
 * The Initial Developer of the Original Code is
 * Auckland Uniservices Ltd, Auckland, New Zealand.
 * Portions created by the Initial Developer are Copyright (C) 2006
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */
#if !defined (__FIELD_LOCATION_HPP__)
#define __FIELD_LOCATION_HPP__

#include "computed_field/computed_field.h"
#include "general/value.h"

struct Cmiss_field;

class Field_location
{
protected:
	FE_value time;
	int number_of_derivatives;

	Field_location(FE_value time = 0.0, int number_of_derivatives = 0) :
		time(time), number_of_derivatives(number_of_derivatives)
	{}

public:

	/* Abstract virtual destructor declaration as we will not make objects of this
		parent class */
	virtual ~Field_location() = 0;

	virtual Field_location *clone() = 0;

	FE_value get_time()
	{
		return time;
	}

	void set_time(FE_value new_time)
	{
		time = new_time;
	}

	int get_number_of_derivatives()
	{
		return number_of_derivatives;
	}

	/** use with care in field evaluation & restore after evaluating with */
	void set_number_of_derivatives(int number_of_derivatives_in)
	{
		number_of_derivatives = number_of_derivatives_in;
	}

	virtual int set_values_for_location(Cmiss_field * /*field*/,
		const FE_value * /*values*/)
	{
		/* Default is that the location can't set the values */
		return 0;
	}
};

class Field_element_xi_location : public Field_location
{
private:
	struct FE_element *element;
	int dimension;
	FE_value xi[MAXIMUM_ELEMENT_XI_DIMENSIONS];
	struct FE_element *top_level_element;

public:
	Field_element_xi_location(struct FE_element *element_in,
			const FE_value *xi_in = NULL, FE_value time_in = 0.0,
			struct FE_element *top_level_element_in = NULL, int number_of_derivatives_in = 0) :
		Field_location(time_in, number_of_derivatives_in),
		element(element_in ? ACCESS(FE_element)(element_in) : 0),
		dimension(element_in ? get_FE_element_dimension(element_in) : 0),
		top_level_element(top_level_element_in ? ACCESS(FE_element)(top_level_element_in) : 0)
	{
		if (xi_in)
		{
			for (int i = 0; i < dimension; i++)
			{
				xi[i] = xi_in[i];
			}
		}
		else
		{
			for (int i = 0; i < dimension; i++)
			{
				xi[i] = 0.0;
			}
		}
	}

	// blank constructor - caller should call set_element_xi & check valid return
	Field_element_xi_location(FE_value time_in = 0.0, int number_of_derivatives_in = 0) :
		Field_location(time_in, number_of_derivatives_in),
		element(0),
		dimension(0),
		top_level_element(0)
	{
	}

	~Field_element_xi_location()
	{
		DEACCESS(FE_element)(&element);
		if (top_level_element)
			DEACCESS(FE_element)(&top_level_element);
	}

	virtual Field_location *clone()
	{
		return new Field_element_xi_location(element, xi, time, top_level_element);
	}

	int get_dimension() const
	{
		return dimension;
	}

	struct FE_element *get_element()
	{
		return element;
	}

	const FE_value *get_xi() const
	{
		return xi;
	}

	FE_element *get_top_level_element()
	{
		return top_level_element;
	}

	int set_element_xi(struct FE_element *element_in,
		int number_of_xi_in, const FE_value *xi_in,
		struct FE_element *top_level_element_in = NULL);
};

class Field_node_location : public Field_location
{
private:
	struct FE_node *node;

public:
	Field_node_location(struct FE_node *node,
		FE_value time = 0, int number_of_derivatives = 0):
		Field_location(time, number_of_derivatives),
		node(ACCESS(FE_node)(node))
	{
	}

	~Field_node_location()
	{
		DEACCESS(FE_node)(&node);
	}

	virtual Field_location *clone()
	{
		return new Field_node_location(node, time);
	}

	FE_node *get_node()
	{
		return node;
	}

	void set_node(FE_node *node_in)
	{
		REACCESS(FE_node)(&node, node_in);
	}
};

class Field_time_location : public Field_location
{
public:
	Field_time_location(FE_value time = 0, int number_of_derivatives = 0):
		Field_location(time, number_of_derivatives)
	{
	}

	~Field_time_location()
	{
	}

	virtual Field_location *clone()
	{
		return new Field_time_location(time);
	}
};

class Field_coordinate_location : public Field_location
{
private:
	Cmiss_field *reference_field;
	int number_of_values;
	FE_value *values;
	FE_value *derivatives;

public:
	Field_coordinate_location(Cmiss_field *reference_field_in,
		int number_of_values_in, const FE_value* values_in, FE_value time = 0,
		int number_of_derivatives_in = 0, const FE_value* derivatives_in = NULL);

	// blank constructor - caller should call set_field_values & check valid return
	Field_coordinate_location(FE_value time = 0) :
		Field_location(time),
		reference_field(0),
		number_of_values(0),
		values(0),
		derivatives(0)
	{
	}

	~Field_coordinate_location();

	virtual Field_location *clone()
	{
		return new Field_coordinate_location(reference_field, number_of_values, values, time, number_of_derivatives, derivatives);
	}

	Cmiss_field *get_reference_field()
	{
		return reference_field;
	}

	int get_number_of_values()
	{
		return number_of_values;
	}

	FE_value *get_values()
	{
		return values;
	}

	int set_field_values(Cmiss_field_id reference_field_in,
		int number_of_values_in, const FE_value *values_in);

	int set_values_for_location(Cmiss_field *field,
		const FE_value *values);

};

#endif /* !defined (__FIELD_LOCATION_HPP__) */
<|endoftext|>


<commit_before><commit_msg>minor code edits, mostly comments<commit_after><|endoftext|>


<commit_before>/**
 * Copyright 2013 Truphone
 */
#include "SegmentCommand.h"

#include <bb/cascades/AbstractPane>
#include <bb/cascades/Application>
#include <bb/cascades/SegmentedControl>
#include <bb/cascades/Option>
#include <QString>
#include <QList>
#include <QObject>

#include "Connection.h"

using bb::cascades::SegmentedControl;
using bb::cascades::Option;
using bb::cascades::Application;

namespace truphone
{
namespace test
{
namespace cascades
{
    const QString SegmentCommand::CMD_NAME = "segment";

    SegmentCommand::SegmentCommand(Connection * const socket,
                               QObject* parent)
        : Command(parent),
          client(socket)
    {
    }

    SegmentCommand::~SegmentCommand()
    {
    }

    bool SegmentCommand::executeCommand(QStringList * const arguments)
    {
        bool ret = false;
        if (arguments->size() == 3)
        {
            SegmentedControl * const obj =
                    Application::instance()->scene()->findChild<SegmentedControl*>
                        (arguments->first());
            arguments->removeFirst();
            if (obj)
            {
                const QString mode = arguments->first();
                arguments->removeFirst();
                if (mode == "index")
                {
                    const int optionCount = obj->count();
                    bool ok = false;
                    const int index = arguments->first().toUInt(&ok);
                    if (ok && index < optionCount)
                    {
                        obj->setSelectedIndex(index);
                        ret = true;
                    }
                    else
                    {
                        this->client->write("ERROR: Index isn't a valid number\r\n");
                    }
                }
                else if (mode == "option")
                {
                    const int optionCount = obj->count();
                    for (int i = 0 ; (i < optionCount) and (not ret) ; i++)
                    {
                        const Option * const option = obj->at(i);
                        if (option)
                        {
                            // basic - the text is set
                            if (option->text() == arguments->first())
                            {
                                obj->setSelectedIndex(i);
                                ret = true;
                            }
                        }
                    }
                    if (not ret)
                    {
                        this->client->write("ERROR: Couldn't find the option\r\n");
                    }
                }
                else
                {
                    this->client->write("ERROR: Invalid selection method, use index or option\r\n");
                }
            }
            else
            {
                this->client->write("ERROR: Couldn't find the segment\r\n");
            }
        }
        else
        {
            this->client->write("ERROR: Need to specify a segment and an option\r\n");
        }
        return ret;
    }

    void SegmentCommand::showHelp()
    {
        this->client->write("> segment <segment> <index | option> <option text>\r\n");
        this->client->write("> i.e. segment mySegment index 1\r\n");
        this->client->write("> i.e. segment mySegment option option5\r\n");
        this->client->write("Select a segment option\r\n");
    }
}  // namespace cascades
}  // namespace test
}  // namespace truphone
<commit_msg>Update the copyright to this year.<commit_after>/**
 * Copyright 2014 Truphone
 */
#include "SegmentCommand.h"

#include <bb/cascades/AbstractPane>
#include <bb/cascades/Application>
#include <bb/cascades/SegmentedControl>
#include <bb/cascades/Option>
#include <QString>
#include <QList>
#include <QObject>

#include "Connection.h"

using bb::cascades::SegmentedControl;
using bb::cascades::Option;
using bb::cascades::Application;

namespace truphone
{
namespace test
{
namespace cascades
{
    const QString SegmentCommand::CMD_NAME = "segment";

    SegmentCommand::SegmentCommand(Connection * const socket,
                               QObject* parent)
        : Command(parent),
          client(socket)
    {
    }

    SegmentCommand::~SegmentCommand()
    {
    }

    bool SegmentCommand::executeCommand(QStringList * const arguments)
    {
        bool ret = false;
        if (arguments->size() == 3)
        {
            SegmentedControl * const obj =
                    Application::instance()->scene()->findChild<SegmentedControl*>
                        (arguments->first());
            arguments->removeFirst();
            if (obj)
            {
                const QString mode = arguments->first();
                arguments->removeFirst();
                if (mode == "index")
                {
                    const int optionCount = obj->count();
                    bool ok = false;
                    const int index = arguments->first().toUInt(&ok);
                    if (ok && index < optionCount)
                    {
                        obj->setSelectedIndex(index);
                        ret = true;
                    }
                    else
                    {
                        this->client->write("ERROR: Index isn't a valid number\r\n");
                    }
                }
                else if (mode == "option")
                {
                    const int optionCount = obj->count();
                    for (int i = 0 ; (i < optionCount) and (not ret) ; i++)
                    {
                        const Option * const option = obj->at(i);
                        if (option)
                        {
                            // basic - the text is set
                            if (option->text() == arguments->first())
                            {
                                obj->setSelectedIndex(i);
                                ret = true;
                            }
                        }
                    }
                    if (not ret)
                    {
                        this->client->write("ERROR: Couldn't find the option\r\n");
                    }
                }
                else
                {
                    this->client->write("ERROR: Invalid selection method, use index or option\r\n");
                }
            }
            else
            {
                this->client->write("ERROR: Couldn't find the segment\r\n");
            }
        }
        else
        {
            this->client->write("ERROR: Need to specify a segment and an option\r\n");
        }
        return ret;
    }

    void SegmentCommand::showHelp()
    {
        this->client->write("> segment <segment> <index | option> <option text>\r\n");
        this->client->write("> i.e. segment mySegment index 1\r\n");
        this->client->write("> i.e. segment mySegment option option5\r\n");
        this->client->write("Select a segment option\r\n");
    }
}  // namespace cascades
}  // namespace test
}  // namespace truphone
<|endoftext|>


<commit_before>/**
 * @file Cosa/Wireless/Driver/NRF24L01P.cpp
 * @version 1.0
 *
 * @section License
 * Copyright (C) 2013, Mikael Patel
 *
 * This 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.
 *
 * 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.
 *
 * This file is part of the Arduino Che Cosa project.
 */

#include "Cosa/Wireless/Driver/NRF24L01P.hh"
#if !defined(BOARD_ATTINYX5)

#include "Cosa/Power.hh"
#include "Cosa/RTC.hh"
#include <util/delay.h>

NRF24L01P::NRF24L01P(uint16_t net, uint8_t dev,
		     Board::DigitalPin csn,
		     Board::DigitalPin ce,
		     Board::ExternalInterruptPin irq) :
  SPI::Driver(csn, SPI::ACTIVE_LOW, SPI::DIV4_CLOCK, 0, SPI::MSB_ORDER, &m_irq),
  Wireless::Driver(net, dev),
  m_ce(ce, 0),
  m_irq(irq, ExternalInterrupt::ON_FALLING_MODE, this),
  m_status(0),
  m_state(POWER_DOWN_STATE),
  m_trans(0),
  m_retrans(0),
  m_drops(0)
{
  set_channel(64);
}

uint8_t
NRF24L01P::read(Command cmd)
{
  spi.acquire(this);
    spi.begin();
      m_status = spi.transfer(cmd);
      uint8_t res = spi.transfer(0);
    spi.end();
  spi.release();
  return (res);
}

void
NRF24L01P::read(Command cmd, void* buf, size_t size)
{
  spi.acquire(this);
    spi.begin();
      m_status = spi.transfer(cmd);
      spi.read(buf, size);
    spi.end();
  spi.release();
}

void
NRF24L01P::write(Command cmd)
{
  spi.acquire(this);
    spi.begin();
      m_status = spi.transfer(cmd);
    spi.end();
  spi.release();
}

void
NRF24L01P::write(Command cmd, uint8_t data)
{
  spi.acquire(this);
    spi.begin();
      m_status = spi.transfer(cmd);
      spi.transfer(data);
    spi.end();
  spi.release();
}

void
NRF24L01P::write(Command cmd, const void* buf, size_t size)
{
  spi.acquire(this);
    spi.begin();
      m_status = spi.transfer(cmd);
      spi.write(buf, size);
    spi.end();
  spi.release();
}

NRF24L01P::status_t
NRF24L01P::read_status()
{
  spi.acquire(this);
    spi.begin();
      m_status = spi.transfer(NOP);
    spi.end();
  spi.release();
  return (m_status);
}

void
NRF24L01P::powerup()
{
  if (m_state != POWER_DOWN_STATE) return;
  m_ce.clear();

  // Setup configuration for powerup and clear interrupts
  write(CONFIG, (_BV(EN_CRC) | _BV(CRCO)  | _BV(PWR_UP)));
  _delay_ms(Tpd2stby_ms);
  m_state = STANDBY_STATE;

  // Flush status
  write(STATUS, (_BV(RX_DR)  | _BV(TX_DS) | _BV(MAX_RT)));
  write(FLUSH_TX);
  write(FLUSH_RX);
}

void
NRF24L01P::set_receiver_mode()
{
  // Check already in receive mode
  if (m_state == RX_STATE) return;

  // Configure primary receiver mode
  write(CONFIG, (_BV(EN_CRC) | _BV(CRCO) | _BV(PWR_UP) | _BV(PRIM_RX)));
  m_ce.set();
  if (m_state == STANDBY_STATE) _delay_us(Tstby2a_us);
  m_state = RX_STATE;
}

void
NRF24L01P::set_transmit_mode(uint8_t dest)
{
  // Setup primary transmit address
  addr_t tx_addr(m_addr.network, dest);
  write(TX_ADDR, &tx_addr, sizeof(tx_addr));

  // Trigger the transmitter mode
  if (m_state != TX_STATE) {
    m_ce.clear();
    write(CONFIG, (_BV(EN_CRC) | _BV(CRCO) | _BV(PWR_UP)));
    m_ce.set();
  }

  // Wait for the transmitter to become active
  if (m_state == STANDBY_STATE) _delay_us(Tstby2a_us);
  m_state = TX_STATE;
}

void
NRF24L01P::standby()
{
  m_ce.clear();
  _delay_us(Thce_us);
  m_state = STANDBY_STATE;
}

void
NRF24L01P::powerdown()
{
  delay(32);
  m_ce.clear();
  write(CONFIG, (_BV(EN_CRC) | _BV(CRCO)));
  m_state = POWER_DOWN_STATE;
}

bool
NRF24L01P::begin(const void* config)
{
  UNUSED(config);

  // Setup hardware features, channel, bitrate, retransmission, dynamic payload
  write(FEATURE, (_BV(EN_DPL) | _BV(EN_ACK_PAY) | _BV(EN_DYN_ACK)));
  write(RF_CH, m_channel);
  write(RF_SETUP, (RF_DR_2MBPS | RF_PWR_0DBM));
  write(SETUP_RETR, ((DEFAULT_ARD << ARD) | (DEFAULT_ARC << ARC)));
  write(DYNPD, DPL_PA);

  // Setup hardware receive pipes address; network (16-bit), device (8-bit)
  // P0: auto-acknowledge (see set_transmit_mode)
  // P1: node address<network:device> with auto-acknowledge
  // P2: broadcast<network:0>
  addr_t rx_addr = m_addr;
  write(SETUP_AW, AW_3BYTES);
  write(RX_ADDR_P1, &rx_addr, sizeof(rx_addr));
  write(RX_ADDR_P2, BROADCAST);
  write(EN_RXADDR, (_BV(ERX_P2) | _BV(ERX_P1)));
  write(EN_AA, (_BV(ENAA_P1)));

  // Ready to go
  powerup();
  spi.attach(this);
  m_irq.enable();
  return (true);
}

int
NRF24L01P::send(uint8_t dest, uint8_t port, const iovec_t* vec)
{
  // Sanity check the payload size
  if (vec == NULL) return (-1);
  size_t len = iovec_size(vec);
  if (len > PAYLOAD_MAX) return (-1);

  // Setting transmit destination
  set_transmit_mode(dest);

  // Write source address and payload to the transmit fifo
  // Fix: Allow larger payload(30*3) with fragmentation
  spi.acquire(this);
    spi.begin();
      uint8_t command = ((dest != BROADCAST)
			 ? W_TX_PAYLOAD
			 : W_TX_PAYLOAD_NO_ACK);
      m_status = spi.transfer(command);
      spi.transfer(m_addr.device);
      spi.transfer(port);
      spi.write(vec);
    spi.end();
  spi.release();
  m_trans += 1;

  // Check for auto-acknowledge pipe(0), and address setup and enable
  if (dest != BROADCAST) {
    addr_t tx_addr(m_addr.network, dest);
    write(RX_ADDR_P0, &tx_addr, sizeof(tx_addr));
    write(EN_RXADDR, (_BV(ERX_P2) | _BV(ERX_P1) | _BV(ERX_P0)));
  }

  // Wait for transmission
  do {
    yield();
    read_status();
  } while (!m_status.tx_ds && !m_status.max_rt);
  bool data_sent = m_status.tx_ds;

  // Check for auto-acknowledge pipe(0) disable
  if (dest != BROADCAST) {
    write(EN_RXADDR, (_BV(ERX_P2) | _BV(ERX_P1)));
  }

  // Reset status bits and read retransmission counter and update
  write(STATUS, _BV(MAX_RT) | _BV(TX_DS));
  observe_tx_t observe = read_observe_tx();
  m_retrans += observe.arc_cnt;

  // Check that the message was delivered
  if (data_sent) return (len);

  // Failed to delivery
  write(FLUSH_TX);
  m_drops += 1;
  return (-2);
}

int
NRF24L01P::send(uint8_t dest, uint8_t port, const void* buf, size_t len)
{
  iovec_t vec[2];
  iovec_t* vp = vec;
  iovec_arg(vp, buf, len);
  iovec_end(vp);
  return (send(dest, port, vec));
}

bool
NRF24L01P::available()
{
  // Check the receiver fifo
  if (read_fifo_status().rx_empty) return (false);

  // Sanity check the size of the payload. Might require a flush
  if (read(R_RX_PL_WID) <= DEVICE_PAYLOAD_MAX) return (true);
  write(FLUSH_RX);
  return (false);
}

int
NRF24L01P::recv(uint8_t& src, uint8_t& port,
		void* buf, size_t size,
		uint32_t ms)
{
  // Run in receiver mode
  set_receiver_mode();

  // Check if there is data available on any pipe
  uint32_t start = RTC::millis();
  while (!available()) {
    if ((ms != 0) && (RTC::since(start) > ms)) return (-2);
    yield();
  }
  m_dest = (m_status.rx_p_no == 1 ? m_addr.device : BROADCAST);
  write(STATUS, _BV(RX_DR));

  // Check for payload error from device (Tab. 20, pp. 51, R_RX_PL_WID)
  uint8_t count = read(R_RX_PL_WID) - 2;
  if ((count > PAYLOAD_MAX) || (count > size)) {
    write(FLUSH_RX);
    return (-1);
  }

  // Read the source address, port and payload
  spi.acquire(this);
    spi.begin();
      m_status = spi.transfer(R_RX_PAYLOAD);
      src = spi.transfer(0);
      port = spi.transfer(0);
      spi.read(buf, count);
    spi.end();
  spi.release();
  return (count);
}

void
NRF24L01P::set_output_power_level(int8_t dBm)
{
  uint8_t pwr = RF_PWR_0DBM;
  if      (dBm < -12) pwr = RF_PWR_18DBM;
  else if (dBm < -6)  pwr = RF_PWR_12DBM;
  else if (dBm < 0)   pwr = RF_PWR_6DBM;
  write(RF_SETUP, (RF_DR_2MBPS | pwr));
}

// Output operators for bitfield status registers
IOStream& operator<<(IOStream& outs, NRF24L01P::status_t status)
{
  outs << PSTR("RX_DR = ") << status.rx_dr
       << PSTR(", TX_DS = ") << status.tx_ds
       << PSTR(", MAX_RT = ") << status.max_rt
       << PSTR(", RX_P_NO = ") << status.rx_p_no
       << PSTR(", TX_FULL = ") << status.tx_full;
  return (outs);
}

IOStream& operator<<(IOStream& outs, NRF24L01P::observe_tx_t observe)
{
  outs << PSTR("PLOS_CNT = ") << observe.plos_cnt
       << PSTR(", ARC_CNT = ") << observe.arc_cnt;
  return (outs);
}

IOStream& operator<<(IOStream& outs, NRF24L01P::fifo_status_t fifo)
{
  outs << PSTR("RX_EMPTY = ") << fifo.rx_empty
       << PSTR(", RX_FULL = ") << fifo.rx_full
       << PSTR(", TX_EMPTY = ") << fifo.tx_empty
       << PSTR(", TX_FULL = ") << fifo.tx_full
       << PSTR(", TX_REUSE = ") << fifo.tx_reuse;
  return (outs);
}

#endif
<commit_msg>Fixed missing auto-ack on pipe#0.<commit_after>/**
 * @file Cosa/Wireless/Driver/NRF24L01P.cpp
 * @version 1.0
 *
 * @section License
 * Copyright (C) 2013, Mikael Patel
 *
 * This 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.
 *
 * 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.
 *
 * This file is part of the Arduino Che Cosa project.
 */

#include "Cosa/Wireless/Driver/NRF24L01P.hh"
#if !defined(BOARD_ATTINYX5)

#include "Cosa/Power.hh"
#include "Cosa/RTC.hh"
#include <util/delay.h>

NRF24L01P::NRF24L01P(uint16_t net, uint8_t dev,
		     Board::DigitalPin csn,
		     Board::DigitalPin ce,
		     Board::ExternalInterruptPin irq) :
  SPI::Driver(csn, SPI::ACTIVE_LOW, SPI::DIV4_CLOCK, 0, SPI::MSB_ORDER, &m_irq),
  Wireless::Driver(net, dev),
  m_ce(ce, 0),
  m_irq(irq, ExternalInterrupt::ON_FALLING_MODE, this),
  m_status(0),
  m_state(POWER_DOWN_STATE),
  m_trans(0),
  m_retrans(0),
  m_drops(0)
{
  set_channel(64);
}

uint8_t
NRF24L01P::read(Command cmd)
{
  spi.acquire(this);
    spi.begin();
      m_status = spi.transfer(cmd);
      uint8_t res = spi.transfer(0);
    spi.end();
  spi.release();
  return (res);
}

void
NRF24L01P::read(Command cmd, void* buf, size_t size)
{
  spi.acquire(this);
    spi.begin();
      m_status = spi.transfer(cmd);
      spi.read(buf, size);
    spi.end();
  spi.release();
}

void
NRF24L01P::write(Command cmd)
{
  spi.acquire(this);
    spi.begin();
      m_status = spi.transfer(cmd);
    spi.end();
  spi.release();
}

void
NRF24L01P::write(Command cmd, uint8_t data)
{
  spi.acquire(this);
    spi.begin();
      m_status = spi.transfer(cmd);
      spi.transfer(data);
    spi.end();
  spi.release();
}

void
NRF24L01P::write(Command cmd, const void* buf, size_t size)
{
  spi.acquire(this);
    spi.begin();
      m_status = spi.transfer(cmd);
      spi.write(buf, size);
    spi.end();
  spi.release();
}

NRF24L01P::status_t
NRF24L01P::read_status()
{
  spi.acquire(this);
    spi.begin();
      m_status = spi.transfer(NOP);
    spi.end();
  spi.release();
  return (m_status);
}

void
NRF24L01P::powerup()
{
  if (m_state != POWER_DOWN_STATE) return;
  m_ce.clear();

  // Setup configuration for powerup and clear interrupts
  write(CONFIG, (_BV(EN_CRC) | _BV(CRCO)  | _BV(PWR_UP)));
  _delay_ms(Tpd2stby_ms);
  m_state = STANDBY_STATE;

  // Flush status
  write(STATUS, (_BV(RX_DR)  | _BV(TX_DS) | _BV(MAX_RT)));
  write(FLUSH_TX);
  write(FLUSH_RX);
}

void
NRF24L01P::set_receiver_mode()
{
  // Check already in receive mode
  if (m_state == RX_STATE) return;

  // Configure primary receiver mode
  write(CONFIG, (_BV(EN_CRC) | _BV(CRCO) | _BV(PWR_UP) | _BV(PRIM_RX)));
  m_ce.set();
  if (m_state == STANDBY_STATE) _delay_us(Tstby2a_us);
  m_state = RX_STATE;
}

void
NRF24L01P::set_transmit_mode(uint8_t dest)
{
  // Setup primary transmit address
  addr_t tx_addr(m_addr.network, dest);
  write(TX_ADDR, &tx_addr, sizeof(tx_addr));

  // Trigger the transmitter mode
  if (m_state != TX_STATE) {
    m_ce.clear();
    write(CONFIG, (_BV(EN_CRC) | _BV(CRCO) | _BV(PWR_UP)));
    m_ce.set();
  }

  // Wait for the transmitter to become active
  if (m_state == STANDBY_STATE) _delay_us(Tstby2a_us);
  m_state = TX_STATE;
}

void
NRF24L01P::standby()
{
  m_ce.clear();
  _delay_us(Thce_us);
  m_state = STANDBY_STATE;
}

void
NRF24L01P::powerdown()
{
  delay(32);
  m_ce.clear();
  write(CONFIG, (_BV(EN_CRC) | _BV(CRCO)));
  m_state = POWER_DOWN_STATE;
}

bool
NRF24L01P::begin(const void* config)
{
  UNUSED(config);

  // Setup hardware features, channel, bitrate, retransmission, dynamic payload
  write(FEATURE, (_BV(EN_DPL) | _BV(EN_ACK_PAY) | _BV(EN_DYN_ACK)));
  write(RF_CH, m_channel);
  write(RF_SETUP, (RF_DR_2MBPS | RF_PWR_0DBM));
  write(SETUP_RETR, ((DEFAULT_ARD << ARD) | (DEFAULT_ARC << ARC)));
  write(DYNPD, DPL_PA);

  // Setup hardware receive pipes address; network (16-bit), device (8-bit)
  // P0: auto-acknowledge (see set_transmit_mode)
  // P1: node address<network:device> with auto-acknowledge
  // P2: broadcast<network:0>
  addr_t rx_addr = m_addr;
  write(SETUP_AW, AW_3BYTES);
  write(RX_ADDR_P1, &rx_addr, sizeof(rx_addr));
  write(RX_ADDR_P2, BROADCAST);
  write(EN_RXADDR, (_BV(ERX_P2) | _BV(ERX_P1)));
  write(EN_AA, (_BV(ENAA_P1) | _BV(ENAA_P0)));

  // Ready to go
  powerup();
  spi.attach(this);
  m_irq.enable();
  return (true);
}

int
NRF24L01P::send(uint8_t dest, uint8_t port, const iovec_t* vec)
{
  // Sanity check the payload size
  if (vec == NULL) return (-1);
  size_t len = iovec_size(vec);
  if (len > PAYLOAD_MAX) return (-1);

  // Setting transmit destination
  set_transmit_mode(dest);

  // Write source address and payload to the transmit fifo
  // Fix: Allow larger payload(30*3) with fragmentation
  spi.acquire(this);
    spi.begin();
      uint8_t command = ((dest != BROADCAST)
			 ? W_TX_PAYLOAD
			 : W_TX_PAYLOAD_NO_ACK);
      m_status = spi.transfer(command);
      spi.transfer(m_addr.device);
      spi.transfer(port);
      spi.write(vec);
    spi.end();
  spi.release();
  m_trans += 1;

  // Check for auto-acknowledge pipe(0), and address setup and enable
  if (dest != BROADCAST) {
    addr_t tx_addr(m_addr.network, dest);
    write(RX_ADDR_P0, &tx_addr, sizeof(tx_addr));
    write(EN_RXADDR, (_BV(ERX_P2) | _BV(ERX_P1) | _BV(ERX_P0)));
  }

  // Wait for transmission
  do {
    yield();
    read_status();
  } while (!m_status.tx_ds && !m_status.max_rt);
  bool data_sent = m_status.tx_ds;

  // Check for auto-acknowledge pipe(0) disable
  if (dest != BROADCAST) {
    write(EN_RXADDR, (_BV(ERX_P2) | _BV(ERX_P1)));
  }

  // Reset status bits and read retransmission counter and update
  write(STATUS, _BV(MAX_RT) | _BV(TX_DS));
  observe_tx_t observe = read_observe_tx();
  m_retrans += observe.arc_cnt;

  // Check that the message was delivered
  if (data_sent) return (len);

  // Failed to delivery
  write(FLUSH_TX);
  m_drops += 1;
  return (-2);
}

int
NRF24L01P::send(uint8_t dest, uint8_t port, const void* buf, size_t len)
{
  iovec_t vec[2];
  iovec_t* vp = vec;
  iovec_arg(vp, buf, len);
  iovec_end(vp);
  return (send(dest, port, vec));
}

bool
NRF24L01P::available()
{
  // Check the receiver fifo
  if (read_fifo_status().rx_empty) return (false);

  // Sanity check the size of the payload. Might require a flush
  if (read(R_RX_PL_WID) <= DEVICE_PAYLOAD_MAX) return (true);
  write(FLUSH_RX);
  return (false);
}

int
NRF24L01P::recv(uint8_t& src, uint8_t& port,
		void* buf, size_t size,
		uint32_t ms)
{
  // Run in receiver mode
  set_receiver_mode();

  // Check if there is data available on any pipe
  uint32_t start = RTC::millis();
  while (!available()) {
    if ((ms != 0) && (RTC::since(start) > ms)) return (-2);
    yield();
  }
  m_dest = (m_status.rx_p_no == 1 ? m_addr.device : BROADCAST);
  write(STATUS, _BV(RX_DR));

  // Check for payload error from device (Tab. 20, pp. 51, R_RX_PL_WID)
  uint8_t count = read(R_RX_PL_WID) - 2;
  if ((count > PAYLOAD_MAX) || (count > size)) {
    write(FLUSH_RX);
    return (-1);
  }

  // Read the source address, port and payload
  spi.acquire(this);
    spi.begin();
      m_status = spi.transfer(R_RX_PAYLOAD);
      src = spi.transfer(0);
      port = spi.transfer(0);
      spi.read(buf, count);
    spi.end();
  spi.release();
  return (count);
}

void
NRF24L01P::set_output_power_level(int8_t dBm)
{
  uint8_t pwr = RF_PWR_0DBM;
  if      (dBm < -12) pwr = RF_PWR_18DBM;
  else if (dBm < -6)  pwr = RF_PWR_12DBM;
  else if (dBm < 0)   pwr = RF_PWR_6DBM;
  write(RF_SETUP, (RF_DR_2MBPS | pwr));
}

// Output operators for bitfield status registers
IOStream& operator<<(IOStream& outs, NRF24L01P::status_t status)
{
  outs << PSTR("RX_DR = ") << status.rx_dr
       << PSTR(", TX_DS = ") << status.tx_ds
       << PSTR(", MAX_RT = ") << status.max_rt
       << PSTR(", RX_P_NO = ") << status.rx_p_no
       << PSTR(", TX_FULL = ") << status.tx_full;
  return (outs);
}

IOStream& operator<<(IOStream& outs, NRF24L01P::observe_tx_t observe)
{
  outs << PSTR("PLOS_CNT = ") << observe.plos_cnt
       << PSTR(", ARC_CNT = ") << observe.arc_cnt;
  return (outs);
}

IOStream& operator<<(IOStream& outs, NRF24L01P::fifo_status_t fifo)
{
  outs << PSTR("RX_EMPTY = ") << fifo.rx_empty
       << PSTR(", RX_FULL = ") << fifo.rx_full
       << PSTR(", TX_EMPTY = ") << fifo.tx_empty
       << PSTR(", TX_FULL = ") << fifo.tx_full
       << PSTR(", TX_REUSE = ") << fifo.tx_reuse;
  return (outs);
}

#endif
<|endoftext|>


<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2017 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */

#include "joynr/RoutingTable.h"

namespace joynr
{

RoutingTable::RoutingTable() : multiIndexContainer()
{
}

RoutingTable::~RoutingTable()
{
    JOYNR_LOG_TRACE(logger(), "destructor: number of entries = {}", multiIndexContainer.size());
}

boost::optional<routingtable::RoutingEntry> RoutingTable::lookupRoutingEntryByParticipantId(
        const std::string& participantId) const
{
    auto& index = boost::multi_index::get<routingtable::tags::ParticipantId>(multiIndexContainer);
    auto found = index.find(participantId);
    if (found == index.end()) {
        return boost::none;
    }
    return *found;
}

std::unordered_set<std::string> RoutingTable::lookupParticipantIdsByAddress(
        std::shared_ptr<const joynr::system::RoutingTypes::Address> searchValue) const
{
    std::unordered_set<std::string> result;
    const auto& addressIndex =
            boost::multi_index::get<routingtable::tags::Address>(multiIndexContainer);
    auto found = addressIndex.equal_range(searchValue);
    for (auto it = found.first; it != found.second; ++it) {
        result.insert(it->participantId);
    }
    return result;
}

bool RoutingTable::containsParticipantId(const std::string& participantId) const
{
    auto& index = boost::multi_index::get<routingtable::tags::ParticipantId>(multiIndexContainer);
    auto found = index.find(participantId);
    return found != index.end();
}

void RoutingTable::add(const std::string& participantId,
                       bool isGloballyVisible,
                       std::shared_ptr<const joynr::system::RoutingTypes::Address> address,
                       std::int64_t expiryDateMs,
                       bool isSticky)
{
    routingtable::RoutingEntry routingEntry(participantId,
                                            std::move(address),
                                            std::move(isGloballyVisible),
                                            std::move(expiryDateMs),
                                            std::move(isSticky));
    auto result = multiIndexContainer.insert(routingEntry);
    if (!result.second) {
        multiIndexContainer.replace(result.first, routingEntry);
    }
    JOYNR_LOG_TRACE(logger(), "Added participantId: {}", participantId);
}

void RoutingTable::remove(const std::string& participantId)
{
    JOYNR_LOG_TRACE(logger(), "Removing registered participantId: {}", participantId);
    multiIndexContainer.erase(participantId);
}

void RoutingTable::purge()
{
    JOYNR_LOG_TRACE(logger(), "Purging expired entries");
    auto& index = boost::multi_index::get<routingtable::tags::ExpiryDate>(multiIndexContainer);
    auto now = std::chrono::duration_cast<std::chrono::milliseconds>(
                       std::chrono::system_clock::now().time_since_epoch()).count();
    auto last = index.upper_bound(now);
    std::vector<std::string> expiredParticipantIds;
    for (auto routingEntryIterator = index.lower_bound(0); routingEntryIterator != last;
         ++routingEntryIterator) {
        if (!routingEntryIterator->isSticky) {
            expiredParticipantIds.push_back(routingEntryIterator->participantId);
        }
    }
    for (auto& participantId : expiredParticipantIds) {
        remove(participantId);
    }
}

bool RoutingTable::AddressEqual::operator()(
        std::shared_ptr<const joynr::system::RoutingTypes::Address> lhs,
        std::shared_ptr<const joynr::system::RoutingTypes::Address> rhs) const
{
    bool result = ((*lhs) == (*rhs));
    return result;
}

size_t RoutingTable::AddressHash::operator()(
        std::shared_ptr<const joynr::system::RoutingTypes::Address> address) const
{
    return address->hashCode();
}

} // namespace joynr
<commit_msg>[C++] RoutingTable logs changes on level info<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2017 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */

#include "joynr/RoutingTable.h"

namespace joynr
{

RoutingTable::RoutingTable() : multiIndexContainer()
{
}

RoutingTable::~RoutingTable()
{
    JOYNR_LOG_TRACE(logger(), "destructor: number of entries = {}", multiIndexContainer.size());
}

boost::optional<routingtable::RoutingEntry> RoutingTable::lookupRoutingEntryByParticipantId(
        const std::string& participantId) const
{
    auto& index = boost::multi_index::get<routingtable::tags::ParticipantId>(multiIndexContainer);
    auto found = index.find(participantId);
    if (found == index.end()) {
        return boost::none;
    }
    return *found;
}

std::unordered_set<std::string> RoutingTable::lookupParticipantIdsByAddress(
        std::shared_ptr<const joynr::system::RoutingTypes::Address> searchValue) const
{
    std::unordered_set<std::string> result;
    const auto& addressIndex =
            boost::multi_index::get<routingtable::tags::Address>(multiIndexContainer);
    auto found = addressIndex.equal_range(searchValue);
    for (auto it = found.first; it != found.second; ++it) {
        result.insert(it->participantId);
    }
    return result;
}

bool RoutingTable::containsParticipantId(const std::string& participantId) const
{
    auto& index = boost::multi_index::get<routingtable::tags::ParticipantId>(multiIndexContainer);
    auto found = index.find(participantId);
    return found != index.end();
}

void RoutingTable::add(const std::string& participantId,
                       bool isGloballyVisible,
                       std::shared_ptr<const joynr::system::RoutingTypes::Address> address,
                       std::int64_t expiryDateMs,
                       bool isSticky)
{
    routingtable::RoutingEntry routingEntry(participantId,
                                            std::move(address),
                                            std::move(isGloballyVisible),
                                            std::move(expiryDateMs),
                                            std::move(isSticky));
    auto result = multiIndexContainer.insert(routingEntry);
    if (!result.second) {
        multiIndexContainer.replace(result.first, routingEntry);
        JOYNR_LOG_INFO(logger(), "Replaced routing entry: {}", routingEntry.toString());
    } else {
        JOYNR_LOG_INFO(logger(), "Added routing entry: {}", routingEntry.toString());
    }
}

void RoutingTable::remove(const std::string& participantId)
{
    JOYNR_LOG_INFO(logger(), "Removing routing entry for participantId: {}", participantId);
    multiIndexContainer.erase(participantId);
}

void RoutingTable::purge()
{
    bool expiredEntriesFound = false;
    auto& index = boost::multi_index::get<routingtable::tags::ExpiryDate>(multiIndexContainer);
    auto now = std::chrono::duration_cast<std::chrono::milliseconds>(
                       std::chrono::system_clock::now().time_since_epoch()).count();
    auto last = index.upper_bound(now);
    std::vector<std::string> expiredParticipantIds;
    for (auto routingEntryIterator = index.lower_bound(0); routingEntryIterator != last;
         ++routingEntryIterator) {
        if (!routingEntryIterator->isSticky) {
            expiredParticipantIds.push_back(routingEntryIterator->participantId);
            expiredEntriesFound = true;
        }
    }
    if (expiredEntriesFound) {
        JOYNR_LOG_INFO(logger(), "Purging expired routing entries");
    }
    for (auto& participantId : expiredParticipantIds) {
        remove(participantId);
    }
}

bool RoutingTable::AddressEqual::operator()(
        std::shared_ptr<const joynr::system::RoutingTypes::Address> lhs,
        std::shared_ptr<const joynr::system::RoutingTypes::Address> rhs) const
{
    bool result = ((*lhs) == (*rhs));
    return result;
}

size_t RoutingTable::AddressHash::operator()(
        std::shared_ptr<const joynr::system::RoutingTypes::Address> address) const
{
    return address->hashCode();
}

} // namespace joynr
<|endoftext|>


<commit_before>/*
* Key codes for multiple platforms
*
* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
*
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
*/

#pragma once

#if defined(_WIN32)
#define KEY_ESCAPE VK_ESCAPE
#define KEY_F1 VK_F1
#define KEY_F2 VK_F2
#define KEY_W 0x57
#define KEY_A 0x41
#define KEY_S 0x53
#define KEY_D 0x44
#define KEY_P 0x50
#define KEY_SPACE 0x20
#define KEY_KPADD 0x6B
#define KEY_KPSUB 0x6D
#define KEY_B 0x42
#define KEY_F 0x46
#define KEY_L 0x4C
#define KEY_N 0x4E
#define KEY_O 0x4F
#define KEY_T 0x54
#elif defined(__ANDROID__)
// Dummy key codes
#define KEY_ESCAPE 0x0
#define KEY_F1 0x1
#define KEY_F2 0x2
#define KEY_W 0x3
#define KEY_A 0x4
#define KEY_S 0x5
#define KEY_D 0x6
#define KEY_P 0x7
#define KEY_SPACE 0x8
#define KEY_KPADD 0x9
#define KEY_KPSUB 0xA
#define KEY_B 0xB
#define KEY_F 0xC
#define KEY_L 0xD
#define KEY_N 0xE
#define KEY_O 0xF
#define KEY_T 0x10
#elif defined(__linux__)
#define KEY_ESCAPE 0x9
#define KEY_F1 0x43
#define KEY_F2 0x44
#define KEY_W 0x19
#define KEY_A 0x26
#define KEY_S 0x27
#define KEY_D 0x28
#define KEY_P 0x21
#define KEY_SPACE 0x41
#define KEY_KPADD 0x56
#define KEY_KPSUB 0x52
#define KEY_B 0x38
#define KEY_F 0x29
#define KEY_L 0x2E
#define KEY_N 0x39
#define KEY_O 0x20
#define KEY_T 0x1C
#endif

// todo: Android gamepad keycodes outside of define for now
#define GAMEPAD_BUTTON_A 0x1000
#define GAMEPAD_BUTTON_B 0x1001
#define GAMEPAD_BUTTON_X 0x1002
#define GAMEPAD_BUTTON_Y 0x1003
#define GAMEPAD_BUTTON_L1 0x1004
#define GAMEPAD_BUTTON_R1 0x1005
#define GAMEPAD_BUTTON_START 0x1006
<commit_msg>Additional keycodes<commit_after>/*
* Key codes for multiple platforms
*
* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
*
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
*/

#pragma once

#if defined(_WIN32)
#define KEY_ESCAPE VK_ESCAPE
#define KEY_F1 VK_F1
#define KEY_F2 VK_F2
#define KEY_F3 VK_F3
#define KEY_F4 VK_F4
#define KEY_W 0x57
#define KEY_A 0x41
#define KEY_S 0x53
#define KEY_D 0x44
#define KEY_P 0x50
#define KEY_SPACE 0x20
#define KEY_KPADD 0x6B
#define KEY_KPSUB 0x6D
#define KEY_B 0x42
#define KEY_F 0x46
#define KEY_L 0x4C
#define KEY_N 0x4E
#define KEY_O 0x4F
#define KEY_T 0x54
#elif defined(__ANDROID__)
// Dummy key codes
#define KEY_ESCAPE 0x0
#define KEY_F1 0x1
#define KEY_F2 0x2
#define KEY_F2 0x11
#define KEY_F2 0x12
#define KEY_W 0x3
#define KEY_A 0x4
#define KEY_S 0x5
#define KEY_D 0x6
#define KEY_P 0x7
#define KEY_SPACE 0x8
#define KEY_KPADD 0x9
#define KEY_KPSUB 0xA
#define KEY_B 0xB
#define KEY_F 0xC
#define KEY_L 0xD
#define KEY_N 0xE
#define KEY_O 0xF
#define KEY_T 0x10
#elif defined(__linux__)
#define KEY_ESCAPE 0x9
#define KEY_F1 0x43
#define KEY_F2 0x44
#define KEY_F3 0x45
#define KEY_F4 0x46
#define KEY_W 0x19
#define KEY_A 0x26
#define KEY_S 0x27
#define KEY_D 0x28
#define KEY_P 0x21
#define KEY_SPACE 0x41
#define KEY_KPADD 0x56
#define KEY_KPSUB 0x52
#define KEY_B 0x38
#define KEY_F 0x29
#define KEY_L 0x2E
#define KEY_N 0x39
#define KEY_O 0x20
#define KEY_T 0x1C
#endif

// todo: Android gamepad keycodes outside of define for now
#define GAMEPAD_BUTTON_A 0x1000
#define GAMEPAD_BUTTON_B 0x1001
#define GAMEPAD_BUTTON_X 0x1002
#define GAMEPAD_BUTTON_Y 0x1003
#define GAMEPAD_BUTTON_L1 0x1004
#define GAMEPAD_BUTTON_R1 0x1005
#define GAMEPAD_BUTTON_START 0x1006
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "EventReceiverTest.h"
#include "Autowiring/Autowired.h"
#include "Autowiring/CoreThread.h"
#include <vector>

using namespace std;

class CopyCounter {
public:
  CopyCounter(void):
    m_count(0)
  {}

  CopyCounter(const CopyCounter& rhs):
    m_count(rhs.m_count + 1)
  {}

  /// <summary>
  /// Special case move ctor, which won't increment the count
  /// </summary>
  CopyCounter(CopyCounter&& rhs):
    m_count(rhs.m_count)
  {}

  int m_count;
};

class CallableInterface:
  public EventReceiver
{
public:
  virtual void ZeroArgs(void) = 0;
  virtual void OneArg(int arg) = 0;
  virtual void CopyVector(const vector<int>& vec) = 0;
  virtual void CopyVectorForwarded(vector<int>&& vec) = 0;
  virtual void TrackCopy(CopyCounter&& ctr) = 0;
  virtual void AllDone(void) = 0;
};

class SimpleSender:
  public EventManager<CallableInterface>
{
};

class SimpleReceiver:
  public CoreThread,
  public CallableInterface
{
public:
  SimpleReceiver(void):
    CoreThread("SimpleReceiver"),
    m_zero(false),
    m_one(false),
    m_oneArg(0),
    m_barrier(2)
  {
    Ready();
  }

  // Manifest of functions called:
  bool m_zero;

  bool m_one;
  int m_oneArg;

  // Copy operation fields:
  vector<int> m_myVec;
  CopyCounter m_myCtr;

  // Continuity barrier:
  boost::barrier m_barrier;

  void ZeroArgs(void) override {
    m_zero = true;
  }

  void OneArg(int arg) override {
    m_one = true;
    m_oneArg = arg;
  }

  void CopyVector(const vector<int>& vec) override {
    // Copy out the argument:
    m_myVec = vec;
  }

  void CopyVectorForwarded(vector<int>&& vec) override {
    // Copy out the argument:
    m_myVec = vec;
  }

  void TrackCopy(CopyCounter&& ctr) override {
    m_myCtr = ctr;
  }

  void AllDone(void) override {
    Stop();
  }

  void Run(void) override {
    m_barrier.wait();
    CoreThread::Run();
  }
};

EventReceiverTest::EventReceiverTest(void) {
  AutoCurrentContext ctxt;

  // Start up the context:
  ctxt->InitiateCoreThreads();
}

TEST_F(EventReceiverTest, SimpleMethodCall) {
  // Try firing the event first:
  sender->Fire(&CallableInterface::ZeroArgs)();
  sender->Fire(&CallableInterface::OneArg)(100);

  // Verify that stuff happens even when the thread isn't running:
  EXPECT_TRUE(receiver->m_zero);
  EXPECT_TRUE(receiver->m_one);
  EXPECT_EQ(100, receiver->m_oneArg);

  // Unblock:
  receiver->m_barrier.wait();
}

TEST_F(EventReceiverTest, DeferredInvoke) {
  // Deferred fire:
  sender->Defer(&CallableInterface::ZeroArgs)();
  sender->Defer(&CallableInterface::OneArg)(101);
  sender->Defer(&CallableInterface::AllDone)();

  // Verify that nothing is hit yet:
  EXPECT_FALSE(receiver->m_zero) << "Zero-argument call made prematurely";
  EXPECT_FALSE(receiver->m_one) << "One-argument call made prematurely";
  EXPECT_TRUE(receiver->IsRunning()) << "Receiver is terminated";

  // Unblock:
  receiver->m_barrier.wait();

  // Now wait until all events are processed:
  receiver->Wait();

  // Validate deferred firing:
  EXPECT_TRUE(receiver->m_zero);
  EXPECT_TRUE(receiver->m_one);
  EXPECT_EQ(101, receiver->m_oneArg) << "Argument was not correctly propagated through a deferred call";
}

TEST_F(EventReceiverTest, NontrivialCopy) {
  static const size_t sc_numElems = 10;

  // Create the vector we're going to copy over:
  vector<int> ascending;
  for(size_t i = 0; i < sc_numElems; i++)
    ascending.push_back(i);

  // Deferred fire:
  sender->Defer(&CallableInterface::CopyVector)(ascending);
  sender->Defer(&CallableInterface::AllDone)();

  // Verify that nothing is hit yet:
  EXPECT_TRUE(receiver->m_myVec.empty()) << "Event handler invoked before barrier was hit; it should have been deferred";
  EXPECT_TRUE(receiver->IsRunning()) << "Receiver is terminated";

  // Unblock:
  receiver->m_barrier.wait();

  // Now wait until all events are processed:
  receiver->Wait();

  // Validate our vectors:
  ASSERT_EQ(10, receiver->m_myVec.size()) << "Receiver was not populated correctly with a vector";
  for(size_t i = 0; i < sc_numElems; i++)
    EXPECT_EQ(i, ascending[i]) << "Element at offset " << i << " was incorrectly copied";
}

TEST_F(EventReceiverTest, VerifyNoUnnecessaryCopies) {
  // Make our copy counter:
  CopyCounter ctr;

  // Verify the counter correctly tracks the number of times it was copied:
  {
    CopyCounter myCopy1 = ctr;
    ASSERT_EQ(1, myCopy1.m_count) << "Copy counter appears to be broken; cannot run test";

    CopyCounter myCopy2 = myCopy1;
    ASSERT_EQ(2, myCopy2.m_count) << "Secondary counter appears to be broken; cannot run test";

    CopyCounter myCopy3(std::move(myCopy2));
    ASSERT_EQ(2, myCopy3.m_count) << "Move ctor doesn't appear to be invoked correctly";

    // Try a move copy
    CopyCounter myCopy4;
    myCopy4 = std::move(myCopy3);
    ASSERT_EQ(2, myCopy4.m_count) << "Move assignment didn't correctly propagate the current count";
  }

  // Now we
}
<commit_msg>Tests made a bit more resilient against unexpected termination<commit_after>#include "stdafx.h"
#include "EventReceiverTest.h"
#include "Autowiring/Autowired.h"
#include "Autowiring/CoreThread.h"
#include <vector>

using namespace std;

class CopyCounter {
public:
  CopyCounter(void):
    m_count(0)
  {}

  CopyCounter(const CopyCounter& rhs):
    m_count(rhs.m_count + 1)
  {}

  /// <summary>
  /// Special case move ctor, which won't increment the count
  /// </summary>
  CopyCounter(CopyCounter&& rhs):
    m_count(rhs.m_count)
  {}

  int m_count;
};

class CallableInterface:
  public EventReceiver
{
public:
  virtual void ZeroArgs(void) = 0;
  virtual void OneArg(int arg) = 0;
  virtual void CopyVector(const vector<int>& vec) = 0;
  virtual void CopyVectorForwarded(vector<int>&& vec) = 0;
  virtual void TrackCopy(CopyCounter&& ctr) = 0;
  virtual void AllDone(void) = 0;
};

class SimpleSender:
  public EventManager<CallableInterface>
{
};

class SimpleReceiver:
  public CoreThread,
  public CallableInterface
{
public:
  SimpleReceiver(void):
    CoreThread("SimpleReceiver"),
    m_zero(false),
    m_one(false),
    m_oneArg(0),
    m_barrier(2),
    m_barrierDone(false)
  {
    Ready();
  }

private:
  // Continuity barrier, used to pause processing while in Run
  boost::barrier m_barrier;
  bool m_barrierDone;

public:
  // Manifest of functions called:
  bool m_zero;

  bool m_one;
  int m_oneArg;

  // Copy operation fields:
  vector<int> m_myVec;
  CopyCounter m_myCtr;

  ///
  // Interface utility methods:
  ///
  void ZeroArgs(void) override {
    m_zero = true;
  }

  void OneArg(int arg) override {
    m_one = true;
    m_oneArg = arg;
  }

  void CopyVector(const vector<int>& vec) override {
    // Copy out the argument:
    m_myVec = vec;
  }

  void CopyVectorForwarded(vector<int>&& vec) override {
    // Copy out the argument:
    m_myVec = vec;
  }

  void TrackCopy(CopyCounter&& ctr) override {
    m_myCtr = ctr;
  }

  // Trivial shutdown override
  void AllDone(void) override {
    Stop();
  }

  // Overridden here so we can hit the barrier if we're still waiting on it
  void Stop() override {
    Proceed();
    CoreThread::Stop();
  }

  /// <summary>
  /// Invoked to cause Run to continue its processing
  /// </summary>
  void Proceed(void) {
    if(!m_barrierDone)
      m_barrier.wait();
    m_barrierDone = true;
  }

  ///
  // Runs the thread
  ///
  void Run(void) override {
    m_barrier.wait();
    CoreThread::Run();
  }
};

EventReceiverTest::EventReceiverTest(void) {
  AutoCurrentContext ctxt;

  // Start up the context:
  ctxt->InitiateCoreThreads();
}

TEST_F(EventReceiverTest, SimpleMethodCall) {
  // Try firing the event first:
  sender->Fire(&CallableInterface::ZeroArgs)();
  sender->Fire(&CallableInterface::OneArg)(100);

  // Verify that stuff happens even when the thread isn't running:
  EXPECT_TRUE(receiver->m_zero);
  EXPECT_TRUE(receiver->m_one);
  EXPECT_EQ(100, receiver->m_oneArg);

  // Unblock:
  receiver->Proceed();
}

TEST_F(EventReceiverTest, DeferredInvoke) {
  // Deferred fire:
  sender->Defer(&CallableInterface::ZeroArgs)();
  sender->Defer(&CallableInterface::OneArg)(101);
  sender->Defer(&CallableInterface::AllDone)();

  // Verify that nothing is hit yet:
  EXPECT_FALSE(receiver->m_zero) << "Zero-argument call made prematurely";
  EXPECT_FALSE(receiver->m_one) << "One-argument call made prematurely";
  EXPECT_TRUE(receiver->IsRunning()) << "Receiver is terminated";

  // Unblock:
  receiver->Proceed();

  // Now wait until all events are processed:
  receiver->Wait();

  // Validate deferred firing:
  EXPECT_TRUE(receiver->m_zero);
  EXPECT_TRUE(receiver->m_one);
  EXPECT_EQ(101, receiver->m_oneArg) << "Argument was not correctly propagated through a deferred call";
}

TEST_F(EventReceiverTest, NontrivialCopy) {
  static const size_t sc_numElems = 10;

  // Create the vector we're going to copy over:
  vector<int> ascending;
  for(size_t i = 0; i < sc_numElems; i++)
    ascending.push_back(i);

  // Deferred fire:
  sender->Defer(&CallableInterface::CopyVector)(ascending);
  sender->Defer(&CallableInterface::AllDone)();

  // Verify that nothing is hit yet:
  EXPECT_TRUE(receiver->m_myVec.empty()) << "Event handler invoked before barrier was hit; it should have been deferred";
  EXPECT_TRUE(receiver->IsRunning()) << "Receiver is terminated";

  // Unblock:
  receiver->Proceed();

  // Now wait until all events are processed:
  receiver->Wait();

  // Validate our vectors:
  ASSERT_EQ(10, receiver->m_myVec.size()) << "Receiver was not populated correctly with a vector";
  for(size_t i = 0; i < sc_numElems; i++)
    EXPECT_EQ(i, ascending[i]) << "Element at offset " << i << " was incorrectly copied";
}

TEST_F(EventReceiverTest, VerifyNoUnnecessaryCopies) {
  // Make our copy counter:
  CopyCounter ctr;

  // Verify the counter correctly tracks the number of times it was copied:
  {
    CopyCounter myCopy1 = ctr;
    ASSERT_EQ(1, myCopy1.m_count) << "Copy counter appears to be broken; cannot run test";

    CopyCounter myCopy2 = myCopy1;
    ASSERT_EQ(2, myCopy2.m_count) << "Secondary counter appears to be broken; cannot run test";

    CopyCounter myCopy3(std::move(myCopy2));
    ASSERT_EQ(2, myCopy3.m_count) << "Move ctor doesn't appear to be invoked correctly";

    // Try a move copy
    CopyCounter myCopy4;
    myCopy4 = std::move(myCopy3);
    ASSERT_EQ(2, myCopy4.m_count) << "Move assignment didn't correctly propagate the current count";
  }

  // Signal the barrier so we can quit:
  //receiver->Proceed();
}
<|endoftext|>


<commit_before>//=====================================================================//
/*! @file
    @brief  ファースト・サンプル（LED 点滅） @n
			※動作周波数は、RXxxx/clock_profile.hpp を参照。
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018, 2022 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/renesas.hpp"

namespace {

/// LED 接続ポートの定義
/// LED を「吸い込み：出力０で点灯させる場合」LED_ACTIVE = 0
/// LED を「吐き出し：出力１で点灯させる場合」LED_ACTIVE = 1
// Memo:
//    ポート出力は、電流を引いた（吸い込み）場合と、電流を掃き出した（吐き出し）場合で、能力が異なります。
//    一般的に、「吸い込み」の方が電流を多く流せる場合が多く、その慣例に従って、「吸い込み」で接続する場合が通例です。
#if defined(SIG_RX62N)
	static constexpr bool LED_ACTIVE = 0;
  #if defined(CQ_FRK)
    // FRK-RX62N(CQ 出版社)
	typedef device::PORT<device::PORT1, device::bitpos::B5, LED_ACTIVE> LED;
  #else
    // BlueBoard-RX62N_100pin
	typedef device::PORT<device::PORT0, device::bitpos::B5, LED_ACTIVE> LED;
  #endif
#elif defined(SIG_RX24T)
	// DIY RX24T board
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT0, device::bitpos::B0, LED_ACTIVE> LED;
#elif defined(SIG_RX71M)
	// DIY RX72M board
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT0, device::bitpos::B7, LED_ACTIVE> LED;
#elif defined(SIG_RX72M)
	// 工事中
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT0, device::bitpos::B7, LED_ACTIVE> LED;
#elif defined(SIG_RX72N)
	// RX72N Envision Kit
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT4, device::bitpos::B0, LED_ACTIVE> LED;
#elif defined(SIG_RX64M)
	// DIY RX64M board
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT0, device::bitpos::B7, LED_ACTIVE> LED;
#elif defined(SIG_RX65N)
	// RX65N Envision Kit
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT7, device::bitpos::B0, LED_ACTIVE> LED;
#elif defined(SIG_RX66T)
	// DIY RX66T board
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT0, device::bitpos::B0, LED_ACTIVE> LED;
#elif defined(SIG_RX72T)
	// DIY RX72T board
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT0, device::bitpos::B1, LED_ACTIVE> LED;
#endif
}

int main(int argc, char** argv);

int main(int argc, char** argv)
{
	SYSTEM_IO::boost_master_clock();

	LED::OUTPUT();  // LED ポートを出力に設定

	LED::P = 0;  // 消灯から開始

	while(1) {
#if 1
		utils::delay::milli_second(250);
		LED::P = 1;  // 点灯
		utils::delay::milli_second(250);
		LED::P = 0;  // 消灯
#else
		// 50KHz 出力
		utils::delay::micro_second(10);
		LED::FLIP();  // 反転
#endif
	}
}
<commit_msg>Update: add RX63T<commit_after>//=====================================================================//
/*! @file
    @brief  ファースト・サンプル（LED 点滅） @n
			※動作周波数は、RXxxx/clock_profile.hpp を参照。
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018, 2022 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/renesas.hpp"

namespace {

/// LED 接続ポートの定義
/// LED を「吸い込み：出力０で点灯させる場合」LED_ACTIVE = 0
/// LED を「吐き出し：出力１で点灯させる場合」LED_ACTIVE = 1
// Memo:
//    ポート出力は、電流を引いた（吸い込み）場合と、電流を掃き出した（吐き出し）場合で、能力が異なります。
//    一般的に、「吸い込み」の方が電流を多く流せる場合が多く、その慣例に従って、「吸い込み」で接続する場合が通例です。
#if defined(SIG_RX63T)
	// DIY RX63T board
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT0, device::bitpos::B0, LED_ACTIVE> LED;
#elif defined(SIG_RX62N)
	static constexpr bool LED_ACTIVE = 0;
  #if defined(CQ_FRK)
    // FRK-RX62N(CQ 出版社)
	typedef device::PORT<device::PORT1, device::bitpos::B5, LED_ACTIVE> LED;
  #else
    // BlueBoard-RX62N_100pin
	typedef device::PORT<device::PORT0, device::bitpos::B5, LED_ACTIVE> LED;
  #endif
#elif defined(SIG_RX24T)
	// DIY RX24T board
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT0, device::bitpos::B0, LED_ACTIVE> LED;
#elif defined(SIG_RX71M)
	// DIY RX72M board
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT0, device::bitpos::B7, LED_ACTIVE> LED;
#elif defined(SIG_RX72M)
	// 工事中
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT0, device::bitpos::B7, LED_ACTIVE> LED;
#elif defined(SIG_RX72N)
	// RX72N Envision Kit
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT4, device::bitpos::B0, LED_ACTIVE> LED;
#elif defined(SIG_RX64M)
	// DIY RX64M board
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT0, device::bitpos::B7, LED_ACTIVE> LED;
#elif defined(SIG_RX65N)
	// RX65N Envision Kit
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT7, device::bitpos::B0, LED_ACTIVE> LED;
#elif defined(SIG_RX66T)
	// DIY RX66T board
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT0, device::bitpos::B0, LED_ACTIVE> LED;
#elif defined(SIG_RX72T)
	// DIY RX72T board
	static constexpr bool LED_ACTIVE = 0;
	typedef device::PORT<device::PORT0, device::bitpos::B1, LED_ACTIVE> LED;
#endif
}

int main(int argc, char** argv);

int main(int argc, char** argv)
{
	SYSTEM_IO::boost_master_clock();

	LED::OUTPUT();  // LED ポートを出力に設定

	LED::P = 0;  // 消灯から開始

	while(1) {
#if 1
		utils::delay::milli_second(250);
		LED::P = 1;  // 点灯
		utils::delay::milli_second(250);
		LED::P = 0;  // 消灯
#else
		// 50KHz 出力
		utils::delay::micro_second(10);
		LED::FLIP();  // 反転
#endif
	}
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#include "ICUBridgeCollationCompareFunctorImpl.hpp"
#include "ICUBridge.hpp"

#include <algorithm>
#include <cstdlib>

#include <Include/XalanAutoPtr.hpp>

#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/XalanUnicode.hpp>

XALAN_CPP_NAMESPACE_BEGIN

const StylesheetExecutionContextDefault::DefaultCollationCompareFunctor		ICUBridgeCollationCompareFunctorImpl::s_defaultFunctor;

inline ICUBridgeCollationCompareFunctorImpl::CollatorType*
createCollator(
			UErrorCode&			theStatus,
			const Locale&		theLocale,
			XalanDOMString*		theLocaleName = 0)
{
	typedef ICUBridgeCollationCompareFunctorImpl::CollatorType	CollatorType;

	if (theLocaleName != 0)
	{
		*theLocaleName = theLocale.getName();

		// Replace _ with -, since that's what xml:lang specifies...
		XalanDOMString::size_type	theIndex;

		while((theIndex = indexOf(*theLocaleName, XalanUnicode::charLowLine)) != theLocaleName->length())
		{
			(*theLocaleName)[theIndex] = XalanUnicode::charHyphenMinus;
		}
	}

	return CollatorType::createInstance(theLocale, theStatus);
}

inline ICUBridgeCollationCompareFunctorImpl::CollatorType*
createCollator(
			UErrorCode&			theStatus,
			XalanDOMString*		theLocaleName = 0)
{
	const char*		theLang =
#if defined(XALAN_STRICT_ANSI_HEADERS)
			std::getenv("LANG");
#else
			getenv("LANG");
#endif

	if (theLang == 0)
	{
#if defined(XALAN_ICU_DEFAULT_LOCALE_PROBLEM)
		return createCollator(theStatus, Locale::US, theLocaleName);
#else
		return createCollator(theStatus, Locale::getDefault(), theLocaleName);
#endif
	}
	else
	{
		return createCollator(theStatus, Locale(theLang), theLocaleName);
	}
}

ICUBridgeCollationCompareFunctorImpl::ICUBridgeCollationCompareFunctorImpl(bool		fCacheCollators) :
	m_isValid(false),
	m_defaultCollator(0),
	m_defaultCollatorLocaleName(),
	m_cacheCollators(fCacheCollators),
	m_collatorCache()
{
	UErrorCode	theStatus = U_ZERO_ERROR;

	m_defaultCollator = createCollator(theStatus, &m_defaultCollatorLocaleName);

	if (U_SUCCESS(theStatus))
	{
		m_isValid = true;
	}
}

ICUBridgeCollationCompareFunctorImpl::~ICUBridgeCollationCompareFunctorImpl()
{
	XALAN_USING_STD(for_each)

	delete m_defaultCollator;

	for_each(
			m_collatorCache.begin(),
			m_collatorCache.end(),
			CollationCacheStruct::CollatorDeleteFunctor());
}

int
ICUBridgeCollationCompareFunctorImpl::doCompare(
			const CollatorType&		theCollator,
			const XalanDOMChar*		theLHS,
			const XalanDOMChar*		theRHS) const
{
#if defined(XALAN_USE_WCHAR_CAST_HACK) && defined(U_WCHAR_IS_UTF16)
	return theCollator.compare(
				(const wchar_t*)theLHS,
				length(theLHS),
				(const wchar_t*)theRHS,
				length(theRHS));
#else
	return theCollator.compare(
				theLHS,
				length(theLHS),
				theRHS,
				length(theRHS));
#endif
}

inline UColAttributeValue
caseOrderConvert(ICUBridgeCollationCompareFunctorImpl::eCaseOrder	theCaseOrder)
{
	switch(theCaseOrder)
	{
	case StylesheetExecutionContext::eLowerFirst:
		return UCOL_LOWER_FIRST;
		break;

	case StylesheetExecutionContext::eUpperFirst:
		return UCOL_UPPER_FIRST;
		break;

	case StylesheetExecutionContext::eDefault:
		break;

	default:
		assert(false);
		break;
	}

	return UCOL_DEFAULT;
}

int
ICUBridgeCollationCompareFunctorImpl::doDefaultCompare(
			const XalanDOMChar*		theLHS,
			const XalanDOMChar*		theRHS) const
{
	if (isValid() == false)
	{
		return s_defaultFunctor(theLHS, theRHS, StylesheetExecutionContext::eDefault);
	}
	else
	{
		assert(m_defaultCollator != 0);

		return doCompare(*m_defaultCollator, theLHS, theRHS);
	}
}

inline ICUBridgeCollationCompareFunctorImpl::CollatorType*
createCollator(
			const XalanDOMChar*		theLocale,
			UErrorCode&				theStatus)
{
	assert(theLocale != 0);

	const XalanDOMString::size_type		theLength = length(theLocale);

	if (theLength >= ULOC_FULLNAME_CAPACITY)
	{
		theStatus = U_ILLEGAL_ARGUMENT_ERROR;

		return 0;
	}
	else
	{
#if defined(XALAN_NON_ASCII_PLATFORM)
		CharVectorType	theVector;

		TranscodeToLocalCodePage(theLocale, theVector, true);

		const char* const	theBuffer = c_str(theVector);
#else
		char	theBuffer[ULOC_FULLNAME_CAPACITY];

		// Since language names must be ASCII, this
		// is the cheapest way to "transcode"...
		for (unsigned int i = 0; i <= theLength; ++i)
		{
			theBuffer[i] = char(theLocale[i]);
		}
#endif
		return ICUBridgeCollationCompareFunctorImpl::CollatorType::createInstance(
					Locale::createFromName(theBuffer),
					theStatus);
	}
}

int
ICUBridgeCollationCompareFunctorImpl::doCompare(
			const XalanDOMChar*		theLHS,
			const XalanDOMChar*		theRHS,
			const XalanDOMChar*		theLocale,
			eCaseOrder				theCaseOrder) const
{
	UErrorCode	theStatus = U_ZERO_ERROR;

	XalanAutoPtr<CollatorType>	theCollator(createCollator(theLocale, theStatus));

	if (U_SUCCESS(theStatus))
	{
		assert(theCollator.get() != 0);

		return doCompare(
				*theCollator.get(),
				theLHS,
				theRHS,
				theCaseOrder);
	}
	else
	{
		return s_defaultFunctor(theLHS, theRHS, theCaseOrder);
	}
}

int
ICUBridgeCollationCompareFunctorImpl::doCompareCached(
			const XalanDOMChar*		theLHS,
			const XalanDOMChar*		theRHS,
			const XalanDOMChar*		theLocale,
			eCaseOrder				theCaseOrder) const
{
	CollatorType*	theCollator = getCachedCollator(theLocale);

	if (theCollator != 0)
	{
		return doCompare(*theCollator, theLHS, theRHS, theCaseOrder);
	}
	else
	{
		UErrorCode	theStatus = U_ZERO_ERROR;

		XalanAutoPtr<CollatorType>	theCollatorGuard(createCollator(theLocale, theStatus));

		if (U_SUCCESS(theStatus))
		{
			assert(theCollatorGuard.get() != 0);

			// OK, there was no error, so cache the instance...
			cacheCollator(theCollatorGuard.get(), theLocale);

			// Release the collator, since it's in the cache and
			// will be controlled by the cache...
			theCollator = theCollatorGuard.release();

			return doCompare(
					*theCollator,
					theLHS,
					theRHS,
					theCaseOrder);
		}
		else
		{
			return s_defaultFunctor(theLHS, theRHS, theCaseOrder);
		}
	}
}

int
ICUBridgeCollationCompareFunctorImpl::doCompare(
			CollatorType&			theCollator,
			const XalanDOMChar*		theLHS,
			const XalanDOMChar*		theRHS,
			eCaseOrder				theCaseOrder) const
{
	UErrorCode	theStatus = U_ZERO_ERROR;

	theCollator.setAttribute(
				UCOL_CASE_FIRST,
				caseOrderConvert(theCaseOrder),
				theStatus);

#if defined(XALAN_USE_WCHAR_CAST_HACK) && defined(U_WCHAR_IS_UTF16)
	return theCollator.compare(
					(const wchar_t*)theLHS,
					length(theLHS),
					(const wchar_t*)theRHS,
					length(theRHS));
#else
	return theCollator.compare(
					theLHS,
					length(theLHS),
					theRHS,
					length(theRHS));
#endif
}

int
ICUBridgeCollationCompareFunctorImpl::operator()(
			const XalanDOMChar*		theLHS,
			const XalanDOMChar*		theRHS,
			eCaseOrder				theCaseOrder) const
{
	if (theCaseOrder == StylesheetExecutionContext::eDefault)
	{
		return doDefaultCompare(theLHS, theRHS);
	}
	else
	{
		return doCompare(
				theLHS,
				theRHS,
				c_wstr(m_defaultCollatorLocaleName),
				theCaseOrder);
	}
}

int
ICUBridgeCollationCompareFunctorImpl::operator()(
			const XalanDOMChar*		theLHS,
			const XalanDOMChar*		theRHS,
			const XalanDOMChar*		theLocale,
			eCaseOrder				theCaseOrder) const
{
	if (theCaseOrder == StylesheetExecutionContext::eDefault &&
		XalanDOMString::equals(m_defaultCollatorLocaleName, theLocale) == true)
	{
		return doDefaultCompare(theLHS, theRHS);
	}
	else if (m_cacheCollators == true)
	{
		return doCompareCached(theLHS, theRHS, theLocale, theCaseOrder);
	}
	else
	{
		return doCompare(theLHS, theRHS, theLocale, theCaseOrder);
	};
}

ICUBridgeCollationCompareFunctorImpl::CollatorType*
ICUBridgeCollationCompareFunctorImpl::getCachedCollator(const XalanDOMChar*		theLocale) const
{
	XALAN_USING_STD(find_if)

	CollatorCacheListType&		theNonConstCache =
#if defined(XALAN_NO_MUTABLE)
		(CollatorCacheListType*)m_collatorCache;
#else
		m_collatorCache;
#endif

	CollatorCacheListType::iterator	i =
		find_if(
			theNonConstCache.begin(),
			theNonConstCache.end(),
			CollationCacheStruct::CollatorFindFunctor(theLocale));

	if (i == theNonConstCache.end())
	{
		return 0;
	}
	else
	{
		// Let's do a quick check to see if we found the first entry.
		// If so, we don't have to update the cache, so just return the
		// appropriate value...
		const CollatorCacheListType::iterator	theBegin =
			theNonConstCache.begin();

		if (i == theBegin)
		{
			return (*i).m_collator;
		}
		else
		{
			// Save the collator, because splice() may invalidate
			// i.
			CollatorType* const		theCollator = (*i).m_collator;

			// Move the entry to the beginning the cache
			theNonConstCache.splice(theBegin, theNonConstCache, i);

			return theCollator;
		}
	}
}

void
ICUBridgeCollationCompareFunctorImpl::cacheCollator(
			CollatorType*			theCollator,
			const XalanDOMChar*		theLocale) const
{
	assert(theCollator != 0);
	assert(theLocale != 0);

	CollatorCacheListType&		theNonConstCache =
#if defined(XALAN_NO_MUTABLE)
		(CollatorCacheListType*)m_collatorCache;
#else
		m_collatorCache;
#endif

	// Is the cache full?
	if (theNonConstCache.size() == eCacheMax)
	{
		// Yes, so guard the collator instance, in case pop_back() throws...
		XalanAutoPtr<CollatorType>	theCollatorGuard(theNonConstCache.back().m_collator);

		theNonConstCache.pop_back();
	}

	theNonConstCache.push_front(CollatorCacheListType::value_type());

	CollatorCacheListType::value_type&		theEntry =
		theNonConstCache.front();

	// Set the locale first, since that might throw an exception...
	theEntry.m_locale = theLocale;

	theEntry.m_collator = theCollator;
}

XALAN_CPP_NAMESPACE_END
<commit_msg>Removed reference to ICU #define.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#include "ICUBridgeCollationCompareFunctorImpl.hpp"
#include "ICUBridge.hpp"

#include <algorithm>
#include <cstdlib>

#include <Include/XalanAutoPtr.hpp>

#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/XalanUnicode.hpp>

XALAN_CPP_NAMESPACE_BEGIN

const StylesheetExecutionContextDefault::DefaultCollationCompareFunctor		ICUBridgeCollationCompareFunctorImpl::s_defaultFunctor;

inline ICUBridgeCollationCompareFunctorImpl::CollatorType*
createCollator(
			UErrorCode&			theStatus,
			const Locale&		theLocale,
			XalanDOMString*		theLocaleName = 0)
{
	typedef ICUBridgeCollationCompareFunctorImpl::CollatorType	CollatorType;

	if (theLocaleName != 0)
	{
		*theLocaleName = theLocale.getName();

		// Replace _ with -, since that's what xml:lang specifies...
		XalanDOMString::size_type	theIndex;

		while((theIndex = indexOf(*theLocaleName, XalanUnicode::charLowLine)) != theLocaleName->length())
		{
			(*theLocaleName)[theIndex] = XalanUnicode::charHyphenMinus;
		}
	}

	return CollatorType::createInstance(theLocale, theStatus);
}

inline ICUBridgeCollationCompareFunctorImpl::CollatorType*
createCollator(
			UErrorCode&			theStatus,
			XalanDOMString*		theLocaleName = 0)
{
	const char*		theLang =
#if defined(XALAN_STRICT_ANSI_HEADERS)
			std::getenv("LANG");
#else
			getenv("LANG");
#endif

	if (theLang == 0)
	{
#if defined(XALAN_ICU_DEFAULT_LOCALE_PROBLEM)
		return createCollator(theStatus, Locale::US, theLocaleName);
#else
		return createCollator(theStatus, Locale::getDefault(), theLocaleName);
#endif
	}
	else
	{
		return createCollator(theStatus, Locale(theLang), theLocaleName);
	}
}

ICUBridgeCollationCompareFunctorImpl::ICUBridgeCollationCompareFunctorImpl(bool		fCacheCollators) :
	m_isValid(false),
	m_defaultCollator(0),
	m_defaultCollatorLocaleName(),
	m_cacheCollators(fCacheCollators),
	m_collatorCache()
{
	UErrorCode	theStatus = U_ZERO_ERROR;

	m_defaultCollator = createCollator(theStatus, &m_defaultCollatorLocaleName);

	if (U_SUCCESS(theStatus))
	{
		m_isValid = true;
	}
}

ICUBridgeCollationCompareFunctorImpl::~ICUBridgeCollationCompareFunctorImpl()
{
	XALAN_USING_STD(for_each)

	delete m_defaultCollator;

	for_each(
			m_collatorCache.begin(),
			m_collatorCache.end(),
			CollationCacheStruct::CollatorDeleteFunctor());
}

int
ICUBridgeCollationCompareFunctorImpl::doCompare(
			const CollatorType&		theCollator,
			const XalanDOMChar*		theLHS,
			const XalanDOMChar*		theRHS) const
{
#if defined(XALAN_USE_WCHAR_CAST_HACK)
	return theCollator.compare(
				(const wchar_t*)theLHS,
				length(theLHS),
				(const wchar_t*)theRHS,
				length(theRHS));
#else
	return theCollator.compare(
				theLHS,
				length(theLHS),
				theRHS,
				length(theRHS));
#endif
}

inline UColAttributeValue
caseOrderConvert(ICUBridgeCollationCompareFunctorImpl::eCaseOrder	theCaseOrder)
{
	switch(theCaseOrder)
	{
	case StylesheetExecutionContext::eLowerFirst:
		return UCOL_LOWER_FIRST;
		break;

	case StylesheetExecutionContext::eUpperFirst:
		return UCOL_UPPER_FIRST;
		break;

	case StylesheetExecutionContext::eDefault:
		break;

	default:
		assert(false);
		break;
	}

	return UCOL_DEFAULT;
}

int
ICUBridgeCollationCompareFunctorImpl::doDefaultCompare(
			const XalanDOMChar*		theLHS,
			const XalanDOMChar*		theRHS) const
{
	if (isValid() == false)
	{
		return s_defaultFunctor(theLHS, theRHS, StylesheetExecutionContext::eDefault);
	}
	else
	{
		assert(m_defaultCollator != 0);

		return doCompare(*m_defaultCollator, theLHS, theRHS);
	}
}

inline ICUBridgeCollationCompareFunctorImpl::CollatorType*
createCollator(
			const XalanDOMChar*		theLocale,
			UErrorCode&				theStatus)
{
	assert(theLocale != 0);

	const XalanDOMString::size_type		theLength = length(theLocale);

	if (theLength >= ULOC_FULLNAME_CAPACITY)
	{
		theStatus = U_ILLEGAL_ARGUMENT_ERROR;

		return 0;
	}
	else
	{
#if defined(XALAN_NON_ASCII_PLATFORM)
		CharVectorType	theVector;

		TranscodeToLocalCodePage(theLocale, theVector, true);

		const char* const	theBuffer = c_str(theVector);
#else
		char	theBuffer[ULOC_FULLNAME_CAPACITY];

		// Since language names must be ASCII, this
		// is the cheapest way to "transcode"...
		for (unsigned int i = 0; i <= theLength; ++i)
		{
			theBuffer[i] = char(theLocale[i]);
		}
#endif
		return ICUBridgeCollationCompareFunctorImpl::CollatorType::createInstance(
					Locale::createFromName(theBuffer),
					theStatus);
	}
}

int
ICUBridgeCollationCompareFunctorImpl::doCompare(
			const XalanDOMChar*		theLHS,
			const XalanDOMChar*		theRHS,
			const XalanDOMChar*		theLocale,
			eCaseOrder				theCaseOrder) const
{
	UErrorCode	theStatus = U_ZERO_ERROR;

	XalanAutoPtr<CollatorType>	theCollator(createCollator(theLocale, theStatus));

	if (U_SUCCESS(theStatus))
	{
		assert(theCollator.get() != 0);

		return doCompare(
				*theCollator.get(),
				theLHS,
				theRHS,
				theCaseOrder);
	}
	else
	{
		return s_defaultFunctor(theLHS, theRHS, theCaseOrder);
	}
}

int
ICUBridgeCollationCompareFunctorImpl::doCompareCached(
			const XalanDOMChar*		theLHS,
			const XalanDOMChar*		theRHS,
			const XalanDOMChar*		theLocale,
			eCaseOrder				theCaseOrder) const
{
	CollatorType*	theCollator = getCachedCollator(theLocale);

	if (theCollator != 0)
	{
		return doCompare(*theCollator, theLHS, theRHS, theCaseOrder);
	}
	else
	{
		UErrorCode	theStatus = U_ZERO_ERROR;

		XalanAutoPtr<CollatorType>	theCollatorGuard(createCollator(theLocale, theStatus));

		if (U_SUCCESS(theStatus))
		{
			assert(theCollatorGuard.get() != 0);

			// OK, there was no error, so cache the instance...
			cacheCollator(theCollatorGuard.get(), theLocale);

			// Release the collator, since it's in the cache and
			// will be controlled by the cache...
			theCollator = theCollatorGuard.release();

			return doCompare(
					*theCollator,
					theLHS,
					theRHS,
					theCaseOrder);
		}
		else
		{
			return s_defaultFunctor(theLHS, theRHS, theCaseOrder);
		}
	}
}

int
ICUBridgeCollationCompareFunctorImpl::doCompare(
			CollatorType&			theCollator,
			const XalanDOMChar*		theLHS,
			const XalanDOMChar*		theRHS,
			eCaseOrder				theCaseOrder) const
{
	UErrorCode	theStatus = U_ZERO_ERROR;

	theCollator.setAttribute(
				UCOL_CASE_FIRST,
				caseOrderConvert(theCaseOrder),
				theStatus);

#if defined(XALAN_USE_WCHAR_CAST_HACK)
	return theCollator.compare(
					(const wchar_t*)theLHS,
					length(theLHS),
					(const wchar_t*)theRHS,
					length(theRHS));
#else
	return theCollator.compare(
					theLHS,
					length(theLHS),
					theRHS,
					length(theRHS));
#endif
}

int
ICUBridgeCollationCompareFunctorImpl::operator()(
			const XalanDOMChar*		theLHS,
			const XalanDOMChar*		theRHS,
			eCaseOrder				theCaseOrder) const
{
	if (theCaseOrder == StylesheetExecutionContext::eDefault)
	{
		return doDefaultCompare(theLHS, theRHS);
	}
	else
	{
		return doCompare(
				theLHS,
				theRHS,
				c_wstr(m_defaultCollatorLocaleName),
				theCaseOrder);
	}
}

int
ICUBridgeCollationCompareFunctorImpl::operator()(
			const XalanDOMChar*		theLHS,
			const XalanDOMChar*		theRHS,
			const XalanDOMChar*		theLocale,
			eCaseOrder				theCaseOrder) const
{
	if (theCaseOrder == StylesheetExecutionContext::eDefault &&
		XalanDOMString::equals(m_defaultCollatorLocaleName, theLocale) == true)
	{
		return doDefaultCompare(theLHS, theRHS);
	}
	else if (m_cacheCollators == true)
	{
		return doCompareCached(theLHS, theRHS, theLocale, theCaseOrder);
	}
	else
	{
		return doCompare(theLHS, theRHS, theLocale, theCaseOrder);
	};
}

ICUBridgeCollationCompareFunctorImpl::CollatorType*
ICUBridgeCollationCompareFunctorImpl::getCachedCollator(const XalanDOMChar*		theLocale) const
{
	XALAN_USING_STD(find_if)

	CollatorCacheListType&		theNonConstCache =
#if defined(XALAN_NO_MUTABLE)
		(CollatorCacheListType*)m_collatorCache;
#else
		m_collatorCache;
#endif

	CollatorCacheListType::iterator	i =
		find_if(
			theNonConstCache.begin(),
			theNonConstCache.end(),
			CollationCacheStruct::CollatorFindFunctor(theLocale));

	if (i == theNonConstCache.end())
	{
		return 0;
	}
	else
	{
		// Let's do a quick check to see if we found the first entry.
		// If so, we don't have to update the cache, so just return the
		// appropriate value...
		const CollatorCacheListType::iterator	theBegin =
			theNonConstCache.begin();

		if (i == theBegin)
		{
			return (*i).m_collator;
		}
		else
		{
			// Save the collator, because splice() may invalidate
			// i.
			CollatorType* const		theCollator = (*i).m_collator;

			// Move the entry to the beginning the cache
			theNonConstCache.splice(theBegin, theNonConstCache, i);

			return theCollator;
		}
	}
}

void
ICUBridgeCollationCompareFunctorImpl::cacheCollator(
			CollatorType*			theCollator,
			const XalanDOMChar*		theLocale) const
{
	assert(theCollator != 0);
	assert(theLocale != 0);

	CollatorCacheListType&		theNonConstCache =
#if defined(XALAN_NO_MUTABLE)
		(CollatorCacheListType*)m_collatorCache;
#else
		m_collatorCache;
#endif

	// Is the cache full?
	if (theNonConstCache.size() == eCacheMax)
	{
		// Yes, so guard the collator instance, in case pop_back() throws...
		XalanAutoPtr<CollatorType>	theCollatorGuard(theNonConstCache.back().m_collator);

		theNonConstCache.pop_back();
	}

	theNonConstCache.push_front(CollatorCacheListType::value_type());

	CollatorCacheListType::value_type&		theEntry =
		theNonConstCache.front();

	// Set the locale first, since that might throw an exception...
	theEntry.m_locale = theLocale;

	theEntry.m_collator = theCollator;
}

XALAN_CPP_NAMESPACE_END
<|endoftext|>


<commit_before>#include <Bull/Core/IO/TextWriter.hpp>

namespace Bull
{
    TextWriter::TextWriter(OutStream& stream) :
        m_stream(stream)
    {
        /// Nothing
    }

    void TextWriter::write(const String& line)
    {
        m_stream.write(ByteArray::memoryCopy(line.getBuffer(), line.getSize()));
    }

    void TextWriter::writeLine(const String& line)
    {
        write(line + '\n');
    }

    TextWriter& TextWriter::operator<<(const char* string)
    {
        write(string);

        return *this;
    }

    TextWriter& TextWriter::operator<<(const String& string)
    {
        write(string);

        return *this;
    }
}<commit_msg>[Core/TextWriter] Use ByteArray::fromString instead of ByteArray::memoryCopy<commit_after>#include <Bull/Core/IO/TextWriter.hpp>

namespace Bull
{
    TextWriter::TextWriter(OutStream& stream) :
        m_stream(stream)
    {
        /// Nothing
    }

    void TextWriter::write(const String& string)
    {
        m_stream.write(ByteArray::fromString(string));
    }

    void TextWriter::writeLine(const String& line)
    {
        write(line + '\n');
    }

    TextWriter& TextWriter::operator<<(const char* string)
    {
        write(string);

        return *this;
    }

    TextWriter& TextWriter::operator<<(const String& string)
    {
        write(string);

        return *this;
    }
}<|endoftext|>