<commit_before>#pragma warning(disable:4996)
#include "QtMainWindow.h"
#include "ui_QtMainWindow.h"
#include "ExternalWebView.h"
#include <QResizeEvent>
#include <QWebFrame>
#include "common/RhoStd.h"
#include "common/RhodesApp.h"
#include "rubyext/WebView.h"
#undef null

QtMainWindow::QtMainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::QtMainWindow),
    wi(new QWebInspector()),
    cb(NULL)
{
    ui->setupUi(this);
    this->ui->webView->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
    this->ui->webView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
    this->move(0,0);
    this->ui->toolBar->hide();
    this->ui->toolBarRight->hide();

    // connecting WebInspector
    wi->setWindowTitle("Web Inspector");
    wi->setPage(ui->webView->page());
    wi->move(416, this->geometry().y());
    wi->resize(850, 600);
    wi->show();
}

QtMainWindow::~QtMainWindow()
{
    delete wi;
    delete ui;
}

void QtMainWindow::setCallback(IMainWindowCallback* callback)
{
    cb = callback;
}

void QtMainWindow::hideEvent(QHideEvent *)
{
    if (cb) cb->onActivate(0);
}

void QtMainWindow::showEvent(QShowEvent *)
{
    if (cb) cb->onActivate(1);
}

void QtMainWindow::closeEvent(QCloseEvent *ce)
{
    wi->close();
    QMainWindow::closeEvent(ce);
}

void QtMainWindow::resizeEvent(QResizeEvent *event)
{
    if (cb)
        cb->updateSizeProperties(event->size().width(), event->size().height()); // ui->webView
}

void QtMainWindow::on_actionBack_triggered()
{
    ui->webView->back();
}

void QtMainWindow::on_webView_linkClicked(const QUrl& url)
{
    QString sUrl = url.toString();
    if (sUrl.contains("rho_open_target=_blank")) {
        if (cb) cb->logEvent("WebView: open external browser");
        ExternalWebView* externalWebView = new ExternalWebView();
        externalWebView->navigate(QUrl(sUrl.remove("rho_open_target=_blank")));
        externalWebView->show();
        externalWebView->activateWindow();
    } else {
        sUrl.remove(QRegExp("#+$"));
        if (sUrl.compare(ui->webView->url().toString())!=0)
            ui->webView->load(QUrl(sUrl));
    }
}

void QtMainWindow::on_webView_loadStarted()
{
    if (cb) cb->logEvent("WebView: loading...");
}

void QtMainWindow::on_webView_loadFinished(bool ok)
{
    if (cb) cb->logEvent((ok?"WebView: loaded ":"WebView: failed ")); // +ui->webView->url().toString()
}

void QtMainWindow::on_webView_urlChanged(QUrl url)
{
    if (cb) cb->logEvent("WebView: URL changed"); // url.toString()
}

void QtMainWindow::on_menuMain_aboutToShow()
{
    if (cb) cb->createCustomMenu();
}

void QtMainWindow::navigate(QString url)
{
    if (url.startsWith("javascript:", Qt::CaseInsensitive)) {
        url.remove(0,11);
        ui->webView->stop();
        ui->webView->page()->mainFrame()->evaluateJavaScript(url);
    } else
        ui->webView->load(QUrl(url));
}

void QtMainWindow::GoBack(void)
{
    ui->webView->back();
}

void QtMainWindow::GoForward(void)
{
    ui->webView->forward();
}

void QtMainWindow::Refresh(void)
{
    ui->webView->reload();
}

void QtMainWindow::toolbarRemoveAllButtons()
{
    ui->toolBar->clear();
    ui->toolBarRight->clear();
}

void QtMainWindow::toolbarShow()
{
    ui->toolBar->show();
    ui->toolBarRight->show();
}

void QtMainWindow::toolbarHide()
{
    ui->toolBar->hide();
    ui->toolBarRight->hide();
}

int QtMainWindow::toolbarGetHeight()
{
    return ui->toolBar->height();
}

void QtMainWindow::toolbarAddAction(const QString & text)
{
    ui->toolBar->addAction(text);
}

void QtMainWindow::on_toolbarAction_triggered(bool checked)
{
    QObject* sender = QObject::sender();
    QAction* action;
    if (sender && (action = dynamic_cast<QAction*>(sender))) {
		rho::String* strAction = new rho::String(action->data().toString().toStdString());
        if ( strcasecmp(strAction->c_str(), "forward") == 0 )
            rho_webview_navigate_forward();
        else
            RHODESAPP().loadUrl(*strAction);
    }
}

void QtMainWindow::toolbarAddAction(const QIcon & icon, const QString & text, const char* action, bool rightAlign)
{
    QAction* qAction = new QAction(icon, text, ui->toolBar);
    qAction->setData(QVariant(action));
    QObject::connect(qAction, SIGNAL(triggered(bool)), this, SLOT(on_toolbarAction_triggered(bool)) );
    if (rightAlign)
        ui->toolBarRight->insertAction( (ui->toolBarRight->actions().size() > 0 ? ui->toolBarRight->actions().last() : 0), qAction);
    else
        ui->toolBar->addAction(qAction);
}

void QtMainWindow::toolbarAddSeparator()
{
    ui->toolBar->addSeparator();
}

void QtMainWindow::setToolbarStyle(bool border, QString background)
{
	QString style = "";
	if (!border) style += "border:0px";
	if (background.length()>0) {
        if (style.length()>0) style += ";";
        style += "background:"+background;
    }
	if (style.length()>0) {
		style = "QToolBar{"+style+"}";
	    ui->toolBar->setStyleSheet(style);
        ui->toolBarRight->setStyleSheet(style);
	}
}

void QtMainWindow::menuAddAction(const QString & text, int item)
{
    QAction* qAction = new QAction(text, ui->toolBar);
    qAction->setData(QVariant(item));
    QObject::connect(qAction, SIGNAL(triggered(bool)), this, SLOT(on_menuAction_triggered(bool)) );
    ui->menuMain->addAction(qAction);
}

void QtMainWindow::menuClear(void)
{
    ui->menuMain->clear();
}

void QtMainWindow::menuAddSeparator()
{
    ui->menuMain->addSeparator();
}

void QtMainWindow::on_menuAction_triggered(bool checked)
{
    QObject* sender = QObject::sender();
    QAction* action;
    if (sender && (action = dynamic_cast<QAction*>(sender)) && cb)
        cb->onCustomMenuItemCommand(action->data().toInt());
}
<commit_msg>RhoSimulator: WebSQL support fixed<commit_after>#pragma warning(disable:4996)
#include "QtMainWindow.h"
#include "ui_QtMainWindow.h"
#include "ExternalWebView.h"
#include <QResizeEvent>
#include <QWebFrame>
#include <QWebSettings>
#include <QWebSecurityOrigin>
#include "common/RhoStd.h"
#include "common/RhodesApp.h"
#include "rubyext/WebView.h"
#undef null

QtMainWindow::QtMainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::QtMainWindow),
    wi(new QWebInspector()),
    cb(NULL)
{
    ui->setupUi(this);

    QWebSettings* qs = QWebSettings::globalSettings(); //this->ui->webView->settings();
    qs->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
    qs->setAttribute(QWebSettings::LocalStorageEnabled, true);
    qs->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, true);
    qs->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, true);
    qs->setOfflineStorageDefaultQuota(1024*1024*1024);

    rho::String rs_dir = RHODESAPP().getRhoRootPath()+RHO_EMULATOR_DIR;
    qs->setOfflineWebApplicationCachePath(rs_dir.c_str());
    qs->setLocalStoragePath(rs_dir.c_str());
    qs->setOfflineStoragePath(rs_dir.c_str());

    this->ui->webView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
    this->ui->webView->page()->mainFrame()->securityOrigin().setDatabaseQuota(1024*1024*1024);

    this->move(0,0);
    this->ui->toolBar->hide();
    this->ui->toolBarRight->hide();

    // connecting WebInspector
    wi->setWindowTitle("Web Inspector");
    wi->setPage(ui->webView->page());
    wi->move(416, this->geometry().y());
    wi->resize(850, 600);
    wi->show();
}

QtMainWindow::~QtMainWindow()
{
    delete wi;
    delete ui;
}

void QtMainWindow::setCallback(IMainWindowCallback* callback)
{
    cb = callback;
}

void QtMainWindow::hideEvent(QHideEvent *)
{
    if (cb) cb->onActivate(0);
}

void QtMainWindow::showEvent(QShowEvent *)
{
    if (cb) cb->onActivate(1);
}

void QtMainWindow::closeEvent(QCloseEvent *ce)
{
    wi->close();
    QMainWindow::closeEvent(ce);
}

void QtMainWindow::resizeEvent(QResizeEvent *event)
{
    if (cb)
        cb->updateSizeProperties(event->size().width(), event->size().height()); // ui->webView
}

void QtMainWindow::on_actionBack_triggered()
{
    ui->webView->back();
}

void QtMainWindow::on_webView_linkClicked(const QUrl& url)
{
    QString sUrl = url.toString();
    if (sUrl.contains("rho_open_target=_blank")) {
        if (cb) cb->logEvent("WebView: open external browser");
        ExternalWebView* externalWebView = new ExternalWebView();
        externalWebView->navigate(QUrl(sUrl.remove("rho_open_target=_blank")));
        externalWebView->show();
        externalWebView->activateWindow();
    } else {
        sUrl.remove(QRegExp("#+$"));
        if (sUrl.compare(ui->webView->url().toString())!=0)
            ui->webView->load(QUrl(sUrl));
    }
}

void QtMainWindow::on_webView_loadStarted()
{
    if (cb) cb->logEvent("WebView: loading...");
}

void QtMainWindow::on_webView_loadFinished(bool ok)
{
    if (cb) cb->logEvent((ok?"WebView: loaded ":"WebView: failed ")); // +ui->webView->url().toString()
}

void QtMainWindow::on_webView_urlChanged(QUrl url)
{
    if (cb) cb->logEvent("WebView: URL changed"); // url.toString()
}

void QtMainWindow::on_menuMain_aboutToShow()
{
    if (cb) cb->createCustomMenu();
}

void QtMainWindow::navigate(QString url)
{
    if (url.startsWith("javascript:", Qt::CaseInsensitive)) {
        url.remove(0,11);
        ui->webView->stop();
        ui->webView->page()->mainFrame()->evaluateJavaScript(url);
    } else
        ui->webView->load(QUrl(url));
}

void QtMainWindow::GoBack(void)
{
    ui->webView->back();
}

void QtMainWindow::GoForward(void)
{
    ui->webView->forward();
}

void QtMainWindow::Refresh(void)
{
    ui->webView->reload();
}

void QtMainWindow::toolbarRemoveAllButtons()
{
    ui->toolBar->clear();
    ui->toolBarRight->clear();
}

void QtMainWindow::toolbarShow()
{
    ui->toolBar->show();
    ui->toolBarRight->show();
}

void QtMainWindow::toolbarHide()
{
    ui->toolBar->hide();
    ui->toolBarRight->hide();
}

int QtMainWindow::toolbarGetHeight()
{
    return ui->toolBar->height();
}

void QtMainWindow::toolbarAddAction(const QString & text)
{
    ui->toolBar->addAction(text);
}

void QtMainWindow::on_toolbarAction_triggered(bool checked)
{
    QObject* sender = QObject::sender();
    QAction* action;
    if (sender && (action = dynamic_cast<QAction*>(sender))) {
		rho::String* strAction = new rho::String(action->data().toString().toStdString());
        if ( strcasecmp(strAction->c_str(), "forward") == 0 )
            rho_webview_navigate_forward();
        else
            RHODESAPP().loadUrl(*strAction);
    }
}

void QtMainWindow::toolbarAddAction(const QIcon & icon, const QString & text, const char* action, bool rightAlign)
{
    QAction* qAction = new QAction(icon, text, ui->toolBar);
    qAction->setData(QVariant(action));
    QObject::connect(qAction, SIGNAL(triggered(bool)), this, SLOT(on_toolbarAction_triggered(bool)) );
    if (rightAlign)
        ui->toolBarRight->insertAction( (ui->toolBarRight->actions().size() > 0 ? ui->toolBarRight->actions().last() : 0), qAction);
    else
        ui->toolBar->addAction(qAction);
}

void QtMainWindow::toolbarAddSeparator()
{
    ui->toolBar->addSeparator();
}

