<commit_before>// ClockTool.cc
// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
//                and Simon Bowden    (rathnor at users.sourceforge.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id$

#include "ClockTool.hh"

#include "ToolTheme.hh"
#include "Screen.hh"
#include "CommandParser.hh"
#include "CommandDialog.hh"
#include "fluxbox.hh"

#include "FbTk/SimpleCommand.hh"
#include "FbTk/ImageControl.hh"
#include "FbTk/Menu.hh"
#include "FbTk/MenuItem.hh"
#include "FbTk/I18n.hh"

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif // HAVE_CONFIG_H

#ifdef HAVE_CTIME
  #include <ctime>
#else
  #include <time.h>
#endif
#include <sys/time.h>
#include <string>
#include <typeinfo>

class ClockMenuItem: public FbTk::MenuItem {
public:
    explicit ClockMenuItem(ClockTool &tool):
        FbTk::MenuItem(""), m_tool(tool) {
        // determine 12/24 hour format
        _FB_USES_NLS;
        if (m_tool.timeFormat().find("%k") != std::string::npos ||
            m_tool.timeFormat().find("%H") != std::string::npos ||
            m_tool.timeFormat().find("%T") != std::string::npos)
            setLabel( _FB_XTEXT(Toolbar, Clock24,   "Clock: 24h",   "set Clockmode to 24h") );
        else
            setLabel( _FB_XTEXT(Toolbar, Clock12,   "Clock: 12h",   "set Clockmode to 12h") );
    }

    void click(int button, int time) {
        std::string newformat = m_tool.timeFormat();
        size_t pos = newformat.find("%k");
        std::string newstr;
        bool clock24hour = true;

        _FB_USES_NLS;

        if (pos != std::string::npos)
            newstr = "%l";
        else if ((pos = newformat.find("%H")) != std::string::npos)
            newstr = "%I";
        else if ((pos = newformat.find("%T")) != std::string::npos)
            newstr = "%r";

        // 12 hour
        if (newstr.empty()) {
            clock24hour = false;
            if ((pos = newformat.find("%l")) != std::string::npos)
                newstr = "%k";
            else if ((pos = newformat.find("%I")) != std::string::npos)
                newstr = "%H";
            else if ((pos = newformat.find("%r")) != std::string::npos)
                newstr = "%T";

        }

        if (!newstr.empty()) {

            newformat.replace(pos, 2, newstr);
            if (!clock24hour) { // erase %P/%p (AM|PM / am|pm)
                pos = newformat.find("%p");
                if (pos != std::string::npos)
                    newformat.erase(pos, 2);
                else if ((pos = newformat.find("%P")) != std::string::npos)
                    newformat.erase(pos, 2);
            }

            m_tool.setTimeFormat(newformat);

            if (m_tool.timeFormat().find("%k") != std::string::npos ||
                m_tool.timeFormat().find("%H") != std::string::npos ||
                m_tool.timeFormat().find("%T") != std::string::npos)
                setLabel( _FB_XTEXT(Toolbar, Clock24,   "Clock: 24h",   "set Clockmode to 24h") );
            else
                setLabel( _FB_XTEXT(Toolbar, Clock12,   "Clock: 12h",   "set Clockmode to 12h") );

        } // else some other strange format...so we don't do anything
        FbTk::MenuItem::click(button, time);
    }
private:
    ClockTool &m_tool;
};

class EditClockFormatCmd: public FbTk::Command {
public:
    void execute() {
        BScreen *screen = Fluxbox::instance()->mouseScreen();
        if (screen == 0)
            return;
        std::string resourcename = screen->name() + ".strftimeFormat";

        CommandDialog *dialog = new CommandDialog(*screen, "Edit Clock Format",
                                                  "SetResourceValue " + resourcename + " ");
        FbTk::RefCount<FbTk::Command> cmd(CommandParser::instance().parseLine("reconfigure"));
        dialog->setPostCommand(cmd);
        dialog->setText(screen->resourceManager().resourceValue(resourcename));
        dialog->show();
    }
};

ClockTool::ClockTool(const FbTk::FbWindow &parent,
                     ToolTheme &theme, BScreen &screen, FbTk::Menu &menu):
    ToolbarItem(ToolbarItem::FIXED),
    m_button(parent, theme.font(), ""),
    m_theme(theme),
    m_screen(screen),
    m_pixmap(0),
    m_timeformat(screen.resourceManager(), std::string("%k:%M"),
                 screen.name() + ".strftimeFormat", screen.altName() + ".StrftimeFormat"),
    m_stringconvertor(FbTk::StringConvertor::ToFbString) {
    // attach signals
    theme.reconfigSig().attach(this);

    std::string time_locale = setlocale(LC_TIME, NULL);
    size_t pos = time_locale.find('.');
    if (pos != std::string::npos)
        time_locale = time_locale.substr(pos+1);
    if (!time_locale.empty())
        m_stringconvertor.setSource(time_locale);

    _FB_USES_NLS;

    // setup timer to check the clock every 0.01 second
    // if nothing has changed, it wont update the graphics
    m_timer.setInterval(1);
    // m_timer.setTimeout(delay); // don't need to set timeout on interval timer
    FbTk::RefCount<FbTk::Command> update_graphic(new FbTk::SimpleCommand<ClockTool>(*this,
                                                                                &ClockTool::updateTime));
    m_timer.setCommand(update_graphic);
    m_timer.start();

    m_button.setGC(m_theme.textGC());

    // setup menu
    FbTk::RefCount<FbTk::Command> saverc(CommandParser::instance().parseLine("saverc"));
    FbTk::MenuItem *item = new ClockMenuItem(*this);
    item->setCommand(saverc);
    menu.insert(item);
    FbTk::RefCount<FbTk::Command> editformat_cmd(new EditClockFormatCmd());
    menu.insert(_FB_XTEXT(Toolbar, ClockEditFormat,   "Edit Clock Format",   "edit Clock Format") , editformat_cmd);

    update(0);
}

ClockTool::~ClockTool() {
    // remove cached pixmap
    if (m_pixmap)
        m_screen.imageControl().removeImage(m_pixmap);
}

void ClockTool::move(int x, int y) {
    m_button.move(x, y);
}

void ClockTool::resize(unsigned int width, unsigned int height) {
    m_button.resize(width, height);
    reRender();
    m_button.clear();
}

void ClockTool::moveResize(int x, int y,
                      unsigned int width, unsigned int height) {
    m_button.moveResize(x, y, width, height);
    reRender();
    m_button.clear();
}

void ClockTool::show() {
    m_button.show();
}

void ClockTool::hide() {
    m_button.hide();
}

void ClockTool::setTimeFormat(const std::string &format) {
    *m_timeformat = format;
    update(0);
}

void ClockTool::update(FbTk::Subject *subj) {
    updateTime();

    // + 2 to make the entire text fit inside
    // we only replace numbers with zeros because everything else should be
    // relatively static. If we replace all text with zeros then widths of
    // proportional fonts with some strftime formats will be considerably off.
    std::string text(m_button.text());

    int textlen = text.size();
    for (int i=0; i < textlen; ++i) {
        if (text[i] > '0' && text[i] <= '9') // don't bother replacing zeros
            text[i] = '0';
    }
    text.append("00"); // pad

    unsigned int new_width = m_button.width();
    unsigned int new_height = m_button.height();
    translateSize(orientation(), new_width, new_height);
    new_width = m_theme.font().textWidth(text.c_str(), text.size());
    translateSize(orientation(), new_width, new_height);
    if (new_width != m_button.width() || new_height != m_button.height()) {
        resize(new_width, new_height);
        resizeSig().notify();
    }

    if (subj != 0 && typeid(*subj) == typeid(ToolTheme))
        renderTheme(m_button.alpha());

}

unsigned int ClockTool::borderWidth() const {
    return m_button.borderWidth();
}

unsigned int ClockTool::width() const {
    return m_button.width();
}

unsigned int ClockTool::height() const {
    return m_button.height();
}

void ClockTool::updateTime() {
    // update clock
    timeval now;
    gettimeofday(&now, 0);
    time_t the_time = now.tv_sec;

    if (the_time != -1) {
        char time_string[255];
        int time_string_len;
        struct tm *time_type = localtime(&the_time);
        if (time_type == 0)
            return;

#ifdef HAVE_STRFTIME
        time_string_len = strftime(time_string, 255, m_timeformat->c_str(), time_type);
        if( time_string_len == 0)
            return;
        std::string text = m_stringconvertor.recode(time_string);
        if (m_button.text() == text)
            return;

        m_button.setText(text);

        unsigned int new_width = m_theme.font().textWidth(time_string, time_string_len) + 2;
        if (new_width > m_button.width()) {
            resize(new_width, m_button.height());
            resizeSig().notify();
        }
#else // dont have strftime so we have to set it to hour:minut
        //        sprintf(time_string, "%d:%d", );
#endif // HAVE_STRFTIME
    }
}

// Just change things that affect the size
void ClockTool::updateSizing() {
    m_button.setBorderWidth(m_theme.border().width());
    // resizes if new timeformat
    update(0);
}

void ClockTool::reRender() {
    if (m_pixmap)
        m_screen.imageControl().removeImage(m_pixmap);

    if (m_theme.texture().usePixmap()) {
        m_pixmap = m_screen.imageControl().renderImage(width(), height(),
                                                       m_theme.texture(), orientation());
        m_button.setBackgroundPixmap(m_pixmap);
    } else {
        m_pixmap = 0;
        m_button.setBackgroundColor(m_theme.texture().color());
    }
}

void ClockTool::renderTheme(unsigned char alpha) {
    m_button.setAlpha(alpha);
    m_button.setJustify(m_theme.justify());

    reRender();

    m_button.setBorderWidth(m_theme.border().width());
    m_button.setBorderColor(m_theme.border().color());
    m_button.clear();
}

void ClockTool::setOrientation(FbTk::Orientation orient) {
    m_button.setOrientation(orient);
    ToolbarItem::setOrientation(orient);
}
<commit_msg>use proper test for whether it's a number.<commit_after>// ClockTool.cc
// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
//                and Simon Bowden    (rathnor at users.sourceforge.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id$

#include "ClockTool.hh"

#include "ToolTheme.hh"
#include "Screen.hh"
#include "CommandParser.hh"
#include "CommandDialog.hh"
#include "fluxbox.hh"

#include "FbTk/SimpleCommand.hh"
#include "FbTk/ImageControl.hh"
#include "FbTk/Menu.hh"
#include "FbTk/MenuItem.hh"
#include "FbTk/I18n.hh"

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif // HAVE_CONFIG_H

#ifdef HAVE_CTIME
  #include <ctime>
#else
  #include <time.h>
