/*
 * SPDX-FileCopyrightText: 2004 Copyright contributors to the cppTango project
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */

#include <tango/server/AttrManip.h>

#include <tango/common/defines.h>

namespace Tango
{

void execute_manip(std::ostream &o_str, const std::string &manip)
{
    //
    // Set the ostream according to the manipulator
    //

    if(manip == "fixed")
    {
        o_str.setf(std::ios::fixed, std::ios::floatfield);
        return;
    }
    else if(manip == "scientific")
    {
        o_str.setf(std::ios::scientific, std::ios::floatfield);
        return;
    }
    else if(manip == "uppercase")
    {
        o_str.setf(std::ios::uppercase);
        return;
    }
    else if(manip == "showpoint")
    {
        o_str.setf(std::ios::showpoint);
        return;
    }
    else if(manip == "showpos")
    {
        o_str.setf(std::ios::showpos);
        return;
    }
    else if(manip.substr(0, 13) == "setprecision(")
    {
        std::string num_str = manip.substr(13, manip.size() - 14);
        TangoSys_MemStream o;
        long num;
        o << num_str;
        o >> num;

        o_str.precision(num);
    }
    else if(manip.substr(0, 5) == "setw(")
    {
        std::string num_str = manip.substr(5, manip.size() - 6);
        TangoSys_MemStream o;
        long num;
        o << num_str;
        o >> num;

        o_str.width(num);
    }
}

std::ostream &operator<<(std::ostream &o_str, const AttrManip &manip)
{
    //
    // Extract each manipulator (; separated) and call the execute_manip for each one
    //

    std::string::size_type start = 0;
    std::string str;
    std::string::size_type pos;

    while((pos = manip.format.find(';', start)) != std::string::npos)
    {
        str = manip.format.substr(start, pos - start);
        start = pos + 1;
        execute_manip(o_str, str);
    }
    if(start != manip.format.size())
    {
        str = manip.format.substr(start);
        execute_manip(o_str, str);
    }

    return o_str;
}

} // namespace Tango