void QtMainWindow::setToolbarStyle(bool border, QString background)
{
	QString style = "";
	if (!border) style += "border:0px";
	if (background.length()>0) {
        if (style.length()>0) style += ";";
        style += "background:"+background;
    }
	if (style.length()>0) {
		style = "QToolBar{"+style+"}";
	    ui->toolBar->setStyleSheet(style);
        ui->toolBarRight->setStyleSheet(style);
	}
}

void QtMainWindow::menuAddAction(const QString & text, int item)
{
    QAction* qAction = new QAction(text, ui->toolBar);
    qAction->setData(QVariant(item));
    QObject::connect(qAction, SIGNAL(triggered(bool)), this, SLOT(on_menuAction_triggered(bool)) );
    ui->menuMain->addAction(qAction);
}

void QtMainWindow::menuClear(void)
{
    ui->menuMain->clear();
}

void QtMainWindow::menuAddSeparator()
{
    ui->menuMain->addSeparator();
}

void QtMainWindow::on_menuAction_triggered(bool checked)
{
    QObject* sender = QObject::sender();
    QAction* action;
    if (sender && (action = dynamic_cast<QAction*>(sender)) && cb)
        cb->onCustomMenuItemCommand(action->data().toInt());
}
<|endoftext|>


<commit_before>
#include <togo/utility.hpp>
#include <togo/assert.hpp>
#include <togo/log.hpp>
#include <togo/kvs.hpp>

#include "../common/helpers.hpp"

#include <cstring>

using namespace togo;

signed
main() {
	memory_init();

	TOGO_LOGF("sizeof(KVS) = %u\n", static_cast<unsigned>(sizeof(KVS)));
	TOGO_LOGF("sizeof(KVS::Value) = %u\n", static_cast<unsigned>(sizeof(KVS::Value)));
	TOGO_LOGF("alignof(KVS) %u\n", static_cast<unsigned>(alignof(KVS)));
	TOGO_LOGF("alignof(KVS::Value) %u\n", static_cast<unsigned>(alignof(KVS::Value)));

	{
		KVS const identity;
		TOGO_ASSERTE(kvs::is_null(identity));
		TOGO_ASSERTE(!kvs::is_integer(identity));
		TOGO_ASSERTE(!kvs::is_decimal(identity));
		TOGO_ASSERTE(!kvs::is_boolean(identity));
		TOGO_ASSERTE(!kvs::is_string(identity));
		TOGO_ASSERTE(!kvs::is_vector(identity));
		TOGO_ASSERTE(!kvs::is_collection(identity));
		TOGO_ASSERTE(!kvs::is_named(identity));
		TOGO_ASSERTE(kvs::size(identity) == 0);
		TOGO_ASSERTE(!kvs::any(identity));
		TOGO_ASSERTE(kvs::empty(identity));
		TOGO_ASSERTE(kvs::begin(identity) == nullptr);
		TOGO_ASSERTE(kvs::end(identity) == nullptr);
	}

	{
		static constexpr char const NAME[]{"bzork"};
		static constexpr char const VALUE[]{"fitz"};
		KVS a{VALUE};
		TOGO_ASSERTE(!kvs::is_named(a));
		TOGO_ASSERTE(kvs::is_string(a));
		TOGO_ASSERTE(kvs::string_size(a) == sizeof(VALUE));
		TOGO_ASSERTE(0 == std::strncmp(VALUE, kvs::string(a), kvs::string_size(a)));

		kvs::set_name(a, NAME);
		TOGO_ASSERTE(kvs::is_named(a));
		TOGO_ASSERTE(kvs::name_size(a) == sizeof(NAME));
		TOGO_ASSERTE(0 == std::strncmp(NAME, kvs::name(a), kvs::name_size(a)));

		TOGO_LOGF("\"%s\" = \"%s\"\n", kvs::name(a), kvs::string(a));

		kvs::integer(a, static_cast<s64>(0xCECECECECECECECE));
		TOGO_ASSERTE(kvs::is_integer(a));
		TOGO_ASSERTE(kvs::integer(a) == static_cast<s64>(0xCECECECECECECECE));

		kvs::boolean(a, false);
		TOGO_ASSERTE(kvs::is_boolean(a));
		TOGO_ASSERTE(kvs::boolean(a) == false);

		kvs::nullify(a);
		TOGO_ASSERTE(kvs::is_null(a));
	}

	return 0;
}
<commit_msg>test/kvs/values: corrected string size assertions.<commit_after>
#include <togo/utility.hpp>
#include <togo/assert.hpp>
#include <togo/log.hpp>
#include <togo/kvs.hpp>

#include "../common/helpers.hpp"

#include <cstring>

using namespace togo;

signed
main() {
	memory_init();

	TOGO_LOGF("sizeof(KVS) = %u\n", static_cast<unsigned>(sizeof(KVS)));
	TOGO_LOGF("sizeof(KVS::Value) = %u\n", static_cast<unsigned>(sizeof(KVS::Value)));
	TOGO_LOGF("alignof(KVS) %u\n", static_cast<unsigned>(alignof(KVS)));
	TOGO_LOGF("alignof(KVS::Value) %u\n", static_cast<unsigned>(alignof(KVS::Value)));

	{
		KVS const identity;
		TOGO_ASSERTE(kvs::is_null(identity));
		TOGO_ASSERTE(!kvs::is_integer(identity));
		TOGO_ASSERTE(!kvs::is_decimal(identity));
		TOGO_ASSERTE(!kvs::is_boolean(identity));
		TOGO_ASSERTE(!kvs::is_string(identity));
		TOGO_ASSERTE(!kvs::is_vector(identity));
		TOGO_ASSERTE(!kvs::is_collection(identity));
		TOGO_ASSERTE(!kvs::is_named(identity));
		TOGO_ASSERTE(kvs::size(identity) == 0);
		TOGO_ASSERTE(!kvs::any(identity));
		TOGO_ASSERTE(kvs::empty(identity));
		TOGO_ASSERTE(kvs::begin(identity) == nullptr);
		TOGO_ASSERTE(kvs::end(identity) == nullptr);
	}

	{
		static constexpr char const NAME[]{"bzork"};
		static constexpr char const VALUE[]{"fitz"};
		KVS a{VALUE};
		TOGO_ASSERTE(!kvs::is_named(a));
		TOGO_ASSERTE(kvs::is_string(a));
		TOGO_ASSERTE(kvs::string_size(a) == std::strlen(VALUE));
		TOGO_ASSERTE(0 == std::strncmp(VALUE, kvs::string(a), kvs::string_size(a)));

		kvs::set_name(a, NAME);
		TOGO_ASSERTE(kvs::is_named(a));
		TOGO_ASSERTE(kvs::name_size(a) == std::strlen(NAME));
		TOGO_ASSERTE(0 == std::strncmp(NAME, kvs::name(a), kvs::name_size(a)));

		TOGO_LOGF("\"%s\" = \"%s\"\n", kvs::name(a), kvs::string(a));

		kvs::integer(a, static_cast<s64>(0xCECECECECECECECE));
		TOGO_ASSERTE(kvs::is_integer(a));
		TOGO_ASSERTE(kvs::integer(a) == static_cast<s64>(0xCECECECECECECECE));

		kvs::boolean(a, false);
		TOGO_ASSERTE(kvs::is_boolean(a));
		TOGO_ASSERTE(kvs::boolean(a) == false);

		kvs::nullify(a);
		TOGO_ASSERTE(kvs::is_null(a));
	}

	return 0;
}
<|endoftext|>


<commit_before>#ifndef MJOLNIR_CORE_MULTIPLE_BASIN_FORCE_FIELD_HPP
#define MJOLNIR_CORE_MULTIPLE_BASIN_FORCE_FIELD_HPP
#include <mjolnir/forcefield/MultipleBasin/MultipleBasinUnitBase.hpp>
#include <mjolnir/core/Topology.hpp>
#include <mjolnir/core/LocalForceField.hpp>
#include <mjolnir/core/GlobalForceField.hpp>
#include <mjolnir/core/ExternalForceField.hpp>
#include <mjolnir/util/string.hpp>
#include <algorithm>
#include <numeric>
#include <memory>

namespace mjolnir
{

// MultipleBasinForceField
//
// In some cases, protein has several domains that undergoes conformational
// changes independently.
//
//  .-.  .-.      __  .-.
// ( A )( B ) -> (A'|( B )
//  `-'  `-'      `-  `-'
//      |            |
//      v            v
//  .-.  __        __ __
// ( A )|B')  ->  (A'|B')
//  `-'  -'        `- -'
//
// To handle such cases, MultipleBasinForceField has several N-basin forcefields
// inside and manage them in a proper way.
//
template<typename traitsT>
class MultipleBasinForceField : public ForceFieldBase<traitsT>
{
  public:
    using traits_type     = traitsT;
    using base_type       = ForceFieldBase<traits_type>;
    using real_type       = typename base_type::real_type;
    using coordinate_type = typename base_type::coordinate_type;
    using system_type     = typename base_type::system_type;
    using topology_type   = Topology;

    using local_forcefield_type    = LocalForceField<traits_type>;
    using global_forcefield_type   = GlobalForceField<traits_type>;
    using external_forcefield_type = ExternalForceField<traits_type>;
    using forcefield_type          = std::tuple<
        local_forcefield_type, global_forcefield_type, external_forcefield_type>;

    // a set of potentials that are correlated in the way of MultipleBasin.
    using multiple_basin_unit_type =
        std::unique_ptr<MultipleBasinUnitBase<traits_type>>;

  public:

    MultipleBasinForceField(forcefield_type&& common,
                            std::vector<multiple_basin_unit_type>&& units)
        : loc_common_(std::move(std::get<0>(common))),
          glo_common_(std::move(std::get<1>(common))),
          ext_common_(std::move(std::get<2>(common))),
          units_(std::move(units))
    {}

    ~MultipleBasinForceField() override = default;
    MultipleBasinForceField(const MultipleBasinForceField&) = delete;
    MultipleBasinForceField(MultipleBasinForceField&&)      = default;
    MultipleBasinForceField& operator=(const MultipleBasinForceField&) = delete;
    MultipleBasinForceField& operator=(MultipleBasinForceField&&)      = default;

    void initialize(const system_type& sys) override
    {
        MJOLNIR_GET_DEFAULT_LOGGER();
        MJOLNIR_LOG_FUNCTION();

        // -------------------------------------------------------------------
        // write topologies. Here we assume topologies are the same

        MJOLNIR_LOG_INFO("writing topology");
        topol_.resize(sys.size());

        for(auto& unit : this->units_)
        {
            // each unit does not know the size of the system.
            // we need to tell them the size.
            unit->write_topology(sys, topol_);
        }
        loc_common_.write_topology(topol_);

        topol_.construct_molecules();

        MJOLNIR_LOG_INFO("initializing forcefields");
        for(auto& unit : this->units_)
        {
            unit->initialize(sys, this->topol_);
        }
        loc_common_.initialize(sys);
        glo_common_.initialize(sys, this->topol_);
        ext_common_.initialize(sys);
        return;
    }

    void calc_force(system_type& sys) const noexcept override
    {
        for(const auto& unit : this->units_)
        {
            unit->calc_force(sys);
        }
        loc_common_.calc_force(sys);
        glo_common_.calc_force(sys);
        ext_common_.calc_force(sys);
        return ;
    }

    real_type calc_energy(const system_type& sys) const noexcept override
    {
        real_type E = real_type(0.0);

        for(const auto& unit : this->units_)
        {
            E += unit->calc_energy(sys);
        }
        E += loc_common_.calc_energy(sys);
        E += glo_common_.calc_energy(sys);
        E += ext_common_.calc_energy(sys);
        return E;
    }

    void update(const system_type& sys) override
    {
        // update parameters (e.g. temperature). TODO: topologies?

        for(auto& unit : this->units_)
        {
            unit->update(sys, this->topol_);
        }
        loc_common_.update(sys);
        glo_common_.update(sys, this->topol_);
        ext_common_.update(sys);
        return;
    }

    // update margin of neighbor list
    void reduce_margin(const real_type dmargin, const system_type& sys) override
    {
        for(auto& unit : this->units_)
        {
            unit->reduce_margin(dmargin, sys);
        }
        loc_common_.reduce_margin(dmargin, sys);
        glo_common_.reduce_margin(dmargin, sys);
        ext_common_.reduce_margin(dmargin, sys);
        return;
    }
    void scale_margin(const real_type scale, const system_type& sys) override
    {
        for(auto& unit : this->units_)
        {
            unit->scale_margin(scale, sys);
        }
        loc_common_.scale_margin(scale, sys);
        glo_common_.scale_margin(scale, sys);
        ext_common_.scale_margin(scale, sys);
        return;
    }