#endif
#include <sys/time.h>
#include <string>
#include <typeinfo>

class ClockMenuItem: public FbTk::MenuItem {
public:
    explicit ClockMenuItem(ClockTool &tool):
        FbTk::MenuItem(""), m_tool(tool) {
        // determine 12/24 hour format
        _FB_USES_NLS;
        if (m_tool.timeFormat().find("%k") != std::string::npos ||
            m_tool.timeFormat().find("%H") != std::string::npos ||
            m_tool.timeFormat().find("%T") != std::string::npos)
            setLabel( _FB_XTEXT(Toolbar, Clock24,   "Clock: 24h",   "set Clockmode to 24h") );
        else
            setLabel( _FB_XTEXT(Toolbar, Clock12,   "Clock: 12h",   "set Clockmode to 12h") );
    }

    void click(int button, int time) {
        std::string newformat = m_tool.timeFormat();
        size_t pos = newformat.find("%k");
        std::string newstr;
        bool clock24hour = true;

        _FB_USES_NLS;

        if (pos != std::string::npos)
            newstr = "%l";
        else if ((pos = newformat.find("%H")) != std::string::npos)
            newstr = "%I";
        else if ((pos = newformat.find("%T")) != std::string::npos)
            newstr = "%r";

        // 12 hour
        if (newstr.empty()) {
            clock24hour = false;
            if ((pos = newformat.find("%l")) != std::string::npos)
                newstr = "%k";
            else if ((pos = newformat.find("%I")) != std::string::npos)
                newstr = "%H";
            else if ((pos = newformat.find("%r")) != std::string::npos)
                newstr = "%T";

        }

        if (!newstr.empty()) {

            newformat.replace(pos, 2, newstr);
            if (!clock24hour) { // erase %P/%p (AM|PM / am|pm)
                pos = newformat.find("%p");
                if (pos != std::string::npos)
                    newformat.erase(pos, 2);
                else if ((pos = newformat.find("%P")) != std::string::npos)
                    newformat.erase(pos, 2);
            }

            m_tool.setTimeFormat(newformat);

            if (m_tool.timeFormat().find("%k") != std::string::npos ||
                m_tool.timeFormat().find("%H") != std::string::npos ||
                m_tool.timeFormat().find("%T") != std::string::npos)
                setLabel( _FB_XTEXT(Toolbar, Clock24,   "Clock: 24h",   "set Clockmode to 24h") );
            else
                setLabel( _FB_XTEXT(Toolbar, Clock12,   "Clock: 12h",   "set Clockmode to 12h") );

        } // else some other strange format...so we don't do anything
        FbTk::MenuItem::click(button, time);
    }
private:
    ClockTool &m_tool;
};

class EditClockFormatCmd: public FbTk::Command {
public:
    void execute() {
        BScreen *screen = Fluxbox::instance()->mouseScreen();
        if (screen == 0)
            return;
        std::string resourcename = screen->name() + ".strftimeFormat";

        CommandDialog *dialog = new CommandDialog(*screen, "Edit Clock Format",
                                                  "SetResourceValue " + resourcename + " ");
        FbTk::RefCount<FbTk::Command> cmd(CommandParser::instance().parseLine("reconfigure"));
        dialog->setPostCommand(cmd);
        dialog->setText(screen->resourceManager().resourceValue(resourcename));
        dialog->show();
    }
};

ClockTool::ClockTool(const FbTk::FbWindow &parent,
                     ToolTheme &theme, BScreen &screen, FbTk::Menu &menu):
    ToolbarItem(ToolbarItem::FIXED),
    m_button(parent, theme.font(), ""),
    m_theme(theme),
    m_screen(screen),
    m_pixmap(0),
    m_timeformat(screen.resourceManager(), std::string("%k:%M"),
                 screen.name() + ".strftimeFormat", screen.altName() + ".StrftimeFormat"),
    m_stringconvertor(FbTk::StringConvertor::ToFbString) {
    // attach signals
    theme.reconfigSig().attach(this);

    std::string time_locale = setlocale(LC_TIME, NULL);
    size_t pos = time_locale.find('.');
    if (pos != std::string::npos)
        time_locale = time_locale.substr(pos+1);
    if (!time_locale.empty())
        m_stringconvertor.setSource(time_locale);

    _FB_USES_NLS;

    // setup timer to check the clock every 0.01 second
    // if nothing has changed, it wont update the graphics
    m_timer.setInterval(1);
    // m_timer.setTimeout(delay); // don't need to set timeout on interval timer
    FbTk::RefCount<FbTk::Command> update_graphic(new FbTk::SimpleCommand<ClockTool>(*this,
                                                                                &ClockTool::updateTime));
    m_timer.setCommand(update_graphic);
    m_timer.start();

    m_button.setGC(m_theme.textGC());

    // setup menu
    FbTk::RefCount<FbTk::Command> saverc(CommandParser::instance().parseLine("saverc"));
    FbTk::MenuItem *item = new ClockMenuItem(*this);
    item->setCommand(saverc);
    menu.insert(item);
    FbTk::RefCount<FbTk::Command> editformat_cmd(new EditClockFormatCmd());
    menu.insert(_FB_XTEXT(Toolbar, ClockEditFormat,   "Edit Clock Format",   "edit Clock Format") , editformat_cmd);

    update(0);
}

ClockTool::~ClockTool() {
    // remove cached pixmap
    if (m_pixmap)
        m_screen.imageControl().removeImage(m_pixmap);
}

void ClockTool::move(int x, int y) {
    m_button.move(x, y);
}

void ClockTool::resize(unsigned int width, unsigned int height) {
    m_button.resize(width, height);
    reRender();
    m_button.clear();
}

void ClockTool::moveResize(int x, int y,
                      unsigned int width, unsigned int height) {
    m_button.moveResize(x, y, width, height);
    reRender();
    m_button.clear();
}

void ClockTool::show() {
    m_button.show();
}

void ClockTool::hide() {
    m_button.hide();
}

void ClockTool::setTimeFormat(const std::string &format) {
    *m_timeformat = format;
    update(0);
}

void ClockTool::update(FbTk::Subject *subj) {
    updateTime();

    // + 2 to make the entire text fit inside
    // we only replace numbers with zeros because everything else should be
    // relatively static. If we replace all text with zeros then widths of
    // proportional fonts with some strftime formats will be considerably off.
    std::string text(m_button.text());

    int textlen = text.size();
    for (int i=0; i < textlen; ++i) {
        if (isdigit(text[i])) // don't bother replacing zeros
            text[i] = '0';
    }
    text.append("00"); // pad

    unsigned int new_width = m_button.width();
    unsigned int new_height = m_button.height();
    translateSize(orientation(), new_width, new_height);
    new_width = m_theme.font().textWidth(text.c_str(), text.size());
    translateSize(orientation(), new_width, new_height);
    if (new_width != m_button.width() || new_height != m_button.height()) {
        resize(new_width, new_height);
        resizeSig().notify();
    }

    if (subj != 0 && typeid(*subj) == typeid(ToolTheme))
        renderTheme(m_button.alpha());

}

unsigned int ClockTool::borderWidth() const {
    return m_button.borderWidth();
}

unsigned int ClockTool::width() const {
    return m_button.width();
}

unsigned int ClockTool::height() const {
    return m_button.height();
}

void ClockTool::updateTime() {
    // update clock
    timeval now;
    gettimeofday(&now, 0);
    time_t the_time = now.tv_sec;

    if (the_time != -1) {
        char time_string[255];
        int time_string_len;
        struct tm *time_type = localtime(&the_time);
        if (time_type == 0)
            return;

#ifdef HAVE_STRFTIME
        time_string_len = strftime(time_string, 255, m_timeformat->c_str(), time_type);
        if( time_string_len == 0)
            return;
        std::string text = m_stringconvertor.recode(time_string);
        if (m_button.text() == text)
            return;

        m_button.setText(text);

        unsigned int new_width = m_theme.font().textWidth(time_string, time_string_len) + 2;
        if (new_width > m_button.width()) {
            resize(new_width, m_button.height());
            resizeSig().notify();
        }
#else // dont have strftime so we have to set it to hour:minut
        //        sprintf(time_string, "%d:%d", );
#endif // HAVE_STRFTIME
    }
}

// Just change things that affect the size
void ClockTool::updateSizing() {
    m_button.setBorderWidth(m_theme.border().width());
    // resizes if new timeformat
    update(0);
}

void ClockTool::reRender() {
    if (m_pixmap)
        m_screen.imageControl().removeImage(m_pixmap);

    if (m_theme.texture().usePixmap()) {
        m_pixmap = m_screen.imageControl().renderImage(width(), height(),
                                                       m_theme.texture(), orientation());
        m_button.setBackgroundPixmap(m_pixmap);
    } else {
        m_pixmap = 0;
        m_button.setBackgroundColor(m_theme.texture().color());
    }
}

void ClockTool::renderTheme(unsigned char alpha) {
    m_button.setAlpha(alpha);
    m_button.setJustify(m_theme.justify());

    reRender();

    m_button.setBorderWidth(m_theme.border().width());
    m_button.setBorderColor(m_theme.border().color());
    m_button.clear();
}

void ClockTool::setOrientation(FbTk::Orientation orient) {
    m_button.setOrientation(orient);
    ToolbarItem::setOrientation(orient);
}
<|endoftext|>


<commit_before>//
// Created by a1 on 16-11-2.
//
#include "encode.h"

static string encode_key_internal(const string& key, const string& field, uint16_t version);
static string encode_meta_val_internal(const char type, uint64_t length, uint16_t version, char del);
static uint64_t encodeScore(const double score);

string encode_meta_key(const Bytes& key){
    string buf;

    buf.append(1, 'M');
    uint16_t slot = (uint16_t)keyHashSlot(key.data(), key.size());
    slot = htobe16(slot);
    buf.append((char *)&slot, sizeof(uint16_t));

    buf.append(key.String());

    return buf;
}

static string encode_key_internal(const string& key, const string& field, uint16_t version){
    string buf;

    buf.append(1, 'S');

    uint16_t len = htobe16((uint16_t)key.size());
    buf.append((char *)&len, sizeof(uint16_t));
    buf.append(key);

    version = htobe16(version);
    buf.append((char *)&version, sizeof(uint16_t));

    buf.append(field);

    return buf;
}

string encode_hash_key(const Bytes& key, const Bytes& field, uint16_t version){
    return encode_key_internal(key.String(), field.String(), version);
}

string encode_set_key(const Bytes& key, const Bytes& member, uint16_t version){
    return encode_key_internal(key.String(), member.String(), version);
}

