Commit ef77ed63 authored by Thomas Ives's avatar Thomas Ives Committed by Thomas Braun
Browse files

server/utils_spec_templ.h: Move into Util.h

This follows what we have done with the w_attribute_spec_templ.h file in
37b41142 (w_attribute.h: Move template specialization to this file,
2025-04-17).
parent ca820e68
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -84,7 +84,6 @@ set(SERVER_HEADERS UserDefaultAttrProp.h
    TimedCmdData.h
    Util.h
    Util_templ.h
    utils_spec_templ.h
    WAttribute.h
    w_attrsetval_templ.h
    WPipe.h
+304 −1
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#include <tango/client/ApiUtil.h>
#include <tango/server/AttrHistoryStack.h>
#include <tango/server/CmdHistoryStack.h>
#include <tango/server/DeviceImpl.h>
#include <tango/server/PollingThreadInfo.h>
#include <tango/server/PollThread.h>
#include <tango/server/RootAttRegistry.h>
@@ -31,7 +32,6 @@
namespace Tango
{

class DeviceImpl;
class DeviceClass;
class DServer;
class AutoTangoMonitor;
@@ -1525,6 +1525,309 @@ std::ostream &operator<<(std::ostream &o_str, const AttrWriteType &writable);
std::ostream &operator<<(std::ostream &o_str, const PipeWriteType &writable);
std::ostream &operator<<(std::ostream &o_str, const DispLevel &level);
std::ostream &operator<<(std::ostream &o_str, const FwdAttError &fae);

//+---------------------------------------------------------------------------------------------------------------
//
// method :
//        Util::fill_cmd_polling_buffer
//
// description :
//        Fill attribute polling buffer with your own data
//        These are template specialization for data type
//                DevBoolean
//                DevUChar
//        This is required because the insertion of these data type in a CORBA Any object requires specific code
//
// args :
//        in :
//             - dev : The device
//            - cmd_name : The command name
//            - data : The command data to be stored in the polling buffer
//
//----------------------------------------------------------------------------------------------------------------

template <>
inline void Util::fill_cmd_polling_buffer(DeviceImpl *dev, std::string &cmd_name, CmdHistoryStack<DevBoolean> &data)
{
    //
    // Check that the device is polled
    //

    if(!dev->is_polled())
    {
        TangoSys_OMemStream o;
        o << "Device " << dev->get_name() << " is not polled" << std::ends;

        TANGO_THROW_EXCEPTION(API_DeviceNotPolled, o.str());
    }

    //
    // Command name in lower case letters and check that it is marked as polled
    //

    std::string obj_name(cmd_name);
    std::transform(obj_name.begin(), obj_name.end(), obj_name.begin(), ::tolower);

    dev->get_polled_obj_by_type_name(Tango::POLL_CMD, obj_name);

    //
    // Check that history is not larger than polling buffer
    //

    size_t nb_elt = data.length();
    long nb_poll = dev->get_cmd_poll_ring_depth(cmd_name);

    if(nb_elt > (size_t) nb_poll)
    {
        TangoSys_OMemStream o;
        o << "The polling buffer depth for command " << cmd_name;
        o << " for device " << dev->get_name();
        o << " is only " << nb_poll;
        o << " which is less than " << nb_elt << "!" << std::ends;

        TANGO_THROW_EXCEPTION(API_DeviceNotPolled, o.str());
    }

    //
    // Take the device monitor before the loop
    // In case of large element number, it is time cousuming to take/release
    // the monitor in the loop
    //

    dev->get_poll_monitor().get_monitor();

    //
    // A loop on each record
    //

    size_t i;
    Tango::DevFailed *save_except = nullptr;
    bool cmd_failed;
    CORBA::Any *any_ptr = nullptr;

    for(i = 0; i < nb_elt; i++)
    {
        save_except = nullptr;
        cmd_failed = false;

        if((data.get_data())[i].err.length() != 0)
        {
            cmd_failed = true;
            try
            {
                save_except = new Tango::DevFailed((data.get_data())[i].err);
            }
            catch(std::bad_alloc &)
            {
                dev->get_poll_monitor().rel_monitor();
                TANGO_THROW_EXCEPTION(API_MemoryAllocation, "Can't allocate memory in server");
            }
        }
        else
        {
            //
            // Allocate memory for the Any object
            //

            try
            {
                any_ptr = new CORBA::Any();
            }
            catch(std::bad_alloc &)
            {
                dev->get_poll_monitor().rel_monitor();
                TANGO_THROW_EXCEPTION(API_MemoryAllocation, "Can't allocate memory in server");
            }

            //
            // Set command value in Any object
            //

            DevBoolean *tmp_ptr = (data.get_data())[i].ptr;
            CORBA::Any::from_boolean tmp(*tmp_ptr);
            (*any_ptr) <<= tmp;

            if((data.get_data())[i].release)
            {
                delete tmp_ptr;
            }
        }

        //
        // Fill one slot of polling buffer
        //

        try
        {
            auto ite = dev->get_polled_obj_by_type_name(Tango::POLL_CMD, obj_name);
            auto when = make_poll_time(data.get_data()[i].tp);
            auto zero = PollClock::duration::zero();
            if(!cmd_failed)
            {
                (*ite)->insert_data(any_ptr, when, zero);
            }
            else
            {
                (*ite)->insert_except(save_except, when, zero);
            }
        }
        catch(Tango::DevFailed &)
        {
            if(!cmd_failed)
            {
                delete any_ptr;
            }
            else
            {
                delete save_except;
            }
        }
    }

    dev->get_poll_monitor().rel_monitor();
}

template <>
inline void Util::fill_cmd_polling_buffer(DeviceImpl *dev, std::string &cmd_name, CmdHistoryStack<DevUChar> &data)
{
    //
    // Check that the device is polled
    //

    if(!dev->is_polled())
    {
        TangoSys_OMemStream o;
        o << "Device " << dev->get_name() << " is not polled" << std::ends;

        TANGO_THROW_EXCEPTION(API_DeviceNotPolled, o.str());
    }

    //
    // Command name in lower case letters and check that it is marked as polled
    //

    std::string obj_name(cmd_name);
    std::transform(obj_name.begin(), obj_name.end(), obj_name.begin(), ::tolower);

    dev->get_polled_obj_by_type_name(Tango::POLL_CMD, obj_name);

    //
    // Check that history is not larger than polling buffer
    //

    size_t nb_elt = data.length();
    long nb_poll = dev->get_cmd_poll_ring_depth(cmd_name);

    if(nb_elt > (size_t) nb_poll)
    {
        TangoSys_OMemStream o;
        o << "The polling buffer depth for command " << cmd_name;
        o << " for device " << dev->get_name();
        o << " is only " << nb_poll;
        o << " which is less than " << nb_elt << "!" << std::ends;

        TANGO_THROW_EXCEPTION(API_DeviceNotPolled, o.str());
    }

    //
    // Take the device monitor before the loop
    // In case of large element number, it is time cousuming to take/release
    // the monitor in the loop
    //

    dev->get_poll_monitor().get_monitor();

    //
    // A loop on each record
    //

    size_t i;
    Tango::DevFailed *save_except = nullptr;
    bool cmd_failed;
    CORBA::Any *any_ptr = nullptr;

    for(i = 0; i < nb_elt; i++)
    {
        save_except = nullptr;
        cmd_failed = false;

        if((data.get_data())[i].err.length() != 0)
        {
            cmd_failed = true;
            try
            {
                save_except = new Tango::DevFailed((data.get_data())[i].err);
            }
            catch(std::bad_alloc &)
            {
                dev->get_poll_monitor().rel_monitor();
                TANGO_THROW_EXCEPTION(API_MemoryAllocation, "Can't allocate memory in server");
            }
        }
        else
        {
            //
            // Allocate memory for the Any object
            //

            try
            {
                any_ptr = new CORBA::Any();
            }
            catch(std::bad_alloc &)
            {
                dev->get_poll_monitor().rel_monitor();
                TANGO_THROW_EXCEPTION(API_MemoryAllocation, "Can't allocate memory in server");
            }

            //
            // Set command value in Any object
            //

            DevUChar *tmp_ptr = (data.get_data())[i].ptr;
            CORBA::Any::from_octet tmp(*tmp_ptr);
            (*any_ptr) <<= tmp;

            if((data.get_data())[i].release)
            {
                delete tmp_ptr;
            }
        }

        //
        // Fill one slot of polling buffer
        //

        try
        {
            auto ite = dev->get_polled_obj_by_type_name(Tango::POLL_CMD, obj_name);
            auto when = make_poll_time(data.get_data()[i].tp);
            auto zero = PollClock::duration::zero();
            if(!cmd_failed)
            {
                (*ite)->insert_data(any_ptr, when, zero);
            }
            else
            {
                (*ite)->insert_except(save_except, when, zero);
            }
        }
        catch(Tango::DevFailed &)
        {
            if(!cmd_failed)
            {
                delete any_ptr;
            }
            else
            {
                delete save_except;
            }
        }
    }

    dev->get_poll_monitor().rel_monitor();
}

} // namespace Tango

#endif /* UTILS */
+0 −321
Original line number Diff line number Diff line
/*
 * SPDX-FileCopyrightText: 2011 Copyright contributors to the cppTango project
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */

#ifndef TANGO_SERVER_UTILS_SPEC_TEMPL_H
#define TANGO_SERVER_UTILS_SPEC_TEMPL_H

#include <tango/server/DeviceImpl.h>
#include <tango/server/tango_clock.h>
#include <tango/server/Util.h>

namespace Tango
{

//+---------------------------------------------------------------------------------------------------------------
//
// method :
//        Util::fill_cmd_polling_buffer
//
// description :
//        Fill attribute polling buffer with your own data
//        These are template specialization for data type
//                DevBoolean
//                DevUChar
//        This is required because the insertion of these data type in a CORBA Any object requires specific code
//
// args :
//        in :
//             - dev : The device
//            - cmd_name : The command name
//            - data : The command data to be stored in the polling buffer
//
//----------------------------------------------------------------------------------------------------------------

template <>
inline void Util::fill_cmd_polling_buffer(DeviceImpl *dev, std::string &cmd_name, CmdHistoryStack<DevBoolean> &data)
{
    //
    // Check that the device is polled
    //

    if(!dev->is_polled())
    {
        TangoSys_OMemStream o;
        o << "Device " << dev->get_name() << " is not polled" << std::ends;

        TANGO_THROW_EXCEPTION(API_DeviceNotPolled, o.str());
    }

    //
    // Command name in lower case letters and check that it is marked as polled
    //

    std::string obj_name(cmd_name);
    std::transform(obj_name.begin(), obj_name.end(), obj_name.begin(), ::tolower);

    dev->get_polled_obj_by_type_name(Tango::POLL_CMD, obj_name);

    //
    // Check that history is not larger than polling buffer
    //

    size_t nb_elt = data.length();
    long nb_poll = dev->get_cmd_poll_ring_depth(cmd_name);

    if(nb_elt > (size_t) nb_poll)
    {
        TangoSys_OMemStream o;
        o << "The polling buffer depth for command " << cmd_name;
        o << " for device " << dev->get_name();
        o << " is only " << nb_poll;
        o << " which is less than " << nb_elt << "!" << std::ends;

        TANGO_THROW_EXCEPTION(API_DeviceNotPolled, o.str());
    }

    //
    // Take the device monitor before the loop
    // In case of large element number, it is time cousuming to take/release
    // the monitor in the loop
    //

    dev->get_poll_monitor().get_monitor();

    //
    // A loop on each record
    //

    size_t i;
    Tango::DevFailed *save_except = nullptr;
    bool cmd_failed;
    CORBA::Any *any_ptr = nullptr;

    for(i = 0; i < nb_elt; i++)
    {
        save_except = nullptr;
        cmd_failed = false;

        if((data.get_data())[i].err.length() != 0)
        {
            cmd_failed = true;
            try
            {
                save_except = new Tango::DevFailed((data.get_data())[i].err);
            }
            catch(std::bad_alloc &)
            {
                dev->get_poll_monitor().rel_monitor();
                TANGO_THROW_EXCEPTION(API_MemoryAllocation, "Can't allocate memory in server");
            }
        }
        else
        {
            //
            // Allocate memory for the Any object
            //

            try
            {
                any_ptr = new CORBA::Any();
            }
            catch(std::bad_alloc &)
            {
                dev->get_poll_monitor().rel_monitor();
                TANGO_THROW_EXCEPTION(API_MemoryAllocation, "Can't allocate memory in server");
            }

            //
            // Set command value in Any object
            //

            DevBoolean *tmp_ptr = (data.get_data())[i].ptr;
            CORBA::Any::from_boolean tmp(*tmp_ptr);
            (*any_ptr) <<= tmp;

            if((data.get_data())[i].release)
            {
                delete tmp_ptr;
            }
        }

        //
        // Fill one slot of polling buffer
        //

        try
        {
            auto ite = dev->get_polled_obj_by_type_name(Tango::POLL_CMD, obj_name);
            auto when = make_poll_time(data.get_data()[i].tp);
            auto zero = PollClock::duration::zero();
            if(!cmd_failed)
            {
                (*ite)->insert_data(any_ptr, when, zero);
            }
            else
            {
                (*ite)->insert_except(save_except, when, zero);
            }
        }
        catch(Tango::DevFailed &)
        {
            if(!cmd_failed)
            {
                delete any_ptr;
            }
            else
            {
                delete save_except;
            }
        }
    }

    dev->get_poll_monitor().rel_monitor();
}

template <>
inline void Util::fill_cmd_polling_buffer(DeviceImpl *dev, std::string &cmd_name, CmdHistoryStack<DevUChar> &data)
{
    //
    // Check that the device is polled
    //

    if(!dev->is_polled())
    {
        TangoSys_OMemStream o;
        o << "Device " << dev->get_name() << " is not polled" << std::ends;

        TANGO_THROW_EXCEPTION(API_DeviceNotPolled, o.str());
    }

    //
    // Command name in lower case letters and check that it is marked as polled
    //

    std::string obj_name(cmd_name);
    std::transform(obj_name.begin(), obj_name.end(), obj_name.begin(), ::tolower);

    dev->get_polled_obj_by_type_name(Tango::POLL_CMD, obj_name);

    //
    // Check that history is not larger than polling buffer
    //

    size_t nb_elt = data.length();
    long nb_poll = dev->get_cmd_poll_ring_depth(cmd_name);

    if(nb_elt > (size_t) nb_poll)
    {
        TangoSys_OMemStream o;
        o << "The polling buffer depth for command " << cmd_name;
        o << " for device " << dev->get_name();
        o << " is only " << nb_poll;
        o << " which is less than " << nb_elt << "!" << std::ends;

        TANGO_THROW_EXCEPTION(API_DeviceNotPolled, o.str());
    }

    //
    // Take the device monitor before the loop
    // In case of large element number, it is time cousuming to take/release
    // the monitor in the loop
    //

    dev->get_poll_monitor().get_monitor();

    //
    // A loop on each record
    //

    size_t i;
    Tango::DevFailed *save_except = nullptr;
    bool cmd_failed;
    CORBA::Any *any_ptr = nullptr;

    for(i = 0; i < nb_elt; i++)
    {
        save_except = nullptr;
        cmd_failed = false;

        if((data.get_data())[i].err.length() != 0)
        {
            cmd_failed = true;
            try
            {
                save_except = new Tango::DevFailed((data.get_data())[i].err);
            }
            catch(std::bad_alloc &)
            {
                dev->get_poll_monitor().rel_monitor();
                TANGO_THROW_EXCEPTION(API_MemoryAllocation, "Can't allocate memory in server");
            }
        }
        else
        {
            //
            // Allocate memory for the Any object
            //

            try
            {
                any_ptr = new CORBA::Any();
            }
            catch(std::bad_alloc &)
            {
                dev->get_poll_monitor().rel_monitor();
                TANGO_THROW_EXCEPTION(API_MemoryAllocation, "Can't allocate memory in server");
            }

            //
            // Set command value in Any object
            //

            DevUChar *tmp_ptr = (data.get_data())[i].ptr;
            CORBA::Any::from_octet tmp(*tmp_ptr);
            (*any_ptr) <<= tmp;

            if((data.get_data())[i].release)
            {
                delete tmp_ptr;
            }
        }

        //
        // Fill one slot of polling buffer
        //

        try
        {
            auto ite = dev->get_polled_obj_by_type_name(Tango::POLL_CMD, obj_name);
            auto when = make_poll_time(data.get_data()[i].tp);
            auto zero = PollClock::duration::zero();
            if(!cmd_failed)
            {
                (*ite)->insert_data(any_ptr, when, zero);
            }
            else
            {
                (*ite)->insert_except(save_except, when, zero);
            }
        }
        catch(Tango::DevFailed &)
        {
            if(!cmd_failed)
            {
                delete any_ptr;
            }
            else
            {
                delete save_except;
            }
        }
    }

    dev->get_poll_monitor().rel_monitor();
}

} // namespace Tango

#endif /* UTILS_SPEC_TPP */