    std::vector<std::string> list_energy_name() const override
    {
        using namespace mjolnir::literals::string_literals;

        std::vector<std::string> retval;
        for(const auto& unit : this->units_)
        {
            auto ls = unit->list_energy_name();
            std::copy(std::make_move_iterator(ls.begin()),
                      std::make_move_iterator(ls.end()),
                      std::back_inserter(retval));
        }
        std::vector<std::string> common;
        auto loc_cmn = loc_common_.list_energy();
        auto glo_cmn = glo_common_.list_energy();
        auto ext_cmn = ext_common_.list_energy();
        std::copy(std::make_move_iterator(loc_cmn.begin()),
                  std::make_move_iterator(loc_cmn.end()),
                  std::back_inserter(common));
        std::copy(std::make_move_iterator(glo_cmn.begin()),
                  std::make_move_iterator(glo_cmn.end()),
                  std::back_inserter(common));
        std::copy(std::make_move_iterator(ext_cmn.begin()),
                  std::make_move_iterator(ext_cmn.end()),
                  std::back_inserter(common));
        if(!common.empty())
        {
            common.front() = "Common{"_s + common.front();
            common.back() += "}"_s;
        }
        return retval;
    }

    std::vector<real_type> dump_energy(const system_type& sys) const override
    {
        std::vector<real_type> retval;
        for(const auto& unit : this->units_)
        {
            const auto ls = unit->dump_energy(sys);
            std::copy(ls.begin(), ls.end(), std::back_inserter(retval));
        }
        const auto loc_cmn = loc_common_.dump_energy(sys);
        const auto glo_cmn = glo_common_.dump_energy(sys);
        const auto ext_cmn = ext_common_.dump_energy(sys);

        std::copy(loc_cmn.begin(), loc_cmn.end(), std::back_inserter(retval));
        std::copy(glo_cmn.begin(), glo_cmn.end(), std::back_inserter(retval));
        std::copy(ext_cmn.begin(), ext_cmn.end(), std::back_inserter(retval));

        return retval;
    }
    topology_type const& topology() const noexcept override {return topol_;}

  private:

    topology_type            topol_;
    local_forcefield_type    loc_common_;
    global_forcefield_type   glo_common_;
    external_forcefield_type ext_common_;

    std::vector<multiple_basin_unit_type> units_;
};

#ifdef MJOLNIR_SEPARATE_BUILD
extern template class MultipleBasinForceField<SimulatorTraits<double, UnlimitedBoundary       >>;
extern template class MultipleBasinForceField<SimulatorTraits<float,  UnlimitedBoundary       >>;
extern template class MultipleBasinForceField<SimulatorTraits<double, CuboidalPeriodicBoundary>>;
extern template class MultipleBasinForceField<SimulatorTraits<float,  CuboidalPeriodicBoundary>>;
#endif

} // mjolnir
#endif// MJOLNIR_CORE_MULTIPLE_BASIN_FORCE_FIELD_HPP
<commit_msg>fix: append common potential names<commit_after>#ifndef MJOLNIR_CORE_MULTIPLE_BASIN_FORCE_FIELD_HPP
#define MJOLNIR_CORE_MULTIPLE_BASIN_FORCE_FIELD_HPP
#include <mjolnir/forcefield/MultipleBasin/MultipleBasinUnitBase.hpp>
#include <mjolnir/core/Topology.hpp>
#include <mjolnir/core/LocalForceField.hpp>
#include <mjolnir/core/GlobalForceField.hpp>
#include <mjolnir/core/ExternalForceField.hpp>
#include <mjolnir/util/string.hpp>
#include <algorithm>
#include <numeric>
#include <memory>

namespace mjolnir
{

// MultipleBasinForceField
//
// In some cases, protein has several domains that undergoes conformational
// changes independently.
//
//  .-.  .-.      __  .-.
// ( A )( B ) -> (A'|( B )
//  `-'  `-'      `-  `-'
//      |            |
//      v            v
//  .-.  __        __ __
// ( A )|B')  ->  (A'|B')
//  `-'  -'        `- -'
//
// To handle such cases, MultipleBasinForceField has several N-basin forcefields
// inside and manage them in a proper way.
//
template<typename traitsT>
class MultipleBasinForceField : public ForceFieldBase<traitsT>
{
  public:
    using traits_type     = traitsT;
    using base_type       = ForceFieldBase<traits_type>;
    using real_type       = typename base_type::real_type;
    using coordinate_type = typename base_type::coordinate_type;
    using system_type     = typename base_type::system_type;
    using topology_type   = Topology;

    using local_forcefield_type    = LocalForceField<traits_type>;
    using global_forcefield_type   = GlobalForceField<traits_type>;
    using external_forcefield_type = ExternalForceField<traits_type>;
    using forcefield_type          = std::tuple<
        local_forcefield_type, global_forcefield_type, external_forcefield_type>;

    // a set of potentials that are correlated in the way of MultipleBasin.
    using multiple_basin_unit_type =
        std::unique_ptr<MultipleBasinUnitBase<traits_type>>;

  public:

    MultipleBasinForceField(forcefield_type&& common,
                            std::vector<multiple_basin_unit_type>&& units)
        : loc_common_(std::move(std::get<0>(common))),
          glo_common_(std::move(std::get<1>(common))),
          ext_common_(std::move(std::get<2>(common))),
          units_(std::move(units))
    {}

    ~MultipleBasinForceField() override = default;
    MultipleBasinForceField(const MultipleBasinForceField&) = delete;
    MultipleBasinForceField(MultipleBasinForceField&&)      = default;
    MultipleBasinForceField& operator=(const MultipleBasinForceField&) = delete;
    MultipleBasinForceField& operator=(MultipleBasinForceField&&)      = default;

    void initialize(const system_type& sys) override
    {
        MJOLNIR_GET_DEFAULT_LOGGER();
        MJOLNIR_LOG_FUNCTION();

        // -------------------------------------------------------------------
        // write topologies. Here we assume topologies are the same

        MJOLNIR_LOG_INFO("writing topology");
        topol_.resize(sys.size());

        for(auto& unit : this->units_)
        {
            // each unit does not know the size of the system.
            // we need to tell them the size.
            unit->write_topology(sys, topol_);
        }
        loc_common_.write_topology(topol_);

        topol_.construct_molecules();

        MJOLNIR_LOG_INFO("initializing forcefields");
        for(auto& unit : this->units_)
        {
            unit->initialize(sys, this->topol_);
        }
        loc_common_.initialize(sys);
        glo_common_.initialize(sys, this->topol_);
        ext_common_.initialize(sys);
        return;
    }

    void calc_force(system_type& sys) const noexcept override
    {
        for(const auto& unit : this->units_)
        {
            unit->calc_force(sys);
        }
        loc_common_.calc_force(sys);
        glo_common_.calc_force(sys);
        ext_common_.calc_force(sys);
        return ;
    }

    real_type calc_energy(const system_type& sys) const noexcept override
    {
        real_type E = real_type(0.0);

        for(const auto& unit : this->units_)
        {
            E += unit->calc_energy(sys);
        }
        E += loc_common_.calc_energy(sys);
        E += glo_common_.calc_energy(sys);
        E += ext_common_.calc_energy(sys);
        return E;
    }

    void update(const system_type& sys) override
    {
        // update parameters (e.g. temperature). TODO: topologies?

        for(auto& unit : this->units_)
        {
            unit->update(sys, this->topol_);
        }
        loc_common_.update(sys);
        glo_common_.update(sys, this->topol_);
        ext_common_.update(sys);
        return;
    }

    // update margin of neighbor list
    void reduce_margin(const real_type dmargin, const system_type& sys) override
    {
        for(auto& unit : this->units_)
        {
            unit->reduce_margin(dmargin, sys);
        }
        loc_common_.reduce_margin(dmargin, sys);
        glo_common_.reduce_margin(dmargin, sys);
        ext_common_.reduce_margin(dmargin, sys);
        return;
    }
    void scale_margin(const real_type scale, const system_type& sys) override
    {
        for(auto& unit : this->units_)
        {
            unit->scale_margin(scale, sys);
        }
        loc_common_.scale_margin(scale, sys);
        glo_common_.scale_margin(scale, sys);
        ext_common_.scale_margin(scale, sys);
        return;
    }

    std::vector<std::string> list_energy_name() const override
    {
        using namespace mjolnir::literals::string_literals;

        std::vector<std::string> retval;
        for(const auto& unit : this->units_)
        {
            auto ls = unit->list_energy_name();
            std::copy(std::make_move_iterator(ls.begin()),
                      std::make_move_iterator(ls.end()),
                      std::back_inserter(retval));
        }
        std::vector<std::string> common;
        auto loc_cmn = loc_common_.list_energy();
        auto glo_cmn = glo_common_.list_energy();
        auto ext_cmn = ext_common_.list_energy();
        std::copy(std::make_move_iterator(loc_cmn.begin()),
                  std::make_move_iterator(loc_cmn.end()),
                  std::back_inserter(common));
        std::copy(std::make_move_iterator(glo_cmn.begin()),
                  std::make_move_iterator(glo_cmn.end()),
                  std::back_inserter(common));
        std::copy(std::make_move_iterator(ext_cmn.begin()),
                  std::make_move_iterator(ext_cmn.end()),
                  std::back_inserter(common));
        if(!common.empty())
        {
            common.front() = "Common{"_s + common.front();
            common.back() += "}"_s;
        }
        std::copy(std::make_move_iterator(common.begin()),
                  std::make_move_iterator(common.end()),
                  std::back_inserter(retval));
        return retval;
    }

    std::vector<real_type> dump_energy(const system_type& sys) const override
    {
        std::vector<real_type> retval;
        for(const auto& unit : this->units_)
        {
            const auto ls = unit->dump_energy(sys);
            std::copy(ls.begin(), ls.end(), std::back_inserter(retval));
        }
        const auto loc_cmn = loc_common_.dump_energy(sys);
        const auto glo_cmn = glo_common_.dump_energy(sys);
        const auto ext_cmn = ext_common_.dump_energy(sys);

        std::copy(loc_cmn.begin(), loc_cmn.end(), std::back_inserter(retval));
        std::copy(glo_cmn.begin(), glo_cmn.end(), std::back_inserter(retval));
        std::copy(ext_cmn.begin(), ext_cmn.end(), std::back_inserter(retval));

        return retval;
    }
    topology_type const& topology() const noexcept override {return topol_;}

  private:

    topology_type            topol_;
    local_forcefield_type    loc_common_;
    global_forcefield_type   glo_common_;
    external_forcefield_type ext_common_;

    std::vector<multiple_basin_unit_type> units_;
};

#ifdef MJOLNIR_SEPARATE_BUILD
extern template class MultipleBasinForceField<SimulatorTraits<double, UnlimitedBoundary       >>;
extern template class MultipleBasinForceField<SimulatorTraits<float,  UnlimitedBoundary       >>;
extern template class MultipleBasinForceField<SimulatorTraits<double, CuboidalPeriodicBoundary>>;
extern template class MultipleBasinForceField<SimulatorTraits<float,  CuboidalPeriodicBoundary>>;
#endif

} // mjolnir
#endif// MJOLNIR_CORE_MULTIPLE_BASIN_FORCE_FIELD_HPP
<|endoftext|>


<commit_before><commit_msg>Fix fix of concurrently running Schmutzes.<commit_after><|endoftext|>


<commit_before>//
// Created by Salvador on 3/22/2015.
//
#include <iostream>

#include "TreeNode.hxx"
#include "sametree.hxx"

using namespace std;

int main(void) {
	Solution sol;

	TreeNode p{5}, q{5};

	cout << sol.isSameTree(p, q) << endl;

	return 0;
}
<commit_msg>fixed test<commit_after>//
// Created by Salvador on 3/22/2015.
//
#include <iostream>

#include "TreeNode.hxx"
#include "sametree.hxx"

using namespace std;

int main(void) {
	Solution sol;

	TreeNode p{5}, q{5};

	cout << sol.isSameTree(&p, &q) << endl;

	return 0;
}
<|endoftext|>


<commit_before>/*
 * jcom.dataspace
 * External for Jamoma: map input to output: y=f(x)
 * Copyright © 2007
 *
 * License: This code is licensed under the terms of the "New BSD License"
 * http://creativecommons.org/licenses/BSD/
 */

