<commit_before>// THIS FILE IS AUTO GENERATED, EDIT AT YOUR OWN RISK
//%L
#include "{{files['declaration']}}"
#include "{{files['entities']}}"
#include <tuple>
//%L
#define myoffsetof(st, m) static_cast<int>((size_t)(&((st *)0)->m))
//%L
// /////////// //
// Base entity //
// /////////// //
//%L
// Base entity constructor.
Entity::Entity(const MessageHandler *messageHandlers, const int* componentOffsets{% for attrib in general.common_entity_attributes %}, {{attrib.get_declaration()}}{% endfor %})
	: messageHandlers(messageHandlers), componentOffsets(componentOffsets){% for attrib in general.common_entity_attributes %}, {{attrib.get_initializer()}}{% endfor %}
{}
//%L
// Base entity deconstructor.
Entity::~Entity()
{}
//%L
// Base entity's message dispatcher.
bool Entity::SendMessage(int msg, const void* data) {
	MessageHandler handler = messageHandlers[msg];
	if (handler) {
		handler(this, data);
		return true;
	}
	return false;
}
//%L
// /////////////// //
// Message helpers //
// /////////////// //
//%L
{% for message in messages %}
bool Entity::{{message.name}}({{message.get_function_args()}}) {
	{% if message.get_num_args() == 0 %}
	return SendMessage({{message.get_enum_name()}}, nullptr);
	{% else %}
	{{message.get_tuple_type()}} data({{message.get_args_names()}});
	return SendMessage({{message.get_enum_name()}}, &data);
	{% endif %}
}
//%L
{% endfor %}
// ////////////////////// //
// Entity implementations //
// ////////////////////// //
//%L
{% for entity in entities %}
// {{entity.get_type_name()}}'s component offset vtable.
//* TODO: doesn't handle component inheritance?
const int {{entity.get_type_name()}}::componentOffsets[] = {
	{% for component in components %}
	{% if component in entity.get_components() %}
	myoffsetof({{entity.get_type_name()}}, {{component.get_variable_name()}}),
	{% else %}
	0,
	{% endif %}
	{% endfor %}
};
//%L
{% for message in entity.get_messages_to_handle() %}
// {{entity.get_type_name()}}'s {{message.get_name()}} message dispatcher.
void {{entity.get_message_handler_name(message)}}(Entity* _entity, const void* {% if message.get_num_args() > 0 %} _data{% endif %}) {
	//* Cast the entity to the correct type (receive an Entity*)
	{{entity.get_type_name()}}* entity = ({{entity.get_type_name()}}*) _entity;
	//%L
	{% if message.get_num_args() == 0 %}
	//* No argument for the message, just call the handlers of all the components
	{% for component in entity.get_components() %}
	{% if message in component.get_messages_to_handle() %}
	entity->{{component.get_variable_name()}}.{{message.get_handler_name()}}();
	{% endif %}
	{% endfor %}
	{% else %}
	//* Cast the message content to the right type (receive a const void*)
	const {{message.get_tuple_type()}}* data = (const {{message.get_tuple_type()}}*) _data;
	{% for component in entity.get_components() %}
	{% if message in component.get_messages_to_handle() %}
	entity->{{component.get_variable_name()}}.{{message.get_handler_name()}}({{message.get_unpacked_tuple_args('*data')}});
	{% endif %}
	{% endfor %}
	{% endif %}
}
//%L
{% endfor%}
// {{entity.get_type_name()}}'s message dispatcher vtable.
const MessageHandler {{entity.get_type_name()}}::messageHandlers[] = {
	{% for message in messages %}
	{% if message in entity.get_messages_to_handle() %}
	{{entity.get_message_handler_name(message)}},
	{% else %}
	nullptr,
	{% endif %}
	{% endfor%}
};
//%L
// {{entity.get_type_name()}}'s constructor.
{{entity.get_type_name()}}::{{entity.get_type_name()}}({% for (i, attrib) in enumerate(general.common_entity_attributes) %}{% if i != 0 %}, {% endif %} {{attrib.get_declaration()}}{% endfor %})
	: Entity(messageHandlers, componentOffsets{% for attrib in general.common_entity_attributes %}, {{attrib.get_name()}}{% endfor %})
	{% for component in entity.get_components() %}
	, {{component.get_variable_name()}}(*this{% for param in component.get_param_names() %}, {{entity.get_params()[component.name][param]}}{% endfor %}{% for required in component.get_required_components() %}, *{{required.get_variable_name()}}{% endfor %}){% endfor %}
{}
//%L
// {{entity.get_type_name()}}'s deconstructor.
//* Destroys all the components in reverse order.
{{entity.get_type_name()}}::~{{entity.get_type_name()}}()
{}
{% endfor %}
//%L
#undef myoffsetof

<commit_msg>Improve formatting in Components.cpp template file a bit.<commit_after>// THIS FILE IS AUTO GENERATED, EDIT AT YOUR OWN RISK
//%L
#include "{{files['declaration']}}"
#include "{{files['entities']}}"
#include <tuple>
//%L
#define myoffsetof(st, m) static_cast<int>((size_t)(&((st *)0)->m))
//%L
// /////////// //
// Base entity //
// /////////// //
//%L
// Base entity constructor.
Entity::Entity(const MessageHandler *messageHandlers, const int* componentOffsets
{%- for attrib in general.common_entity_attributes -%}
	, {{attrib.get_declaration()}}
{%- endfor -%})
	: messageHandlers(messageHandlers), componentOffsets(componentOffsets)
{%- for attrib in general.common_entity_attributes -%}
	, {{attrib.get_initializer()}}
{%- endfor %}
{}
//%L
// Base entity deconstructor.
Entity::~Entity()
{}
//%L
// Base entity's message dispatcher.
bool Entity::SendMessage(int msg, const void* data) {
	MessageHandler handler = messageHandlers[msg];
	if (handler) {
		handler(this, data);
		return true;
	}
	return false;
}
//%L
// /////////////// //
// Message helpers //
// /////////////// //
//%L
{% for message in messages %}
bool Entity::{{message.name}}({{message.get_function_args()}}) {
{% if message.get_num_args() == 0 %}
	return SendMessage({{message.get_enum_name()}}, nullptr);
{% else %}
	{{message.get_tuple_type()}} data({{message.get_args_names()}});
	return SendMessage({{message.get_enum_name()}}, &data);
{% endif %}
}
//%L
{% endfor %}
// ////////////////////// //
// Entity implementations //
// ////////////////////// //
//%L
{% for entity in entities %}
// {{entity.get_type_name()}}'s component offset vtable.
//* TODO: doesn't handle component inheritance?
const int {{entity.get_type_name()}}::componentOffsets[] = {
{% for component in components %}
{% if component in entity.get_components() %}
	myoffsetof({{entity.get_type_name()}}, {{component.get_variable_name()}}),
{% else %}
	0,
{% endif %}
{% endfor %}
};
//%L
{% for message in entity.get_messages_to_handle() %}
// {{entity.get_type_name()}}'s {{message.get_name()}} message dispatcher.
void {{entity.get_message_handler_name(message)}}(Entity* _entity, const void* {% if message.get_num_args() > 0 %} _data{% endif %}) {
	//* Cast the entity to the correct type (receive an Entity*)
	{{entity.get_type_name()}}* entity = ({{entity.get_type_name()}}*) _entity;
{% if message.get_num_args() == 0 %}
{% for component in entity.get_components() %}
{% if message in component.get_messages_to_handle() %}
	//* No argument for the message, just call the handlers of all the components
	entity->{{component.get_variable_name()}}.{{message.get_handler_name()}}();
{% endif %}
{% endfor %}
{% else %}
	//* Cast the message content to the right type (receive a const void*)
	const {{message.get_tuple_type()}}* data = (const {{message.get_tuple_type()}}*) _data;
{% for component in entity.get_components() %}
{% if message in component.get_messages_to_handle() %}
	entity->{{component.get_variable_name()}}.{{message.get_handler_name()}}({{message.get_unpacked_tuple_args('*data')}});
{% endif %}
{% endfor %}
{% endif %}
}
//%L
{% endfor%}
// {{entity.get_type_name()}}'s message dispatcher vtable.
const MessageHandler {{entity.get_type_name()}}::messageHandlers[] = {
{% for message in messages %}
{% if message in entity.get_messages_to_handle() %}
	{{entity.get_message_handler_name(message)}},
{% else %}
	nullptr,
{% endif %}
{% endfor%}
};
//%L
// {{entity.get_type_name()}}'s constructor.
{{entity.get_type_name()}}::{{entity.get_type_name()}}(
{%- for (i, attrib) in enumerate(general.common_entity_attributes) -%}
{%- if i != 0 -%}, {%- endif -%}
	{{attrib.get_declaration()}}
{%- endfor -%})
	: Entity(messageHandlers, componentOffsets
{%- for attrib in general.common_entity_attributes -%}
	, {{attrib.get_name()}}
{%- endfor -%})
{%- for component in entity.get_components() %}
	, {{component.get_variable_name()}}(*this
{%- for param in component.get_param_names() -%}
	, {{entity.get_params()[component.name][param]}}
{%- endfor -%}
{%- for required in component.get_required_components() -%}
	, *{{required.get_variable_name()}}
{%- endfor -%})
{%- endfor %}
{}
//%L
// {{entity.get_type_name()}}'s deconstructor.
//* Destroys all the components in reverse order.
{{entity.get_type_name()}}::~{{entity.get_type_name()}}()
{}
{% endfor %}
//%L
#undef myoffsetof

//* vi:ts=4:ai:filetype=jinja:
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#ifndef INCLUDED_SD_SOURCE_UI_FRAMEWORK_CONFIGURATION_CONFIGURATIONCLASSIFIER_HXX
#define INCLUDED_SD_SOURCE_UI_FRAMEWORK_CONFIGURATION_CONFIGURATIONCLASSIFIER_HXX

#include <com/sun/star/drawing/framework/XConfiguration.hpp>

#include <vector>