string encode_zset_key(const Bytes& key, const Bytes& member, uint16_t version){
    return encode_key_internal(key.String(), member.String(), version);
}

static uint64_t encodeScore(const double score) {
    int64_t iscore;
    if (score < 0) {
        iscore = (int64_t)(score * 100000LL - 0.5) + ZSET_SCORE_SHIFT;
    } else {
        iscore = (int64_t)(score * 100000LL + 0.5) + ZSET_SCORE_SHIFT;
    }
    return (uint64_t)(iscore);
}

string encode_zscore_key(const Bytes& key, const Bytes& member, double score, uint16_t version){
    string buf;

    buf.append(1, DataType::ZSCORE);

    uint16_t len = htobe16((uint16_t)key.size());
    buf.append((char *)&len, sizeof(uint16_t));
    buf.append(key.data(), key.size());

    version = htobe16(version);
    buf.append((char *)&version, sizeof(uint16_t));

    uint64_t new_score = encodeScore(score);
    new_score = htobe64(new_score);
    buf.append((char *)&new_score, sizeof(uint64_t));

    buf.append(member.data(), member.size());

    return buf;
}

string encode_list_key(const Bytes& key, uint64_t seq, uint16_t version){
    string buf;

    buf.append(1, 'S');

    uint16_t len = htobe16((uint16_t)key.size());
    buf.append((char *)&len, sizeof(uint16_t));
    buf.append(key.String());

    version = htobe16(version);
    buf.append((char *)&version, sizeof(uint16_t));

    seq = htobe64(seq);
    buf.append((char *)&seq, sizeof(uint64_t));

    return buf;
}

string encode_kv_val(const string& val, uint16_t version, char del){
    string buf;
    buf.append(1, DataType::KV);

    version = htobe16(version);
    buf.append((char *)&version, sizeof(uint16_t));

    buf.append(1, del);

    buf.append(val);
    return buf;
}

static string encode_meta_val_internal(const char type, uint64_t length, uint16_t version, char del){
    string buf;

    buf.append(1, type);
    version = htobe16(version);
    buf.append((char *)&version, sizeof(uint16_t));

    buf.append(1, del);

    length = htobe64(length);
    buf.append((char *)&length, sizeof(uint64_t));

    return buf;
}

string encode_hash_meta_val(uint64_t length, uint16_t version, char del){
    return encode_meta_val_internal(DataType::HSIZE, length, version, del);
}

string encode_set_meta_val(uint64_t length, uint16_t version, char del){
    return encode_meta_val_internal(DataType::SSIZE, length, version, del);
}

string encode_zset_meta_val(uint64_t length, uint16_t version, char del){
    return encode_meta_val_internal(DataType::ZSIZE, length, version, del);
}

string encode_list_meta_val(uint64_t length, uint64_t left, uint64_t right, uint16_t version, char del){
    string buf;

    buf.append(1, DataType::LSIZE);
    version = htobe16(version);
    buf.append((char *)&version, sizeof(uint16_t));

    buf.append(1, del);

    length = htobe64(length);
    buf.append((char *)&length, sizeof(uint64_t));

    left = htobe64(left);
    buf.append((char *)&left, sizeof(uint64_t));

    right = htobe64(right);
    buf.append((char *)&right, sizeof(uint64_t));

    return buf;
}

/*
 * delete key
 */
string encode_delete_key(const Bytes& key, char key_type, uint16_t version){
    string buf;
    buf.append(1, KEY_DELETE_MASK);

    uint16_t slot = (uint16_t)keyHashSlot(key.data(), key.size());
    slot = htobe16(slot);
    buf.append((char *)&slot, sizeof(uint16_t));

    uint16_t len = htobe16((uint16_t)key.size());
    buf.append((char *)&len, sizeof(uint16_t));
    buf.append(key.String());

    version = htobe16(version);
    buf.append((char *)&version, sizeof(uint16_t));

    buf.append(1, key_type);

    return buf;
}
<commit_msg>encode_key_internal<commit_after>//
// Created by a1 on 16-11-2.
//
#include "encode.h"

static string encode_key_internal(char type, const string& key, const string& field, uint16_t version);
static string encode_meta_val_internal(const char type, uint64_t length, uint16_t version, char del);
static uint64_t encodeScore(const double score);

string encode_meta_key(const Bytes& key){
    string buf;

    buf.append(1, 'M');
    uint16_t slot = (uint16_t)keyHashSlot(key.data(), key.size());
    slot = htobe16(slot);
    buf.append((char *)&slot, sizeof(uint16_t));

    buf.append(key.String());

    return buf;
}

static string encode_key_internal(char type, const string& key, const string& field, uint16_t version){
    string buf;

    buf.append(1, type);

    uint16_t len = htobe16((uint16_t)key.size());
    buf.append((char *)&len, sizeof(uint16_t));
    buf.append(key);

    version = htobe16(version);
    buf.append((char *)&version, sizeof(uint16_t));

    buf.append(field);

    return buf;
}

string encode_hash_key(const Bytes& key, const Bytes& field, uint16_t version){
    return encode_key_internal('S', key.String(), field.String(), version);
}

string encode_set_key(const Bytes& key, const Bytes& member, uint16_t version){
    return encode_key_internal('S', key.String(), member.String(), version);
}

string encode_zset_key(const Bytes& key, const Bytes& member, uint16_t version){
    return encode_key_internal('S', key.String(), member.String(), version);
}

static uint64_t encodeScore(const double score) {
    int64_t iscore;
    if (score < 0) {
        iscore = (int64_t)(score * 100000LL - 0.5) + ZSET_SCORE_SHIFT;
    } else {
        iscore = (int64_t)(score * 100000LL + 0.5) + ZSET_SCORE_SHIFT;
    }
    return (uint64_t)(iscore);
}

string encode_zscore_key(const Bytes& key, const Bytes& member, double score, uint16_t version){
    string buf;

    buf.append(1, DataType::ZSCORE);

    uint16_t len = htobe16((uint16_t)key.size());
    buf.append((char *)&len, sizeof(uint16_t));
    buf.append(key.data(), key.size());

    version = htobe16(version);
    buf.append((char *)&version, sizeof(uint16_t));

    uint64_t new_score = encodeScore(score);
    new_score = htobe64(new_score);
    buf.append((char *)&new_score, sizeof(uint64_t));

    buf.append(member.data(), member.size());

    return buf;
}

string encode_list_key(const Bytes& key, uint64_t seq, uint16_t version){
    string buf;

    buf.append(1, 'S');

    uint16_t len = htobe16((uint16_t)key.size());
    buf.append((char *)&len, sizeof(uint16_t));
    buf.append(key.String());

    version = htobe16(version);
    buf.append((char *)&version, sizeof(uint16_t));

    seq = htobe64(seq);
    buf.append((char *)&seq, sizeof(uint64_t));

    return buf;
}

string encode_kv_val(const string& val, uint16_t version, char del){
    string buf;
    buf.append(1, DataType::KV);

    version = htobe16(version);
    buf.append((char *)&version, sizeof(uint16_t));

    buf.append(1, del);

    buf.append(val);
    return buf;
}

static string encode_meta_val_internal(const char type, uint64_t length, uint16_t version, char del){
    string buf;

    buf.append(1, type);
    version = htobe16(version);
    buf.append((char *)&version, sizeof(uint16_t));

    buf.append(1, del);

    length = htobe64(length);
    buf.append((char *)&length, sizeof(uint64_t));

    return buf;
}

string encode_hash_meta_val(uint64_t length, uint16_t version, char del){
    return encode_meta_val_internal(DataType::HSIZE, length, version, del);
}

string encode_set_meta_val(uint64_t length, uint16_t version, char del){
    return encode_meta_val_internal(DataType::SSIZE, length, version, del);
}

string encode_zset_meta_val(uint64_t length, uint16_t version, char del){
    return encode_meta_val_internal(DataType::ZSIZE, length, version, del);
}

string encode_list_meta_val(uint64_t length, uint64_t left, uint64_t right, uint16_t version, char del){
    string buf;

    buf.append(1, DataType::LSIZE);
    version = htobe16(version);
    buf.append((char *)&version, sizeof(uint16_t));

    buf.append(1, del);

    length = htobe64(length);
    buf.append((char *)&length, sizeof(uint64_t));

    left = htobe64(left);
    buf.append((char *)&left, sizeof(uint64_t));

    right = htobe64(right);
    buf.append((char *)&right, sizeof(uint64_t));

    return buf;
}

/*
 * delete key
 */