#include "Jamoma.h"

// Data Structure for this object
typedef struct _dataspace{
	t_object		ob;
	//void			*outlet_active;
	void			*outlet_native;
	DataspaceLib	*dataspace;
	long			ac;						// for return values from the dataspace conversion
	t_atom			*av;					//	...
	t_symbol		*attr_dataspace;		// name of the dataspace -- e.g. "temperature"
	t_symbol		*attr_dataspace_active;	// name of the current unit within the dataspace -- e.g. "celsius"
	t_symbol		*attr_dataspace_native;	// name of the desired native unit within the dataspace -- e.g. "celsius"
} t_dataspace;

// Prototypes for methods
void*		dataspace_new(t_symbol *name, long argc, t_atom *argv);
void		dataspace_free(t_dataspace *obj);
void		dataspace_assist(t_dataspace *obj, void *b, long m, long a, char *s);
void		dataspace_int(t_dataspace *obj, long x);
void		dataspace_float(t_dataspace *obj, double x);
void		dataspace_list(t_dataspace *obj, t_symbol *msg, long argc, t_atom *argv);
void		dataspace_getDataspaces(t_dataspace *obj);
void		dataspace_getUnits(t_dataspace *obj);
t_max_err	dataspace_setDataspace(t_dataspace *obj, void *attr, long argc, t_atom *argv);
t_max_err	dataspace_setDataspaceActive(t_dataspace *obj, void *attr, long argc, t_atom *argv);
t_max_err	dataspace_setDataspaceNative(t_dataspace *obj, void *attr, long argc, t_atom *argv);

// Globals
t_class		*dataspace_class;

/************************************************************************************/
// Main() Function

int JAMOMA_EXPORT_MAXOBJ main(void)
{
	t_class *c;

	jamoma_init();
	common_symbols_init();

	// Define our class
	c = class_new("jcom.dataspace",(method)dataspace_new, (method)dataspace_free, sizeof(t_dataspace), (method)0L, A_GIMME, 0);

	// Make methods accessible for our class:
	class_addmethod(c, (method)dataspace_int,			"int",				A_GIMME, 0);
	class_addmethod(c, (method)dataspace_float,			"float",			A_GIMME, 0);
	class_addmethod(c, (method)dataspace_list,			"list",				A_GIMME, 0);
	class_addmethod(c, (method)dataspace_getDataspaces,	"dataspaces.get",	0);
 	class_addmethod(c, (method)dataspace_getUnits,		"units.get",		A_GIMME, 0);
	class_addmethod(c, (method)dataspace_assist,		"assist",			A_CANT, 0);
    class_addmethod(c, (method)object_obex_dumpout, 	"dumpout",			A_CANT, 0);

	class_addattr(c,
		attr_offset_new("dataspace", _sym_symbol, 0,
		(method)0, (method)dataspace_setDataspace, calcoffset(t_dataspace, attr_dataspace)));
/*
	class_addattr(c,
		attr_offset_new("unit.active", _sym_symbol, 0,
		(method)0, (method)dataspace_setDataspaceActive, calcoffset(t_dataspace, attr_dataspace_active)));
	class_addattr(c,
		attr_offset_new("unit.native", _sym_symbol, 0,
		(method)0, (method)dataspace_setDataspaceNative, calcoffset(t_dataspace, attr_dataspace_native)));
*/
	CLASS_ATTR_SYM(c,		"input",	0,		t_dataspace,	attr_dataspace_active);
	CLASS_ATTR_ACCESSORS(c,	"input",	NULL,	dataspace_setDataspaceActive);

	CLASS_ATTR_SYM(c,		"output",	0,		t_dataspace,	attr_dataspace_native);
	CLASS_ATTR_ACCESSORS(c,	"output",	NULL,	dataspace_setDataspaceNative);

	// Finalize our class
	class_register(CLASS_BOX, c);
	dataspace_class = c;
	return 0;
}

/************************************************************************************/
// Object Life

void *dataspace_new(t_symbol *name, long argc, t_atom *argv)
{
	t_dataspace *obj;									// Declare an object (based on our struct)

	obj = (t_dataspace *)object_alloc(dataspace_class);		// Create object, store pointer to it (get 1 inlet free)
	if (obj) {
		object_obex_store((void *)obj, _sym_dumpout, (object *)outlet_new(obj,NULL));
	    //obj->outlet_active = outlet_new(obj, 0);
	    obj->outlet_native = outlet_new(obj, 0);
		obj->dataspace = NULL;
		obj->attr_dataspace_active = _sym_nothing;
		obj->attr_dataspace_native = _sym_nothing;

		attr_args_process(obj, argc, argv);
		if (!obj->dataspace)
			object_attr_setsym(obj, gensym("dataspace"), gensym("temperature"));

		obj->av = (t_atom*)sysmem_newptr(sizeof(t_atom) * 3);	// just allocating three for now -- limited list support
	}
	return obj;										// Return pointer to our instance
}

void dataspace_free(t_dataspace *obj)
{
	sysmem_freeptr(obj->av);
	if (obj->dataspace)
		delete obj->dataspace;
}

/************************************************************************************/
// Methods bound to input/inlets

// Method for Assistance Messages
void dataspace_assist(t_dataspace *x, void *b, long msg, long arg, char *dst)
{
	if (msg==1) 							// Inlets
		strcpy(dst, "x");
	else if (msg==2) { 					// Outlets
		switch(arg) {
			case 0: strcpy(dst, "y=f(x)"); break;
			default: strcpy(dst, "dumpout"); break;
 		}
 	}
}

void dataspace_int(t_dataspace *obj, long x)
{
	dataspace_float(obj, (double)x);
}

void dataspace_float(t_dataspace *obj, double x)
{
	t_atom	a[1];

	atom_setfloat(a, x);
	obj->dataspace->convert(1, a, &obj->ac, &obj->av);
	outlet_anything(obj->outlet_native, _sym_float, obj->ac, obj->av);
	//outlet_float(obj->outlet_active, x);
}

void dataspace_list(t_dataspace *obj, t_symbol *msg, long argc, t_atom *argv)
{
	obj->dataspace->convert(argc, argv, &obj->ac, &obj->av);
	outlet_anything(obj->outlet_native, _sym_list, obj->ac, obj->av);
	//outlet_anything(obj->outlet_active, _sym_list, argc, argv);
}

void dataspace_getDataspaces(t_dataspace *obj)
{
	t_atom		a[2];
	t_symbol	**dataspaceNames = NULL;
	long		numDataspaces = 0;
	long		i;

	atom_setsym(a+0, gensym("clear"));
	object_obex_dumpout(obj, gensym("DataspacesMenu"), 1, a);

	jamoma_getDataspaceList(&numDataspaces, &dataspaceNames);

	for (i=0; i<numDataspaces; i++) {
		atom_setsym(a+0, gensym("append"));
		atom_setsym(a+1, dataspaceNames[i]);
		object_obex_dumpout(obj, gensym("DataspacesMenu"), 2, a);
	}

	if (numDataspaces)
		sysmem_freeptr(dataspaceNames);
}

void dataspace_getUnits(t_dataspace *obj)
{
	t_atom		a[2];
	t_symbol	**unitNames = NULL;
	long		numUnits = 0;
	long		i;

	atom_setsym(a+0, gensym("clear"));
	object_obex_dumpout(obj, gensym("UnitMenu"), 1, a);

	obj->dataspace->getAvailableUnits(&numUnits, &unitNames);

	for (i=0; i<numUnits; i++) {
		atom_setsym(a+0, gensym("append"));
		atom_setsym(a+1, unitNames[i]);
		object_obex_dumpout(obj, gensym("UnitMenu"), 2, a);
	}

	if (numUnits)
		sysmem_freeptr(unitNames);
}

// ATTRIBUTE:
t_max_err dataspace_setDataspace(t_dataspace *obj, void *attr, long argc, t_atom *argv)
{
	obj->attr_dataspace = atom_getsym(argv);
	jamoma_getDataspace(obj->attr_dataspace, &obj->dataspace);
	obj->attr_dataspace_active = obj->dataspace->neutralUnit;
	obj->attr_dataspace_native = obj->dataspace->neutralUnit;
	return MAX_ERR_NONE;
}

// ATTRIBUTE:
t_max_err dataspace_setDataspaceActive(t_dataspace *obj, void *attr, long argc, t_atom *argv)
{
	obj->attr_dataspace_active = atom_getsym(argv);
	obj->dataspace->setInputUnit(obj->attr_dataspace_active);
	return MAX_ERR_NONE;
}

// ATTRIBUTE:
t_max_err dataspace_setDataspaceNative(t_dataspace *obj, void *attr, long argc, t_atom *argv)
{
	obj->attr_dataspace_native = atom_getsym(argv);
	obj->dataspace->setOutputUnit(obj->attr_dataspace_native);
	return MAX_ERR_NONE;
}

<commit_msg>Adding pragma marks for simplified navigation in Xcode<commit_after>/*
 * jcom.dataspace
 * External for Jamoma: map input to output: y=f(x)
 * Copyright © 2007
 *
 * License: This code is licensed under the terms of the "New BSD License"
 * http://creativecommons.org/licenses/BSD/
 */

#include "Jamoma.h"

// Data Structure for this object
typedef struct _dataspace{
	t_object		ob;
	//void			*outlet_active;
	void			*outlet_native;
	DataspaceLib	*dataspace;
	long			ac;						// for return values from the dataspace conversion
	t_atom			*av;					//	...
	t_symbol		*attr_dataspace;		// name of the dataspace -- e.g. "temperature"
	t_symbol		*attr_dataspace_active;	// name of the current unit within the dataspace -- e.g. "celsius"
	t_symbol		*attr_dataspace_native;	// name of the desired native unit within the dataspace -- e.g. "celsius"
} t_dataspace;

// Prototypes for methods
void*		dataspace_new(t_symbol *name, long argc, t_atom *argv);
void		dataspace_free(t_dataspace *obj);
void		dataspace_assist(t_dataspace *obj, void *b, long m, long a, char *s);
void		dataspace_int(t_dataspace *obj, long x);
void		dataspace_float(t_dataspace *obj, double x);
void		dataspace_list(t_dataspace *obj, t_symbol *msg, long argc, t_atom *argv);
void		dataspace_getDataspaces(t_dataspace *obj);
void		dataspace_getUnits(t_dataspace *obj);
t_max_err	dataspace_setDataspace(t_dataspace *obj, void *attr, long argc, t_atom *argv);
t_max_err	dataspace_setDataspaceActive(t_dataspace *obj, void *attr, long argc, t_atom *argv);
t_max_err	dataspace_setDataspaceNative(t_dataspace *obj, void *attr, long argc, t_atom *argv);

// Globals
t_class		*dataspace_class;

#pragma mark -
#pragma mark main
/************************************************************************************/
// Main() Function

int JAMOMA_EXPORT_MAXOBJ main(void)
{
	t_class *c;

	jamoma_init();
	common_symbols_init();

	// Define our class
	c = class_new("jcom.dataspace",(method)dataspace_new, (method)dataspace_free, sizeof(t_dataspace), (method)0L, A_GIMME, 0);

	// Make methods accessible for our class:
	class_addmethod(c, (method)dataspace_int,			"int",				A_GIMME, 0);
	class_addmethod(c, (method)dataspace_float,			"float",			A_GIMME, 0);
	class_addmethod(c, (method)dataspace_list,			"list",				A_GIMME, 0);
	class_addmethod(c, (method)dataspace_getDataspaces,	"dataspaces.get",	0);
 	class_addmethod(c, (method)dataspace_getUnits,		"units.get",		A_GIMME, 0);
	class_addmethod(c, (method)dataspace_assist,		"assist",			A_CANT, 0);
    class_addmethod(c, (method)object_obex_dumpout, 	"dumpout",			A_CANT, 0);

	class_addattr(c,
		attr_offset_new("dataspace", _sym_symbol, 0,
		(method)0, (method)dataspace_setDataspace, calcoffset(t_dataspace, attr_dataspace)));
/*
	class_addattr(c,
		attr_offset_new("unit.active", _sym_symbol, 0,
		(method)0, (method)dataspace_setDataspaceActive, calcoffset(t_dataspace, attr_dataspace_active)));
	class_addattr(c,
		attr_offset_new("unit.native", _sym_symbol, 0,
		(method)0, (method)dataspace_setDataspaceNative, calcoffset(t_dataspace, attr_dataspace_native)));
*/
	CLASS_ATTR_SYM(c,		"input",	0,		t_dataspace,	attr_dataspace_active);
	CLASS_ATTR_ACCESSORS(c,	"input",	NULL,	dataspace_setDataspaceActive);

	CLASS_ATTR_SYM(c,		"output",	0,		t_dataspace,	attr_dataspace_native);
	CLASS_ATTR_ACCESSORS(c,	"output",	NULL,	dataspace_setDataspaceNative);

	// Finalize our class
	class_register(CLASS_BOX, c);
	dataspace_class = c;
	return 0;
}