namespace sd { namespace framework {

/** A ConfigurationClassifier object compares two configurations of
    resources and gives access to the differences.  It is used mainly when
    changes to the current configuration have been requested and the various
    resource controllers have to be supplied with the set of resources that
    are to be activated or deactivated.
*/
class ConfigurationClassifier
{
public:
    /** Create a new ConfigurationClassifier object that will compare the
        two given configurations.
    */
    ConfigurationClassifier (
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::drawing::framework::XConfiguration>& rxConfiguration1,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::drawing::framework::XConfiguration>& rxConfiguration2);

    /** Calculate three lists of resource ids.  These contain the resources
        that belong to one configuration but not the other, or that belong
        to both configurations.
        @return
            When the two configurations differ then return <TRUE/>.  When
            they are equivalent then return <FALSE/>.
    */
    bool Partition (void);

    typedef ::std::vector<com::sun::star::uno::Reference<
        ::com::sun::star::drawing::framework::XResourceId> > ResourceIdVector;

    /** Return the resources that belong to the configuration given as
        rxConfiguration1 to the constructor but that do not belong to
        rxConfiguration2.
        @return
            A reference to the, possibly empty, list of resources is
            returned.  This reference remains valid as long as the called
            ConfigurationClassifier object stays alive.
    */
    const ResourceIdVector& GetC1minusC2 (void) const;

    /** Return the resources that belong to the configuration given as
        rxConfiguration2 to the constructor but that do not belong to
        rxConfiguration1.
        @return
            A reference to the, possibly empty, list of resources is
            returned.  This reference remains valid as long as the called
            ConfigurationClassifier object stays alive.
    */
    const ResourceIdVector& GetC2minusC1 (void) const;

    /** Return the resources that belong to both the configurations that
        where given to the constructor.
        @return
            A reference to the, possibly empty, list of resources is
            returned.  This reference remains valid as long as the called
            ConfigurationClassifier object stays alive.
    */
    const ResourceIdVector& GetC1andC2 (void) const;

    void TraceResourceIdVector (
        const sal_Char* pMessage,
        const ResourceIdVector& rResources) const;

private:
    ::com::sun::star::uno::Reference<
        ::com::sun::star::drawing::framework::XConfiguration> mxConfiguration1;
    ::com::sun::star::uno::Reference<
        ::com::sun::star::drawing::framework::XConfiguration> mxConfiguration2;

    /** After the call to Classify() this vector holds all elements from
        mxConfiguration1 that are not in mxConfiguration2.
    */
    ResourceIdVector maC1minusC2;

    /** After the call to Classify() this vector holds all elements from
        mxConfiguration2 that are not in mxConfiguration1.
    */
    ResourceIdVector maC2minusC1;

    /** After the call to Classify() this vector holds all elements that are
        member both of mxConfiguration1 and mxConfiguration2.
    */
    ResourceIdVector maC1andC2;

    /** Put all the elements in the two gven sequences of resource ids and
        copy them into one of the resource id result vectors maC1minusC2,
        maC2minusC1, and maC1andC2.  This is done by using only the resource
        URLs for classification.  Therefor this method calls itself
        recursively.
        @param rS1
            One sequence of XResourceId objects.
        @param rS2
            Another sequence of XResourceId objects.
    */
    void PartitionResources (
        const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::Reference<
                ::com::sun::star::drawing::framework::XResourceId> >& rS1,
        const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::Reference<
                ::com::sun::star::drawing::framework::XResourceId> >& rS2);

    /** Compare the given sequences of resource ids and put their elements
        in one of three vectors depending on whether an element belongs to
        both sequences or to one but not the other.  Note that only the
        resource URLs of the XResourceId objects are used for the
        classification.
        @param rS1
            One sequence of XResourceId objects.
        @param rS2
            Another sequence of XResourceId objects.
    */
    void ClassifyResources (
        const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::Reference<
                ::com::sun::star::drawing::framework::XResourceId> >& rS1,
        const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::Reference<
                ::com::sun::star::drawing::framework::XResourceId> >& rS2,
        ResourceIdVector& rS1minusS2,
        ResourceIdVector& rS2minusS1,
        ResourceIdVector& rS1andS2);

    /** Copy the resources given in rSource to the list of resources
        specified by rTarget.  Resources bound to the ones in rSource,
        either directly or indirectly, are copied as well.
        @param rSource
            All resources and the ones bound to them, either directly or
            indirectly, are copied.
        @param rxConfiguration
            This configuration is used to determine the resources bound to
            the ones in rSource.
        @param rTarget
            This list is filled with resources from rSource and the ones
            bound to them.
    */
    void CopyResources (
        const ResourceIdVector& rSource,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::drawing::framework::XConfiguration>& rxConfiguration,
        ResourceIdVector& rTarget);
};

} } // end of namespace sd::framework

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>typo: gven -> given<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#ifndef INCLUDED_SD_SOURCE_UI_FRAMEWORK_CONFIGURATION_CONFIGURATIONCLASSIFIER_HXX
#define INCLUDED_SD_SOURCE_UI_FRAMEWORK_CONFIGURATION_CONFIGURATIONCLASSIFIER_HXX

#include <com/sun/star/drawing/framework/XConfiguration.hpp>

#include <vector>

namespace sd { namespace framework {

/** A ConfigurationClassifier object compares two configurations of
    resources and gives access to the differences.  It is used mainly when
    changes to the current configuration have been requested and the various
    resource controllers have to be supplied with the set of resources that
    are to be activated or deactivated.
*/
class ConfigurationClassifier
{
public:
    /** Create a new ConfigurationClassifier object that will compare the
        two given configurations.
    */
    ConfigurationClassifier (
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::drawing::framework::XConfiguration>& rxConfiguration1,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::drawing::framework::XConfiguration>& rxConfiguration2);

    /** Calculate three lists of resource ids.  These contain the resources
        that belong to one configuration but not the other, or that belong
        to both configurations.
        @return
            When the two configurations differ then return <TRUE/>.  When
            they are equivalent then return <FALSE/>.
    */
    bool Partition (void);

    typedef ::std::vector<com::sun::star::uno::Reference<
        ::com::sun::star::drawing::framework::XResourceId> > ResourceIdVector;

    /** Return the resources that belong to the configuration given as
        rxConfiguration1 to the constructor but that do not belong to
        rxConfiguration2.
        @return
            A reference to the, possibly empty, list of resources is
            returned.  This reference remains valid as long as the called
            ConfigurationClassifier object stays alive.
    */
    const ResourceIdVector& GetC1minusC2 (void) const;

    /** Return the resources that belong to the configuration given as
        rxConfiguration2 to the constructor but that do not belong to
        rxConfiguration1.
        @return
            A reference to the, possibly empty, list of resources is
            returned.  This reference remains valid as long as the called
            ConfigurationClassifier object stays alive.
    */
    const ResourceIdVector& GetC2minusC1 (void) const;

    /** Return the resources that belong to both the configurations that
        where given to the constructor.
        @return
            A reference to the, possibly empty, list of resources is
            returned.  This reference remains valid as long as the called
            ConfigurationClassifier object stays alive.
    */
    const ResourceIdVector& GetC1andC2 (void) const;

    void TraceResourceIdVector (
        const sal_Char* pMessage,
        const ResourceIdVector& rResources) const;

private:
    ::com::sun::star::uno::Reference<
        ::com::sun::star::drawing::framework::XConfiguration> mxConfiguration1;
    ::com::sun::star::uno::Reference<
        ::com::sun::star::drawing::framework::XConfiguration> mxConfiguration2;

    /** After the call to Classify() this vector holds all elements from
        mxConfiguration1 that are not in mxConfiguration2.
    */
    ResourceIdVector maC1minusC2;

    /** After the call to Classify() this vector holds all elements from
        mxConfiguration2 that are not in mxConfiguration1.
    */
    ResourceIdVector maC2minusC1;

    /** After the call to Classify() this vector holds all elements that are
        member both of mxConfiguration1 and mxConfiguration2.
    */
    ResourceIdVector maC1andC2;

    /** Put all the elements in the two given sequences of resource ids and
        copy them into one of the resource id result vectors maC1minusC2,
        maC2minusC1, and maC1andC2.  This is done by using only the resource
        URLs for classification.  Therefor this method calls itself
        recursively.
        @param rS1
            One sequence of XResourceId objects.
        @param rS2
            Another sequence of XResourceId objects.
    */
    void PartitionResources (
        const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::Reference<
                ::com::sun::star::drawing::framework::XResourceId> >& rS1,
        const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::Reference<
                ::com::sun::star::drawing::framework::XResourceId> >& rS2);

    /** Compare the given sequences of resource ids and put their elements
        in one of three vectors depending on whether an element belongs to
        both sequences or to one but not the other.  Note that only the
        resource URLs of the XResourceId objects are used for the
        classification.
        @param rS1
            One sequence of XResourceId objects.
        @param rS2
            Another sequence of XResourceId objects.
    */
    void ClassifyResources (
        const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::Reference<
                ::com::sun::star::drawing::framework::XResourceId> >& rS1,
        const ::com::sun::star::uno::Sequence<
            ::com::sun::star::uno::Reference<
                ::com::sun::star::drawing::framework::XResourceId> >& rS2,
        ResourceIdVector& rS1minusS2,
        ResourceIdVector& rS2minusS1,
        ResourceIdVector& rS1andS2);

    /** Copy the resources given in rSource to the list of resources
        specified by rTarget.  Resources bound to the ones in rSource,
        either directly or indirectly, are copied as well.
        @param rSource
            All resources and the ones bound to them, either directly or
            indirectly, are copied.
        @param rxConfiguration
            This configuration is used to determine the resources bound to
            the ones in rSource.
        @param rTarget
            This list is filled with resources from rSource and the ones
            bound to them.
    */
    void CopyResources (
        const ResourceIdVector& rSource,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::drawing::framework::XConfiguration>& rxConfiguration,
        ResourceIdVector& rTarget);
};

} } // end of namespace sd::framework

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before><commit_msg>The 'bInitialized' state needs to be global, and unset in lo_destroy()<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unnecessary `#include` lines.<commit_after><|endoftext|>


<commit_before>#include <cstdint>
#include <cstring>
#include <iostream>
#include "utest_helper.hpp"