string encode_delete_key(const Bytes& key, char key_type, uint16_t version){
    string buf;
    buf.append(1, KEY_DELETE_MASK);

    uint16_t slot = (uint16_t)keyHashSlot(key.data(), key.size());
    slot = htobe16(slot);
    buf.append((char *)&slot, sizeof(uint16_t));

    uint16_t len = htobe16((uint16_t)key.size());
    buf.append((char *)&len, sizeof(uint16_t));
    buf.append(key.String());

    version = htobe16(version);
    buf.append((char *)&version, sizeof(uint16_t));

    buf.append(1, key_type);

    return buf;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: TestPanel.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 19:15:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "TestPanel.hxx"
#include "taskpane/ScrollPanel.hxx"
#include "taskpane/TaskPaneControlFactory.hxx"

#include <vcl/lstbox.hxx>
#include <vcl/button.hxx>

namespace sd { namespace toolpanel {

/** This factory class is used to create instances of TestPanel.  It can be
    extended so that its constructor stores arguments that later are passed
    to new TestPanel objects.
*/
class TestPanelFactory
    : public ControlFactory
{
protected:
    virtual TreeNode* InternalCreateControl (TreeNode* pTreeNode)
    {
        return new TestPanel (pTreeNode);
    }
};

class Wrapper
    : public TreeNode
{
public:
    Wrapper (
        TreeNode* pParent,
        Size aPreferredSize,
        ::Window* pWrappedControl,
        bool bIsResizable)
        : TreeNode (pParent),
          maPreferredSize(aPreferredSize),
          mpWrappedControl(pWrappedControl),
          mbIsResizable(bIsResizable)
    {
        mpWrappedControl->Show();
    }
    virtual ~Wrapper (void)
    {
        delete mpWrappedControl;
    }

    virtual Size GetPreferredSize (void)
    {
        return maPreferredSize;
    }
    virtual sal_Int32 GetPreferredWidth (sal_Int32 nHeigh)
    {
        return maPreferredSize.Width();
    }
    virtual sal_Int32 GetPreferredHeight (sal_Int32 nWidth)
    {
        return maPreferredSize.Height();
    }
    virtual ::Window* GetWindow (void)
    {
        return mpWrappedControl;
    }
    virtual bool IsResizable (void)
    {
        return mbIsResizable;
    }
    virtual bool IsExpandable (void) const
    {
        return false;
    }
    virtual bool IsExpanded (void) const
    {
        return true;
    }

private:
    Size maPreferredSize;
    ::Window* mpWrappedControl;
    bool mbIsResizable;
};

TestPanel::TestPanel (TreeNode* pParent)
    : SubToolPanel (pParent)
{
    // Create a scrollable panel with two list boxes.
    ScrollPanel* pScrollPanel = new ScrollPanel (this);

    ListBox* pBox = new ListBox (pScrollPanel->GetWindow());
    int i;
    for (i=1; i<=20; i++)
    {
        XubString aString (XubString::CreateFromAscii("Text "));
        aString.Append (XubString::CreateFromInt32(i));
        aString.Append (XubString::CreateFromAscii("/20"));
        pBox->InsertEntry (aString);
    }
    pScrollPanel->AddControl (
        ::std::auto_ptr<TreeNode>(new Wrapper (
            pScrollPanel, Size (200,300), pBox, true)),
        String::CreateFromAscii ("First ListBox"),
        0);

    pBox = new ListBox (pScrollPanel->GetWindow());
    for (i=1; i<=20; i++)
    {
        XubString aString (XubString::CreateFromAscii("More Text "));
        aString.Append (XubString::CreateFromInt32(i));
        aString.Append (XubString::CreateFromAscii("/20"));
        pBox->InsertEntry (aString);
    }
    pScrollPanel->AddControl (
        ::std::auto_ptr<TreeNode>(new Wrapper (
            pScrollPanel, Size (200,300), pBox, true)),
        String::CreateFromAscii ("Second ListBox"),
        0);

    AddControl (::std::auto_ptr<TreeNode>(pScrollPanel));

    // Add a fixed size button.
    Button* pButton = new OKButton (this);
    AddControl (
        ::std::auto_ptr<TreeNode>(new Wrapper (
            this, Size (100,30), pButton, false)),
        String::CreateFromAscii ("Button Area"),
        0);
}

TestPanel::~TestPanel (void)
{
}

std::auto_ptr<ControlFactory> TestPanel::CreateControlFactory (void)
{
    return std::auto_ptr<ControlFactory>(new TestPanelFactory());
}

} } // end of namespace ::sd::toolpanel
<commit_msg>INTEGRATION: CWS sdwarningsbegone (1.6.38); FILE MERGED 2006/11/22 12:42:15 cl 1.6.38.1: #i69285# warning free code changes for unxlngi6.pro<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: TestPanel.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-12 18:44:19 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "TestPanel.hxx"
#include "taskpane/ScrollPanel.hxx"
#include "taskpane/TaskPaneControlFactory.hxx"

#include <vcl/lstbox.hxx>
#include <vcl/button.hxx>

namespace sd { namespace toolpanel {

/** This factory class is used to create instances of TestPanel.  It can be
    extended so that its constructor stores arguments that later are passed
    to new TestPanel objects.
*/
class TestPanelFactory
    : public ControlFactory
{
protected:
    virtual TreeNode* InternalCreateControl (TreeNode* pTreeNode)
    {
        return new TestPanel (pTreeNode);
    }
};

class Wrapper
    : public TreeNode
{
public:
    Wrapper (
        TreeNode* pParent,
        Size aPreferredSize,
        ::Window* pWrappedControl,
        bool bIsResizable)
        : TreeNode (pParent),
          maPreferredSize(aPreferredSize),
          mpWrappedControl(pWrappedControl),
          mbIsResizable(bIsResizable)
    {
        mpWrappedControl->Show();
    }
    virtual ~Wrapper (void)
    {
        delete mpWrappedControl;
    }

    virtual Size GetPreferredSize (void)
    {
        return maPreferredSize;
    }
    virtual sal_Int32 GetPreferredWidth (sal_Int32 )
    {
        return maPreferredSize.Width();
    }
    virtual sal_Int32 GetPreferredHeight (sal_Int32 )
    {
        return maPreferredSize.Height();
    }
    virtual ::Window* GetWindow (void)
    {
        return mpWrappedControl;
    }
    virtual bool IsResizable (void)
    {
        return mbIsResizable;
    }
    virtual bool IsExpandable (void) const
    {
        return false;
    }
    virtual bool IsExpanded (void) const
    {
        return true;
    }

private:
    Size maPreferredSize;
    ::Window* mpWrappedControl;
    bool mbIsResizable;
};

TestPanel::TestPanel (TreeNode* pParent)
    : SubToolPanel (pParent)
{
    // Create a scrollable panel with two list boxes.
    ScrollPanel* pScrollPanel = new ScrollPanel (this);

    ListBox* pBox = new ListBox (pScrollPanel->GetWindow());
    int i;
    for (i=1; i<=20; i++)
    {
        XubString aString (XubString::CreateFromAscii("Text "));
        aString.Append (XubString::CreateFromInt32(i));
        aString.Append (XubString::CreateFromAscii("/20"));
        pBox->InsertEntry (aString);
    }
    pScrollPanel->AddControl (
        ::std::auto_ptr<TreeNode>(new Wrapper (
            pScrollPanel, Size (200,300), pBox, true)),
        String::CreateFromAscii ("First ListBox"),
        0);

    pBox = new ListBox (pScrollPanel->GetWindow());
    for (i=1; i<=20; i++)
    {
        XubString aString (XubString::CreateFromAscii("More Text "));
        aString.Append (XubString::CreateFromInt32(i));
        aString.Append (XubString::CreateFromAscii("/20"));
        pBox->InsertEntry (aString);
    }
    pScrollPanel->AddControl (
        ::std::auto_ptr<TreeNode>(new Wrapper (
            pScrollPanel, Size (200,300), pBox, true)),
        String::CreateFromAscii ("Second ListBox"),
        0);

    AddControl (::std::auto_ptr<TreeNode>(pScrollPanel));

    // Add a fixed size button.
    Button* pButton = new OKButton (this);
    AddControl (
        ::std::auto_ptr<TreeNode>(new Wrapper (
            this, Size (100,30), pButton, false)),
        String::CreateFromAscii ("Button Area"),
        0);
}

TestPanel::~TestPanel (void)
{
}

std::auto_ptr<ControlFactory> TestPanel::CreateControlFactory (void)
{
    return std::auto_ptr<ControlFactory>(new TestPanelFactory());
}

} } // end of namespace ::sd::toolpanel
<|endoftext|>


<commit_before><commit_msg>Add test for re-grouping of formulas in DeleteRow().<commit_after><|endoftext|>


<commit_before>// Copyright © 2014 German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.
//
// Author: Christian Kellner <kellner@bio.lmu.de>

#include <nix/DataType.hpp>

#include <string>
#include <stdexcept>
#include <map>
#include <algorithm>

namespace nix {

std::string data_type_to_string(DataType dtype) {

    std::string str;

    switch(dtype) {

    case DataType::Bool:    str = "Bool";    break;
    case DataType::Char:    str = "Char";    break;
    case DataType::Float:   str = "Float";   break;
    case DataType::Double:  str = "Double";  break;
    case DataType::Int8:    str = "Int8";    break;
    case DataType::Int16:   str = "Int16";   break;
    case DataType::Int32:   str = "Int32";   break;
    case DataType::Int64:   str = "Int64";   break;
    case DataType::UInt8:   str = "UInt8";   break;
    case DataType::UInt16:  str = "UInt16";  break;
    case DataType::UInt32:  str = "UInt32";  break;
    case DataType::UInt64:  str = "UInt64";  break;
    case DataType::String:  str = "String";  break;
    case DataType::Nothing: str = "Nothing"; break;
    default:
        str = "FIXME";
    }

    return str;
}

DataType string_to_data_type(std::string dtype) {

    struct data_type_map : public std::map<std::string, DataType> {
        data_type_map() {
            (*this)["bool"] = DataType::Bool;
            (*this)["char"] = DataType::Char;
            (*this)["float"] = DataType::Float;
            (*this)["single"] = DataType::Float;
            (*this)["double"] = DataType::Double;
            (*this)["int8"] = DataType::Int8;
            (*this)["int16"] = DataType::Int16;
            (*this)["int32"] = DataType::Int32;
            (*this)["int64"] = DataType::Int64;
            (*this)["uint8"] = DataType::UInt8;
            (*this)["uint16"] = DataType::UInt16;
            (*this)["uint32"] = DataType::UInt32;
            (*this)["uint64"] = DataType::UInt64;
            (*this)["string"] = DataType::String;
            (*this)["nothing"] = DataType::Nothing;
        }
    };

    static data_type_map dt;

    std::string dtype_l = dtype;
    std::transform(dtype_l.begin(), dtype_l.end(), dtype_l.begin(), ::tolower);

    return dt[dtype];
}

std::ostream &operator<<(std::ostream &out, const DataType dtype) {
    out << data_type_to_string(dtype);
    return out;
}

size_t data_type_to_size(DataType dtype) {
    switch(dtype) {

        case DataType::Bool:
            return sizeof(bool);

        case DataType::Int8:
        case DataType::UInt8:
            return 1;

        case DataType::Int16:
        case DataType::UInt16:
            return 2;

        case DataType::Int32:
        case DataType::UInt32:
        case DataType::Float:
            return 4;

        case DataType::Int64:
        case DataType::UInt64:
        case DataType::Double:
            return 8;

        //strings are char *, but not sure that is the correct thing to do here
        case DataType::String:
            return sizeof(char *);

        default:
            throw std::invalid_argument("Unkown DataType");
    }
}

}
<commit_msg>changed data type struct to just map<commit_after>// Copyright © 2014 German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.
//
// Author: Christian Kellner <kellner@bio.lmu.de>

#include <nix/DataType.hpp>

#include <string>
#include <stdexcept>
#include <map>
#include <algorithm>

namespace nix {

std::string data_type_to_string(DataType dtype) {

    std::string str;

    switch(dtype) {

    case DataType::Bool:    str = "Bool";    break;
    case DataType::Char:    str = "Char";    break;
    case DataType::Float:   str = "Float";   break;
    case DataType::Double:  str = "Double";  break;
    case DataType::Int8:    str = "Int8";    break;
    case DataType::Int16:   str = "Int16";   break;
    case DataType::Int32:   str = "Int32";   break;
    case DataType::Int64:   str = "Int64";   break;
    case DataType::UInt8:   str = "UInt8";   break;
    case DataType::UInt16:  str = "UInt16";  break;
    case DataType::UInt32:  str = "UInt32";  break;
    case DataType::UInt64:  str = "UInt64";  break;
    case DataType::String:  str = "String";  break;
    case DataType::Nothing: str = "Nothing"; break;
    default:
        str = "FIXME";
    }

    return str;
}

DataType string_to_data_type(std::string dtype) {

    static std::map<std::string, DataType> type_map = {
        {"bool", DataType::Bool},
        {"char", DataType::Char},
        {"float", DataType::Float},
        {"single", DataType::Float},
        {"double", DataType::Double},
        {"int8", DataType::Int8},
        {"int16", DataType::Int16},
        {"int32", DataType::Int32},
        {"int64", DataType::Int64},
        {"uint8", DataType::UInt8},
        {"uint16", DataType::UInt16},
        {"uint32", DataType::UInt32},
        {"uint64", DataType::UInt64},
        {"string", DataType::String},
        {"nothing", DataType::Nothing}
    };

    std::string dtype_l = dtype;
    std::transform(dtype_l.begin(), dtype_l.end(), dtype_l.begin(), ::tolower);

    return type_map[dtype];
}

std::ostream &operator<<(std::ostream &out, const DataType dtype) {
    out << data_type_to_string(dtype);
    return out;
}

size_t data_type_to_size(DataType dtype) {
    switch(dtype) {

        case DataType::Bool:
            return sizeof(bool);

        case DataType::Int8:
        case DataType::UInt8:
            return 1;

        case DataType::Int16:
        case DataType::UInt16:
            return 2;

        case DataType::Int32:
        case DataType::UInt32:
        case DataType::Float:
            return 4;

        case DataType::Int64:
        case DataType::UInt64:
        case DataType::Double:
            return 8;

        //strings are char *, but not sure that is the correct thing to do here
        case DataType::String:
            return sizeof(char *);

        default:
            throw std::invalid_argument("Unkown DataType");
    }
}

}
<|endoftext|>


<commit_before>#include "variable_tests.h"

#include <gtest/gtest.h>

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST(VariableTests, constructor) {
  cyclopts::Variable::Bound lbound(cyclopts::Variable::NEG_INF);
  cyclopts::Variable::Bound ubound(cyclopts::Variable::FINITE);
  cyclopts::Variable::VarType type(cyclopts::Variable::LINEAR);

  cyclopts::Variable::Variable var(lbound, ubound, type);
  EXPECT_EQ(var.lbound(), lbound);
  EXPECT_EQ(var.ubound(), ubound);
  EXPECT_EQ(var.type(), type);
}

<commit_msg>test update. tag: move and squash<commit_after>#include "variable_tests.h"

#include <gtest/gtest.h>

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST(VariableTests, constructor) {
  cyclopts::Variable::Bound lbound(cyclopts::Variable::NEG_INF);
  cyclopts::Variable::Bound ubound(cyclopts::Variable::FINITE);
  cyclopts::Variable::VarType type(cyclopts::Variable::LINEAR);

  cyclopts::Variable var(lbound, ubound, type);
  EXPECT_EQ(var.lbound(), lbound);
  EXPECT_EQ(var.ubound(), ubound);
  EXPECT_EQ(var.type(), type);
}

<|endoftext|>


<commit_before>#define _BSD_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <unistd.h>
#include "ptbox.h"

pt_debugger::pt_debugger() : on_return_callback(NULL) {}

bool has_null(char *buf, unsigned long size) {
    for (unsigned long i = 0; i < size; ++i) {
        if (buf[i] == '\0')
            return true;
    }
    return false;
}

void pt_debugger::set_process(pt_process *proc) {
    process = proc;
}

void pt_debugger::new_process() {}

void pt_debugger::settid(pid_t tid) {
    this->tid = tid;
#if defined(__FreeBSD__)
    reg bsd_regs;
    ptrace(PT_GETREGS, tid, &bsd_regs, 0);
    map_regs_to_linux(&bsd_reg, &bsd_converted_regs);
#endif
}

long pt_debugger::peek_reg(int idx) {
#if defined(__FreeBSD__)
    return (int*)((char *)&bsd_converted_regs + idx * sizeof(long));
#else
    return ptrace(PTRACE_PEEKUSER, tid, sizeof(long) * idx, 0);
#endif
}

void pt_debugger::poke_reg(int idx, long data) {
#if defined(__FreeBSD__)
    *(int*)((char *)&bsd_converted_regs + idx * sizeof(long)) = (int) data;

    reg bsd_regs;
    map_regs_from_linux(&bsd_regs, &bsd_converted_regs);
    ptrace(PT_SETREGS, tid, &bsd_regs, 0);
#else
    ptrace(PTRACE_POKEUSER, tid, sizeof(long) * idx, data);
#endif
}

char *pt_debugger::readstr(unsigned long addr, size_t max_size) {
    size_t size = 4096, read = 0;
    char *buf = (char *) malloc(size);
    union {
        long val;
        char byte[sizeof(long)];
    } data;

    while (true) {
        if (read + sizeof(long) > size) {
            if (max_size && size >= max_size) {
                buf[max_size-1] = 0;
                break;
            }

            size += 4096;
            if (max_size && size > max_size)
                size = max_size;

            void *nbuf = realloc(buf, size);
            if (!nbuf) {
                buf[size-4097] = 0;
                break;
            }
            buf = (char *) nbuf;
        }
#if defined(__FreeBSD__)
        data.val = ptrace(PT_READ_D, tid, addr + read, 0);
#else
        data.val = ptrace(PTRACE_PEEKDATA, tid, addr + read, NULL);
#endif
        memcpy(buf + read, data.byte, sizeof(long));
        if (has_null(data.byte, sizeof(long)))
            break;
        read += sizeof(long);
    }
    return buf;
}

void pt_debugger::freestr(char *buf) {
    free(buf);
}

pt_debugger::~pt_debugger() {}
<commit_msg>Cast to caddr_t religiously; #192<commit_after>#define _BSD_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <unistd.h>
#include "ptbox.h"

pt_debugger::pt_debugger() : on_return_callback(NULL) {}

bool has_null(char *buf, unsigned long size) {
    for (unsigned long i = 0; i < size; ++i) {
        if (buf[i] == '\0')
            return true;
    }
    return false;
}

void pt_debugger::set_process(pt_process *proc) {
    process = proc;
}

void pt_debugger::new_process() {}

void pt_debugger::settid(pid_t tid) {
    this->tid = tid;
#if defined(__FreeBSD__)
    reg bsd_regs;
    ptrace(PT_GETREGS, tid, (caddr_t) &bsd_regs, 0);
    map_regs_to_linux(&bsd_reg, &bsd_converted_regs);
#endif
}

long pt_debugger::peek_reg(int idx) {
#if defined(__FreeBSD__)
    return (int*)((char *)&bsd_converted_regs + idx * sizeof(long));
#else
    return ptrace(PTRACE_PEEKUSER, tid, sizeof(long) * idx, 0);
#endif
}

void pt_debugger::poke_reg(int idx, long data) {
#if defined(__FreeBSD__)
    *(int*)((char *)&bsd_converted_regs + idx * sizeof(long)) = (int) data;

    reg bsd_regs;
    map_regs_from_linux(&bsd_regs, &bsd_converted_regs);
    ptrace(PT_SETREGS, tid, (caddr_t) &bsd_regs, 0);
#else
    ptrace(PTRACE_POKEUSER, tid, sizeof(long) * idx, data);
#endif
}

char *pt_debugger::readstr(unsigned long addr, size_t max_size) {
    size_t size = 4096, read = 0;
    char *buf = (char *) malloc(size);
    union {
        long val;
        char byte[sizeof(long)];
    } data;

    while (true) {
        if (read + sizeof(long) > size) {
            if (max_size && size >= max_size) {
                buf[max_size-1] = 0;
                break;
            }

            size += 4096;
            if (max_size && size > max_size)
                size = max_size;

            void *nbuf = realloc(buf, size);
            if (!nbuf) {
                buf[size-4097] = 0;
                break;
            }
            buf = (char *) nbuf;
        }
#if defined(__FreeBSD__)
        data.val = ptrace(PT_READ_D, tid, (caddr_t) (addr + read), 0);
#else
        data.val = ptrace(PTRACE_PEEKDATA, tid, addr + read, NULL);
#endif
        memcpy(buf + read, data.byte, sizeof(long));
        if (has_null(data.byte, sizeof(long)))
            break;
        read += sizeof(long);
    }
    return buf;
}

void pt_debugger::freestr(char *buf) {
    free(buf);
}

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


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2017 Ruben Van Boxem
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 **/

#include "test.h++"

#include "core/application.h++"

#include <thread>

namespace
{
  using skui::test::check;
  using skui::test::require;

  void test_arguments()
  {
    const auto& arguments = skui::core::application::instance().commandline_arguments;

    require(arguments.size() == 1, "correct number of arguments.");
    check(arguments[0] == "skui is awesome", "arguments passed correctly.");
  }

  void test_execute_and_quit()
  {
    auto app = &skui::core::application::instance();
    constexpr int exit_code = 1;
    int return_value = 0;
    std::thread t([app, &return_value] { return_value = app->execute(); });

    app->quit(exit_code);

    t.join();

    check(return_value = exit_code, "application::execute returns exit code passed to quit().");
  }
}

int main(int argc, char* argv[])
{
  const skui::core::application app(argc, argv);

  test_arguments();
  test_execute_and_quit();

  return skui::test::exit_code;
}
<commit_msg>Fix typo in test.<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2017 Ruben Van Boxem
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 **/

#include "test.h++"

#include "core/application.h++"

#include <thread>

namespace
{
  using skui::test::check;
  using skui::test::require;

  void test_arguments()
  {
    const auto& arguments = skui::core::application::instance().commandline_arguments;

    require(arguments.size() == 1, "correct number of arguments.");
    check(arguments[0] == "skui is awesome", "arguments passed correctly.");
  }

  void test_execute_and_quit()
  {
    auto app = &skui::core::application::instance();
    constexpr int exit_code = 1;
    int return_value = 0;
    std::thread t([app, &return_value] { return_value = app->execute(); });

    app->quit(exit_code);

    t.join();

    check(return_value == exit_code, "application::execute returns exit code passed to quit().");
  }
}

int main(int argc, char* argv[])
{
  const skui::core::application app(argc, argv);

  test_arguments();
  test_execute_and_quit();

  return skui::test::exit_code;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2007, 2008, 2009, 2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

/// \file urbi/uvalue.hh
#ifndef URBI_UVALUE_HH
# define URBI_UVALUE_HH

# include <libport/warning-push.hh>

# include <vector>

# include <libport/hash.hh>
# include <libport/preproc.hh>
# include <libport/traits.hh>
# include <libport/ufloat.h>

# include <urbi/fwd.hh>
# include <urbi/export.hh>
# include <urbi/ubinary.hh>

namespace urbi
{

  /// If a kernel version was associated to this stream, its value.
  URBI_SDK_API
  int& kernelMajor(std::ostream& o);

  // UValue and other related types

  /// Possible value types a UValue can contain.
  enum UDataType
  {
    DATA_BINARY,
    DATA_DICTIONARY,
    DATA_DOUBLE,
    DATA_LIST,
    DATA_OBJECT,
    DATA_STRING,
    DATA_SLOTNAME,
    DATA_VOID
  };

  /*--------.
  | UList.  |
  `--------*/

  /// Class storing URBI List type
  class URBI_SDK_API UList
  {
  public:
    UList();
    UList(const UList &b);
    ~UList();

    UList& operator=(const UList &b);

    // Assign a container to the UList
    template<typename T>
    UList& operator=(const T& container);

    UList& operator=(UVar& v);

    // Transform the UList to a container.
    template<typename T>
    T as();

    // Append an element to the end.
    template<typename T>
    UList&
    push_back(const T& v);

    void pop_back();

    UValue& front();

    UValue& operator[](size_t i);
    const UValue& operator[](size_t i) const;

    size_t size() const;
    void setOffset(size_t n);

    std::ostream& print(std::ostream& o) const;

    // The actual contents.
    std::vector<UValue*> array;

  private:
    void clear();
    size_t offset;
  };

  URBI_SDK_API
  std::ostream& operator<< (std::ostream& o, const UList& t);

  /*--------------.
  | UDictionary.  |
  `--------------*/
  typedef boost::unordered_map<std::string, UValue> UDictionary;

  /*--------------.
  | UNamedValue.  |
  `--------------*/

  class URBI_SDK_API UNamedValue
  {
  public:
    UNamedValue(const std::string& n = "", UValue* v = 0);
    // Used on errors.
    static UNamedValue& error();
    std::string name;
    UValue* val;
  };

  /*----------------.
  | UObjectStruct.  |
  `----------------*/

  class URBI_SDK_API UObjectStruct
  {
  public:
    UObjectStruct();
    UObjectStruct(const UObjectStruct &b);
    UObjectStruct& operator=(const UObjectStruct &b);
    ~UObjectStruct();

    /// Return UValue::error() on errors.
    UValue& operator[](const std::string& s);

    /// Return UNamedValue::error() on errors.
    const UNamedValue& operator[](size_t i) const;
    UNamedValue& operator [](size_t i);

    size_t size() const;

    std::ostream& print(std::ostream& o) const;

    std::string refName;
    std::vector<UNamedValue> array;
  };

  URBI_SDK_API
  std::ostream& operator<< (std::ostream& o, const UObjectStruct& t);

  /*---------.
  | UValue.  |
  `---------*/

  /** Container for a value that handles all types known to URBI.
   */
  class URBI_SDK_API UValue
  {
  public:
    UDataType       type;
    ufloat          val;  ///< value if of type DATA_DOUBLE
    union
    {
      std::string* stringValue; ///< value if of type DATA_STRING
      UBinary* binary;          ///< value if of type DATA_BINARY
      UList* list;              ///< value if of type DATA_LIST
      UDictionary* dictionary;  ///< value if of type DATA_DICTIONARY
      UObjectStruct* object;    ///< value if of type DATA_OBJ
      void* storage;            ///< internal
    };

    UValue();
    UValue(const UValue&);

    ~UValue();

    UValue& operator=(const UValue&);
    /// Setter. If copy is false, binary data if present is not copied.
    /// This is dangerous, as the user must ensure that the source UValue
    /// lives longer than this one.
    UValue& set(const UValue&, bool copy=true);
    /// Delete content and reset type to void.
    void clear();
    /// A specific UValue used when we want to return an error.
    /// For instance, out-of-bound access returns this object.
    static UValue& error();

    /// We use an operator , that behaves like an assignment.  The
    /// only difference is when the rhs is void, in which case it is
    /// the regular comma which is used.  This allows to write "uval,
    /// expr" to mean "compute expr and assign its result to uval,
    /// unless expr is void".
    UValue& operator, (const UValue &b);

    /// Return a legible definition of UDataType
    const char* format_string() const;

#define CTOR_AND_ASSIGN_AND_COMMA(Type)           \
    explicit UValue(Type, bool copy=true);	  \
    UValue& operator=(Type);			  \
    UValue& operator,(Type rhs);

// Types convertibles to DATA_DOUBLE
#define URBI_DERIVED_NUMERIC_TYPES                     \
  LIBPORT_LIST(int, long, unsigned int, unsigned long, \
               unsigned long long, long long,)

#define URBI_NUMERIC_TYPES                                     \
  LIBPORT_LIST(ufloat, int, long, unsigned int, unsigned long, \
               unsigned long long, long long,)

// Types convertibles to DATA_STRING
#define URBI_STRING_TYPES \
  LIBPORT_LIST(const char*, const void*, const std::string&,)

#define URBI_MISC_TYPES                                          \
  LIBPORT_LIST(const UBinary&, const UList&, const UDictionary&, \
               const UObjectStruct&, const USound&, const UImage&,)

# ifndef SWIG
    LIBPORT_LIST_APPLY(CTOR_AND_ASSIGN_AND_COMMA, URBI_NUMERIC_TYPES)
    LIBPORT_LIST_APPLY(CTOR_AND_ASSIGN_AND_COMMA, URBI_STRING_TYPES)
    LIBPORT_LIST_APPLY(CTOR_AND_ASSIGN_AND_COMMA, URBI_MISC_TYPES)
# else
    // UFloats.
    CTOR_AND_ASSIGN_AND_COMMA(ufloat);
    CTOR_AND_ASSIGN_AND_COMMA(int);
    CTOR_AND_ASSIGN_AND_COMMA(long);
    CTOR_AND_ASSIGN_AND_COMMA(unsigned int);
    CTOR_AND_ASSIGN_AND_COMMA(unsigned long);
    CTOR_AND_ASSIGN_AND_COMMA(unsigned long long);
    CTOR_AND_ASSIGN_AND_COMMA(long long);

    // Strings.
    CTOR_AND_ASSIGN_AND_COMMA(const char*);
    CTOR_AND_ASSIGN_AND_COMMA(const void*);
    CTOR_AND_ASSIGN_AND_COMMA(const std::string&);

    // Others.
    CTOR_AND_ASSIGN_AND_COMMA(const UBinary&);
    CTOR_AND_ASSIGN_AND_COMMA(const UList&);
    CTOR_AND_ASSIGN_AND_COMMA(const UDictionary&);
    CTOR_AND_ASSIGN_AND_COMMA(const UObjectStruct&);
    CTOR_AND_ASSIGN_AND_COMMA(const USound&);
    CTOR_AND_ASSIGN_AND_COMMA(const UImage&);
# endif

#undef CTOR_AND_ASSIGN_AND_COMMA

#define CAST_OPERATOR(Type) \
    operator Type() const;

# ifndef SWIG
    LIBPORT_LIST_APPLY(CAST_OPERATOR, URBI_NUMERIC_TYPES)
# else
    operator ufloat() const;
    operator std::string() const;
    operator int() const;
    operator unsigned int() const;
    operator long() const;
    operator unsigned long() const;
    operator bool() const;
# endif
#undef CAST_OPERATOR

#ifdef DOXYGEN
    // Doxygens needs a prototype for ufloat.
    operator ufloat() const;
#endif

    operator std::string() const;
    operator bool() const;

    /// Accessor. Gives us an implicit operator UBinary() const
    operator const UBinary&() const;

    /// Deep copy.
    operator UList() const;

    /// Deep copy.
    operator UDictionary() const;

    /// Shallow copy.
    operator UImage() const;

    /// Shallow copy.
    operator USound() const;

    /// This operator does nothing, but helps with the previous operator,.
    /// Indeed, when writing "uval, void_expr", the compiler complains
    /// about uval being evaluated for nothing.  Let's have it believe
    /// we're doing something...
    UValue& operator()();

    /// Parse an uvalue in current message+pos, returns pos of end of
    /// match -pos of error if error.
    int parse(const char* message,
	      int pos,
	      const binaries_type& bins,
	      binaries_type::const_iterator& binpos);

    /// Print itself on \c s, and return it.
    std::ostream& print(std::ostream& s) const;

    // Huge hack.
    static const bool copy = true;
  };

  inline
  std::ostream&
  operator<<(std::ostream& s, const UValue& v);

  inline
  std::ostream&
  operator<<(std::ostream& s, const UDictionary& d);

  /*----------.
  | Casters.  |
  `----------*/

  // For each Type, define an operator() that casts its UValue&
  // argument into Type.  We need partial specialization.

  template <typename Type>
  struct uvalue_caster
  {
  };

  // T -> UVar&  if T = UVar
  // T -> T      otherwise.
  template <typename T>
  struct uvar_ref_traits
  {
    typedef T type;
  };

  template <>
  struct uvar_ref_traits<UVar>
  {
    typedef UVar& type;
  };

  // Run the uvalue_caster<Type> on v.

  /* NM: Why exactly are we moving the const away?
   * I'm dropping it for UValue as it makes unnecessary copy.
   */

   template<typename T> struct uvalue_cast_return_type
   {
     typedef typename libport::traits::remove_reference<T>::type type;
   };

   template<> struct uvalue_cast_return_type<const UValue&>
   {
     typedef const UValue& type;
   };

  template <typename Type>
  typename uvar_ref_traits<typename uvalue_cast_return_type<Type>::type>::type
  uvalue_cast (UValue& v);

} // namespace urbi

#define SYNCLINE_PUSH()                                         \
  "//#push " BOOST_PP_STRINGIZE(__LINE__) " \"" __FILE__ "\"\n"

#define SYNCLINE_POP()                          \
  "//#pop\n"

#define SYNCLINE_WRAP(...)                      \
  SYNCLINE_PUSH()                               \
  __VA_ARGS__                                   \
  "\n"                                          \
  SYNCLINE_POP()

#define URBI_STRUCT_CAST_FIELD(_, cname, field)                      \
if (!libport::mhas(dict, BOOST_PP_STRINGIZE(field)))                 \
  GD_WARN("Serialized data for " #cname "is missing field"           \
          BOOST_PP_STRINGIZE(field));                                \
else                                                                 \
{                                                                    \
  uvalue_cast_bounce(res.field, dict[BOOST_PP_STRINGIZE(field)]);    \
}

#define URBI_STRUCT_BCAST_FIELD(_, cname, field) \
  dict[BOOST_PP_STRINGIZE(field)], c.field;

#define URBI_REGISTER_STRUCT(cname, ...)                                 \
namespace urbi {                                                         \
  template<> struct uvalue_caster<cname>                                 \
  {                                                                      \
    cname operator()(UValue& v)                                          \
    {                                                                    \
      if (v.type != DATA_DICTIONARY)                                     \
        throw std::runtime_error("invalid cast to " #cname "from "       \
                                 + string_cast(v));                      \
      UDictionary& dict = *v.dictionary;                                 \
      cname res;                                                         \
      LIBPORT_VAARGS_APPLY(URBI_STRUCT_CAST_FIELD, cname, __VA_ARGS__);  \
      return res;                                                        \
    }                                                                    \
  };                                                                     \
UValue& operator,(UValue& v, const cname &c)                             \
  {                                                                        \
    v = UDictionary();                                                     \
    UDictionary& dict = *v.dictionary;                                     \
    dict["$sn"] = BOOST_PP_STRINGIZE(cname);                               \
    LIBPORT_VAARGS_APPLY(URBI_STRUCT_BCAST_FIELD, cname, __VA_ARGS__);     \
    return v;                                                              \
  }                                                                        \
}

/** Packed data structure.
 *  This template class behaves exactly as a std::vector, except it gets
 *  serialized efficiently in a Binary, whereas std::vector is converted in
 *  an urbiscript list.
 */
template<typename T> class UPackedData: public std::vector<T>
{
public:
  UPackedData() {};
  UPackedData(const std::vector<T>& src): std::vector<T>(src) {};
  template<typename I> UPackedData(I begin, I end):std::vector<T>(begin, end){};
};

# include <urbi/uvalue.hxx>

# include <libport/warning-pop.hh>

#endif // ! URBI_UVALUE_HH
<commit_msg>Small Struct: Fix a warning.<commit_after>/*
 * Copyright (C) 2007, 2008, 2009, 2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

/// \file urbi/uvalue.hh
#ifndef URBI_UVALUE_HH
# define URBI_UVALUE_HH

# include <libport/warning-push.hh>

# include <vector>

# include <libport/hash.hh>
# include <libport/preproc.hh>
# include <libport/traits.hh>
# include <libport/ufloat.h>

# include <urbi/fwd.hh>
# include <urbi/export.hh>
# include <urbi/ubinary.hh>

namespace urbi
{

  /// If a kernel version was associated to this stream, its value.
  URBI_SDK_API
  int& kernelMajor(std::ostream& o);

  // UValue and other related types

  /// Possible value types a UValue can contain.
  enum UDataType
  {
    DATA_BINARY,
    DATA_DICTIONARY,
    DATA_DOUBLE,
    DATA_LIST,
    DATA_OBJECT,
    DATA_STRING,
    DATA_SLOTNAME,
    DATA_VOID
  };

  /*--------.
  | UList.  |
  `--------*/

  /// Class storing URBI List type
  class URBI_SDK_API UList
  {
  public:
    UList();
    UList(const UList &b);
    ~UList();

    UList& operator=(const UList &b);

    // Assign a container to the UList
    template<typename T>
    UList& operator=(const T& container);

    UList& operator=(UVar& v);

    // Transform the UList to a container.
    template<typename T>
    T as();

    // Append an element to the end.
    template<typename T>
    UList&
    push_back(const T& v);

    void pop_back();

    UValue& front();

    UValue& operator[](size_t i);
    const UValue& operator[](size_t i) const;

    size_t size() const;
    void setOffset(size_t n);

    std::ostream& print(std::ostream& o) const;

    // The actual contents.
    std::vector<UValue*> array;

  private:
    void clear();
    size_t offset;
  };

  URBI_SDK_API
  std::ostream& operator<< (std::ostream& o, const UList& t);

  /*--------------.
  | UDictionary.  |
  `--------------*/
  typedef boost::unordered_map<std::string, UValue> UDictionary;

  /*--------------.
  | UNamedValue.  |
  `--------------*/

  class URBI_SDK_API UNamedValue
  {
  public:
    UNamedValue(const std::string& n = "", UValue* v = 0);
    // Used on errors.
    static UNamedValue& error();
    std::string name;
    UValue* val;
  };

  /*----------------.
  | UObjectStruct.  |
  `----------------*/

  class URBI_SDK_API UObjectStruct
  {
  public:
    UObjectStruct();
    UObjectStruct(const UObjectStruct &b);
    UObjectStruct& operator=(const UObjectStruct &b);
    ~UObjectStruct();

    /// Return UValue::error() on errors.
    UValue& operator[](const std::string& s);

    /// Return UNamedValue::error() on errors.
    const UNamedValue& operator[](size_t i) const;
    UNamedValue& operator [](size_t i);

    size_t size() const;

    std::ostream& print(std::ostream& o) const;

    std::string refName;
    std::vector<UNamedValue> array;
  };

  URBI_SDK_API
  std::ostream& operator<< (std::ostream& o, const UObjectStruct& t);

  /*---------.
  | UValue.  |
  `---------*/

  /** Container for a value that handles all types known to URBI.
   */
  class URBI_SDK_API UValue
  {
  public:
    UDataType       type;
    ufloat          val;  ///< value if of type DATA_DOUBLE
    union
    {
      std::string* stringValue; ///< value if of type DATA_STRING
      UBinary* binary;          ///< value if of type DATA_BINARY
      UList* list;              ///< value if of type DATA_LIST
      UDictionary* dictionary;  ///< value if of type DATA_DICTIONARY
      UObjectStruct* object;    ///< value if of type DATA_OBJ
      void* storage;            ///< internal
    };

    UValue();
    UValue(const UValue&);

    ~UValue();

    UValue& operator=(const UValue&);
    /// Setter. If copy is false, binary data if present is not copied.
    /// This is dangerous, as the user must ensure that the source UValue
    /// lives longer than this one.
    UValue& set(const UValue&, bool copy=true);
    /// Delete content and reset type to void.
    void clear();
    /// A specific UValue used when we want to return an error.
    /// For instance, out-of-bound access returns this object.
    static UValue& error();

    /// We use an operator , that behaves like an assignment.  The
    /// only difference is when the rhs is void, in which case it is
    /// the regular comma which is used.  This allows to write "uval,
    /// expr" to mean "compute expr and assign its result to uval,
    /// unless expr is void".
    UValue& operator, (const UValue &b);

    /// Return a legible definition of UDataType
    const char* format_string() const;

#define CTOR_AND_ASSIGN_AND_COMMA(Type)           \
    explicit UValue(Type, bool copy=true);	  \
    UValue& operator=(Type);			  \
    UValue& operator,(Type rhs);

// Types convertibles to DATA_DOUBLE
#define URBI_DERIVED_NUMERIC_TYPES                     \
  LIBPORT_LIST(int, long, unsigned int, unsigned long, \
               unsigned long long, long long,)

#define URBI_NUMERIC_TYPES                                     \
  LIBPORT_LIST(ufloat, int, long, unsigned int, unsigned long, \
               unsigned long long, long long,)

// Types convertibles to DATA_STRING
#define URBI_STRING_TYPES \
  LIBPORT_LIST(const char*, const void*, const std::string&,)

#define URBI_MISC_TYPES                                          \
  LIBPORT_LIST(const UBinary&, const UList&, const UDictionary&, \
               const UObjectStruct&, const USound&, const UImage&,)

# ifndef SWIG
    LIBPORT_LIST_APPLY(CTOR_AND_ASSIGN_AND_COMMA, URBI_NUMERIC_TYPES)
    LIBPORT_LIST_APPLY(CTOR_AND_ASSIGN_AND_COMMA, URBI_STRING_TYPES)
    LIBPORT_LIST_APPLY(CTOR_AND_ASSIGN_AND_COMMA, URBI_MISC_TYPES)
# else
    // UFloats.
    CTOR_AND_ASSIGN_AND_COMMA(ufloat);
    CTOR_AND_ASSIGN_AND_COMMA(int);
    CTOR_AND_ASSIGN_AND_COMMA(long);
    CTOR_AND_ASSIGN_AND_COMMA(unsigned int);
    CTOR_AND_ASSIGN_AND_COMMA(unsigned long);
    CTOR_AND_ASSIGN_AND_COMMA(unsigned long long);
    CTOR_AND_ASSIGN_AND_COMMA(long long);

    // Strings.
    CTOR_AND_ASSIGN_AND_COMMA(const char*);
    CTOR_AND_ASSIGN_AND_COMMA(const void*);
    CTOR_AND_ASSIGN_AND_COMMA(const std::string&);

    // Others.
    CTOR_AND_ASSIGN_AND_COMMA(const UBinary&);
    CTOR_AND_ASSIGN_AND_COMMA(const UList&);
    CTOR_AND_ASSIGN_AND_COMMA(const UDictionary&);
    CTOR_AND_ASSIGN_AND_COMMA(const UObjectStruct&);
    CTOR_AND_ASSIGN_AND_COMMA(const USound&);
    CTOR_AND_ASSIGN_AND_COMMA(const UImage&);
# endif

#undef CTOR_AND_ASSIGN_AND_COMMA

#define CAST_OPERATOR(Type) \
    operator Type() const;

# ifndef SWIG
    LIBPORT_LIST_APPLY(CAST_OPERATOR, URBI_NUMERIC_TYPES)
# else
    operator ufloat() const;
    operator std::string() const;
    operator int() const;
    operator unsigned int() const;
    operator long() const;
    operator unsigned long() const;
    operator bool() const;
# endif
#undef CAST_OPERATOR

#ifdef DOXYGEN
    // Doxygens needs a prototype for ufloat.
    operator ufloat() const;
#endif

    operator std::string() const;
    operator bool() const;

    /// Accessor. Gives us an implicit operator UBinary() const
    operator const UBinary&() const;

    /// Deep copy.
    operator UList() const;

    /// Deep copy.
    operator UDictionary() const;

    /// Shallow copy.
    operator UImage() const;

    /// Shallow copy.
    operator USound() const;

    /// This operator does nothing, but helps with the previous operator,.
    /// Indeed, when writing "uval, void_expr", the compiler complains
    /// about uval being evaluated for nothing.  Let's have it believe
    /// we're doing something...
    UValue& operator()();

    /// Parse an uvalue in current message+pos, returns pos of end of
    /// match -pos of error if error.
    int parse(const char* message,
	      int pos,
	      const binaries_type& bins,
	      binaries_type::const_iterator& binpos);

    /// Print itself on \c s, and return it.
    std::ostream& print(std::ostream& s) const;

    // Huge hack.
    static const bool copy = true;
  };

  inline
  std::ostream&
  operator<<(std::ostream& s, const UValue& v);

  inline
  std::ostream&
  operator<<(std::ostream& s, const UDictionary& d);

  /*----------.
  | Casters.  |
  `----------*/

  // For each Type, define an operator() that casts its UValue&
  // argument into Type.  We need partial specialization.

  template <typename Type>
  struct uvalue_caster
  {
  };

  // T -> UVar&  if T = UVar
  // T -> T      otherwise.
  template <typename T>
  struct uvar_ref_traits
  {
    typedef T type;
  };

  template <>
  struct uvar_ref_traits<UVar>
  {
    typedef UVar& type;
  };

  // Run the uvalue_caster<Type> on v.

  /* NM: Why exactly are we moving the const away?
   * I'm dropping it for UValue as it makes unnecessary copy.
   */

   template<typename T> struct uvalue_cast_return_type
   {
     typedef typename libport::traits::remove_reference<T>::type type;
   };

   template<> struct uvalue_cast_return_type<const UValue&>
   {
     typedef const UValue& type;
   };

  template <typename Type>
  typename uvar_ref_traits<typename uvalue_cast_return_type<Type>::type>::type
  uvalue_cast (UValue& v);

} // namespace urbi

#define SYNCLINE_PUSH()                                         \
  "//#push " BOOST_PP_STRINGIZE(__LINE__) " \"" __FILE__ "\"\n"

#define SYNCLINE_POP()                          \
  "//#pop\n"

#define SYNCLINE_WRAP(...)                      \
  SYNCLINE_PUSH()                               \
  __VA_ARGS__                                   \
  "\n"                                          \
  SYNCLINE_POP()

#define URBI_STRUCT_CAST_FIELD(_, Cname, Field)                         \
  if (libport::mhas(dict, BOOST_PP_STRINGIZE(Field)))                   \
    uvalue_cast_bounce(res.Field, dict[BOOST_PP_STRINGIZE(Field)]);     \
  else                                                                  \
    GD_WARN("Serialized data for " #Cname "is missing field"            \
            BOOST_PP_STRINGIZE(Field));                                 \

#define URBI_STRUCT_BCAST_FIELD(_, Cname, Field)        \
  dict[BOOST_PP_STRINGIZE(Field)], c.Field;

#define URBI_REGISTER_STRUCT(Cname, ...)                                \
  namespace urbi                                                        \
  {                                                                     \
    template<>                                                          \
      struct uvalue_caster<Cname>                                       \
    {                                                                   \
      Cname operator()(UValue& v)                                       \
      {                                                                 \
        if (v.type != DATA_DICTIONARY)                                  \
          throw std::runtime_error("invalid cast to " #Cname "from "    \
                                   + string_cast(v));                   \
        UDictionary& dict = *v.dictionary;                              \
        Cname res;                                                      \
        LIBPORT_VAARGS_APPLY(URBI_STRUCT_CAST_FIELD, Cname, __VA_ARGS__); \
        return res;                                                     \
      }                                                                 \
    };                                                                  \
                                                                        \
    static UValue& operator,(UValue& v, const Cname &c)                 \
    {                                                                   \
      v = UDictionary();                                                \
      UDictionary& dict = *v.dictionary;                                \
      dict["$sn"] = BOOST_PP_STRINGIZE(Cname);                          \
      LIBPORT_VAARGS_APPLY(URBI_STRUCT_BCAST_FIELD, Cname, __VA_ARGS__); \
      return v;                                                         \
    }                                                                   \
  }

/** Packed data structure.
 *  This template class behaves exactly as a std::vector, except it gets
 *  serialized efficiently in a Binary, whereas std::vector is converted in
 *  an urbiscript list.
 */
template<typename T> class UPackedData: public std::vector<T>
{
public:
  UPackedData() {};
  UPackedData(const std::vector<T>& src): std::vector<T>(src) {};
  template<typename I> UPackedData(I begin, I end):std::vector<T>(begin, end){};
};

# include <urbi/uvalue.hxx>

# include <libport/warning-pop.hh>

#endif // ! URBI_UVALUE_HH
<|endoftext|>


<commit_before>#ifndef SDK_REMOTE_TESTS_TESTS_HH
# define SDK_REMOTE_TESTS_TESTS_HH

# include <libport/debug.hh>
# include <libport/semaphore.hh>
# include <libport/program-name.hh>
# include <libport/unistd.h>

# include <urbi/uclient.hh>
# include <urbi/usyncclient.hh>

/* Liburbi test suite
= Architecture =

Each file corresponds to an 'atomic' test.

Test file layout
- #includes "tests.hh"
- write callbacks, ensure global unique names
- a call to BEGIN_TEST(testname, clientname, syncclientname),
   testname must be filename-without-extension
- code of the test:
- setup callbacks, the callback function dump is provided: it displays the
  message and increments dumpSem semaphore. Setting a Wildcard or at least
  an error callback is recommended.
  - c++ code using UClient & client, USyncClient &syncClient made available
  - expected output in comments:
   //= <expected output>
- a call to END_TEST

<expected output>
  <type> <tag> <value>
<type>
  D|E|S for data, error, system
*/

/// Display a debug message.
#define VERBOSE(S)                              \
  do {                                          \
    GD_CATEGORY(TEST);                          \
    std::ostringstream o;                       \
    o << S;                                     \
    GD_INFO(o.str());                           \
  } while (0)

/// Send S to the Client.
#define SEND_(Client, S)                                \
  do {							\
    VERBOSE("Sending: " << S);				\
    Client.send("%s", (std::string(S) + "\n").c_str());	\
  } while (0)

/// Send S to client/syncclient.
#define SEND(S)	  SEND_(client, S)
#define SSEND(S)  SEND_(syncClient, S)

/*----------.
| SyncGet.  |
`----------*/

template <typename T>
inline
T
sget(urbi::USyncClient& c, const std::string& msg)
{
  VERBOSE("syncGet: Asking " << msg);
  T res;
  assert(urbi::getValue(c.syncGet(msg), res));
  return res;
}

/// syncGet E from the syncClient.
#define SGET(Type, E)                           \
  sget<Type>(syncClient, E)

std::string sget_error(urbi::USyncClient& c, const std::string& msg);

/// Send a computation, expect an error.
#define SGET_ERROR(E)                           \
  sget_error(syncClient, E)

extern libport::Semaphore dumpSem;

/// display the value, increment dumpSem.
urbi::UCallbackAction dump(const urbi::UMessage& msg);
/// display the value, incremente dumpSem remove callback if 0
urbi::UCallbackAction removeOnZero(const urbi::UMessage& msg);

#define BEGIN_TEST(Name, ClientName, SyncClientName)    \
  void                                                  \
  Name(urbi::UClient& ClientName,                       \
       urbi::USyncClient& SyncClientName)               \
  {                                                     \
    VERBOSE("starting test " << #Name);

#define END_TEST                                \
    sleep(3);                                   \
    SSEND("quit;");                             \
    SEND("shutdown;");                          \
  }

void dispatch(const std::string& method, urbi::UClient& client,
	      urbi::USyncClient& syncClient);

/// \a Name is the base name of the C++ file containing the function
/// \a Name.
#define TESTS_RUN(Name)							\
  do {									\
    if (method == #Name)						\
    {									\
      void Name(urbi::UClient&, urbi::USyncClient&);			\
      Name(client, syncClient);						\
      return;								\
    }									\
  } while (0)

#endif // SDK_REMOTE_TESTS_TESTS_HH
<commit_msg>tests: Use send simpler and cleaner.<commit_after>#ifndef SDK_REMOTE_TESTS_TESTS_HH
# define SDK_REMOTE_TESTS_TESTS_HH

# include <libport/debug.hh>
# include <libport/semaphore.hh>
# include <libport/program-name.hh>
# include <libport/unistd.h>

# include <urbi/uclient.hh>
# include <urbi/usyncclient.hh>

/* Liburbi test suite
= Architecture =

Each file corresponds to an 'atomic' test.

Test file layout
- #includes "tests.hh"
- write callbacks, ensure global unique names
- a call to BEGIN_TEST(testname, clientname, syncclientname),
   testname must be filename-without-extension
- code of the test:
- setup callbacks, the callback function dump is provided: it displays the
  message and increments dumpSem semaphore. Setting a Wildcard or at least
  an error callback is recommended.
  - c++ code using UClient & client, USyncClient &syncClient made available
  - expected output in comments:
   //= <expected output>
- a call to END_TEST

<expected output>
  <type> <tag> <value>
<type>
  D|E|S for data, error, system
*/

/// Display a debug message.
#define VERBOSE(S)                              \
  do {                                          \
    GD_CATEGORY(TEST);                          \
    std::ostringstream o;                       \
    o << S;                                     \
    GD_INFO(o.str());                           \
  } while (0)

/// Send S to the Client.
#define SEND_(Client, S)                                \
  do {							\
    VERBOSE("Sending: " << S);				\
    Client.send("%s\n", (std::string(S)).c_str());	\
  } while (0)

/// Send S to client/syncclient.
#define SEND(S)	  SEND_(client, S)
#define SSEND(S)  SEND_(syncClient, S)

/*----------.
| SyncGet.  |
`----------*/

template <typename T>
inline
T
sget(urbi::USyncClient& c, const std::string& msg)
{
  VERBOSE("syncGet: Asking " << msg);
  T res;
  assert(urbi::getValue(c.syncGet(msg), res));
  return res;
}

/// syncGet E from the syncClient.
#define SGET(Type, E)                           \
  sget<Type>(syncClient, E)

std::string sget_error(urbi::USyncClient& c, const std::string& msg);

/// Send a computation, expect an error.
#define SGET_ERROR(E)                           \
  sget_error(syncClient, E)

extern libport::Semaphore dumpSem;

/// display the value, increment dumpSem.
urbi::UCallbackAction dump(const urbi::UMessage& msg);
/// display the value, incremente dumpSem remove callback if 0
urbi::UCallbackAction removeOnZero(const urbi::UMessage& msg);

#define BEGIN_TEST(Name, ClientName, SyncClientName)    \
  void                                                  \
  Name(urbi::UClient& ClientName,                       \
       urbi::USyncClient& SyncClientName)               \
  {                                                     \
    VERBOSE("starting test " << #Name);

#define END_TEST                                \
    sleep(3);                                   \
    SSEND("quit;");                             \
    SEND("shutdown;");                          \
  }

void dispatch(const std::string& method, urbi::UClient& client,
	      urbi::USyncClient& syncClient);

/// \a Name is the base name of the C++ file containing the function
/// \a Name.
#define TESTS_RUN(Name)							\
  do {									\
    if (method == #Name)						\
    {									\
      void Name(urbi::UClient&, urbi::USyncClient&);			\
      Name(client, syncClient);						\
      return;								\
    }									\
  } while (0)

#endif // SDK_REMOTE_TESTS_TESTS_HH
<|endoftext|>