#pragma mark -
#pragma mark life cycle
/************************************************************************************/
// Object Life

void *dataspace_new(t_symbol *name, long argc, t_atom *argv)
{
	t_dataspace *obj;									// Declare an object (based on our struct)

	obj = (t_dataspace *)object_alloc(dataspace_class);		// Create object, store pointer to it (get 1 inlet free)
	if (obj) {
		object_obex_store((void *)obj, _sym_dumpout, (object *)outlet_new(obj,NULL));
	    //obj->outlet_active = outlet_new(obj, 0);
	    obj->outlet_native = outlet_new(obj, 0);
		obj->dataspace = NULL;
		obj->attr_dataspace_active = _sym_nothing;
		obj->attr_dataspace_native = _sym_nothing;

		attr_args_process(obj, argc, argv);
		if (!obj->dataspace)
			object_attr_setsym(obj, gensym("dataspace"), gensym("temperature"));

		obj->av = (t_atom*)sysmem_newptr(sizeof(t_atom) * 3);	// just allocating three for now -- limited list support
	}
	return obj;										// Return pointer to our instance
}

void dataspace_free(t_dataspace *obj)
{
	sysmem_freeptr(obj->av);
	if (obj->dataspace)
		delete obj->dataspace;
}

#pragma mark -
#pragma mark methods
/************************************************************************************/
// Methods bound to input/inlets

// Method for Assistance Messages
void dataspace_assist(t_dataspace *x, void *b, long msg, long arg, char *dst)
{
	if (msg==1) 							// Inlets
		strcpy(dst, "x");
	else if (msg==2) { 					// Outlets
		switch(arg) {
			case 0: strcpy(dst, "y=f(x)"); break;
			default: strcpy(dst, "dumpout"); break;
 		}
 	}
}

void dataspace_int(t_dataspace *obj, long x)
{
	dataspace_float(obj, (double)x);
}

void dataspace_float(t_dataspace *obj, double x)
{
	t_atom	a[1];

	atom_setfloat(a, x);
	obj->dataspace->convert(1, a, &obj->ac, &obj->av);
	outlet_anything(obj->outlet_native, _sym_float, obj->ac, obj->av);
	//outlet_float(obj->outlet_active, x);
}

void dataspace_list(t_dataspace *obj, t_symbol *msg, long argc, t_atom *argv)
{
	obj->dataspace->convert(argc, argv, &obj->ac, &obj->av);
	outlet_anything(obj->outlet_native, _sym_list, obj->ac, obj->av);
	//outlet_anything(obj->outlet_active, _sym_list, argc, argv);
}

void dataspace_getDataspaces(t_dataspace *obj)
{
	t_atom		a[2];
	t_symbol	**dataspaceNames = NULL;
	long		numDataspaces = 0;
	long		i;

	atom_setsym(a+0, gensym("clear"));
	object_obex_dumpout(obj, gensym("DataspacesMenu"), 1, a);

	jamoma_getDataspaceList(&numDataspaces, &dataspaceNames);

	for (i=0; i<numDataspaces; i++) {
		atom_setsym(a+0, gensym("append"));
		atom_setsym(a+1, dataspaceNames[i]);
		object_obex_dumpout(obj, gensym("DataspacesMenu"), 2, a);
	}

	if (numDataspaces)
		sysmem_freeptr(dataspaceNames);
}

void dataspace_getUnits(t_dataspace *obj)
{
	t_atom		a[2];
	t_symbol	**unitNames = NULL;
	long		numUnits = 0;
	long		i;

	atom_setsym(a+0, gensym("clear"));
	object_obex_dumpout(obj, gensym("UnitMenu"), 1, a);

	obj->dataspace->getAvailableUnits(&numUnits, &unitNames);

	for (i=0; i<numUnits; i++) {
		atom_setsym(a+0, gensym("append"));
		atom_setsym(a+1, unitNames[i]);
		object_obex_dumpout(obj, gensym("UnitMenu"), 2, a);
	}

	if (numUnits)
		sysmem_freeptr(unitNames);
}

#pragma mark -
#pragma mark attributes
// ATTRIBUTE:
t_max_err dataspace_setDataspace(t_dataspace *obj, void *attr, long argc, t_atom *argv)
{
	obj->attr_dataspace = atom_getsym(argv);
	jamoma_getDataspace(obj->attr_dataspace, &obj->dataspace);
	obj->attr_dataspace_active = obj->dataspace->neutralUnit;
	obj->attr_dataspace_native = obj->dataspace->neutralUnit;
	return MAX_ERR_NONE;
}

// ATTRIBUTE:
t_max_err dataspace_setDataspaceActive(t_dataspace *obj, void *attr, long argc, t_atom *argv)
{
	obj->attr_dataspace_active = atom_getsym(argv);
	obj->dataspace->setInputUnit(obj->attr_dataspace_active);
	return MAX_ERR_NONE;
}

// ATTRIBUTE:
t_max_err dataspace_setDataspaceNative(t_dataspace *obj, void *attr, long argc, t_atom *argv)
{
	obj->attr_dataspace_native = atom_getsym(argv);
	obj->dataspace->setOutputUnit(obj->attr_dataspace_native);
	return MAX_ERR_NONE;
}

<|endoftext|>


<commit_before>/*********************************************************************************
* Copyright (c) 2014 David D. Marshall <ddmarsha@calpoly.edu>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    David D. Marshall - initial code and implementation
********************************************************************************/

#ifndef eli_geom_curve_piecewise_cst_airfoil_creator_hpp
#define eli_geom_curve_piecewise_cst_airfoil_creator_hpp

#include <vector>

#include "eli/code_eli.hpp"

#include "eli/geom/curve/piecewise.hpp"
#include "eli/geom/curve/piecewise_creator_base.hpp"
#include "eli/geom/curve/bezier.hpp"
#include "eli/geom/curve/piecewise_polynomial_creator.hpp"
#include "eli/geom/curve/pseudo/cst_airfoil.hpp"

namespace eli
{
  namespace geom
  {
    namespace curve
    {
      template<typename data__, unsigned short dim__, typename tol__>
      class piecewise_cst_airfoil_creator : public piecewise_creator_base<data__, dim__, tol__>
      {
        public:
          typedef piecewise_creator_base<data__, dim__, tol__> base_class_type;
          typedef typename base_class_type::data_type data_type;
          typedef typename base_class_type::point_type point_type;
          typedef typename base_class_type::index_type index_type;
          typedef typename base_class_type::tolerance_type tolerance_type;
          typedef eli::geom::curve::pseudo::cst_airfoil<data_type> cst_airfoil_type;
          typedef typename cst_airfoil_type::point_type cst_airfoil_point_type;
          typedef typename cst_airfoil_type::control_point_type cst_airfoil_control_point_type;
          typedef unsigned short dimension_type;

          piecewise_cst_airfoil_creator() : piecewise_creator_base<data_type, dim__, tolerance_type>(2, 0), cst(1) {}
          piecewise_cst_airfoil_creator(const piecewise_cst_airfoil_creator<data_type, dim__, tolerance_type> &pca)
            : piecewise_creator_base<data_type, dim__, tolerance_type>(pca), cst(pca.cst) {}
          ~piecewise_cst_airfoil_creator() {}

          void set_airfoil(const cst_airfoil_type &ca)
          {
            cst = ca;
          }

          void get_airfoil(cst_airfoil_type &ca) const
          {
            ca = cst;
          }

          bool set_conditions(const cst_airfoil_type &ca)
          {
            set_airfoil(ca);

            return true;
          }

          /** This method creates an exact bezier representation of a CST airfoil upper and
           *  lower surface. It uses the method from "Creating Exact Bezier Representations of CST
           *  Shapes" by Marshall, AIAA paper 2013-3077.
           */
          virtual bool create(piecewise<bezier, data_type, dim__, tolerance_type> &pc) const
          {
            typedef piecewise<bezier, data_type, dim__, tolerance_type> piecewise_curve_type;
            typedef typename piecewise_curve_type::curve_type curve_type;

            typename curve_type::monomial_coefficient_type bezu_mono_coef, bezl_mono_coef;
            typename cst_airfoil_type::monomial_coefficient_type cstu_mono_coef, cstl_mono_coef;

            // extract the monomial coefficients from the CST airfoil
            cst.get_upper_monomial_coefficients(cstu_mono_coef);
            cst.get_lower_monomial_coefficients(cstl_mono_coef);

            // convert the original coefficients to new monomial coefficients
            index_type i, nu(cstu_mono_coef.rows()-1), nl(cstl_mono_coef.rows()-1);
            data_type dte_upper(cst.get_upper_trailing_edge_thickness()), dte_lower(cst.get_lower_trailing_edge_thickness());
            bezu_mono_coef.resize(2*nu+3+1, dim__);
            bezl_mono_coef.resize(2*nl+3+1, dim__);
            bezu_mono_coef.setZero();
            bezl_mono_coef.setZero();

            // upper
            i=0;
            bezu_mono_coef(2*i+1, 1)=cstu_mono_coef(i, 0);
            bezu_mono_coef(2*i+2, 0)=1;
            bezu_mono_coef(2*i+2, 1)=dte_upper;
            for (i=1; i<=nu; ++i)
            {
              bezu_mono_coef(2*i+1, 1)=cstu_mono_coef(i, 0)-cstu_mono_coef(i-1, 0);
            }
            i=nu+1;
            bezu_mono_coef(2*i+1, 1)=-cstu_mono_coef(i-1);

            // lower
            i=0;
            bezl_mono_coef(2*i+1, 1)=cstl_mono_coef(i, 0);
            bezl_mono_coef(2*i+2, 0)=1;
            bezl_mono_coef(2*i+2, 1)=-dte_lower;
            for (i=1; i<=nu; ++i)
            {
              bezl_mono_coef(2*i+1, 1)=cstl_mono_coef(i, 0)-cstl_mono_coef(i-1, 0);
            }
            i=nu+1;
            bezl_mono_coef(2*i+1, 1)=-cstl_mono_coef(i-1);

            // create the lower and upper curve
            piecewise_polynomial_creator<data_type, dim__, tolerance_type> poly_creator;
            pseudo::polynomial<data__, dim__> cu, cl;
            bool rtn_flag;

            for (dimension_type j=0; j<dim__; ++j)
            {
              cu.set_coefficients(bezu_mono_coef.col(j), j);
              cl.set_coefficients(bezl_mono_coef.col(j), j);
            }

            // lower
            rtn_flag=poly_creator.set_conditions(cl);
            if (!rtn_flag)
            {
              assert(false);
              return false;
            }
            poly_creator.set_t0(this->get_t0());
            poly_creator.set_segment_dt(this->get_segment_dt(0), 0);
            rtn_flag=poly_creator.create(pc);
            if (!rtn_flag)
            {
              assert(false);
              return false;
            }
            pc.reverse();

            // upper
            piecewise_curve_type pc_temp;
            rtn_flag=poly_creator.set_conditions(cu);
            if (!rtn_flag)
            {
              assert(false);
              return false;
            }
            poly_creator.set_t0(this->get_t0()+this->get_segment_dt(0));
            poly_creator.set_segment_dt(this->get_segment_dt(1), 0);
            rtn_flag=poly_creator.create(pc_temp);
            if (!rtn_flag)
            {
              assert(false);
              return false;
            }
            pc.push_back(pc_temp);

            return true;
          }

        private:
          cst_airfoil_type cst;
      };
    }
  }
}
#endif
<commit_msg>Fixed bug with creating CST airfoil with different degrees for upper and lower curves<commit_after>/*********************************************************************************
* Copyright (c) 2014 David D. Marshall <ddmarsha@calpoly.edu>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    David D. Marshall - initial code and implementation
********************************************************************************/

#ifndef eli_geom_curve_piecewise_cst_airfoil_creator_hpp
#define eli_geom_curve_piecewise_cst_airfoil_creator_hpp