void compiler_vector_inc(void)
{
  const int n = 64;
  char dst[n];
  char src[n];

  OCL_CREATE_KERNEL("compiler_vector_inc");
  OCL_CREATE_BUFFER(buf[0], 0, n, NULL);
  OCL_CREATE_BUFFER(buf[1], 0, n, NULL);
  OCL_SET_ARG(0, sizeof(cl_mem), &buf[0]);
  OCL_SET_ARG(1, sizeof(cl_mem), &buf[1]);
  globals[0] = n / 2;
  locals[0] = 16;

  for (int i = 0; i < n; ++i) {
    dst[i] = i;
    src[i] = (i / 2) % 4;
  }
  OCL_MAP_BUFFER(0);
  OCL_MAP_BUFFER(1);
  memcpy(buf_data[0], dst, n);
  memcpy(buf_data[1], src, n);
  OCL_UNMAP_BUFFER(0);
  OCL_UNMAP_BUFFER(1);

  OCL_NDRANGE(1);

  OCL_MAP_BUFFER(0);
  char *dest = ((char *)buf_data[0]);
  for (int i=0; i<n; ++i) {
    char wish;
    if (src[i/2] < 2)
      wish = dst[i] + 1;
    else
      wish = dst[i] - 1;
    OCL_ASSERT(dest[i] == wish);
  }
  OCL_UNMAP_BUFFER(0);
}

MAKE_UTEST_FROM_FUNCTION(compiler_vector_inc);
<commit_msg>utests: put compiler_vector_inc into known issue list.<commit_after>#include <cstdint>
#include <cstring>
#include <iostream>
#include "utest_helper.hpp"

void compiler_vector_inc(void)
{
  const int n = 64;
  char dst[n];
  char src[n];

  OCL_CREATE_KERNEL("compiler_vector_inc");
  OCL_CREATE_BUFFER(buf[0], 0, n, NULL);
  OCL_CREATE_BUFFER(buf[1], 0, n, NULL);
  OCL_SET_ARG(0, sizeof(cl_mem), &buf[0]);
  OCL_SET_ARG(1, sizeof(cl_mem), &buf[1]);
  globals[0] = n / 2;
  locals[0] = 16;

  for (int i = 0; i < n; ++i) {
    dst[i] = i;
    src[i] = (i / 2) % 4;
  }
  OCL_MAP_BUFFER(0);
  OCL_MAP_BUFFER(1);
  memcpy(buf_data[0], dst, n);
  memcpy(buf_data[1], src, n);
  OCL_UNMAP_BUFFER(0);
  OCL_UNMAP_BUFFER(1);

  OCL_NDRANGE(1);

  OCL_MAP_BUFFER(0);
  char *dest = ((char *)buf_data[0]);
  for (int i=0; i<n; ++i) {
    char wish;
    if (src[i/2] < 2)
      wish = dst[i] + 1;
    else
      wish = dst[i] - 1;
    OCL_ASSERT(dest[i] == wish);
  }
  OCL_UNMAP_BUFFER(0);
}

MAKE_UTEST_FROM_FUNCTION_WITH_ISSUE(compiler_vector_inc);
<|endoftext|>


<commit_before>#include "PathTask.hpp"
#include "Robosub/HighLevelControl.h"
#include "std_msgs/String.h"

/**
 * @brief The constructor. Subscribes to all needed topics and sets up callbacks
 */
PathTask::PathTask()
 : m_nodeHandle(),
   m_pathSubscriber(),
   m_taskStateSubscriber(),
   m_highLevelMotorPublisher(),
   m_taskCompletePublisher(),
   m_isEnabled(false),
   m_mode(0)
{
   m_pathSubscriber = m_nodeHandle.subscribe("img_rec/paths", 10, &PathTask::pathCallback, this);
   m_taskStateSubscriber = m_nodeHandle.subscribe("Module_Enable", 10, &PathTask::moduleEnableCallback, this);
   m_highLevelMotorPublisher = m_nodeHandle.advertise<Robosub::HighLevelControl>("High_Level_Motor_Control", 10);
   m_taskCompletePublisher = m_nodeHandle.advertise<std_msgs::String>("Task_Completion", 10);
}

/**
 * @brief The destructor
 */
PathTask::~PathTask()
{

}

/**
 * @brief The module enable message callback
 *
 * @param msg The module enabled message
 */
void PathTask::moduleEnableCallback(const Robosub::ModuleEnableMsg& msg)
{
	if (msg.Module == "PathTask")
	{
		if (msg.State == true)
		{
			printf("PathTask: enabled\n");
			m_isEnabled = true;
			m_mode = 0;
		}
		else
		{
			printf("PathTask: Disabled\n");
			m_isEnabled = false;
		}
	}
}

/**
 * @brief The path callback
 *
 * @param msg The image recognition object message
 */
void PathTask::pathCallback(const SubImageRecognition::ImgRecObject& msg)
{
	if (m_isEnabled)
	{
	  //first get centered, then rotate, then recenter if needed
	  float moveX = msg.center_x - 320;
	  float moveY = msg.center_y - 240;
    float turn = msg.rotation;

    if (m_mode == 0)
    {
      if (moveX <= 330 && moveX >= 310 && moveY <= 250 && moveY >= 230)
      {
        //we have arrived, lets spin
        if (turn <= 1 && turn >= -1)
        {
          //signal complete
          reportSuccess(true);
        }
        else
        {
          m_mode = 1;
        }
      }
      else if (moveX > 330 || moveX < 310)
      {
        printf("Correcting straf by: %f\n", moveX);
        publishMotor("Straf", "Manual", moveX);
      }
      else if (moveY > 250 || moveY < 230)
      {
        printf("Correcting forward by: %f\n", moveY);
        publishMotor("Forward", "Manual", moveY);
      }
    }

    if (m_mode == 1)
    {
      if (turn <= 1 && turn >= -1)
      {
        m_mode = 0;
      }
      else
      {
        printf("Correcting turn by: %f\n", turn);
        publishMotor("Turn", "Manual", turn);
      }
    }
	}
}

void PathTask::reportSuccess(bool success)
{
	std_msgs::StringMultiArray msg;

	msg.data = "PathTask";
	if (success)
	{
		msg.data += " Success";
	}
	else
	{
	  msg.data = " Failure";
	}
	m_taskCompletePublisher.publish(msg);
}

void PathTask::publishMotor(std::string direction, std::string motion, float value)
{
  Robosub::HighLevelControl msg;
  msg.Direction = direction;
  msg.MotionType = motion;
  msg.Value = value;

  m_highLevelMotorPublisher.publish(msg);
}
<commit_msg>changed topic name<commit_after>#include "PathTask.hpp"
#include "Robosub/HighLevelControl.h"
#include "std_msgs/String.h"

/**
 * @brief The constructor. Subscribes to all needed topics and sets up callbacks
 */
PathTask::PathTask()
 : m_nodeHandle(),
   m_pathSubscriber(),
   m_taskStateSubscriber(),
   m_highLevelMotorPublisher(),
   m_taskCompletePublisher(),
   m_isEnabled(false),
   m_mode(0)
{
   m_pathSubscriber = m_nodeHandle.subscribe("img_rec/paths", 10, &PathTask::pathCallback, this);
   m_taskStateSubscriber = m_nodeHandle.subscribe("Module_Enable", 10, &PathTask::moduleEnableCallback, this);
   m_highLevelMotorPublisher = m_nodeHandle.advertise<Robosub::HighLevelControl>("High_Level_Motion", 10);
   m_taskCompletePublisher = m_nodeHandle.advertise<std_msgs::String>("Task_Completion", 10);
}

/**
 * @brief The destructor
 */
PathTask::~PathTask()
{

}

/**
 * @brief The module enable message callback
 *
 * @param msg The module enabled message
 */
void PathTask::moduleEnableCallback(const Robosub::ModuleEnableMsg& msg)
{
	if (msg.Module == "PathTask")
	{
		if (msg.State == true)
		{
			printf("PathTask: enabled\n");
			m_isEnabled = true;
			m_mode = 0;
		}
		else
		{
			printf("PathTask: Disabled\n");
			m_isEnabled = false;
		}
	}
}

/**
 * @brief The path callback
 *
 * @param msg The image recognition object message
 */
void PathTask::pathCallback(const SubImageRecognition::ImgRecObject& msg)
{
	if (m_isEnabled)
	{
	  //first get centered, then rotate, then recenter if needed
	  float moveX = msg.center_x - 320;
	  float moveY = msg.center_y - 240;
    float turn = msg.rotation;

    if (m_mode == 0)
    {
      if (moveX <= 330 && moveX >= 310 && moveY <= 250 && moveY >= 230)
      {
        //we have arrived, lets spin
        if (turn <= 1 && turn >= -1)
        {
          //signal complete
          reportSuccess(true);
        }
        else
        {
          m_mode = 1;
        }
      }
      else if (moveX > 330 || moveX < 310)
      {
        printf("Correcting straf by: %f\n", moveX);
        publishMotor("Straf", "Manual", moveX);
      }
      else if (moveY > 250 || moveY < 230)
      {
        printf("Correcting forward by: %f\n", moveY);
        publishMotor("Forward", "Manual", moveY);
      }
    }

    if (m_mode == 1)
    {
      if (turn <= 1 && turn >= -1)
      {
        m_mode = 0;
      }
      else
      {
        printf("Correcting turn by: %f\n", turn);
        publishMotor("Turn", "Manual", turn);
      }
    }
	}
}

void PathTask::reportSuccess(bool success)
{
	std_msgs::StringMultiArray msg;

	msg.data = "PathTask";
	if (success)
	{
		msg.data += " Success";
	}
	else
	{
	  msg.data = " Failure";
	}
	m_taskCompletePublisher.publish(msg);
}