#include <vector>

#include "eli/code_eli.hpp"

#include "eli/geom/curve/piecewise.hpp"
#include "eli/geom/curve/piecewise_creator_base.hpp"
#include "eli/geom/curve/bezier.hpp"
#include "eli/geom/curve/piecewise_polynomial_creator.hpp"
#include "eli/geom/curve/pseudo/cst_airfoil.hpp"

namespace eli
{
  namespace geom
  {
    namespace curve
    {
      template<typename data__, unsigned short dim__, typename tol__>
      class piecewise_cst_airfoil_creator : public piecewise_creator_base<data__, dim__, tol__>
      {
        public:
          typedef piecewise_creator_base<data__, dim__, tol__> base_class_type;
          typedef typename base_class_type::data_type data_type;
          typedef typename base_class_type::point_type point_type;
          typedef typename base_class_type::index_type index_type;
          typedef typename base_class_type::tolerance_type tolerance_type;
          typedef eli::geom::curve::pseudo::cst_airfoil<data_type> cst_airfoil_type;
          typedef typename cst_airfoil_type::point_type cst_airfoil_point_type;
          typedef typename cst_airfoil_type::control_point_type cst_airfoil_control_point_type;
          typedef unsigned short dimension_type;

          piecewise_cst_airfoil_creator() : piecewise_creator_base<data_type, dim__, tolerance_type>(2, 0), cst(1) {}
          piecewise_cst_airfoil_creator(const piecewise_cst_airfoil_creator<data_type, dim__, tolerance_type> &pca)
            : piecewise_creator_base<data_type, dim__, tolerance_type>(pca), cst(pca.cst) {}
          ~piecewise_cst_airfoil_creator() {}

          void set_airfoil(const cst_airfoil_type &ca)
          {
            cst = ca;
          }

          void get_airfoil(cst_airfoil_type &ca) const
          {
            ca = cst;
          }

          bool set_conditions(const cst_airfoil_type &ca)
          {
            set_airfoil(ca);

            return true;
          }

          /** This method creates an exact bezier representation of a CST airfoil upper and
           *  lower surface. It uses the method from "Creating Exact Bezier Representations of CST
           *  Shapes" by Marshall, AIAA paper 2013-3077.
           */
          virtual bool create(piecewise<bezier, data_type, dim__, tolerance_type> &pc) const
          {
            typedef piecewise<bezier, data_type, dim__, tolerance_type> piecewise_curve_type;
            typedef typename piecewise_curve_type::curve_type curve_type;

            typename curve_type::monomial_coefficient_type bezu_mono_coef, bezl_mono_coef;
            typename cst_airfoil_type::monomial_coefficient_type cstu_mono_coef, cstl_mono_coef;

            // extract the monomial coefficients from the CST airfoil
            cst.get_upper_monomial_coefficients(cstu_mono_coef);
            cst.get_lower_monomial_coefficients(cstl_mono_coef);

            // convert the original coefficients to new monomial coefficients
            index_type i, nu(cstu_mono_coef.rows()-1), nl(cstl_mono_coef.rows()-1);
            data_type dte_upper(cst.get_upper_trailing_edge_thickness()), dte_lower(cst.get_lower_trailing_edge_thickness());
            bezu_mono_coef.resize(2*nu+3+1, dim__);
            bezl_mono_coef.resize(2*nl+3+1, dim__);
            bezu_mono_coef.setZero();
            bezl_mono_coef.setZero();

            // upper
            i=0;
            bezu_mono_coef(2*i+1, 1)=cstu_mono_coef(i, 0);
            bezu_mono_coef(2*i+2, 0)=1;
            bezu_mono_coef(2*i+2, 1)=dte_upper;
            for (i=1; i<=nu; ++i)
            {
              bezu_mono_coef(2*i+1, 1)=cstu_mono_coef(i, 0)-cstu_mono_coef(i-1, 0);
            }
            i=nu+1;
            bezu_mono_coef(2*i+1, 1)=-cstu_mono_coef(i-1);

            // lower
            i=0;
            bezl_mono_coef(2*i+1, 1)=cstl_mono_coef(i, 0);
            bezl_mono_coef(2*i+2, 0)=1;
            bezl_mono_coef(2*i+2, 1)=-dte_lower;
            for (i=1; i<=nl; ++i)
            {
              bezl_mono_coef(2*i+1, 1)=cstl_mono_coef(i, 0)-cstl_mono_coef(i-1, 0);
            }
            i=nl+1;
            bezl_mono_coef(2*i+1, 1)=-cstl_mono_coef(i-1);

            // create the lower and upper curve
            piecewise_polynomial_creator<data_type, dim__, tolerance_type> poly_creator;
            pseudo::polynomial<data__, dim__> cu, cl;
            bool rtn_flag;

            for (dimension_type j=0; j<dim__; ++j)
            {
              cu.set_coefficients(bezu_mono_coef.col(j), j);
              cl.set_coefficients(bezl_mono_coef.col(j), j);
            }

            // lower
            rtn_flag=poly_creator.set_conditions(cl);
            if (!rtn_flag)
            {
              assert(false);
              return false;
            }
            poly_creator.set_t0(this->get_t0());
            poly_creator.set_segment_dt(this->get_segment_dt(0), 0);
            rtn_flag=poly_creator.create(pc);
            if (!rtn_flag)
            {
              assert(false);
              return false;
            }
            pc.reverse();

            // upper
            piecewise_curve_type pc_temp;
            rtn_flag=poly_creator.set_conditions(cu);
            if (!rtn_flag)
            {
              assert(false);
              return false;
            }
            poly_creator.set_t0(this->get_t0()+this->get_segment_dt(0));
            poly_creator.set_segment_dt(this->get_segment_dt(1), 0);
            rtn_flag=poly_creator.create(pc_temp);
            if (!rtn_flag)
            {
              assert(false);
              return false;
            }
            pc.push_back(pc_temp);

            return true;
          }

        private:
          cst_airfoil_type cst;
      };
    }
  }
}
#endif
<|endoftext|>


<commit_before><commit_msg>Fixed a segfault bug that is revealed only when resizing an empty ListBox to a very small size<commit_after><|endoftext|>


<commit_before>#include "stactive_record.h"
using namespace stactiverecord;
using namespace std;
Sar_Dbi * Sar_Dbi::dbi;

/**
   This is an example of a one to one object relationship.  A lock has a single key and a key fits
   a single lock.  The class definitions are more complicated than they need to be - this is
   just a typical situation.
**/

// forward declaration of Key.
class Key;

class Lock : public Record<Lock> {
public:
  static string classname;
  string name;
  Key * key;
  Lock() : Record<Lock>() { init();  };
  Lock(int id) : Record<Lock>(id) { init(); };
  void init() {
    get("name", name, "Unknown");
    if(isset<Key>())
      getOne<Key>(*key);
  };
  void save() {
    set("name", name);
    // if key variable has been set
    if(key->has_been_saved())
      setOne<Key>(*key);
    Record<Lock>::save();
  };
  void update() {
    Record<Lock>::update();
    init();
  };
};
string Lock::classname = "lock";

class Key : public Record<Key> {
public:
  static string classname;
  string name;
  Lock lock;
  Key() : Record<Key>() { init(); };
  Key(int id) : Record<Key>(id) { init(); };
  void init() {
    get("name", name, "Unknown");
    if(isset<Lock>())
      getOne<Lock>(lock);
  };
  void save() {
    set("name", name);
    // if teacher variable has been set
    if(lock.has_been_saved())
      setOne<Lock>(lock);
    Record<Key>::save();
  };
  void update() {
    Record<Key>::update();
    init();
  };
};
string Key::classname = "key";

int main(int argc, char* argv[]) {
  if(argc != 2) {
    std::cout << "Usage: ./one_to_many <scheme://[user[:password]@host[:port]/]database>\n";
    return 1;
  }
  Sar_Dbi::dbi = Sar_Dbi::makeStorage(std::string(argv[1]));

  Key key;
  key.name = "The Key";
  key.save();

  Lock lock;
  lock.name = "The Lock";
  lock.key = key;
  lock.save;

  key.update();
  cout << "The lock for " << key.name << " is " << key.lock.name << "\n";

  delete Sar_Dbi::dbi;
  return 0;
};
<commit_msg>finished one_to_one<commit_after>#include "stactive_record.h"
using namespace stactiverecord;
using namespace std;
Sar_Dbi * Sar_Dbi::dbi;

/**
   This is an example of a one to one object relationship.  A lock has a single key and a key fits
   a single lock.
**/

class Lock : public Record<Lock> {
public:
  Lock() : Record<Lock>() {};
  Lock(int id) : Record<Lock>(id) {};
  static string classname;
};
string Lock::classname = "lock";

class Key : public Record<Key> {
public:
  Key() : Record<Key>() {};
  Key(int id) : Record<Key>(id) {};
  static string classname;
};
string Key::classname = "key";

int main(int argc, char* argv[]) {
  if(argc != 2) {
    std::cout << "Usage: ./one_to_many <scheme://[user[:password]@host[:port]/]database>\n";
    return 1;
  }
  Sar_Dbi::dbi = Sar_Dbi::makeStorage(std::string(argv[1]));

  Key key;
  key.set("name", "The Key");
  key.save();

  Lock lock;
  lock.set("name", "The Lock");
  lock.setOne<Key>(key);
  lock.save();

  Key dbkey(key.id);
  string key_name, lock_name;
  dbkey.get("name", key_name);
  Lock dblock;
  dbkey.getOne<Lock>(dblock);
  dblock.get("name", lock_name);

  cout << "The lock for " << key_name << " is " << lock_name << "\n";

  delete Sar_Dbi::dbi;
  return 0;
};
<|endoftext|>


<commit_before><commit_msg>fixed layout for openwindow when you open from new<commit_after><|endoftext|>


<commit_before><commit_msg>Patch from Todd Whiteman to show brace highlight background over caret line background.<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "webkit/glue/glue_serialize.h"

#include <string>

#include "base/pickle.h"
#include "base/utf_string_conversions.h"
#include "googleurl/src/gurl.h"
#include "third_party/WebKit/WebKit/chromium/public/WebData.h"
#include "third_party/WebKit/WebKit/chromium/public/WebHistoryItem.h"
#include "third_party/WebKit/WebKit/chromium/public/WebHTTPBody.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPoint.h"
#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
#include "third_party/WebKit/WebKit/chromium/public/WebVector.h"
#include "webkit/glue/webkit_glue.h"

using WebKit::WebData;
using WebKit::WebHistoryItem;
using WebKit::WebHTTPBody;
using WebKit::WebPoint;
using WebKit::WebString;
using WebKit::WebUChar;
using WebKit::WebVector;

namespace webkit_glue {

struct SerializeObject {
  SerializeObject() : iter(NULL) {}
  SerializeObject(const char* data, int len) : pickle(data, len), iter(NULL) {}

  std::string GetAsString() {
    return std::string(static_cast<const char*>(pickle.data()), pickle.size());
  }

  Pickle pickle;
  mutable void* iter;
  mutable int version;
};

// TODO(mpcomplete): obsolete versions 1 and 2 after 1/1/2008.
// Version ID used in reading/writing history items.
// 1: Initial revision.
// 2: Added case for NULL string versus "". Version 2 code can read Version 1
//    data, but not vice versa.
// 3: Version 2 was broken, it stored number of WebUChars, not number of bytes.
//    This version checks and reads v1 and v2 correctly.
// 4: Adds support for storing FormData::identifier().
// 5: Adds support for empty FormData
// 6: Adds support for documentSequenceNumbers
// Should be const, but unit tests may modify it.
int kVersion = 6;

// A bunch of convenience functions to read/write to SerializeObjects.
// The serializers assume the input data is in the correct format and so does
// no error checking.
inline void WriteData(const void* data, int length, SerializeObject* obj) {
  obj->pickle.WriteData(static_cast<const char*>(data), length);
}

inline void ReadData(const SerializeObject* obj, const void** data,
                     int* length) {
  const char* tmp = NULL;
  obj->pickle.ReadData(&obj->iter, &tmp, length);
  *data = tmp;
}

inline bool ReadBytes(const SerializeObject* obj, const void** data,
                     int length) {
  const char *tmp;
  if (!obj->pickle.ReadBytes(&obj->iter, &tmp, length))
    return false;
  *data = tmp;
  return true;
}

inline void WriteInteger(int data, SerializeObject* obj) {
  obj->pickle.WriteInt(data);
}

inline int ReadInteger(const SerializeObject* obj) {
  int tmp = 0;
  obj->pickle.ReadInt(&obj->iter, &tmp);
  return tmp;
}

inline void WriteInteger64(int64 data, SerializeObject* obj) {
  obj->pickle.WriteInt64(data);
}

inline int64 ReadInteger64(const SerializeObject* obj) {
  int64 tmp = 0;
  obj->pickle.ReadInt64(&obj->iter, &tmp);
  return tmp;
}

inline void WriteReal(double data, SerializeObject* obj) {
  WriteData(&data, sizeof(double), obj);
}

inline double ReadReal(const SerializeObject* obj) {
  const void* tmp;
  int length = 0;
  ReadData(obj, &tmp, &length);
  if (length > 0 && length >= static_cast<int>(sizeof(0.0)))
    return *static_cast<const double*>(tmp);
  else
    return 0.0;
}

inline void WriteBoolean(bool data, SerializeObject* obj) {
  obj->pickle.WriteInt(data ? 1 : 0);
}

inline bool ReadBoolean(const SerializeObject* obj) {
  bool tmp = false;
  obj->pickle.ReadBool(&obj->iter, &tmp);
  return tmp;
}

// Read/WriteString pickle the WebString as <int length><WebUChar* data>.
// If length == -1, then the WebString itself is NULL (WebString()).
// Otherwise the length is the number of WebUChars (not bytes) in the WebString.
inline void WriteString(const WebString& str, SerializeObject* obj) {
  switch (kVersion) {
    case 1:
      // Version 1 writes <length in bytes><string data>.
      // It saves WebString() and "" as "".
      obj->pickle.WriteInt(str.length() * sizeof(WebUChar));
      obj->pickle.WriteBytes(str.data(), str.length() * sizeof(WebUChar));
      break;
    case 2:
      // Version 2 writes <length in WebUChar><string data>.
      // It uses -1 in the length field to mean WebString().
      if (str.isNull()) {
        obj->pickle.WriteInt(-1);
      } else {
        obj->pickle.WriteInt(str.length());
        obj->pickle.WriteBytes(str.data(),
                               str.length() * sizeof(WebUChar));
      }
      break;
    default:
      // Version 3+ writes <length in bytes><string data>.
      // It uses -1 in the length field to mean WebString().
      if (str.isNull()) {
        obj->pickle.WriteInt(-1);
      } else {
        obj->pickle.WriteInt(str.length() * sizeof(WebUChar));
        obj->pickle.WriteBytes(str.data(),
                               str.length() * sizeof(WebUChar));
      }
      break;
  }
}

// This reads a serialized WebString from obj. If a string can't be read,
// WebString() is returned.
inline WebString ReadString(const SerializeObject* obj) {
  int length;

  // Versions 1, 2, and 3 all start with an integer.
  if (!obj->pickle.ReadInt(&obj->iter, &length))
    return WebString();

  // Starting with version 2, -1 means WebString().
  if (length == -1)
    return WebString();

  // In version 2, the length field was the length in WebUChars.
  // In version 1 and 3 it is the length in bytes.
  int bytes = ((obj->version == 2) ? length * sizeof(WebUChar) : length);

  const void* data;
  if (!ReadBytes(obj, &data, bytes))
    return WebString();
  return WebString(static_cast<const WebUChar*>(data), bytes / sizeof(WebUChar));
}

// Writes a Vector of Strings into a SerializeObject for serialization.
static void WriteStringVector(
    const WebVector<WebString>& data, SerializeObject* obj) {
  WriteInteger(static_cast<int>(data.size()), obj);
  for (size_t i = 0, c = data.size(); i < c; ++i) {
    unsigned ui = static_cast<unsigned>(i);  // sigh
    WriteString(data[ui], obj);
  }
}

static WebVector<WebString> ReadStringVector(const SerializeObject* obj) {
  int num_elements = ReadInteger(obj);
  WebVector<WebString> result(static_cast<size_t>(num_elements));
  for (int i = 0; i < num_elements; ++i)
    result[i] = ReadString(obj);
  return result;
}

// Writes a FormData object into a SerializeObject for serialization.
static void WriteFormData(const WebHTTPBody& http_body, SerializeObject* obj) {
  WriteBoolean(!http_body.isNull(), obj);

  if (http_body.isNull())
    return;

  WriteInteger(static_cast<int>(http_body.elementCount()), obj);
  WebHTTPBody::Element element;
  for (size_t i = 0; http_body.elementAt(i, element); ++i) {
    WriteInteger(element.type, obj);
    if (element.type == WebHTTPBody::Element::TypeData) {
      WriteData(element.data.data(), static_cast<int>(element.data.size()),
                obj);
    } else {
      WriteString(element.filePath, obj);
    }
  }
  WriteInteger64(http_body.identifier(), obj);
}

static WebHTTPBody ReadFormData(const SerializeObject* obj) {
  // In newer versions, an initial boolean indicates if we have form data.
  if (obj->version >= 5 && !ReadBoolean(obj))
    return WebHTTPBody();

  // In older versions, 0 elements implied no form data.
  int num_elements = ReadInteger(obj);
  if (num_elements == 0 && obj->version < 5)
    return WebHTTPBody();

  WebHTTPBody http_body;
  http_body.initialize();

  for (int i = 0; i < num_elements; ++i) {
    int type = ReadInteger(obj);
    if (type == WebHTTPBody::Element::TypeData) {
      const void* data;
      int length = -1;
      ReadData(obj, &data, &length);
      if (length >= 0)
        http_body.appendData(WebData(static_cast<const char*>(data), length));
    } else {
      http_body.appendFile(ReadString(obj));
    }
  }
  if (obj->version >= 4)
    http_body.setIdentifier(ReadInteger64(obj));

  return http_body;
}

// Writes the HistoryItem data into the SerializeObject object for
// serialization.
static void WriteHistoryItem(
    const WebHistoryItem& item, SerializeObject* obj) {
  // WARNING: This data may be persisted for later use. As such, care must be
  // taken when changing the serialized format. If a new field needs to be
  // written, only adding at the end will make it easier to deal with loading
  // older versions. Similarly, this should NOT save fields with sensitive
  // data, such as password fields.
  WriteInteger(kVersion, obj);
  WriteString(item.urlString(), obj);
  WriteString(item.originalURLString(), obj);
  WriteString(item.target(), obj);
  WriteString(item.parent(), obj);
  WriteString(item.title(), obj);
  WriteString(item.alternateTitle(), obj);
  WriteReal(item.lastVisitedTime(), obj);
  WriteInteger(item.scrollOffset().x, obj);
  WriteInteger(item.scrollOffset().y, obj);
  WriteBoolean(item.isTargetItem(), obj);
  WriteInteger(item.visitCount(), obj);
  WriteString(item.referrer(), obj);

  WriteStringVector(item.documentState(), obj);

  WriteInteger64(item.documentSequenceNumber(), obj);

  // Yes, the referrer is written twice.  This is for backwards
  // compatibility with the format.
  WriteFormData(item.httpBody(), obj);
  WriteString(item.httpContentType(), obj);
  WriteString(item.referrer(), obj);

  // Subitems
  const WebVector<WebHistoryItem>& children = item.children();
  WriteInteger(static_cast<int>(children.size()), obj);
  for (size_t i = 0, c = children.size(); i < c; ++i)
    WriteHistoryItem(children[i], obj);
}

// Creates a new HistoryItem tree based on the serialized string.
// Assumes the data is in the format returned by WriteHistoryItem.
static WebHistoryItem ReadHistoryItem(
    const SerializeObject* obj, bool include_form_data) {
  // See note in WriteHistoryItem. on this.
  obj->version = ReadInteger(obj);

  if (obj->version > kVersion || obj->version < 1)
    return WebHistoryItem();

  WebHistoryItem item;
  item.initialize();

  item.setURLString(ReadString(obj));
  item.setOriginalURLString(ReadString(obj));
  item.setTarget(ReadString(obj));
  item.setParent(ReadString(obj));
  item.setTitle(ReadString(obj));
  item.setAlternateTitle(ReadString(obj));
  item.setLastVisitedTime(ReadReal(obj));
  int x = ReadInteger(obj);
  int y = ReadInteger(obj);
  item.setScrollOffset(WebPoint(x, y));
  item.setIsTargetItem(ReadBoolean(obj));
  item.setVisitCount(ReadInteger(obj));
  item.setReferrer(ReadString(obj));

  item.setDocumentState(ReadStringVector(obj));

  if (obj->version >= 6)
    item.setDocumentSequenceNumber(ReadInteger64(obj));

  // The extra referrer string is read for backwards compat.
  const WebHTTPBody& http_body = ReadFormData(obj);
  const WebString& http_content_type = ReadString(obj);
  ALLOW_UNUSED const WebString& unused_referrer = ReadString(obj);
  if (include_form_data) {
    item.setHTTPBody(http_body);
    item.setHTTPContentType(http_content_type);
  }

  // Subitems
  int num_children = ReadInteger(obj);
  for (int i = 0; i < num_children; ++i)
    item.appendToChildren(ReadHistoryItem(obj, include_form_data));

  return item;
}

// Serialize a HistoryItem to a string, using our JSON Value serializer.
std::string HistoryItemToString(const WebHistoryItem& item) {
  if (item.isNull())
    return std::string();

  SerializeObject obj;
  WriteHistoryItem(item, &obj);
  return obj.GetAsString();
}

// Reconstruct a HistoryItem from a string, using our JSON Value deserializer.
// This assumes that the given serialized string has all the required key,value
// pairs, and does minimal error checking. If |include_form_data| is true,
// the form data from a post is restored, otherwise the form data is empty.
static WebHistoryItem HistoryItemFromString(
    const std::string& serialized_item,
    bool include_form_data) {
  if (serialized_item.empty())
    return WebHistoryItem();

  SerializeObject obj(serialized_item.data(),
                      static_cast<int>(serialized_item.length()));
  return ReadHistoryItem(&obj, include_form_data);
}

WebHistoryItem HistoryItemFromString(
    const std::string& serialized_item) {
  return HistoryItemFromString(serialized_item, true);
}

// For testing purposes only.
void HistoryItemToVersionedString(const WebHistoryItem& item, int version,
                                  std::string* serialized_item) {
  if (item.isNull()) {
    serialized_item->clear();
    return;
  }

  // Temporarily change the version.
  int real_version = kVersion;
  kVersion = version;

  SerializeObject obj;
  WriteHistoryItem(item, &obj);
  *serialized_item = obj.GetAsString();

  kVersion = real_version;
}

std::string CreateHistoryStateForURL(const GURL& url) {
  WebHistoryItem item;
  item.initialize();
  item.setURLString(UTF8ToUTF16(url.spec()));

  return HistoryItemToString(item);
}

std::string RemoveFormDataFromHistoryState(const std::string& content_state) {
  const WebHistoryItem& item = HistoryItemFromString(content_state, false);
  if (item.isNull()) {
    // Couldn't parse the string, return an empty string.
    return std::string();
  }

  return HistoryItemToString(item);
}

}  // namespace webkit_glue
<commit_msg>Resolve issues with GlueSerializeTest.BackwardsCompatibleTest by appending the new documentSequenceNumber entry to the end of the pickle.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "webkit/glue/glue_serialize.h"

#include <string>

#include "base/pickle.h"
#include "base/utf_string_conversions.h"
#include "googleurl/src/gurl.h"
#include "third_party/WebKit/WebKit/chromium/public/WebData.h"
#include "third_party/WebKit/WebKit/chromium/public/WebHistoryItem.h"
#include "third_party/WebKit/WebKit/chromium/public/WebHTTPBody.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPoint.h"
#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
#include "third_party/WebKit/WebKit/chromium/public/WebVector.h"
#include "webkit/glue/webkit_glue.h"

using WebKit::WebData;
using WebKit::WebHistoryItem;
using WebKit::WebHTTPBody;
using WebKit::WebPoint;
using WebKit::WebString;
using WebKit::WebUChar;
using WebKit::WebVector;

namespace webkit_glue {

struct SerializeObject {
  SerializeObject() : iter(NULL) {}
  SerializeObject(const char* data, int len) : pickle(data, len), iter(NULL) {}

  std::string GetAsString() {
    return std::string(static_cast<const char*>(pickle.data()), pickle.size());
  }