void PathTask::publishMotor(std::string direction, std::string motion, float value)
{
  Robosub::HighLevelControl msg;
  msg.Direction = direction;
  msg.MotionType = motion;
  msg.Value = value;

  m_highLevelMotorPublisher.publish(msg);
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/perv/p9_ram_putspr.H $     */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
//-----------------------------------------------------------------------------------
///
/// @file p9_ram_putspr.H
/// @brief Utility to implement Put SPR Register by ramming
///
//-----------------------------------------------------------------------------------
// *HWP HWP Owner        : Liu Yang Fan <shliuyf@cn.ibm.com>
// *HWP HWP Backup Owner : Gou Peng Fei <shgoupf@cn.ibm.com>
// *HWP FW Owner         : Thi Tran <thi@us.ibm.com>
// *HWP Team             : Perv
// *HWP Level            : 2
// *HWP Consumed by      : None (Cronus test only)
//-----------------------------------------------------------------------------------

#ifndef _P9_RAM_PUTSPR_H_
#define _P9_RAM_PUTSPR_H_

//-----------------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------------
#include <fapi2.H>
#include <p9_ram_core.H>
#include <p9_spr_name_map.H>

//function pointer typedef definition for HWP call support
typedef fapi2::ReturnCode (*p9_ram_putspr_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target,
        const uint8_t i_thread,
        const std::string i_name,
        const fapi2::buffer<uint64_t>* i_buffer);

extern "C" {
//-----------------------------------------------------------------------------------
// Function prototype
//-----------------------------------------------------------------------------------
/// @brief Implement Put SPR Register by ramming
/// @param[in] i_target   => core target
/// @param[in] i_thread   => thread number
/// @param[in] i_name     => register name
/// @param[in] i_buffer   => register value
/// @return FAPI_RC_SUCCESS if the setup completes successfully
//
    fapi2::ReturnCode p9_ram_putspr(const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target,
                                    const uint8_t i_thread,
                                    const std::string i_name,
                                    const fapi2::buffer<uint64_t>* i_buffer);

} //extern"C"

#endif //_P9_RAM_PUTSPR_H_
<commit_msg>L3 Update - p9_ram_core HWPs<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/perv/p9_ram_putspr.H $     */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
//-----------------------------------------------------------------------------------
///
/// @file p9_ram_putspr.H
/// @brief Utility to implement Put SPR Register by ramming
///
//-----------------------------------------------------------------------------------
// *HWP HWP Owner        : Liu Yang Fan <shliuyf@cn.ibm.com>
// *HWP HWP Backup Owner : Gou Peng Fei <shgoupf@cn.ibm.com>
// *HWP FW Owner         : Thi Tran <thi@us.ibm.com>
// *HWP Team             : Perv
// *HWP Level            : 3
// *HWP Consumed by      : None (Cronus test only)
//-----------------------------------------------------------------------------------

#ifndef _P9_RAM_PUTSPR_H_
#define _P9_RAM_PUTSPR_H_

//-----------------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------------
#include <fapi2.H>
#include <p9_ram_core.H>
#include <p9_spr_name_map.H>

//function pointer typedef definition for HWP call support
typedef fapi2::ReturnCode (*p9_ram_putspr_FP_t)
(const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target,
 const uint8_t i_thread,
 const std::string i_name,
 const fapi2::buffer<uint64_t>* i_buffer);

extern "C" {
//-----------------------------------------------------------------------------------
// Function prototype
//-----------------------------------------------------------------------------------
/// @brief Implement Put SPR Register by ramming
/// @param[in] i_target   => core target
/// @param[in] i_thread   => thread number
/// @param[in] i_name     => register name
/// @param[in] i_buffer   => register value
/// @return FAPI_RC_SUCCESS if the operation completes successfully
//
    fapi2::ReturnCode p9_ram_putspr(const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target,
                                    const uint8_t i_thread,
                                    const std::string i_name,
                                    const fapi2::buffer<uint64_t>* i_buffer);

} //extern"C"

#endif //_P9_RAM_PUTSPR_H_
<|endoftext|>


<commit_before>/* LICENSE NOTICE
	Copyright (c) 2009, Frederick Emmott <mail@fredemmott.co.uk>

	Permission to use, copy, modify, and/or distribute this software for any
	purpose with or without fee is hereby granted, provided that the above
	copyright notice and this permission notice appear in all copies.

	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
	WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
	MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
	ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
	WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
	ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
	OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "Service.h"

#include "FileCacheMaintainer.h"
#include "OutputDevice.h"
#include "RequestCacheMaintainer.h"
#include "ServicePrivate.h"

#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QGenericArgument>
#include <QReadLocker>
#include <QMetaMethod>
#include <QMetaObject>
#include <QStringList>
#include <QThread>
#include <QXmlStreamWriter>

namespace FastCgiQt
{
	// Static variables
	bool Service::Private::usingFileCache(false);
	Cache Service::Private::fileCache(10*1024*1024);
	Cache Service::Private::requestCache(10*1024*1024);

	Service::Service(const Request& request, QObject* parent)
		:
			ClientIOInterface(request, NULL, NULL, parent)
	{
		d = new Service::Private();
		d->dispatchingRequest = false;
		FileCacheMaintainer::instance(&d->fileCache);
	}

	QByteArray Service::readFile(const QString& path, bool useCache)
	{
		const QString prefix = path.startsWith('/') ? "" : QCoreApplication::applicationDirPath() + "/";
		const QString fullPath = prefix + path;

		if(d->canCacheThisRequest)
		{
			// not if use-cache:
			// if caching of this file isn't wanted, then surely the
			// request cache should be invalidated here too
			RequestCacheMaintainer::instance(&d->requestCache)->addDependency(d->urlFragment, fullPath);
		}

		if(useCache && d->fileCache.contains(fullPath))
		{
			return d->fileCache[fullPath]->data;
		}

		QFile file(fullPath);
		file.open(QIODevice::ReadOnly);
		Q_ASSERT(file.isOpen());

		if(this->usingFileCache() && useCache && file.size() < fileCacheSize())
		{
			CacheEntry* entry = new CacheEntry(QDateTime::currentDateTime(), file.readAll());
			QWriteLocker lock(d->fileCache.readWriteLock());
			d->fileCache.insert(fullPath, entry);
			return entry->data;
		}
		else
		{
			return file.readAll();
		}
	}

	int Service::fileCacheSize()
	{
		return Service::Private::fileCache.maxCost();
	}

	void Service::cacheThisRequest()
	{
		OutputDevice* outputDevice = qobject_cast<OutputDevice*>(out.device());
		Q_ASSERT(outputDevice);
		Q_ASSERT(!outputDevice->haveSentData());
		outputDevice->setMode(OutputDevice::Logged);
		d->canCacheThisRequest = true;
	}

	void Service::dispatchRequest(const QString& urlFragment)
	{
		// Don't stack-overflow if a subclass calls the wrong function
		if(d->dispatchingRequest)
		{
			qFatal(
				"Recursion detected in FastCgiQt::Service::dispatchRequest(). "
				"You probably have a subclass calling dispatchRequest which "
				"should be calling dispatchUncachedRequest instead."
			);
			return;
		}

		OutputDevice* outputDevice = qobject_cast<OutputDevice*>(out.device());
		Q_ASSERT(outputDevice);

		{
			QReadLocker lock(d->fileCache.readWriteLock());
			if(d->requestCache.contains(urlFragment))
			{
				CacheEntry* cacheEntry = d->requestCache[urlFragment];

				if(!isExpired(urlFragment, cacheEntry->timeStamp))
				{
					outputDevice->setSendingHeadersEnabled(false);
					outputDevice->write(cacheEntry->data);
					return;
				}
			}
		}

		d->urlFragment = urlFragment;

		d->canCacheThisRequest = false;

		d->dispatchingRequest = true;
		dispatchUncachedRequest(urlFragment);
		d->dispatchingRequest = false;

		if(d->canCacheThisRequest)
		{
			CacheEntry* cacheEntry = new CacheEntry(QDateTime::currentDateTime(), outputDevice->buffer());
			d->requestCache.insert(urlFragment, cacheEntry);
		}
	}

	void Service::dispatchUncachedRequest(const QString& urlFragment)
	{
		d->fillMap(this);
		Q_FOREACH(const Service::Private::UrlMapEntry& action, d->forwardMap)
		{
			QRegExp re(action.first);
			if(re.exactMatch(urlFragment))
			{
				QStringList parameters(re.capturedTexts());
				parameters.takeFirst();
				d->invokeMethod(
					this,
					action.second,
					parameters
				);
				return;
			}
		}
		///@todo FIXME
		setHeader("status", "404");

		out << "
404 Not Found
";
	}

	void Service::dumpCacheInformation()
	{
		QReadLocker fileLock(d->fileCache.readWriteLock());
		QReadLocker requestLock(d->requestCache.readWriteLock());
		QXmlStreamWriter xml(out.device());
		xml.writeStartDocument();
		xml.writeStartElement("html");
			xml.writeStartElement("head");
				xml.writeTextElement("title", tr("Cache Information"));
			xml.writeEndElement();
			xml.writeStartElement("body");
				xml.writeTextElement("h1", tr("Cache Information"));
				xml.writeStartElement("dl");
					xml.writeTextElement("dt", tr("File cache size:"));
					xml.writeTextElement("dd", tr("%1 bytes").arg(d->fileCache.totalCost()));
					xml.writeTextElement("dt", tr("Maximum file cache size:"));
					xml.writeTextElement("dd", tr("%1 bytes").arg(d->fileCache.maxCost()));
					xml.writeTextElement("dt", tr("Items in file cache:"));
					xml.writeStartElement("dd");
						xml.writeCharacters(tr("%1 files:").arg(d->fileCache.count()));
						xml.writeStartElement("ul");
							Q_FOREACH(const QString& file, d->fileCache.keys())
							{
								xml.writeTextElement("li", QString("'%1' (%2 bytes)").arg(file).arg(d->fileCache[file]->data.length()));
							}
						xml.writeEndElement();
					xml.writeEndElement();
					xml.writeTextElement("dt", tr("Request cache size:"));
					xml.writeTextElement("dd", tr("%1 bytes").arg(d->requestCache.totalCost()));
					xml.writeTextElement("dt", tr("Request cache size:"));
					xml.writeTextElement("dd", tr("%1 bytes").arg(d->requestCache.maxCost()));
					xml.writeTextElement("dt", tr("Items in request cache:"));
					xml.writeStartElement("dd");
						xml.writeCharacters(tr("%1 pages:").arg(d->requestCache.count()));
						xml.writeStartElement("ul");
							Q_FOREACH(const QString& urlFragment, d->requestCache.keys())
							{
								xml.writeStartElement("li");
									xml.writeCharacters(QString("'%1' (%2 bytes)").arg(urlFragment).arg(d->requestCache[urlFragment]->data.length()));
									xml.writeTextElement("p", tr("File dependencies:"));
									xml.writeStartElement("ul");
										Q_FOREACH(const QString& file, RequestCacheMaintainer::instance(&d->requestCache)->dependencies(urlFragment))
										{
											xml.writeTextElement("li", file);
										}
									xml.writeEndElement();
								xml.writeEndElement();
							}
						xml.writeEndElement();
					xml.writeEndElement();
				xml.writeEndElement();
			xml.writeEndElement();
		xml.writeEndElement();
		xml.writeEndDocument();
	}

	void Service::Private::invokeMethod(
		QObject* object,
		const QMetaMethod& method,
		const QStringList& parameters
	)
	{
		// Work out the method name
		QString methodName(method.signature());
		methodName = methodName.left(methodName.indexOf('('));

		// Sort out the arguments
		QList<QByteArray> parameterTypes = method.parameterTypes();
		Q_ASSERT(parameterTypes.count() == parameters.count());
		QGenericArgument arguments[10];
		for(int i = 0; i < parameters.count(); ++i)
		{
			Q_ASSERT(parameterTypes.at(i) == "QString");
			arguments[i] = Q_ARG(QString, parameters.at(i));
		}
		QMetaObject::invokeMethod(
			object,
			methodName.toLatin1().constData(),
			arguments[0],
			arguments[1],
			arguments[2],
			arguments[3],
			arguments[4],
			arguments[5],
			arguments[6],
			arguments[7],
			arguments[8],
			arguments[9]
		);
	}

	bool Service::usingFileCache()
	{
		return Service::Private::usingFileCache;
	}

	void Service::setUsingFileCache(bool useFileCache)
	{
		Service::Private::usingFileCache = useFileCache;
		if(!useFileCache)
		{
			clearFileCache();
		}
	}

	void Service::clearFileCache()
	{
		Service::Private::fileCache.clear();
	}

	void Service::setFileCacheSize(int maximumSize)
	{
		Service::Private::fileCache.setMaxCost(maximumSize);
	}

	void Service::Private::fillMap(Service* service)
	{
		if(!forwardMap.isEmpty())
		{
			return;
		}
		// Make a map of SLOT(foo) -> metamethod
		QMap<QString, QMetaMethod> slotsToMethods;
		const QMetaObject* mo = service->metaObject();
		for(
			int i = Service::staticMetaObject.methodOffset();
			i < mo->methodCount();
			++i
		)
		{
			QMetaMethod mm = mo->method(i);
			if(mm.access() != QMetaMethod::Public || mm.methodType() != QMetaMethod::Slot)
			{
				continue;
			}

			Q_ASSERT(mm.parameterTypes().count() <= 10);

			Q_FOREACH(const QString& type, mm.parameterTypes())
			{
				Q_ASSERT(type == "QString");
			}

			slotsToMethods.insert(
				QString("%1%2").arg(QSLOT_CODE).arg(mm.signature()),
				mm
			);
		}

		Service::UrlMap urlMap = service->urlMap();
		for(
			QList<QPair<QString, const char*> >::ConstIterator it = urlMap.constBegin();
			it != urlMap.constEnd();
			++it
		)
		{
			QByteArray normalized = QMetaObject::normalizedSignature(it->second);
			if(!slotsToMethods.contains(normalized.constData()))
			{
				qFatal("Couldn't find a public slot matching '%s'.", normalized.constData());
			}
			///@todo check captures vs parameters
			forwardMap.append(qMakePair(QRegExp(it->first), slotsToMethods.value(normalized)));
			Q_ASSERT(forwardMap.last().first.isValid());
		}
	}

	Service::~Service()
	{
		delete d;
	}

	int Service::requestCacheSize()
	{
		return Service::Private::requestCache.maxCost();
	}

	void Service::setRequestCacheSize(int size)
	{
		Service::Private::requestCache.setMaxCost(size);
	}

	bool Service::isExpired(const QString& urlFragment, const QDateTime& generated)
	{
		Q_UNUSED(urlFragment);
		Q_UNUSED(generated);
		return false;
	}

	void Service::UrlMap::append(const QString& regexp, const char* slot)
	{
		QList<QPair<QString, const char*> >::append(qMakePair(regexp, slot));
	}

}
<commit_msg>Fix typo on cache dump page<commit_after>/* LICENSE NOTICE
	Copyright (c) 2009, Frederick Emmott <mail@fredemmott.co.uk>

	Permission to use, copy, modify, and/or distribute this software for any
	purpose with or without fee is hereby granted, provided that the above
	copyright notice and this permission notice appear in all copies.

	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
	WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
	MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
	ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
	WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
	ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
	OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "Service.h"

#include "FileCacheMaintainer.h"
#include "OutputDevice.h"
#include "RequestCacheMaintainer.h"
#include "ServicePrivate.h"

#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QGenericArgument>
#include <QReadLocker>
#include <QMetaMethod>
#include <QMetaObject>
#include <QStringList>
#include <QThread>
#include <QXmlStreamWriter>

namespace FastCgiQt
{
	// Static variables
	bool Service::Private::usingFileCache(false);
	Cache Service::Private::fileCache(10*1024*1024);
	Cache Service::Private::requestCache(10*1024*1024);

	Service::Service(const Request& request, QObject* parent)
		:
			ClientIOInterface(request, NULL, NULL, parent)
	{
		d = new Service::Private();
		d->dispatchingRequest = false;
		FileCacheMaintainer::instance(&d->fileCache);
	}

	QByteArray Service::readFile(const QString& path, bool useCache)
	{
		const QString prefix = path.startsWith('/') ? "" : QCoreApplication::applicationDirPath() + "/";
		const QString fullPath = prefix + path;

		if(d->canCacheThisRequest)
		{
			// not if use-cache:
			// if caching of this file isn't wanted, then surely the
			// request cache should be invalidated here too
			RequestCacheMaintainer::instance(&d->requestCache)->addDependency(d->urlFragment, fullPath);
		}

		if(useCache && d->fileCache.contains(fullPath))
		{
			return d->fileCache[fullPath]->data;
		}

		QFile file(fullPath);
		file.open(QIODevice::ReadOnly);
		Q_ASSERT(file.isOpen());

		if(this->usingFileCache() && useCache && file.size() < fileCacheSize())
		{
			CacheEntry* entry = new CacheEntry(QDateTime::currentDateTime(), file.readAll());
			QWriteLocker lock(d->fileCache.readWriteLock());
			d->fileCache.insert(fullPath, entry);
			return entry->data;
		}
		else
		{
			return file.readAll();
		}
	}

	int Service::fileCacheSize()
	{
		return Service::Private::fileCache.maxCost();
	}

	void Service::cacheThisRequest()
	{
		OutputDevice* outputDevice = qobject_cast<OutputDevice*>(out.device());
		Q_ASSERT(outputDevice);
		Q_ASSERT(!outputDevice->haveSentData());
		outputDevice->setMode(OutputDevice::Logged);
		d->canCacheThisRequest = true;
	}

	void Service::dispatchRequest(const QString& urlFragment)
	{
		// Don't stack-overflow if a subclass calls the wrong function
		if(d->dispatchingRequest)
		{
			qFatal(
				"Recursion detected in FastCgiQt::Service::dispatchRequest(). "
				"You probably have a subclass calling dispatchRequest which "
				"should be calling dispatchUncachedRequest instead."
			);
			return;
		}

		OutputDevice* outputDevice = qobject_cast<OutputDevice*>(out.device());
		Q_ASSERT(outputDevice);

		{
			QReadLocker lock(d->fileCache.readWriteLock());
			if(d->requestCache.contains(urlFragment))
			{
				CacheEntry* cacheEntry = d->requestCache[urlFragment];

				if(!isExpired(urlFragment, cacheEntry->timeStamp))
				{
					outputDevice->setSendingHeadersEnabled(false);
					outputDevice->write(cacheEntry->data);
					return;
				}
			}
		}

		d->urlFragment = urlFragment;

		d->canCacheThisRequest = false;

		d->dispatchingRequest = true;
		dispatchUncachedRequest(urlFragment);
		d->dispatchingRequest = false;

		if(d->canCacheThisRequest)
		{
			CacheEntry* cacheEntry = new CacheEntry(QDateTime::currentDateTime(), outputDevice->buffer());
			d->requestCache.insert(urlFragment, cacheEntry);
		}
	}

	void Service::dispatchUncachedRequest(const QString& urlFragment)
	{
		d->fillMap(this);
		Q_FOREACH(const Service::Private::UrlMapEntry& action, d->forwardMap)
		{
			QRegExp re(action.first);
			if(re.exactMatch(urlFragment))
			{
				QStringList parameters(re.capturedTexts());
				parameters.takeFirst();
				d->invokeMethod(
					this,
					action.second,
					parameters
				);
				return;
			}
		}
		///@todo FIXME
		setHeader("status", "404");

		out << "
404 Not Found
";
	}

	void Service::dumpCacheInformation()
	{
		QReadLocker fileLock(d->fileCache.readWriteLock());
		QReadLocker requestLock(d->requestCache.readWriteLock());
		QXmlStreamWriter xml(out.device());
		xml.writeStartDocument();
		xml.writeStartElement("html");
			xml.writeStartElement("head");
				xml.writeTextElement("title", tr("Cache Information"));
			xml.writeEndElement();
			xml.writeStartElement("body");
				xml.writeTextElement("h1", tr("Cache Information"));
				xml.writeStartElement("dl");
					xml.writeTextElement("dt", tr("File cache size:"));
					xml.writeTextElement("dd", tr("%1 bytes").arg(d->fileCache.totalCost()));
					xml.writeTextElement("dt", tr("Maximum file cache size:"));
					xml.writeTextElement("dd", tr("%1 bytes").arg(d->fileCache.maxCost()));
					xml.writeTextElement("dt", tr("Items in file cache:"));
					xml.writeStartElement("dd");
						xml.writeCharacters(tr("%1 files:").arg(d->fileCache.count()));
						xml.writeStartElement("ul");
							Q_FOREACH(const QString& file, d->fileCache.keys())
							{
								xml.writeTextElement("li", QString("'%1' (%2 bytes)").arg(file).arg(d->fileCache[file]->data.length()));
							}
						xml.writeEndElement();
					xml.writeEndElement();
					xml.writeTextElement("dt", tr("Request cache size:"));
					xml.writeTextElement("dd", tr("%1 bytes").arg(d->requestCache.totalCost()));
					xml.writeTextElement("dt", tr("Maximum equest cache size:"));
					xml.writeTextElement("dd", tr("%1 bytes").arg(d->requestCache.maxCost()));
					xml.writeTextElement("dt", tr("Items in request cache:"));
					xml.writeStartElement("dd");
						xml.writeCharacters(tr("%1 pages:").arg(d->requestCache.count()));
						xml.writeStartElement("ul");
							Q_FOREACH(const QString& urlFragment, d->requestCache.keys())
							{
								xml.writeStartElement("li");
									xml.writeCharacters(QString("'%1' (%2 bytes)").arg(urlFragment).arg(d->requestCache[urlFragment]->data.length()));
									xml.writeTextElement("p", tr("File dependencies:"));
									xml.writeStartElement("ul");
										Q_FOREACH(const QString& file, RequestCacheMaintainer::instance(&d->requestCache)->dependencies(urlFragment))
										{
											xml.writeTextElement("li", file);
										}
									xml.writeEndElement();
								xml.writeEndElement();
							}
						xml.writeEndElement();
					xml.writeEndElement();
				xml.writeEndElement();
			xml.writeEndElement();
		xml.writeEndElement();
		xml.writeEndDocument();
	}

	void Service::Private::invokeMethod(
		QObject* object,
		const QMetaMethod& method,
		const QStringList& parameters
	)
	{
		// Work out the method name
		QString methodName(method.signature());
		methodName = methodName.left(methodName.indexOf('('));

		// Sort out the arguments
		QList<QByteArray> parameterTypes = method.parameterTypes();
		Q_ASSERT(parameterTypes.count() == parameters.count());
		QGenericArgument arguments[10];
		for(int i = 0; i < parameters.count(); ++i)
		{
			Q_ASSERT(parameterTypes.at(i) == "QString");
			arguments[i] = Q_ARG(QString, parameters.at(i));
		}
		QMetaObject::invokeMethod(
			object,
			methodName.toLatin1().constData(),
			arguments[0],
			arguments[1],
			arguments[2],
			arguments[3],
			arguments[4],
			arguments[5],
			arguments[6],
			arguments[7],
			arguments[8],
			arguments[9]
		);
	}

	bool Service::usingFileCache()
	{
		return Service::Private::usingFileCache;
	}

	void Service::setUsingFileCache(bool useFileCache)
	{
		Service::Private::usingFileCache = useFileCache;
		if(!useFileCache)
		{
			clearFileCache();
		}
	}

	void Service::clearFileCache()
	{
		Service::Private::fileCache.clear();
	}

	void Service::setFileCacheSize(int maximumSize)
	{
		Service::Private::fileCache.setMaxCost(maximumSize);
	}

	void Service::Private::fillMap(Service* service)
	{
		if(!forwardMap.isEmpty())
		{
			return;
		}
		// Make a map of SLOT(foo) -> metamethod
		QMap<QString, QMetaMethod> slotsToMethods;
		const QMetaObject* mo = service->metaObject();
		for(
			int i = Service::staticMetaObject.methodOffset();
			i < mo->methodCount();
			++i
		)
		{
			QMetaMethod mm = mo->method(i);
			if(mm.access() != QMetaMethod::Public || mm.methodType() != QMetaMethod::Slot)
			{
				continue;
			}

			Q_ASSERT(mm.parameterTypes().count() <= 10);

			Q_FOREACH(const QString& type, mm.parameterTypes())
			{
				Q_ASSERT(type == "QString");
			}

			slotsToMethods.insert(
				QString("%1%2").arg(QSLOT_CODE).arg(mm.signature()),
				mm
			);
		}

		Service::UrlMap urlMap = service->urlMap();
		for(
			QList<QPair<QString, const char*> >::ConstIterator it = urlMap.constBegin();
			it != urlMap.constEnd();
			++it
		)
		{
			QByteArray normalized = QMetaObject::normalizedSignature(it->second);
			if(!slotsToMethods.contains(normalized.constData()))
			{
				qFatal("Couldn't find a public slot matching '%s'.", normalized.constData());
			}
			///@todo check captures vs parameters
			forwardMap.append(qMakePair(QRegExp(it->first), slotsToMethods.value(normalized)));
			Q_ASSERT(forwardMap.last().first.isValid());
		}
	}

	Service::~Service()
	{
		delete d;
	}

	int Service::requestCacheSize()
	{
		return Service::Private::requestCache.maxCost();
	}

	void Service::setRequestCacheSize(int size)
	{
		Service::Private::requestCache.setMaxCost(size);
	}

	bool Service::isExpired(const QString& urlFragment, const QDateTime& generated)
	{
		Q_UNUSED(urlFragment);
		Q_UNUSED(generated);
		return false;
	}

	void Service::UrlMap::append(const QString& regexp, const char* slot)
	{
		QList<QPair<QString, const char*> >::append(qMakePair(regexp, slot));
	}

}
<|endoftext|>


<commit_before>#include "sql_statement.hpp"
#include "sqlite_dbconn.hpp"

#include <sqlite3.h>
#include <string>

using std::string;

namespace sqloxx
{
namespace detail
{

SQLStatement::SQLStatement
(	SQLiteDBConn& p_sqlite_dbconn,
	string const& str
):
	m_statement(0),
	m_sqlite_dbconn(p_sqlite_dbconn),
	m_is_locked(false)
{
	if (!p_sqlite_dbconn.is_valid())
	{
		throw InvalidConnection
		(	"Attempt to initialize SQLStatement with invalid "
			"DatabaseConnection."
		);
	}
	char const* cstr = str.c_str();
	char const** tail = &cstr;
	sqlite3_prepare_v2
	(	m_sqlite_dbconn.m_connection,
		cstr,
		str.length() + 1,
		&m_statement,
		tail
	);
	check_ok();
	for (char const* it = *tail; *it != '\0'; ++it)
	{
		switch (*it)
		{
		case ';':
		case ' ':
			// The character is harmless.
			break;
		default:
			// But character is bad.
			sqlite3_finalize(m_statement);
			m_statement = 0;
			throw TooManyStatements
			(	"Compound SQL statement passed to constructor of "
				"SQLStatement - which can handle only single statements."
			);
		}
	}
	return;
}

SQLStatement::~SQLStatement()
{
	if (m_statement)
	{
		// WARNING This can cause segfault in certain circumstances when
		// called from destructor of SharedSQLStatement.
		sqlite3_finalize(m_statement);
		m_statement = 0;
	}
}

void
SQLStatement::check_column(int index, int value_type)
{
	int const num_columns = sqlite3_column_count(m_statement);
	if (num_columns == 0)
	{
		throw NoResultRowException("Result row not available.");
	}
	if (index >= num_columns)
	{
		throw ResultIndexOutOfRange("Index is out of range.");
	}
	if (index < 0)
	{
		throw ResultIndexOutOfRange("Index is negative.");
	}
	if (value_type != sqlite3_column_type(m_statement, index))
	{
		throw ValueTypeException
		(	"Value type at index does not match specified value type."
		);
	}
	return;
}

void
SQLStatement::check_ok()
{
	try
	{
		m_sqlite_dbconn.check_ok();
	}
	catch (SQLiteException&)
	{
		sqlite3_finalize(m_statement);
		m_statement = 0;
		throw;
	}
	return;
}

void
SQLStatement::bind
(	std::string const& parameter_name,
	int value
)
{
	sqlite3_bind_int(m_statement, parameter_index(parameter_name), value);
	check_ok();
	return;
}

void
SQLStatement::bind
(	string const& parameter_name,
	int64_t value
)
{
	sqlite3_bind_int64(m_statement, parameter_index(parameter_name), value);
	check_ok();
	return;
}

void
SQLStatement::bind
(	string const& parameter_name,
	string const& str
)
{
	sqlite3_bind_text
	(	m_statement,
		parameter_index(parameter_name),
		str.c_str(),
		-1,
		0
	);
	check_ok();
	return;
}

bool
SQLStatement::step()
{
	switch (sqlite3_step(m_statement))
	{
	case SQLITE_DONE:
		return false;
		assert (false);  // Execution never reaches here
	case SQLITE_ROW:
		return true;
		assert (false);  // Execution never reaches here
	default:
		;
		// Do nothing
	}
	check_ok();
	assert (false);  // Execution should never reach here.
	return false;  // Silence compiler re. return from non-void function.
}

void
SQLStatement::step_final()
{
	if (step())
	{
		reset();
		throw UnexpectedResultRow
		(	"Statement yielded a result set when none was expected."
		);
	}
	return;
}

int
SQLStatement::parameter_index
(	string const& parameter_name
)
const
{
	int const ret = sqlite3_bind_parameter_index
	(	m_statement,
		parameter_name.c_str()
	);
	if (ret == 0)
	{
		throw SQLiteException("Could not find parameter index.");
	}
	assert (ret > 0);
	return ret;
}

}  // namespace detail
}  // namespace sqloxx
<commit_msg>Minor tweak to comment.<commit_after>#include "sql_statement.hpp"
#include "sqlite_dbconn.hpp"

#include <sqlite3.h>
#include <string>

using std::string;

namespace sqloxx
{
namespace detail
{

SQLStatement::SQLStatement
(	SQLiteDBConn& p_sqlite_dbconn,
	string const& str
):
	m_statement(0),
	m_sqlite_dbconn(p_sqlite_dbconn),
	m_is_locked(false)
{
	if (!p_sqlite_dbconn.is_valid())
	{
		throw InvalidConnection
		(	"Attempt to initialize SQLStatement with invalid "
			"DatabaseConnection."
		);
	}
	char const* cstr = str.c_str();
	char const** tail = &cstr;
	sqlite3_prepare_v2
	(	m_sqlite_dbconn.m_connection,
		cstr,
		str.length() + 1,
		&m_statement,
		tail
	);
	check_ok();
	for (char const* it = *tail; *it != '\0'; ++it)
	{
		switch (*it)
		{
		case ';':
		case ' ':
			// The character is harmless.
			break;
		default:
			// The character is bad.
			sqlite3_finalize(m_statement);
			m_statement = 0;
			// Note this will have thrown already if first statement is
			// ungrammatical.
			throw TooManyStatements
			(	"Compound SQL statement passed to constructor of "
				"SQLStatement - which can handle only single statements."
			);
		}
	}
	return;
}

SQLStatement::~SQLStatement()
{
	if (m_statement)
	{
		// WARNING This can cause segfault in certain circumstances when
		// called from destructor of SharedSQLStatement.
		sqlite3_finalize(m_statement);
		m_statement = 0;
	}
}

void
SQLStatement::check_column(int index, int value_type)
{
	int const num_columns = sqlite3_column_count(m_statement);
	if (num_columns == 0)
	{
		throw NoResultRowException("Result row not available.");
	}
	if (index >= num_columns)
	{
		throw ResultIndexOutOfRange("Index is out of range.");
	}
	if (index < 0)
	{
		throw ResultIndexOutOfRange("Index is negative.");
	}
	if (value_type != sqlite3_column_type(m_statement, index))
	{
		throw ValueTypeException
		(	"Value type at index does not match specified value type."
		);
	}
	return;
}

void
SQLStatement::check_ok()
{
	try
	{
		m_sqlite_dbconn.check_ok();
	}
	catch (SQLiteException&)
	{
		sqlite3_finalize(m_statement);
		m_statement = 0;
		throw;
	}
	return;
}

void
SQLStatement::bind
(	std::string const& parameter_name,
	int value
)
{
	sqlite3_bind_int(m_statement, parameter_index(parameter_name), value);
	check_ok();
	return;
}

void
SQLStatement::bind
(	string const& parameter_name,
	int64_t value
)
{
	sqlite3_bind_int64(m_statement, parameter_index(parameter_name), value);
	check_ok();
	return;
}

void
SQLStatement::bind
(	string const& parameter_name,
	string const& str
)
{
	sqlite3_bind_text
	(	m_statement,
		parameter_index(parameter_name),
		str.c_str(),
		-1,
		0
	);
	check_ok();
	return;
}

bool
SQLStatement::step()
{
	switch (sqlite3_step(m_statement))
	{
	case SQLITE_DONE:
		return false;
		assert (false);  // Execution never reaches here
	case SQLITE_ROW:
		return true;
		assert (false);  // Execution never reaches here
	default:
		;
		// Do nothing
	}
	check_ok();
	assert (false);  // Execution should never reach here.
	return false;  // Silence compiler re. return from non-void function.
}

void
SQLStatement::step_final()
{
	if (step())
	{
		reset();
		throw UnexpectedResultRow
		(	"Statement yielded a result set when none was expected."
		);
	}
	return;
}

int
SQLStatement::parameter_index
(	string const& parameter_name
)
const
{
	int const ret = sqlite3_bind_parameter_index
	(	m_statement,
		parameter_name.c_str()
	);
	if (ret == 0)
	{
		throw SQLiteException("Could not find parameter index.");
	}
	assert (ret > 0);
	return ret;
}

}  // namespace detail
}  // namespace sqloxx
<|endoftext|>


<commit_before><commit_msg>new loplugin: VCL widget reference checker<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (c) 2007-2008 Digital Bazaar, Inc.  All rights reserved.
 */
#include "db/rt/DynamicObjectIterator.h"

#include "db/rt/Exception.h"

using namespace db::rt;

DynamicObjectIteratorImpl::DynamicObjectIteratorImpl(DynamicObject dyno)
{
   mObject = dyno;
   mIndex = -1;

   if(mObject->getType() == Map)
   {
      mMapNext = mMapCurrent = mObject->mMap->begin();
   }
   else if(mObject->getType() == Array)
   {
      mArrayNext = mArrayCurrent = mObject->mArray->begin();
   }
   else
   {
      mFinished = false;
   }
}

DynamicObjectIteratorImpl::~DynamicObjectIteratorImpl()
{
}

DynamicObject& DynamicObjectIteratorImpl::next()
{
   DynamicObject* rval = NULL;
   mIndex++;

   if(mObject->getType() == Map)
   {
      mMapCurrent = mMapNext;
      mMapNext++;
      rval = &mMapCurrent->second;
   }
   else if(mObject->getType() == Array)
   {
      mArrayCurrent = mArrayNext;
      mArrayNext++;
      rval = &(*mArrayCurrent);
   }
   else if(!mFinished)
   {
      // return this object
      rval = &mObject;
      mFinished = true;
   }

   return *rval;
}

bool DynamicObjectIteratorImpl::hasNext()
{
   bool rval = false;

   if(mObject->getType() == Map)
   {
      rval = (mMapNext != mObject->mMap->end());
   }
   else if(mObject->getType() == Array)
   {
      rval = (mArrayNext != mObject->mArray->end());
   }
   else
   {
      rval = !mFinished;
   }

   return rval;
}

void DynamicObjectIteratorImpl::remove()
{
   if(mObject->getType() == Map)
   {
      mObject->mMap->erase(mMapCurrent);
   }
   else if(mObject->getType() == Array)
   {
      mObject->mArray->erase(mArrayCurrent);
   }
   else
   {
      // not supported
      ExceptionRef e = new Exception(
         "DynamicObjectIterator::remove() not supported!");
      Exception::setLast(e, false);
   }
}

const char* DynamicObjectIteratorImpl::getName()
{
   const char* rval;

   if(mObject->getType() == Map)
   {
      rval = mMapCurrent->first;
   }
   else
   {
      rval = "";
   }

   return rval;
}

int DynamicObjectIteratorImpl::getIndex()
{
   return mIndex;
}

DynamicObjectIterator::DynamicObjectIterator(DynamicObjectIteratorImpl* impl) :
   Collectable<DynamicObjectIteratorImpl>(impl)
{
}

DynamicObjectIterator::~DynamicObjectIterator()
{
}
<commit_msg>Fix leak.<commit_after>/*
 * Copyright (c) 2007-2008 Digital Bazaar, Inc.  All rights reserved.
 */
#include "db/rt/DynamicObjectIterator.h"

#include "db/rt/Exception.h"

using namespace db::rt;

DynamicObjectIteratorImpl::DynamicObjectIteratorImpl(DynamicObject dyno)
{
   mObject = dyno;
   mIndex = -1;

   if(mObject->getType() == Map)
   {
      mMapNext = mMapCurrent = mObject->mMap->begin();
   }
   else if(mObject->getType() == Array)
   {
      mArrayNext = mArrayCurrent = mObject->mArray->begin();
   }
   else
   {
      mFinished = false;
   }
}

DynamicObjectIteratorImpl::~DynamicObjectIteratorImpl()
{
}

DynamicObject& DynamicObjectIteratorImpl::next()
{
   DynamicObject* rval = NULL;
   mIndex++;

   if(mObject->getType() == Map)
   {
      mMapCurrent = mMapNext;
      mMapNext++;
      rval = &mMapCurrent->second;
   }
   else if(mObject->getType() == Array)
   {
      mArrayCurrent = mArrayNext;
      mArrayNext++;
      rval = &(*mArrayCurrent);
   }
   else if(!mFinished)
   {
      // return this object
      rval = &mObject;
      mFinished = true;
   }

   return *rval;
}

bool DynamicObjectIteratorImpl::hasNext()
{
   bool rval = false;

   if(mObject->getType() == Map)
   {
      rval = (mMapNext != mObject->mMap->end());
   }
   else if(mObject->getType() == Array)
   {
      rval = (mArrayNext != mObject->mArray->end());
   }
   else
   {
      rval = !mFinished;
   }

   return rval;
}

void DynamicObjectIteratorImpl::remove()
{
   if(mObject->getType() == Map)
   {
      // NOTE: We already have the iterator here so just duplicating the key
      // free instead of calling mMap->removeMember(mMapCurrent->first)
      free((char*)mMapCurrent->first);
      mObject->mMap->erase(mMapCurrent);
   }
   else if(mObject->getType() == Array)
   {
      mObject->mArray->erase(mArrayCurrent);
   }
   else
   {
      // not supported
      ExceptionRef e = new Exception(
         "DynamicObjectIterator::remove() not supported!");
      Exception::setLast(e, false);
   }
}

const char* DynamicObjectIteratorImpl::getName()
{
   const char* rval;

   if(mObject->getType() == Map)
   {
      rval = mMapCurrent->first;
   }
   else
   {
      rval = "";
   }

   return rval;
}

int DynamicObjectIteratorImpl::getIndex()
{
   return mIndex;
}

DynamicObjectIterator::DynamicObjectIterator(DynamicObjectIteratorImpl* impl) :
   Collectable<DynamicObjectIteratorImpl>(impl)
{
}

DynamicObjectIterator::~DynamicObjectIterator()
{
}
<|endoftext|>


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

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

/*===========================================================================*/
/*===============================[ Includes ]================================*/
/*===========================================================================*/
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#include "ogr_feature.h"
#pragma GCC diagnostic pop

#include "otbOGRFeatureWrapper.h"
#include "otbJoinContainer.h"
#include <boost/array.hpp>
/*===========================================================================*/
/*===========================[ Static Assertions ]===========================*/
/*===========================================================================*/
namespace otb { namespace ogr {
namespace internal {
BOOST_STATIC_ASSERT(!(boost::is_same<
  MemberGetterPtr<int,         &OGRFeature::GetFieldAsInteger>,
  MemberGetterPtr<double,      &OGRFeature::GetFieldAsDouble>
  >::value
  ));

BOOST_STATIC_ASSERT(!(boost::is_same< int, float >::value));
BOOST_STATIC_ASSERT(!(boost::is_same<
    int_<OFTReal  >::type,
    int_<OFTString>::type
    >::value
));
BOOST_STATIC_ASSERT(!(boost::is_same<
    at<FieldType_Map,  float>,
    void_
    >::value
));
BOOST_STATIC_ASSERT(!(boost::is_same<
    at<FieldType_Map,  double>,
    int_<OFTReal>
    >::value
));
BOOST_STATIC_ASSERT(!(boost::is_same<
    at<FieldType_Map,  double >::type,
    at<FieldType_Map,  int >::type
    >::value
));
BOOST_STATIC_ASSERT((
    at<FieldType_Map,  double>::type::value !=
    at<FieldType_Map,  int   >::type::value
));
BOOST_STATIC_ASSERT(!(boost::is_same<
    at<FieldGetters_Map, int_<OFTReal> >,
    at<FieldGetters_Map, int_<OFTString> >
    >::value
));

BOOST_MPL_ASSERT((boost::is_array<int[42]>));
BOOST_MPL_ASSERT_NOT((boost::is_array<boost::array<int, 42> >));
BOOST_MPL_ASSERT_NOT((boost::is_array<std::vector<int> >));

BOOST_STATIC_ASSERT((boost::is_contiguous<int*>::value));
BOOST_STATIC_ASSERT((boost::is_contiguous<int[42]>::value));
BOOST_STATIC_ASSERT((boost::is_contiguous<boost::array<int, 42> >::value));
BOOST_STATIC_ASSERT((boost::is_contiguous<std::vector<int> >::value));

BOOST_MPL_ASSERT((boost::is_same<int, CppToOGRConverter_trait<int>::type >));
BOOST_MPL_ASSERT((boost::is_same<char*, CppToOGRConverter_trait<char[8]>::type >));
BOOST_MPL_ASSERT_NOT((boost::is_same<char*, char[8] >));

}
} } // end namespace otb::ogr

/*===========================================================================*/
/*===============================[ FieldDefn ]===============================*/
/*===========================================================================*/

std::string otb::ogr::FieldDefn::GetName() const
{
  assert(m_Definition && "No field definition wrapped");
  return m_Definition->GetNameRef();
}

OGRFieldType otb::ogr::FieldDefn::GetType() const
{
  assert(m_Definition && "No field definition wrapped");
  return m_Definition->GetType();
}

std::ostream & otb::ogr::operator<<(std::ostream & os, otb::ogr::FieldDefn const& defn)
{
  return os << defn.GetName()
    << " (" << OGRFieldDefn::GetFieldTypeName(defn.GetType()) << ")";
}
/*===========================================================================*/
/*=================================[ Field ]=================================*/
/*===========================================================================*/

otb::ogr::Field::Field(otb::ogr::Feature & feature, size_t index)
: m_Definition(*feature.ogr().GetFieldDefnRef(index))
, m_Feature(feature.sptr())
, m_index(index)
{
  CheckInvariants();
}

std::ostream & otb::ogr::Field::UncheckedPrintSelf(
  std::ostream& os, itk::Indent indent) const
{
  //const itk::Indent one_indent = itk::Indent().GetNextIndent();
  // os << indent << "|" << one_indent << "+ ";
  os << indent << this->GetName() << ": ";
  switch (this->GetType())
    {
  case OFTInteger:
    os << this->GetValue<int>();
    break;
  case OFTIntegerList:
    os << '{';
    otb::Join(os, this->GetValue<std::vector<int> >(), ", ") << '}';
    break;
  case OFTReal   :
    os << this->GetValue<double>();
    break;
  case OFTRealList:
    os << '{';
    otb::Join(os, this->GetValue<std::vector<double> >(), ", ") << '}';
    break;
  case OFTString :
    os << this->GetValue<std::string>();
    break;
  default:
    os << "??? -> " << this->GetType();
    break;
    }
  os << " (" << OGRFieldDefn::GetFieldTypeName(this->GetType()) << ")";
  os << "\n";
  return os;
}

bool otb::ogr::Field::UncheckedHasBeenSet() const
{
  return m_Feature->IsFieldSet(m_index);
}

void otb::ogr::Field::UncheckedUnset() const
{
  m_Feature->UnsetField(m_index);
}

void otb::ogr::Field::UncheckedAssign(Field const& f)
{
  if (f.HasBeenSet())
    {
    OGRField & of = f.ogr();
    m_Feature->SetField(m_index, &of); // OGR API copies *of
    }
  else // not sure OGR setField handle the case where new fields are unset
    {
    this->Unset();
    }
}
<commit_msg>COMP: MSVC: ifdef gaurd for pragma GCC<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

/*===========================================================================*/
/*===============================[ Includes ]================================*/
/*===========================================================================*/
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#include "ogr_feature.h"
#pragma GCC diagnostic pop
#else
#include "ogr_feature.h"
#endif
#include "otbOGRFeatureWrapper.h"
#include "otbJoinContainer.h"
#include <boost/array.hpp>
/*===========================================================================*/
/*===========================[ Static Assertions ]===========================*/
/*===========================================================================*/
namespace otb { namespace ogr {
namespace internal {
BOOST_STATIC_ASSERT(!(boost::is_same<
  MemberGetterPtr<int,         &OGRFeature::GetFieldAsInteger>,
  MemberGetterPtr<double,      &OGRFeature::GetFieldAsDouble>
  >::value
  ));

BOOST_STATIC_ASSERT(!(boost::is_same< int, float >::value));
BOOST_STATIC_ASSERT(!(boost::is_same<
    int_<OFTReal  >::type,
    int_<OFTString>::type
    >::value
));
BOOST_STATIC_ASSERT(!(boost::is_same<
    at<FieldType_Map,  float>,
    void_
    >::value
));
BOOST_STATIC_ASSERT(!(boost::is_same<
    at<FieldType_Map,  double>,
    int_<OFTReal>
    >::value
));
BOOST_STATIC_ASSERT(!(boost::is_same<
    at<FieldType_Map,  double >::type,
    at<FieldType_Map,  int >::type
    >::value
));
BOOST_STATIC_ASSERT((
    at<FieldType_Map,  double>::type::value !=
    at<FieldType_Map,  int   >::type::value
));
BOOST_STATIC_ASSERT(!(boost::is_same<
    at<FieldGetters_Map, int_<OFTReal> >,
    at<FieldGetters_Map, int_<OFTString> >
    >::value
));

BOOST_MPL_ASSERT((boost::is_array<int[42]>));
BOOST_MPL_ASSERT_NOT((boost::is_array<boost::array<int, 42> >));
BOOST_MPL_ASSERT_NOT((boost::is_array<std::vector<int> >));

BOOST_STATIC_ASSERT((boost::is_contiguous<int*>::value));
BOOST_STATIC_ASSERT((boost::is_contiguous<int[42]>::value));
BOOST_STATIC_ASSERT((boost::is_contiguous<boost::array<int, 42> >::value));
BOOST_STATIC_ASSERT((boost::is_contiguous<std::vector<int> >::value));

BOOST_MPL_ASSERT((boost::is_same<int, CppToOGRConverter_trait<int>::type >));
BOOST_MPL_ASSERT((boost::is_same<char*, CppToOGRConverter_trait<char[8]>::type >));
BOOST_MPL_ASSERT_NOT((boost::is_same<char*, char[8] >));

}
} } // end namespace otb::ogr

/*===========================================================================*/
/*===============================[ FieldDefn ]===============================*/
/*===========================================================================*/

std::string otb::ogr::FieldDefn::GetName() const
{
  assert(m_Definition && "No field definition wrapped");
  return m_Definition->GetNameRef();
}

OGRFieldType otb::ogr::FieldDefn::GetType() const
{
  assert(m_Definition && "No field definition wrapped");
  return m_Definition->GetType();
}

std::ostream & otb::ogr::operator<<(std::ostream & os, otb::ogr::FieldDefn const& defn)
{
  return os << defn.GetName()
    << " (" << OGRFieldDefn::GetFieldTypeName(defn.GetType()) << ")";
}
/*===========================================================================*/
/*=================================[ Field ]=================================*/
/*===========================================================================*/

otb::ogr::Field::Field(otb::ogr::Feature & feature, size_t index)
: m_Definition(*feature.ogr().GetFieldDefnRef(index))
, m_Feature(feature.sptr())
, m_index(index)
{
  CheckInvariants();
}

std::ostream & otb::ogr::Field::UncheckedPrintSelf(
  std::ostream& os, itk::Indent indent) const
{
  //const itk::Indent one_indent = itk::Indent().GetNextIndent();
  // os << indent << "|" << one_indent << "+ ";
  os << indent << this->GetName() << ": ";
  switch (this->GetType())
    {
  case OFTInteger:
    os << this->GetValue<int>();
    break;
  case OFTIntegerList:
    os << '{';
    otb::Join(os, this->GetValue<std::vector<int> >(), ", ") << '}';
    break;
  case OFTReal   :
    os << this->GetValue<double>();
    break;
  case OFTRealList:
    os << '{';
    otb::Join(os, this->GetValue<std::vector<double> >(), ", ") << '}';
    break;
  case OFTString :
    os << this->GetValue<std::string>();
    break;
  default:
    os << "??? -> " << this->GetType();
    break;
    }
  os << " (" << OGRFieldDefn::GetFieldTypeName(this->GetType()) << ")";
  os << "\n";
  return os;
}

bool otb::ogr::Field::UncheckedHasBeenSet() const
{
  return m_Feature->IsFieldSet(m_index);
}

void otb::ogr::Field::UncheckedUnset() const
{
  m_Feature->UnsetField(m_index);
}

void otb::ogr::Field::UncheckedAssign(Field const& f)
{
  if (f.HasBeenSet())
    {
    OGRField & of = f.ogr();
    m_Feature->SetField(m_index, &of); // OGR API copies *of
    }
  else // not sure OGR setField handle the case where new fields are unset
    {
    this->Unset();
    }
}
<|endoftext|>