  Pickle pickle;
  mutable void* iter;
  mutable int version;
};

// TODO(mpcomplete): obsolete versions 1 and 2 after 1/1/2008.
// Version ID used in reading/writing history items.
// 1: Initial revision.
// 2: Added case for NULL string versus "". Version 2 code can read Version 1
//    data, but not vice versa.
// 3: Version 2 was broken, it stored number of WebUChars, not number of bytes.
//    This version checks and reads v1 and v2 correctly.
// 4: Adds support for storing FormData::identifier().
// 5: Adds support for empty FormData
// 6: Adds support for documentSequenceNumbers
// Should be const, but unit tests may modify it.
int kVersion = 6;

// A bunch of convenience functions to read/write to SerializeObjects.
// The serializers assume the input data is in the correct format and so does
// no error checking.
inline void WriteData(const void* data, int length, SerializeObject* obj) {
  obj->pickle.WriteData(static_cast<const char*>(data), length);
}

inline void ReadData(const SerializeObject* obj, const void** data,
                     int* length) {
  const char* tmp = NULL;
  obj->pickle.ReadData(&obj->iter, &tmp, length);
  *data = tmp;
}

inline bool ReadBytes(const SerializeObject* obj, const void** data,
                     int length) {
  const char *tmp;
  if (!obj->pickle.ReadBytes(&obj->iter, &tmp, length))
    return false;
  *data = tmp;
  return true;
}

inline void WriteInteger(int data, SerializeObject* obj) {
  obj->pickle.WriteInt(data);
}

inline int ReadInteger(const SerializeObject* obj) {
  int tmp = 0;
  obj->pickle.ReadInt(&obj->iter, &tmp);
  return tmp;
}

inline void WriteInteger64(int64 data, SerializeObject* obj) {
  obj->pickle.WriteInt64(data);
}

inline int64 ReadInteger64(const SerializeObject* obj) {
  int64 tmp = 0;
  obj->pickle.ReadInt64(&obj->iter, &tmp);
  return tmp;
}

inline void WriteReal(double data, SerializeObject* obj) {
  WriteData(&data, sizeof(double), obj);
}

inline double ReadReal(const SerializeObject* obj) {
  const void* tmp;
  int length = 0;
  ReadData(obj, &tmp, &length);
  if (length > 0 && length >= static_cast<int>(sizeof(0.0)))
    return *static_cast<const double*>(tmp);
  else
    return 0.0;
}

inline void WriteBoolean(bool data, SerializeObject* obj) {
  obj->pickle.WriteInt(data ? 1 : 0);
}

inline bool ReadBoolean(const SerializeObject* obj) {
  bool tmp = false;
  obj->pickle.ReadBool(&obj->iter, &tmp);
  return tmp;
}

// Read/WriteString pickle the WebString as <int length><WebUChar* data>.
// If length == -1, then the WebString itself is NULL (WebString()).
// Otherwise the length is the number of WebUChars (not bytes) in the WebString.
inline void WriteString(const WebString& str, SerializeObject* obj) {
  switch (kVersion) {
    case 1:
      // Version 1 writes <length in bytes><string data>.
      // It saves WebString() and "" as "".
      obj->pickle.WriteInt(str.length() * sizeof(WebUChar));
      obj->pickle.WriteBytes(str.data(), str.length() * sizeof(WebUChar));
      break;
    case 2:
      // Version 2 writes <length in WebUChar><string data>.
      // It uses -1 in the length field to mean WebString().
      if (str.isNull()) {
        obj->pickle.WriteInt(-1);
      } else {
        obj->pickle.WriteInt(str.length());
        obj->pickle.WriteBytes(str.data(),
                               str.length() * sizeof(WebUChar));
      }
      break;
    default:
      // Version 3+ writes <length in bytes><string data>.
      // It uses -1 in the length field to mean WebString().
      if (str.isNull()) {
        obj->pickle.WriteInt(-1);
      } else {
        obj->pickle.WriteInt(str.length() * sizeof(WebUChar));
        obj->pickle.WriteBytes(str.data(),
                               str.length() * sizeof(WebUChar));
      }
      break;
  }
}

// This reads a serialized WebString from obj. If a string can't be read,
// WebString() is returned.
inline WebString ReadString(const SerializeObject* obj) {
  int length;

  // Versions 1, 2, and 3 all start with an integer.
  if (!obj->pickle.ReadInt(&obj->iter, &length))
    return WebString();

  // Starting with version 2, -1 means WebString().
  if (length == -1)
    return WebString();

  // In version 2, the length field was the length in WebUChars.
  // In version 1 and 3 it is the length in bytes.
  int bytes = ((obj->version == 2) ? length * sizeof(WebUChar) : length);

  const void* data;
  if (!ReadBytes(obj, &data, bytes))
    return WebString();
  return WebString(static_cast<const WebUChar*>(data), bytes / sizeof(WebUChar));
}

// Writes a Vector of Strings into a SerializeObject for serialization.
static void WriteStringVector(
    const WebVector<WebString>& data, SerializeObject* obj) {
  WriteInteger(static_cast<int>(data.size()), obj);
  for (size_t i = 0, c = data.size(); i < c; ++i) {
    unsigned ui = static_cast<unsigned>(i);  // sigh
    WriteString(data[ui], obj);
  }
}

static WebVector<WebString> ReadStringVector(const SerializeObject* obj) {
  int num_elements = ReadInteger(obj);
  WebVector<WebString> result(static_cast<size_t>(num_elements));
  for (int i = 0; i < num_elements; ++i)
    result[i] = ReadString(obj);
  return result;
}

// Writes a FormData object into a SerializeObject for serialization.
static void WriteFormData(const WebHTTPBody& http_body, SerializeObject* obj) {
  WriteBoolean(!http_body.isNull(), obj);

  if (http_body.isNull())
    return;

  WriteInteger(static_cast<int>(http_body.elementCount()), obj);
  WebHTTPBody::Element element;
  for (size_t i = 0; http_body.elementAt(i, element); ++i) {
    WriteInteger(element.type, obj);
    if (element.type == WebHTTPBody::Element::TypeData) {
      WriteData(element.data.data(), static_cast<int>(element.data.size()),
                obj);
    } else {
      WriteString(element.filePath, obj);
    }
  }
  WriteInteger64(http_body.identifier(), obj);
}

static WebHTTPBody ReadFormData(const SerializeObject* obj) {
  // In newer versions, an initial boolean indicates if we have form data.
  if (obj->version >= 5 && !ReadBoolean(obj))
    return WebHTTPBody();

  // In older versions, 0 elements implied no form data.
  int num_elements = ReadInteger(obj);
  if (num_elements == 0 && obj->version < 5)
    return WebHTTPBody();

  WebHTTPBody http_body;
  http_body.initialize();

  for (int i = 0; i < num_elements; ++i) {
    int type = ReadInteger(obj);
    if (type == WebHTTPBody::Element::TypeData) {
      const void* data;
      int length = -1;
      ReadData(obj, &data, &length);
      if (length >= 0)
        http_body.appendData(WebData(static_cast<const char*>(data), length));
    } else {
      http_body.appendFile(ReadString(obj));
    }
  }
  if (obj->version >= 4)
    http_body.setIdentifier(ReadInteger64(obj));

  return http_body;
}

// Writes the HistoryItem data into the SerializeObject object for
// serialization.
static void WriteHistoryItem(
    const WebHistoryItem& item, SerializeObject* obj) {
  // WARNING: This data may be persisted for later use. As such, care must be
  // taken when changing the serialized format. If a new field needs to be
  // written, only adding at the end will make it easier to deal with loading
  // older versions. Similarly, this should NOT save fields with sensitive
  // data, such as password fields.
  WriteInteger(kVersion, obj);
  WriteString(item.urlString(), obj);
  WriteString(item.originalURLString(), obj);
  WriteString(item.target(), obj);
  WriteString(item.parent(), obj);
  WriteString(item.title(), obj);
  WriteString(item.alternateTitle(), obj);
  WriteReal(item.lastVisitedTime(), obj);
  WriteInteger(item.scrollOffset().x, obj);
  WriteInteger(item.scrollOffset().y, obj);
  WriteBoolean(item.isTargetItem(), obj);
  WriteInteger(item.visitCount(), obj);
  WriteString(item.referrer(), obj);

  WriteStringVector(item.documentState(), obj);

  // Yes, the referrer is written twice.  This is for backwards
  // compatibility with the format.
  WriteFormData(item.httpBody(), obj);
  WriteString(item.httpContentType(), obj);
  WriteString(item.referrer(), obj);

  // Subitems
  const WebVector<WebHistoryItem>& children = item.children();
  WriteInteger(static_cast<int>(children.size()), obj);
  for (size_t i = 0, c = children.size(); i < c; ++i)
    WriteHistoryItem(children[i], obj);

  WriteInteger64(item.documentSequenceNumber(), obj);
}

// Creates a new HistoryItem tree based on the serialized string.
// Assumes the data is in the format returned by WriteHistoryItem.
static WebHistoryItem ReadHistoryItem(
    const SerializeObject* obj, bool include_form_data) {
  // See note in WriteHistoryItem. on this.
  obj->version = ReadInteger(obj);

  if (obj->version > kVersion || obj->version < 1)
    return WebHistoryItem();

  WebHistoryItem item;
  item.initialize();

  item.setURLString(ReadString(obj));
  item.setOriginalURLString(ReadString(obj));
  item.setTarget(ReadString(obj));
  item.setParent(ReadString(obj));
  item.setTitle(ReadString(obj));
  item.setAlternateTitle(ReadString(obj));
  item.setLastVisitedTime(ReadReal(obj));
  int x = ReadInteger(obj);
  int y = ReadInteger(obj);
  item.setScrollOffset(WebPoint(x, y));
  item.setIsTargetItem(ReadBoolean(obj));
  item.setVisitCount(ReadInteger(obj));
  item.setReferrer(ReadString(obj));

  item.setDocumentState(ReadStringVector(obj));

  // The extra referrer string is read for backwards compat.
  const WebHTTPBody& http_body = ReadFormData(obj);
  const WebString& http_content_type = ReadString(obj);
  ALLOW_UNUSED const WebString& unused_referrer = ReadString(obj);
  if (include_form_data) {
    item.setHTTPBody(http_body);
    item.setHTTPContentType(http_content_type);
  }

  // Subitems
  int num_children = ReadInteger(obj);
  for (int i = 0; i < num_children; ++i)
    item.appendToChildren(ReadHistoryItem(obj, include_form_data));

  if (obj->version >= 6)
    item.setDocumentSequenceNumber(ReadInteger64(obj));

  return item;
}

// Serialize a HistoryItem to a string, using our JSON Value serializer.
std::string HistoryItemToString(const WebHistoryItem& item) {
  if (item.isNull())
    return std::string();

  SerializeObject obj;
  WriteHistoryItem(item, &obj);
  return obj.GetAsString();
}

// Reconstruct a HistoryItem from a string, using our JSON Value deserializer.
// This assumes that the given serialized string has all the required key,value
// pairs, and does minimal error checking. If |include_form_data| is true,
// the form data from a post is restored, otherwise the form data is empty.
static WebHistoryItem HistoryItemFromString(
    const std::string& serialized_item,
    bool include_form_data) {
  if (serialized_item.empty())
    return WebHistoryItem();

  SerializeObject obj(serialized_item.data(),
                      static_cast<int>(serialized_item.length()));
  return ReadHistoryItem(&obj, include_form_data);
}

WebHistoryItem HistoryItemFromString(
    const std::string& serialized_item) {
  return HistoryItemFromString(serialized_item, true);
}

// For testing purposes only.
void HistoryItemToVersionedString(const WebHistoryItem& item, int version,
                                  std::string* serialized_item) {
  if (item.isNull()) {
    serialized_item->clear();
    return;
  }

  // Temporarily change the version.
  int real_version = kVersion;
  kVersion = version;

  SerializeObject obj;
  WriteHistoryItem(item, &obj);
  *serialized_item = obj.GetAsString();

  kVersion = real_version;
}

std::string CreateHistoryStateForURL(const GURL& url) {
  WebHistoryItem item;
  item.initialize();
  item.setURLString(UTF8ToUTF16(url.spec()));

  return HistoryItemToString(item);
}

std::string RemoveFormDataFromHistoryState(const std::string& content_state) {
  const WebHistoryItem& item = HistoryItemFromString(content_state, false);
  if (item.isNull()) {
    // Couldn't parse the string, return an empty string.
    return std::string();
  }

  return HistoryItemToString(item);
}

}  // namespace webkit_glue
<|endoftext|>