<commit_before>
/**
 * @file Playlist.cpp
 * @brief Playlist implementation
 *
 * @todo Load in background, notifying of changes.
 * @todo Use a database backend to avoid hitting fmod heavily.
 */

#include "Playlist.moc"

#include "SortedSet.h"
#include "defs.h"
#include "Scene.h"
#include "PlaylistModel.h"

#include <QDebug>
#include <QDragEnterEvent>
#include <QUrl>
#include <QDirIterator>
#include <QDesktopServices>
#include <QDateTime>
#include <QSortFilterProxyModel>

#include <QSqlDatabase>
#include <QSqlRecord>
#include <QSqlQuery>
#include <QSqlError>

#include <QtConcurrentRun>

#include <boost/bind.hpp>

#include <QtFMOD/System.h>
#include <QtFMOD/Sound.h>
#include <QtFMOD/Tag.h>

struct Playlist::Private
{
    SortedSet<QUrl> urls;

    QSqlDatabase db;
    PlaylistModel* model;
    QSortFilterProxyModel* proxyModel;
    QStringList nameFilters;

    QStringList albumTags;
    QStringList titleTags;
    QStringList artistTags;

    Private (Playlist* q) :
        db(QSqlDatabase::addDatabase("QPSQL")),
        model(new PlaylistModel(urls, db, q)),
        proxyModel(new QSortFilterProxyModel(q))
    {
        nameFilters
            //<< "*.aif"
            //<< "*.aiff"
            << "*.mp3"
            //<< "*.wav"
            ;

        albumTags  << "ALBUM" << "TAL" << "icy-name";
        titleTags  << "TITLE" << "TT2" << "icy-url";
        artistTags << "ARTIST" << "TP1";

        proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
        proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
        proxyModel->setFilterRole(FilterRole);
        proxyModel->setSourceModel(model);
    }
};

Playlist::Playlist (QWidget* parent) :
    QWidget(parent),
    d(new Private(this))
{
    setupUi(this);

    initDb();

    tableView->setModel(d->proxyModel);

    connect(filterLineEdit, SIGNAL(textChanged(const QString&)),
            d->proxyModel, SLOT(setFilterWildcard(const QString&)));
}

Playlist::~Playlist ()
{
}

void Playlist::update ()
{
    QSqlQuery q;
    q.prepare("select url from streams order by url");
    if (q.exec()) {
        while (q.next()) {
            QUrl url (q.value(0).toString());
            d->urls << url;
            d->model->insertRow(d->urls.indexOf(url));
        }
    }

    QtConcurrent::run(boost::bind(&Playlist::scanDir, this,
                                  QDesktopServices::storageLocation(
                                      QDesktopServices::MusicLocation)));
}

void Playlist::initDb ()
{
    QDir dataDir (
        QDesktopServices::storageLocation(QDesktopServices::DataLocation));
    QDir::home().mkpath(dataDir.path());

#if 0
    d->db.setDatabaseName(dataDir.filePath("fyreware.db"));
#else
    d->db.setHostName("localhost");
    d->db.setDatabaseName("fyreware");
#endif

    if (!d->db.open()) {
        qFatal("failed to open database");
    }

    QSqlRecord record (d->db.record("streams"));
    if (record.isEmpty()) {
        QSqlQuery q;
        q.exec(
            "create table streams ("
            "    url varchar primary key,"
            "    album varchar,"
            "    title varchar,"
            "    artist varchar,"
            "    createdAt timestamp,"
            "    updatedAt timestamp"
            ")"
            );
    }
}

/**
 * @warning Designed to run in separate thread.
 */
void Playlist::scanDir (const QString& path)
{
    QScopedPointer<QtFMOD::System> fsys (new QtFMOD::System);
    fsys->init(1);

    QString connectionName ("tmp%0");
    connectionName = connectionName.arg((quint64)QThread::currentThreadId());
    {
        QSqlDatabase db = QSqlDatabase::cloneDatabase(d->db, connectionName);
        if (!db.open()) {
            qFatal("failed to open database");
        }

        QDirIterator dit (path, d->nameFilters, QDir::Files,
                          QDirIterator::Subdirectories);
        while (dit.hasNext()) {
            dit.next();
            scanFile(dit.filePath(), db, fsys.data());
        }

        db.close();
    }
    QSqlDatabase::removeDatabase(connectionName);
}

static inline
QVariant findTag (const QHash<QString, QtFMOD::Tag>& tags,
                  const QStringList& names)
{
    foreach (const QString& tag, names) {
        if (tags.contains(tag)) {
            return tags[tag].value();
        }
    }
    return QVariant();
}

/**
 * @warning Designed to run in separate thread.
 */
void Playlist::scanFile (
    const QString& path,
    QSqlDatabase& db,
    QtFMOD::System* fsys
    )
{
    QSqlQuery q (db);

    QUrl url (path);
    QFileInfo fileInfo (path);

    q.prepare("select updatedAt from streams where url = :url limit 1");
    q.bindValue(":url", url.toString());
    if (!q.exec()) {
        qWarning() << q.lastError();
        qWarning() << q.lastQuery();
        return;
    }

    enum Op {
        Skip,
        Insert,
        Update
    };

    Op op = Skip;

    if (q.size() == 0) {
        op = Insert;
    } else {
        q.first();
        QDateTime updatedAt (q.value(0).toDateTime());
        if (url.scheme().isEmpty()) {
            // assuming it is a file
            if (!fileInfo.exists()) {
                qWarning() << path << "does not exist";
                op = Skip;
            } else if (updatedAt <= fileInfo.lastModified()) {
                op = Skip;
            } else {
                op = Update;
            }
        } else {
            Q_ASSERT(url.scheme() == "http");
            op = Update;
        }
    }

    if (op == Skip) {
        return;
    }

    QSharedPointer<QtFMOD::Sound> sound (
        fsys->createStream(path, FMOD_OPENONLY));

    if (fsys->error() != FMOD_OK) {
        qWarning() << "fmod failed to open" << path;
        Q_ASSERT(sound->isNull());
    } else {
        Q_ASSERT(!sound.isNull());

        QHash<QString, QtFMOD::Tag> tags (sound->tags());

        switch (op) {
        case Insert: {
            q.prepare(
                "insert into streams "
                "(url, album, title, artist, createdAt, updatedAt) "
                "values "
                "(:url, :album, :title, :artist, :createdAt, :updatedAt)"
                );
            q.bindValue(":createdAt", QDateTime::currentDateTime());
            break;
        }
        case Update: {
            q.prepare(
                "update streams set "
                "album = :album "
                "title = :title "
                "artist = :artist "
                "updatedAt = :updatedAt "
                "where url = :url"
                );
            break;
        }
        default: {
            qFatal("invalid op");
            break;
        }
        }

        q.bindValue(":url"   , url.toString());
        q.bindValue(":album" , findTag(tags, d->albumTags));
        q.bindValue(":title" , findTag(tags, d->titleTags));
        q.bindValue(":artist", findTag(tags, d->artistTags));
        q.bindValue(":updatedAt", fileInfo.lastModified());

        if (!q.exec()) {
            qWarning() << q.lastError();
            qWarning() << q.lastQuery();
        } else {
            if (op == Insert) {
                d->urls << url;
                d->model->insertRow(d->urls.indexOf(url));
            }
        }
    }
}

void Playlist::dragEnterEvent (QDragEnterEvent* evt)
{
    if (evt->mimeData()->hasFormat("text/uri-list")) {
        if (evt->source() == this) {
            evt->setDropAction(Qt::MoveAction);
            evt->accept();
        } else {
            evt->acceptProposedAction();
        }
    } else {
        evt->ignore();
    }
}

void Playlist::dragMoveEvent (QDragMoveEvent* evt)
{
    if (evt->mimeData()->hasFormat("text/uri-list")) {
        if (evt->source() == this) {
            evt->setDropAction(Qt::MoveAction);
            evt->accept();
        } else {
            evt->acceptProposedAction();
        }
    } else {
        evt->ignore();
    }
}

void Playlist::dropEvent (QDropEvent* evt)
{
    if (evt->mimeData()->hasFormat("text/uri-list")) {
        if (evt->source() == this) {
            evt->setDropAction(Qt::MoveAction);
            evt->accept();
        } else {
            evt->acceptProposedAction();
        }
    } else {
        evt->ignore();
    }
}
<commit_msg>sqlite database<commit_after>
/**
 * @file Playlist.cpp
 * @brief Playlist implementation
 *
 * @todo Load in background, notifying of changes.
 * @todo Use a database backend to avoid hitting fmod heavily.
 */

#include "Playlist.moc"

#include "SortedSet.h"
#include "defs.h"
#include "Scene.h"
#include "PlaylistModel.h"

#include <QDebug>
#include <QDragEnterEvent>
#include <QUrl>
#include <QDirIterator>
#include <QDesktopServices>
#include <QDateTime>
#include <QSortFilterProxyModel>

#include <QSqlDatabase>
#include <QSqlRecord>
#include <QSqlQuery>
#include <QSqlError>

#include <QtConcurrentRun>

#include <boost/bind.hpp>

#include <QtFMOD/System.h>
#include <QtFMOD/Sound.h>
#include <QtFMOD/Tag.h>

struct Playlist::Private
{
    SortedSet<QUrl> urls;

    QSqlDatabase db;
    PlaylistModel* model;
    QSortFilterProxyModel* proxyModel;
    QStringList nameFilters;

    QStringList albumTags;
    QStringList titleTags;
    QStringList artistTags;

    Private (Playlist* q) :
        db(QSqlDatabase::addDatabase("QSQLITE")),
        model(new PlaylistModel(urls, db, q)),
        proxyModel(new QSortFilterProxyModel(q))
    {
        nameFilters
            //<< "*.aif"
            //<< "*.aiff"
            << "*.mp3"
            //<< "*.wav"
            ;

        albumTags  << "ALBUM" << "TAL" << "icy-name";
        titleTags  << "TITLE" << "TT2" << "icy-url";
        artistTags << "ARTIST" << "TP1";

        proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
        proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
        proxyModel->setFilterRole(FilterRole);
        proxyModel->setSourceModel(model);
    }
};

Playlist::Playlist (QWidget* parent) :
    QWidget(parent),
    d(new Private(this))
{
    setupUi(this);

    initDb();

    tableView->setModel(d->proxyModel);

    connect(filterLineEdit, SIGNAL(textChanged(const QString&)),
            d->proxyModel, SLOT(setFilterWildcard(const QString&)));
}

Playlist::~Playlist ()
{
}

void Playlist::update ()
{
    QSqlQuery q;
    q.prepare("select url from streams order by url");
    if (q.exec()) {
        while (q.next()) {
            QUrl url (q.value(0).toString());
            d->urls << url;
            d->model->insertRow(d->urls.indexOf(url));
        }
    }

    QtConcurrent::run(boost::bind(&Playlist::scanDir, this,
                                  QDesktopServices::storageLocation(
                                      QDesktopServices::MusicLocation)));
}

void Playlist::initDb ()
{
    QDir dataDir (
        QDesktopServices::storageLocation(QDesktopServices::DataLocation));
    QDir::home().mkpath(dataDir.path());

    d->db.setDatabaseName(dataDir.filePath("fyreware.db"));

    if (!d->db.open()) {
        qFatal("failed to open database");
    }

    QSqlRecord record (d->db.record("streams"));
    if (record.isEmpty()) {
        QSqlQuery q;
        q.exec(
            "create table streams ("
            "    url varchar primary key,"
            "    album varchar,"
            "    title varchar,"
            "    artist varchar,"
            "    createdAt timestamp,"
            "    updatedAt timestamp"
            ")"
            );
    }
}

/**
 * @warning Designed to run in separate thread.
 */
void Playlist::scanDir (const QString& path)
{
    QScopedPointer<QtFMOD::System> fsys (new QtFMOD::System);
    fsys->init(1);

    QString connectionName ("tmp%0");
    connectionName = connectionName.arg((quint64)QThread::currentThreadId());
    {
        QSqlDatabase db = QSqlDatabase::cloneDatabase(d->db, connectionName);
        if (!db.open()) {
            qFatal("failed to open database");
        }

        QDirIterator dit (path, d->nameFilters, QDir::Files,
                          QDirIterator::Subdirectories);
        while (dit.hasNext()) {
            dit.next();
            scanFile(dit.filePath(), db, fsys.data());
        }

        db.close();
    }
    QSqlDatabase::removeDatabase(connectionName);
}

static inline
QVariant findTag (const QHash<QString, QtFMOD::Tag>& tags,
                  const QStringList& names)
{
    foreach (const QString& tag, names) {
        if (tags.contains(tag)) {
            return tags[tag].value();
        }
    }
    return QVariant();
}

/**
 * @warning Designed to run in separate thread.
 */
void Playlist::scanFile (
    const QString& path,
    QSqlDatabase& db,
    QtFMOD::System* fsys
    )
{
    QSqlQuery q (db);

    QUrl url (path);
    QFileInfo fileInfo (path);

    q.prepare("select updatedAt from streams where url = :url limit 1");
    q.bindValue(":url", url.toString());
    if (!q.exec()) {
        qWarning() << q.lastError();
        qWarning() << q.lastQuery();
        return;
    }

    enum Op {
        Skip,
        Insert,
        Update
    };

    Op op = Skip;

    if (q.size() == 0) {
        op = Insert;
    } else {
        q.first();
        QDateTime updatedAt (q.value(0).toDateTime());
        if (url.scheme().isEmpty()) {
            // assuming it is a file
            if (!fileInfo.exists()) {
                qWarning() << path << "does not exist";
                op = Skip;
            } else if (updatedAt <= fileInfo.lastModified()) {
                op = Skip;
            } else {
                op = Update;
            }
        } else {
            Q_ASSERT(url.scheme() == "http");
            op = Update;
        }
    }

    if (op == Skip) {
        return;
    }

    QSharedPointer<QtFMOD::Sound> sound (
        fsys->createStream(path, FMOD_OPENONLY));

    if (fsys->error() != FMOD_OK) {
        qWarning() << "fmod failed to open" << path;
        Q_ASSERT(sound->isNull());
    } else {
        Q_ASSERT(!sound.isNull());

        QHash<QString, QtFMOD::Tag> tags (sound->tags());

        switch (op) {
        case Insert: {
            q.prepare(
                "insert into streams "
                "(url, album, title, artist, createdAt, updatedAt) "
                "values "
                "(:url, :album, :title, :artist, :createdAt, :updatedAt)"
                );
            q.bindValue(":createdAt", QDateTime::currentDateTime());
            break;
        }
        case Update: {
            q.prepare(
                "update streams set "
                "album = :album "
                "title = :title "
                "artist = :artist "
                "updatedAt = :updatedAt "
                "where url = :url"
                );
            break;
        }
        default: {
            qFatal("invalid op");
            break;
        }
        }

        q.bindValue(":url"   , url.toString());
        q.bindValue(":album" , findTag(tags, d->albumTags));
        q.bindValue(":title" , findTag(tags, d->titleTags));
        q.bindValue(":artist", findTag(tags, d->artistTags));
        q.bindValue(":updatedAt", fileInfo.lastModified());

        if (!q.exec()) {
            qWarning() << q.lastError();
            qWarning() << q.lastQuery();
        } else {
            if (op == Insert) {
                d->urls << url;
                d->model->insertRow(d->urls.indexOf(url));
            }
        }
    }
}

void Playlist::dragEnterEvent (QDragEnterEvent* evt)
{
    if (evt->mimeData()->hasFormat("text/uri-list")) {
        if (evt->source() == this) {
            evt->setDropAction(Qt::MoveAction);
            evt->accept();
        } else {
            evt->acceptProposedAction();
        }
    } else {
        evt->ignore();
    }
}

void Playlist::dragMoveEvent (QDragMoveEvent* evt)
{
    if (evt->mimeData()->hasFormat("text/uri-list")) {
        if (evt->source() == this) {
            evt->setDropAction(Qt::MoveAction);
            evt->accept();
        } else {
            evt->acceptProposedAction();
        }
    } else {
        evt->ignore();
    }
}

void Playlist::dropEvent (QDropEvent* evt)
{
    if (evt->mimeData()->hasFormat("text/uri-list")) {
        if (evt->source() == this) {
            evt->setDropAction(Qt::MoveAction);
            evt->accept();
        } else {
            evt->acceptProposedAction();
        }
    } else {
        evt->ignore();
    }
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

// mapnik
#include <mapnik/agg_renderer.hpp>
#include <mapnik/image_scaling.hpp>
#include <mapnik/image_compositing.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/agg_rasterizer.hpp>
#include <mapnik/image_data.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/raster.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/warp.hpp>
#include <mapnik/config.hpp>

// stl
#include <cmath>

namespace mapnik {

template <typename T>
void agg_renderer<T>::process(raster_symbolizer const& sym,
                              mapnik::feature_impl & feature,
                              proj_transform const& prj_trans)
{
    raster_ptr const& source = feature.get_raster();
    if (source)
    {
        // If there's a colorizer defined, use it to color the raster in-place
        raster_colorizer_ptr colorizer = sym.get_colorizer();
        if (colorizer)
            colorizer->colorize(source,feature);

        box2d<double> target_ext = box2d<double>(source->ext_);
        prj_trans.backward(target_ext, PROJ_ENVELOPE_POINTS);
        box2d<double> ext = t_.forward(target_ext);
        int start_x = static_cast<int>(ext.minx());
        int start_y = static_cast<int>(ext.miny());
        int end_x = static_cast<int>(ceil(ext.maxx()));
        int end_y = static_cast<int>(ceil(ext.maxy()));
        int raster_width = end_x - start_x;
        int raster_height = end_y - start_y;
        if (raster_width > 0 && raster_height > 0)
        {
            image_data_32 target_data(raster_width,raster_height);
            raster target(target_ext, target_data);
            scaling_method_e scaling_method = sym.get_scaling_method();
            double filter_radius = sym.calculate_filter_factor();
            if (!prj_trans.equal())
            {
                double offset_x = ext.minx() - start_x;
                double offset_y = ext.miny() - start_y;
                reproject_and_scale_raster(target, *source, prj_trans,
                                 offset_x, offset_y,
                                 sym.get_mesh_size(),
                                 filter_radius,
                                 scaling_method);
            }
            else
            {
                if (scaling_method == SCALING_BILINEAR8)
                {
                    scale_image_bilinear8<image_data_32>(target.data_,source->data_, 0.0, 0.0);
                } else
                {
                    double scaling_ratio = ext.width() / source->data_.width();
                    scale_image_agg<image_data_32>(target.data_,
                                                   source->data_,
                                                   scaling_method,
                                                   scaling_ratio,
                                                   0.0,
                                                   0.0,
                                                   filter_radius);
                }
            }
            composite(current_buffer_->data(), target.data_, sym.comp_op(), sym.get_opacity(), start_x, start_y, true);
        }
    }
}

template void agg_renderer<image_32>::process(raster_symbolizer const&,
                                              mapnik::feature_impl &,
                                              proj_transform const&);

}
<commit_msg>formatting<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

// mapnik
#include <mapnik/agg_renderer.hpp>
#include <mapnik/image_scaling.hpp>
#include <mapnik/image_compositing.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/agg_rasterizer.hpp>
#include <mapnik/image_data.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/raster.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/warp.hpp>
#include <mapnik/config.hpp>

// stl
#include <cmath>

namespace mapnik {

template <typename T>
void agg_renderer<T>::process(raster_symbolizer const& sym,
                              mapnik::feature_impl & feature,
                              proj_transform const& prj_trans)
{
    raster_ptr const& source = feature.get_raster();
    if (source)
    {
        // If there's a colorizer defined, use it to color the raster in-place
        raster_colorizer_ptr colorizer = sym.get_colorizer();
        if (colorizer)
            colorizer->colorize(source,feature);

        box2d<double> target_ext = box2d<double>(source->ext_);
        prj_trans.backward(target_ext, PROJ_ENVELOPE_POINTS);
        box2d<double> ext = t_.forward(target_ext);
        int start_x = static_cast<int>(ext.minx());
        int start_y = static_cast<int>(ext.miny());
        int end_x = static_cast<int>(ceil(ext.maxx()));
        int end_y = static_cast<int>(ceil(ext.maxy()));
        int raster_width = end_x - start_x;
        int raster_height = end_y - start_y;
        if (raster_width > 0 && raster_height > 0)
        {
            image_data_32 target_data(raster_width,raster_height);
            raster target(target_ext, target_data);
            scaling_method_e scaling_method = sym.get_scaling_method();
            double filter_radius = sym.calculate_filter_factor();
            if (!prj_trans.equal())
            {
                double offset_x = ext.minx() - start_x;
                double offset_y = ext.miny() - start_y;
                reproject_and_scale_raster(target, *source, prj_trans,
                                 offset_x, offset_y,
                                 sym.get_mesh_size(),
                                 filter_radius,
                                 scaling_method);
            }
            else
            {
                if (scaling_method == SCALING_BILINEAR8)
                {
                    scale_image_bilinear8<image_data_32>(target.data_,source->data_, 0.0, 0.0);
                }
                else
                {
                    double scaling_ratio = ext.width() / source->data_.width();
                    scale_image_agg<image_data_32>(target.data_,
                                                   source->data_,
                                                   scaling_method,
                                                   scaling_ratio,
                                                   0.0,
                                                   0.0,
                                                   filter_radius);
                }
            }
            composite(current_buffer_->data(), target.data_, sym.comp_op(), sym.get_opacity(), start_x, start_y, true);
        }
    }
}

template void agg_renderer<image_32>::process(raster_symbolizer const&,
                                              mapnik::feature_impl &,
                                              proj_transform const&);

}
<|endoftext|>


<commit_before>/*
 * (C) Copyright 2016 Kurento (http://kurento.org/)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <gst/gst.h>
#include "MediaPipeline.hpp"
#include "MediaPipelineImpl.hpp"
#include "RegionOfInterest.hpp"
#include "RelativePoint.hpp"
#include "RegionOfInterestConfig.hpp"
#include <CrowdDetectorFilterImplFactory.hpp>
#include "CrowdDetectorFilterImpl.hpp"
#include <jsonrpc/JsonSerializer.hpp>
#include <KurentoException.hpp>
#include "SignalHandler.hpp"

#define GST_CAT_DEFAULT kurento_crowd_detector_filter_impl
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_DEFAULT_NAME "KurentoCrowdDetectorFilterImpl"

#define ROIS_PARAM "rois"
#define PROCESSING_WIDTH "processing-width"

namespace kurento
{
namespace module
{
namespace crowddetector
{

static GstStructure *
get_structure_from_roi (std::shared_ptr<RegionOfInterest> roi)
{
  GstStructure *roiStructure, *configRoiSt;
  std::shared_ptr<RegionOfInterestConfig> config;
  int pointCount = 0;

  roiStructure = gst_structure_new_empty (roi->getId().c_str() );

  if (roiStructure == NULL) {
    throw KurentoException (MEDIA_OBJECT_ILLEGAL_PARAM_ERROR,
                            "Invalid roi name");
  }

  for (std::shared_ptr<RelativePoint> point : roi->getPoints() ) {
    GstStructure *pointSt;
    std::string name = "point" + std::to_string (pointCount ++);

    pointSt = gst_structure_new (name.c_str(),
                                 "x", G_TYPE_FLOAT, point->getX(),
                                 "y", G_TYPE_FLOAT, point->getY(),
                                 NULL);

    gst_structure_set (roiStructure,
                       name.c_str(), GST_TYPE_STRUCTURE, pointSt,
                       NULL);

    gst_structure_free (pointSt);
  }

  config = roi->getRegionOfInterestConfig();
  configRoiSt = gst_structure_new ("config",
                                   "id", G_TYPE_STRING, roi->getId().c_str(),
                                   "occupancy_level_min", G_TYPE_INT, config->getOccupancyLevelMin(),
                                   "occupancy_level_med", G_TYPE_INT, config->getOccupancyLevelMed(),
                                   "occupancy_level_max", G_TYPE_INT, config->getOccupancyLevelMax(),
                                   "occupancy_num_frames_to_event", G_TYPE_INT,
                                   config->getOccupancyNumFramesToEvent(),
                                   "fluidity_level_min", G_TYPE_INT, config->getFluidityLevelMin(),
                                   "fluidity_level_med", G_TYPE_INT, config->getFluidityLevelMed(),
                                   "fluidity_level_max", G_TYPE_INT, config->getFluidityLevelMax(),
                                   "fluidity_num_frames_to_event", G_TYPE_INT,
                                   config->getFluidityNumFramesToEvent(),
                                   "send_optical_flow_event", G_TYPE_BOOLEAN, config->getSendOpticalFlowEvent(),
                                   "optical_flow_num_frames_to_event", G_TYPE_INT,
                                   config->getOpticalFlowNumFramesToEvent(),
                                   "optical_flow_num_frames_to_reset", G_TYPE_INT,
                                   config->getOpticalFlowNumFramesToReset(),
                                   "optical_flow_angle_offset", G_TYPE_INT, config->getOpticalFlowAngleOffset(),
                                   NULL);
  gst_structure_set (roiStructure,
                     "config", GST_TYPE_STRUCTURE, configRoiSt,
                     NULL);

  gst_structure_free (configRoiSt);

  return roiStructure;
}

void CrowdDetectorFilterImpl::busMessage (GstMessage *message)
{
  const GstStructure *st;
  gchar *roiID;
  const gchar *type;
  std::string roiIDStr, typeStr;

  if (GST_MESSAGE_SRC (message) != GST_OBJECT (crowdDetector) ||
      GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT) {
    return;
  }

  st = gst_message_get_structure (message);
  type = gst_structure_get_name (st);

  if (!gst_structure_get (st, "roi", G_TYPE_STRING , &roiID, NULL) ) {
    GST_WARNING ("The message does not contain the roi ID");
    return;
  }

  roiIDStr = roiID;
  typeStr = type;

  g_free (roiID);

  if (typeStr == "fluidity-event") {

    double fluidity_percentage;
    int fluidity_level;

    if (! (gst_structure_get (st, "fluidity_percentage", G_TYPE_DOUBLE,
                              &fluidity_percentage, NULL) ) ) {
      GST_WARNING ("The message does not contain the fluidity percentage");
      return;
    }

    if (! (gst_structure_get (st, "fluidity_level", G_TYPE_INT,
                              &fluidity_level, NULL) ) ) {
      GST_WARNING ("The message does not contain the fluidity level");
      return;
    }

    try {
      CrowdDetectorFluidity event (shared_from_this(),
                                   CrowdDetectorFluidity::getName(),
                                   fluidity_percentage, fluidity_level,
                                   roiIDStr);
      signalCrowdDetectorFluidity (event);
    } catch (std::bad_weak_ptr &e) {
    }
  } else if (typeStr == "occupancy-event") {

    double occupancy_percentage;
    int occupancy_level;

    if (! (gst_structure_get (st, "occupancy_percentage", G_TYPE_DOUBLE,
                              &occupancy_percentage, NULL) ) ) {
      GST_WARNING ("The message does not contain the occupancy percentage");
      return;
    }

    if (! (gst_structure_get (st, "occupancy_level", G_TYPE_INT,
                              &occupancy_level, NULL) ) ) {
      GST_WARNING ("The message does not contain the occupancy level");
      return;
    }

    try {
      CrowdDetectorOccupancy event (shared_from_this(),
                                    CrowdDetectorOccupancy::getName(),
                                    occupancy_percentage, occupancy_level,
                                    roiIDStr);
      signalCrowdDetectorOccupancy (event);
    } catch (std::bad_weak_ptr &e) {
    }
  } else if (typeStr == "direction-event") {

    double direction_angle;

    if (! (gst_structure_get (st, "direction_angle", G_TYPE_DOUBLE,
                              &direction_angle, NULL) ) ) {
      GST_WARNING ("The message does not contain the direction angle");
      return;
    }

    try {
      CrowdDetectorDirection event ( shared_from_this(),
                                     CrowdDetectorDirection::getName(),
                                     direction_angle, roiIDStr);
      signalCrowdDetectorDirection (event);
    } catch (std::bad_weak_ptr &e) {
    }
  } else {
    GST_WARNING ("The message does not have the correct name");
  }
}

void CrowdDetectorFilterImpl::postConstructor ()
{
  GstBus *bus;
  std::shared_ptr<MediaPipelineImpl> pipe;

  FilterImpl::postConstructor ();

  pipe = std::dynamic_pointer_cast<MediaPipelineImpl> (getMediaPipeline() );

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipe->getPipeline() ) );

  bus_handler_id = register_signal_handler (G_OBJECT (bus),
                   "message",
                   std::function <void (GstElement *, GstMessage *) >
                   (std::bind (&CrowdDetectorFilterImpl::busMessage, this,
                               std::placeholders::_2) ),
                   std::dynamic_pointer_cast<CrowdDetectorFilterImpl>
                   (shared_from_this() ) );

  g_object_unref (bus);
}

CrowdDetectorFilterImpl::CrowdDetectorFilterImpl (const
    boost::property_tree::ptree &config,
    std::shared_ptr<MediaPipeline> mediaPipeline,
    const std::vector<std::shared_ptr<RegionOfInterest>> &rois)  : FilterImpl (
        config, std::dynamic_pointer_cast<MediaPipelineImpl>
        (mediaPipeline) )
{
  GstStructure *roisStructure;

  g_object_set (element, "filter-factory", "crowddetector", NULL);

  g_object_get (G_OBJECT (element), "filter", &crowdDetector, NULL);

  if (crowdDetector == NULL) {
    throw KurentoException (MEDIA_OBJECT_NOT_AVAILABLE,
                            "Media Object not available");
  }

  roisStructure = gst_structure_new_empty  ("Rois");

  for (auto roi : rois) {
    GstStructure *roiStructureAux = get_structure_from_roi (roi);

    gst_structure_set (roisStructure,
                       roi->getId().c_str(), GST_TYPE_STRUCTURE,
                       roiStructureAux,
                       NULL);

    gst_structure_free (roiStructureAux);
  }

  g_object_set (G_OBJECT (crowdDetector), ROIS_PARAM, roisStructure, NULL);
  gst_structure_free (roisStructure);

  bus_handler_id = 0;
  // There is no need to reference crowddetector because its life cycle is the same as the filter life cycle
  g_object_unref (crowdDetector);
}

CrowdDetectorFilterImpl::~CrowdDetectorFilterImpl()
{
  std::shared_ptr<MediaPipelineImpl> pipe;

  if (bus_handler_id > 0) {
    pipe = std::dynamic_pointer_cast<MediaPipelineImpl> (getMediaPipeline() );
    GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (pipe->getPipeline() ) );
    unregister_signal_handler (bus, bus_handler_id);
    g_object_unref (bus);
  }
}

int CrowdDetectorFilterImpl::getProcessingWidth ()
{
  int ret;

  g_object_get (G_OBJECT (crowdDetector), PROCESSING_WIDTH, &ret, NULL);

  return ret;
}

void CrowdDetectorFilterImpl::setProcessingWidth (int processingWidth)
{
  g_object_set (G_OBJECT (crowdDetector), PROCESSING_WIDTH, processingWidth,
                NULL);
}

MediaObjectImpl *
CrowdDetectorFilterImplFactory::createObject (const boost::property_tree::ptree
    &config, std::shared_ptr<MediaPipeline> mediaPipeline,
    const std::vector<std::shared_ptr<RegionOfInterest>> &rois) const
{
  return new CrowdDetectorFilterImpl (config, mediaPipeline, rois);
}

CrowdDetectorFilterImpl::StaticConstructor
CrowdDetectorFilterImpl::staticConstructor;

CrowdDetectorFilterImpl::StaticConstructor::StaticConstructor()
{
  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0,
                           GST_DEFAULT_NAME);
}

} /* crowddetector */
} /* module */
} /* kurento */
<commit_msg>fixup! deprecate JSON-RPC roiID for roiId<commit_after>/*
 * (C) Copyright 2016 Kurento (http://kurento.org/)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <gst/gst.h>
#include "MediaPipeline.hpp"
#include "MediaPipelineImpl.hpp"
#include "RegionOfInterest.hpp"
#include "RelativePoint.hpp"
#include "RegionOfInterestConfig.hpp"
#include <CrowdDetectorFilterImplFactory.hpp>
#include "CrowdDetectorFilterImpl.hpp"
#include <jsonrpc/JsonSerializer.hpp>
#include <KurentoException.hpp>
#include "SignalHandler.hpp"

#define GST_CAT_DEFAULT kurento_crowd_detector_filter_impl
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_DEFAULT_NAME "KurentoCrowdDetectorFilterImpl"

#define ROIS_PARAM "rois"
#define PROCESSING_WIDTH "processing-width"

namespace kurento
{
namespace module
{
namespace crowddetector
{

static GstStructure *
get_structure_from_roi (std::shared_ptr<RegionOfInterest> roi)
{
  GstStructure *roiStructure, *configRoiSt;
  std::shared_ptr<RegionOfInterestConfig> config;
  int pointCount = 0;

  roiStructure = gst_structure_new_empty (roi->getId().c_str() );

  if (roiStructure == NULL) {
    throw KurentoException (MEDIA_OBJECT_ILLEGAL_PARAM_ERROR,
                            "Invalid roi name");
  }

  for (std::shared_ptr<RelativePoint> point : roi->getPoints() ) {
    GstStructure *pointSt;
    std::string name = "point" + std::to_string (pointCount ++);

    pointSt = gst_structure_new (name.c_str(),
                                 "x", G_TYPE_FLOAT, point->getX(),
                                 "y", G_TYPE_FLOAT, point->getY(),
                                 NULL);

    gst_structure_set (roiStructure,
                       name.c_str(), GST_TYPE_STRUCTURE, pointSt,
                       NULL);

    gst_structure_free (pointSt);
  }

  config = roi->getRegionOfInterestConfig();
  configRoiSt = gst_structure_new ("config",
                                   "id", G_TYPE_STRING, roi->getId().c_str(),
                                   "occupancy_level_min", G_TYPE_INT, config->getOccupancyLevelMin(),
                                   "occupancy_level_med", G_TYPE_INT, config->getOccupancyLevelMed(),
                                   "occupancy_level_max", G_TYPE_INT, config->getOccupancyLevelMax(),
                                   "occupancy_num_frames_to_event", G_TYPE_INT,
                                   config->getOccupancyNumFramesToEvent(),
                                   "fluidity_level_min", G_TYPE_INT, config->getFluidityLevelMin(),
                                   "fluidity_level_med", G_TYPE_INT, config->getFluidityLevelMed(),
                                   "fluidity_level_max", G_TYPE_INT, config->getFluidityLevelMax(),
                                   "fluidity_num_frames_to_event", G_TYPE_INT,
                                   config->getFluidityNumFramesToEvent(),
                                   "send_optical_flow_event", G_TYPE_BOOLEAN, config->getSendOpticalFlowEvent(),
                                   "optical_flow_num_frames_to_event", G_TYPE_INT,
                                   config->getOpticalFlowNumFramesToEvent(),
                                   "optical_flow_num_frames_to_reset", G_TYPE_INT,
                                   config->getOpticalFlowNumFramesToReset(),
                                   "optical_flow_angle_offset", G_TYPE_INT, config->getOpticalFlowAngleOffset(),
                                   NULL);
  gst_structure_set (roiStructure,
                     "config", GST_TYPE_STRUCTURE, configRoiSt,
                     NULL);

  gst_structure_free (configRoiSt);

  return roiStructure;
}

void CrowdDetectorFilterImpl::busMessage (GstMessage *message)
{
  const GstStructure *st;
  gchar *roiID;
  const gchar *type;
  std::string roiIDStr, typeStr;

  if (GST_MESSAGE_SRC (message) != GST_OBJECT (crowdDetector) ||
      GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT) {
    return;
  }

  st = gst_message_get_structure (message);
  type = gst_structure_get_name (st);

  if (!gst_structure_get (st, "roi", G_TYPE_STRING , &roiID, NULL) ) {
    GST_WARNING ("The message does not contain the roi ID");
    return;
  }

  roiIDStr = roiID;
  typeStr = type;

  g_free (roiID);

  if (typeStr == "fluidity-event") {

    double fluidity_percentage;
    int fluidity_level;

    if (! (gst_structure_get (st, "fluidity_percentage", G_TYPE_DOUBLE,
                              &fluidity_percentage, NULL) ) ) {
      GST_WARNING ("The message does not contain the fluidity percentage");
      return;
    }

    if (! (gst_structure_get (st, "fluidity_level", G_TYPE_INT,
                              &fluidity_level, NULL) ) ) {
      GST_WARNING ("The message does not contain the fluidity level");
      return;
    }

    try {
      CrowdDetectorFluidity event (shared_from_this(),
                                   CrowdDetectorFluidity::getName(),
                                   fluidity_percentage, fluidity_level,
                                   roiIDStr, roiIDStr);
      signalCrowdDetectorFluidity (event);
    } catch (std::bad_weak_ptr &e) {
    }
  } else if (typeStr == "occupancy-event") {

    double occupancy_percentage;
    int occupancy_level;

    if (! (gst_structure_get (st, "occupancy_percentage", G_TYPE_DOUBLE,
                              &occupancy_percentage, NULL) ) ) {
      GST_WARNING ("The message does not contain the occupancy percentage");
      return;
    }

    if (! (gst_structure_get (st, "occupancy_level", G_TYPE_INT,
                              &occupancy_level, NULL) ) ) {
      GST_WARNING ("The message does not contain the occupancy level");
      return;
    }

    try {
      CrowdDetectorOccupancy event (shared_from_this(),
                                    CrowdDetectorOccupancy::getName(),
                                    occupancy_percentage, occupancy_level,
                                    roiIDStr, roiIDStr);
      signalCrowdDetectorOccupancy (event);
    } catch (std::bad_weak_ptr &e) {
    }
  } else if (typeStr == "direction-event") {

    double direction_angle;

    if (! (gst_structure_get (st, "direction_angle", G_TYPE_DOUBLE,
                              &direction_angle, NULL) ) ) {
      GST_WARNING ("The message does not contain the direction angle");
      return;
    }

    try {
      CrowdDetectorDirection event ( shared_from_this(),
                                     CrowdDetectorDirection::getName(),
                                     direction_angle, roiIDStr, roiIDStr);
      signalCrowdDetectorDirection (event);
    } catch (std::bad_weak_ptr &e) {
    }
  } else {
    GST_WARNING ("The message does not have the correct name");
  }
}

void CrowdDetectorFilterImpl::postConstructor ()
{
  GstBus *bus;
  std::shared_ptr<MediaPipelineImpl> pipe;

  FilterImpl::postConstructor ();

  pipe = std::dynamic_pointer_cast<MediaPipelineImpl> (getMediaPipeline() );

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipe->getPipeline() ) );

  bus_handler_id = register_signal_handler (G_OBJECT (bus),
                   "message",
                   std::function <void (GstElement *, GstMessage *) >
                   (std::bind (&CrowdDetectorFilterImpl::busMessage, this,
                               std::placeholders::_2) ),
                   std::dynamic_pointer_cast<CrowdDetectorFilterImpl>
                   (shared_from_this() ) );

  g_object_unref (bus);
}

CrowdDetectorFilterImpl::CrowdDetectorFilterImpl (const
    boost::property_tree::ptree &config,
    std::shared_ptr<MediaPipeline> mediaPipeline,
    const std::vector<std::shared_ptr<RegionOfInterest>> &rois)  : FilterImpl (
        config, std::dynamic_pointer_cast<MediaPipelineImpl>
        (mediaPipeline) )
{
  GstStructure *roisStructure;

  g_object_set (element, "filter-factory", "crowddetector", NULL);

  g_object_get (G_OBJECT (element), "filter", &crowdDetector, NULL);

  if (crowdDetector == NULL) {
    throw KurentoException (MEDIA_OBJECT_NOT_AVAILABLE,
                            "Media Object not available");
  }

  roisStructure = gst_structure_new_empty  ("Rois");

  for (auto roi : rois) {
    GstStructure *roiStructureAux = get_structure_from_roi (roi);

    gst_structure_set (roisStructure,
                       roi->getId().c_str(), GST_TYPE_STRUCTURE,
                       roiStructureAux,
                       NULL);

    gst_structure_free (roiStructureAux);
  }

  g_object_set (G_OBJECT (crowdDetector), ROIS_PARAM, roisStructure, NULL);
  gst_structure_free (roisStructure);

  bus_handler_id = 0;
  // There is no need to reference crowddetector because its life cycle is the same as the filter life cycle
  g_object_unref (crowdDetector);
}

CrowdDetectorFilterImpl::~CrowdDetectorFilterImpl()
{
  std::shared_ptr<MediaPipelineImpl> pipe;

  if (bus_handler_id > 0) {
    pipe = std::dynamic_pointer_cast<MediaPipelineImpl> (getMediaPipeline() );
    GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (pipe->getPipeline() ) );
    unregister_signal_handler (bus, bus_handler_id);
    g_object_unref (bus);
  }
}

int CrowdDetectorFilterImpl::getProcessingWidth ()
{
  int ret;

  g_object_get (G_OBJECT (crowdDetector), PROCESSING_WIDTH, &ret, NULL);

  return ret;
}

void CrowdDetectorFilterImpl::setProcessingWidth (int processingWidth)
{
  g_object_set (G_OBJECT (crowdDetector), PROCESSING_WIDTH, processingWidth,
                NULL);
}

MediaObjectImpl *
CrowdDetectorFilterImplFactory::createObject (const boost::property_tree::ptree
    &config, std::shared_ptr<MediaPipeline> mediaPipeline,
    const std::vector<std::shared_ptr<RegionOfInterest>> &rois) const
{
  return new CrowdDetectorFilterImpl (config, mediaPipeline, rois);
}

CrowdDetectorFilterImpl::StaticConstructor
CrowdDetectorFilterImpl::staticConstructor;

CrowdDetectorFilterImpl::StaticConstructor::StaticConstructor()
{
  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0,
                           GST_DEFAULT_NAME);
}

} /* crowddetector */
} /* module */
} /* kurento */
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <stan/agrad/fwd.hpp>
#include <stan/agrad/rev.hpp>
#include <test/unit/agrad/util.hpp>

TEST(AgradFwdOperatorLessThan,Fvar) {
  using stan::agrad::fvar;
  fvar<double> v4 = 4;
  fvar<double> v5 = 5;
  double d4 = 4;
  double d5 = 5;

  EXPECT_TRUE(v4 < v5);
  EXPECT_TRUE(v4 < d5);
  EXPECT_TRUE(d4 < v5);
  EXPECT_TRUE(d4 < d5);

  int i4 = 4;
  int i5 = 5;

  EXPECT_TRUE(v4 < v5);
  EXPECT_TRUE(v4 < i5);
  EXPECT_TRUE(i4 < v5);
  EXPECT_TRUE(i4 < i5);
  EXPECT_TRUE(i4 < d5);
  EXPECT_TRUE(d4 < i5);
}

TEST(AgradFwdOperatorLessThan, FvarVar) {
  using stan::agrad::fvar;
  using stan::agrad::var;

  fvar<var> x(0.5,1.3);
  fvar<var> y(1.5,1.0);
  fvar<var> z(0.5,1.3);

  EXPECT_FALSE(z < x);
  EXPECT_FALSE(y < x);
  EXPECT_FALSE(y < z);
}

TEST(AgradFwdOperatorLessThan, FvarFvarDouble) {
  using stan::agrad::fvar;

  fvar<fvar<double> > x;
  x.val_.val_ = 1.5;
  x.val_.d_ = 1.0;

  fvar<fvar<double> > y;
  y.val_.val_ = 0.5;
  y.d_.val_ = 1.0;

  fvar<fvar<double> > z;
  z.val_.val_ = 0.5;
  z.d_.val_ = 1.0;

  EXPECT_TRUE(y < x);
  EXPECT_TRUE(z < x);
  EXPECT_FALSE(y < z);
}
TEST(AgradFwdOperatorLessThan, FvarFvarVar) {
  using stan::agrad::fvar;
  using stan::agrad::var;

  fvar<fvar<var> > x;
  x.val_.val_ = 1.5;
  x.val_.d_ = 1.0;

  fvar<fvar<var> > y;
  y.val_.val_ = 0.5;
  y.d_.val_ = 1.0;

  fvar<fvar<var> > z;
  z.val_.val_ = 0.5;
  z.d_.val_ = 1.0;

  EXPECT_TRUE(y < x);
  EXPECT_TRUE(z < x);
  EXPECT_FALSE(y < z);
}
<commit_msg>added NaN test for op_lt<commit_after>#include <gtest/gtest.h>
#include <stan/agrad/fwd.hpp>
#include <stan/agrad/rev.hpp>
#include <test/unit/agrad/util.hpp>

TEST(AgradFwdOperatorLessThan,Fvar) {
  using stan::agrad::fvar;
  fvar<double> v4 = 4;
  fvar<double> v5 = 5;
  double d4 = 4;
  double d5 = 5;

  EXPECT_TRUE(v4 < v5);
  EXPECT_TRUE(v4 < d5);
  EXPECT_TRUE(d4 < v5);
  EXPECT_TRUE(d4 < d5);

  int i4 = 4;
  int i5 = 5;

  EXPECT_TRUE(v4 < v5);
  EXPECT_TRUE(v4 < i5);
  EXPECT_TRUE(i4 < v5);
  EXPECT_TRUE(i4 < i5);
  EXPECT_TRUE(i4 < d5);
  EXPECT_TRUE(d4 < i5);
}

TEST(AgradFwdOperatorLessThan, FvarVar) {
  using stan::agrad::fvar;
  using stan::agrad::var;

  fvar<var> x(0.5,1.3);
  fvar<var> y(1.5,1.0);
  fvar<var> z(0.5,1.3);

  EXPECT_FALSE(z < x);
  EXPECT_FALSE(y < x);
  EXPECT_FALSE(y < z);
}

TEST(AgradFwdOperatorLessThan, FvarFvarDouble) {
  using stan::agrad::fvar;

  fvar<fvar<double> > x;
  x.val_.val_ = 1.5;
  x.val_.d_ = 1.0;

  fvar<fvar<double> > y;
  y.val_.val_ = 0.5;
  y.d_.val_ = 1.0;

  fvar<fvar<double> > z;
  z.val_.val_ = 0.5;
  z.d_.val_ = 1.0;

  EXPECT_TRUE(y < x);
  EXPECT_TRUE(z < x);
  EXPECT_FALSE(y < z);
}
TEST(AgradFwdOperatorLessThan, FvarFvarVar) {
  using stan::agrad::fvar;
  using stan::agrad::var;

  fvar<fvar<var> > x;
  x.val_.val_ = 1.5;
  x.val_.d_ = 1.0;

  fvar<fvar<var> > y;
  y.val_.val_ = 0.5;
  y.d_.val_ = 1.0;

  fvar<fvar<var> > z;
  z.val_.val_ = 0.5;
  z.d_.val_ = 1.0;

  EXPECT_TRUE(y < x);
  EXPECT_TRUE(z < x);
  EXPECT_FALSE(y < z);
}

TEST(AgradFwdOperatorLessThan, lt_nan) {
  using stan::agrad::fvar;
  using stan::agrad::var;
  double nan = std::numeric_limits<double>::quiet_NaN();
  double a = 3.0;
  fvar<double> nan_fd = std::numeric_limits<double>::quiet_NaN();
  fvar<double> a_fd = 3.0;
  fvar<var> nan_fv = std::numeric_limits<double>::quiet_NaN();
  fvar<var> a_fv = 3.0;
  fvar<fvar<double> > nan_ffd = std::numeric_limits<double>::quiet_NaN();
  fvar<fvar<double> > a_ffd = 3.0;
  fvar<fvar<var> > nan_ffv = std::numeric_limits<double>::quiet_NaN();
  fvar<fvar<var> > a_ffv = 3.0;

  EXPECT_FALSE(a < nan_fd);
  EXPECT_FALSE(a_fd < nan_fd);
  EXPECT_FALSE(nan < nan_fd);
  EXPECT_FALSE(nan_fd < nan_fd);
  EXPECT_FALSE(a_fd < nan);
  EXPECT_FALSE(nan_fd < nan);
  EXPECT_FALSE(nan_fd < a);
  EXPECT_FALSE(nan_fd < a_fd);
  EXPECT_FALSE(nan < a_fd);

  EXPECT_FALSE(a < nan_fv);
  EXPECT_FALSE(a_fv < nan_fv);
  EXPECT_FALSE(nan < nan_fv);
  EXPECT_FALSE(nan_fv < nan_fv);
  EXPECT_FALSE(a_fv < nan);
  EXPECT_FALSE(nan_fv < nan);
  EXPECT_FALSE(nan_fv < a);
  EXPECT_FALSE(nan_fv < a_fv);
  EXPECT_FALSE(nan < a_fv);

  EXPECT_FALSE(a < nan_ffd);
  EXPECT_FALSE(a_ffd < nan_ffd);
  EXPECT_FALSE(nan < nan_ffd);
  EXPECT_FALSE(nan_ffd < nan_ffd);
  EXPECT_FALSE(a_ffd < nan);
  EXPECT_FALSE(nan_ffd < nan);
  EXPECT_FALSE(nan_ffd < a);
  EXPECT_FALSE(nan_ffd < a_ffd);
  EXPECT_FALSE(nan < a_ffd);

  EXPECT_FALSE(a < nan_ffv);
  EXPECT_FALSE(a_ffv < nan_ffv);
  EXPECT_FALSE(nan < nan_ffv);
  EXPECT_FALSE(nan_ffv < nan_ffv);
  EXPECT_FALSE(a_ffv < nan);
  EXPECT_FALSE(nan_ffv < nan);
  EXPECT_FALSE(nan_ffv < a);
  EXPECT_FALSE(nan_ffv < a_ffv);
  EXPECT_FALSE(nan < a_ffv);
}
<|endoftext|>


<commit_before>/*     Iridium Utilities -- Iridium Cryptography Utilities
 *  Sha256.cpp
 *
 *  Copyright (c) 2009, Daniel Reiter Horn
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of Iridium nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "Sha256.hpp"
#include "internal_sha2.hpp"
#include <stdexcept>
namespace Iridium {
static unsigned char numToHex(unsigned int num) {
    if (num<10)
        return num+'0';
    if (num<16)
        return (num-10)+'a';
    return 'x';
}
static unsigned int numFromHex(unsigned char charValue) {
    if (charValue>='0'&&charValue<='9')
        return charValue-'0';
    if (charValue>='a'&&charValue<='f')
        return 10 + (charValue-'a');
    if (charValue>='A'&&charValue<='F')
        return 10 + (charValue-'A');
    static char error_message[]="Charater \'X\' not a hexidecimal number";
     error_message[10]=charValue;
    //not thread safe--but you'll get at least one of the error messages
    throw std::invalid_argument(error_message);
    return 0;
}
std::string SHA256::convertToHexString() const {
    std::string retval;
    retval.resize(hex_size);
    for (unsigned int i=0;i<static_size;++i) {
        retval[i*2]=numToHex(mData[i]/16);
        retval[i*2+1]=numToHex(mData[i]%16);
    }
    return retval;
}

Array<char,SHA256::hex_size> SHA256::convertToHex() const {
    Array<char,hex_size> retval;
    for (unsigned int i=0;i<static_size;++i) {
        retval[i*2]=numToHex(mData[i]/16);
        retval[i*2+1]=numToHex(mData[i]%16);
    }
    return retval;
}
SHA256 SHA256::convertFromHex(const char*data){
    SHA256 retval;
    for (unsigned int i=0;i<static_size;++i) {
        retval.mData[i]=numFromHex(data[i*2])*16+numFromHex(data[i*2+1]);
    }
    return retval;
}
SHA256 SHA256::convertFromHex(const std::string&data){
    if (data.length()!=64)
        throw std::invalid_argument("input string was the wrong length for a SHA256 Digest");
    return convertFromHex(data.data());
}
SHA256 SHA256::computeDigest(const void*data, size_t length) {
    SHA256 retval;
    Iridium::Util::Internal::SHA256_CTX context;
    Iridium::Util::Internal::SHA256_Init(&context);
    Iridium::Util::Internal::SHA256_Update(&context, (const unsigned char*)data, length);
    Iridium::Util::Internal::SHA256_Final(retval.mData.data(), &context);
    return retval;
}
SHA256 SHA256::computeDigest(const std::string&data) {
    SHA256 retval;
    Iridium::Util::Internal::SHA256_CTX context;
    Iridium::Util::Internal::SHA256_Init(&context);
    Iridium::Util::Internal::SHA256_Update(&context, (const unsigned char*)data.data(), data.length());
    Iridium::Util::Internal::SHA256_Final(retval.mData.data(), &context);
    return retval;
}
}
<commit_msg>needs iostream to build in release<commit_after>/*     Iridium Utilities -- Iridium Cryptography Utilities
 *  Sha256.cpp
 *
 *  Copyright (c) 2009, Daniel Reiter Horn
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of Iridium nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "Sha256.hpp"
#include "internal_sha2.hpp"
#include <stdexcept>
#include <iostream>
namespace Iridium {
static unsigned char numToHex(unsigned int num) {
    if (num<10)
        return num+'0';
    if (num<16)
        return (num-10)+'a';
    return 'x';
}
static unsigned int numFromHex(unsigned char charValue) {
    if (charValue>='0'&&charValue<='9')
        return charValue-'0';
    if (charValue>='a'&&charValue<='f')
        return 10 + (charValue-'a');
    if (charValue>='A'&&charValue<='F')
        return 10 + (charValue-'A');
    static char error_message[]="Charater \'X\' not a hexidecimal number";
     error_message[10]=charValue;
    //not thread safe--but you'll get at least one of the error messages
    throw std::invalid_argument(error_message);
    return 0;
}
std::string SHA256::convertToHexString() const {
    std::string retval;
    retval.resize(hex_size);
    for (unsigned int i=0;i<static_size;++i) {
        retval[i*2]=numToHex(mData[i]/16);
        retval[i*2+1]=numToHex(mData[i]%16);
    }
    return retval;
}

Array<char,SHA256::hex_size> SHA256::convertToHex() const {
    Array<char,hex_size> retval;
    for (unsigned int i=0;i<static_size;++i) {
        retval[i*2]=numToHex(mData[i]/16);
        retval[i*2+1]=numToHex(mData[i]%16);
    }
    return retval;
}
SHA256 SHA256::convertFromHex(const char*data){
    SHA256 retval;
    for (unsigned int i=0;i<static_size;++i) {
        retval.mData[i]=numFromHex(data[i*2])*16+numFromHex(data[i*2+1]);
    }
    return retval;
}
SHA256 SHA256::convertFromHex(const std::string&data){
    if (data.length()!=64)
        throw std::invalid_argument("input string was the wrong length for a SHA256 Digest");
    return convertFromHex(data.data());
}
SHA256 SHA256::computeDigest(const void*data, size_t length) {
    SHA256 retval;
    Iridium::Util::Internal::SHA256_CTX context;
    Iridium::Util::Internal::SHA256_Init(&context);
    Iridium::Util::Internal::SHA256_Update(&context, (const unsigned char*)data, length);
    Iridium::Util::Internal::SHA256_Final(retval.mData.data(), &context);
    return retval;
}
SHA256 SHA256::computeDigest(const std::string&data) {
    SHA256 retval;
    Iridium::Util::Internal::SHA256_CTX context;
    Iridium::Util::Internal::SHA256_Init(&context);
    Iridium::Util::Internal::SHA256_Update(&context, (const unsigned char*)data.data(), data.length());
    Iridium::Util::Internal::SHA256_Final(retval.mData.data(), &context);
    return retval;
}
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.6  2000/02/08 00:59:19  roddey
 * Support for new intrinsic encoder for IBM-1047 code page.
 *
 * Revision 1.5  2000/02/06 07:48:06  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.4  2000/01/12 20:44:50  roddey
 * Ooops, I checked in the URL.cpp file with a L"localhost" style string in it. This is not legal for
 * some of our compilers, so a new string was added XMLUni and used in its place.
 *
 * Revision 1.3  1999/12/18 00:18:10  roddey
 * More changes to support the new, completely orthagonal support for
 * intrinsic encodings.
 *
 * Revision 1.2  1999/12/15 19:41:29  roddey
 * Support for the new transcoder system, where even intrinsic encodings are
 * done via the same transcoder abstraction as external ones.
 *
 * Revision 1.1.1.1  1999/11/09 01:05:56  twl
 * Initial checkin
 *
 * Revision 1.4  1999/11/08 20:45:21  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
//  This file contains the grunt work constants for Unicode characters and
//  common Unicode constant strings. These cannot be created normally because
//  we have to compile on systems that cannot do the L"" style prefix. So
//  they must be created as constant values for Unicode code points and the
//  strings built up as arrays of those constants.
// ---------------------------------------------------------------------------

#if !defined(XMLUNI_HPP)
#define XMLUNI_HPP

#include <util/XML4CDefs.hpp>

// ---------------------------------------------------------------------------
//  Constants for the Unicode characters of interest to us in an XML parser
//  We don't put these inside the class because then they could not be const
//  inline values, which would have significant performance ramifications.
//
//  We cannot use a namespace because of the requirement to support old
//  compilers.
// ---------------------------------------------------------------------------
const XMLCh chNull                  = 0x00;
const XMLCh chHTab                  = 0x09;
const XMLCh chLF                    = 0x0A;
const XMLCh chCR                    = 0x0D;
const XMLCh chAmpersand             = 0x26;
const XMLCh chAsterisk              = 0x2A;
const XMLCh chAt                    = 0x40;
const XMLCh chBackSlash             = 0x5C;
const XMLCh chBang                  = 0x21;
const XMLCh chCloseAngle            = 0x3E;
const XMLCh chCloseCurly            = 0x7D;
const XMLCh chCloseParen            = 0x29;
const XMLCh chCloseSquare           = 0x5D;
const XMLCh chColon                 = 0x3A;
const XMLCh chComma                 = 0x2C;
const XMLCh chDash                  = 0x2D;
const XMLCh chDollarSign            = 0x24;
const XMLCh chDoubleQuote           = 0x22;
const XMLCh chEqual                 = 0x3D;
const XMLCh chForwardSlash          = 0x2F;
const XMLCh chGrave                 = 0x60;
const XMLCh chOpenAngle             = 0x3C;
const XMLCh chOpenCurly             = 0x7B;
const XMLCh chOpenParen             = 0x28;
const XMLCh chOpenSquare            = 0x5B;
const XMLCh chPercent               = 0x25;
const XMLCh chPeriod                = 0x2E;
const XMLCh chPipe                  = 0x7C;
const XMLCh chPlus                  = 0x2B;
const XMLCh chPound                 = 0x23;
const XMLCh chQuestion              = 0x3F;
const XMLCh chSingleQuote           = 0x27;
const XMLCh chSpace                 = 0x20;
const XMLCh chSemiColon             = 0x3B;
const XMLCh chTilde                 = 0x7E;
const XMLCh chUnderscore            = 0x5F;

const XMLCh chSwappedUnicodeMarker  = XMLCh(0xFFFE);
const XMLCh chUnicodeMarker         = XMLCh(0xFEFF);

const XMLCh chDigit_0               = 0x30;
const XMLCh chDigit_1               = 0x31;
const XMLCh chDigit_2               = 0x32;
const XMLCh chDigit_3               = 0x33;
const XMLCh chDigit_4               = 0x34;
const XMLCh chDigit_5               = 0x35;
const XMLCh chDigit_6               = 0x36;
const XMLCh chDigit_7               = 0x37;
const XMLCh chDigit_8               = 0x38;
const XMLCh chDigit_9               = 0x39;

const XMLCh chLatin_A               = 0x41;
const XMLCh chLatin_B               = 0x42;
const XMLCh chLatin_C               = 0x43;
const XMLCh chLatin_D               = 0x44;
const XMLCh chLatin_E               = 0x45;
const XMLCh chLatin_F               = 0x46;
const XMLCh chLatin_G               = 0x47;
const XMLCh chLatin_H               = 0x48;
const XMLCh chLatin_I               = 0x49;
const XMLCh chLatin_J               = 0x4A;
const XMLCh chLatin_K               = 0x4B;
const XMLCh chLatin_L               = 0x4C;
const XMLCh chLatin_M               = 0x4D;
const XMLCh chLatin_N               = 0x4E;
const XMLCh chLatin_O               = 0x4F;
const XMLCh chLatin_P               = 0x50;
const XMLCh chLatin_Q               = 0x51;
const XMLCh chLatin_R               = 0x52;
const XMLCh chLatin_S               = 0x53;
const XMLCh chLatin_T               = 0x54;
const XMLCh chLatin_U               = 0x55;
const XMLCh chLatin_V               = 0x56;
const XMLCh chLatin_W               = 0x57;
const XMLCh chLatin_X               = 0x58;
const XMLCh chLatin_Y               = 0x59;
const XMLCh chLatin_Z               = 0x5A;

const XMLCh chLatin_a               = 0x61;
const XMLCh chLatin_b               = 0x62;
const XMLCh chLatin_c               = 0x63;
const XMLCh chLatin_d               = 0x64;
const XMLCh chLatin_e               = 0x65;
const XMLCh chLatin_f               = 0x66;
const XMLCh chLatin_g               = 0x67;
const XMLCh chLatin_h               = 0x68;
const XMLCh chLatin_i               = 0x69;
const XMLCh chLatin_j               = 0x6A;
const XMLCh chLatin_k               = 0x6B;
const XMLCh chLatin_l               = 0x6C;
const XMLCh chLatin_m               = 0x6D;
const XMLCh chLatin_n               = 0x6E;
const XMLCh chLatin_o               = 0x6F;
const XMLCh chLatin_p               = 0x70;
const XMLCh chLatin_q               = 0x71;
const XMLCh chLatin_r               = 0x72;
const XMLCh chLatin_s               = 0x73;
const XMLCh chLatin_t               = 0x74;
const XMLCh chLatin_u               = 0x75;
const XMLCh chLatin_v               = 0x76;
const XMLCh chLatin_w               = 0x77;
const XMLCh chLatin_x               = 0x78;
const XMLCh chLatin_y               = 0x79;
const XMLCh chLatin_z               = 0x7A;

class XMLUTIL_EXPORT XMLUni
{
public :
    // -----------------------------------------------------------------------
    //  These are constant strings that are common in XML data. Because
    //  of the limitation of the compilers we have to work with, these are
    //  done as arrays of XMLCh characters, not as constant strings.
    // -----------------------------------------------------------------------
    static const XMLCh fgAnyString[];
    static const XMLCh fgAttListString[];
    static const XMLCh fgCommentString[];
    static const XMLCh fgCDATAString[];
    static const XMLCh fgDefaultString[];
    static const XMLCh fgDocTypeString[];
    static const XMLCh fgDefaultEBCDICEncodingString[];
    static const XMLCh fgEBCDICEncodingString[];
    static const XMLCh fgEBCDICEncodingString2[];
    static const XMLCh fgElemString[];
    static const XMLCh fgEmptyString[];
    static const XMLCh fgEncodingString[];
    static const XMLCh fgEntitString[];
    static const XMLCh fgEntityString[];
    static const XMLCh fgEntitiesString[];
    static const XMLCh fgEnumerationString[];
    static const XMLCh fgExceptDomain[];
    static const XMLCh fgFixedString[];
    static const XMLCh fgGlobalNSURIName[];
    static const XMLCh fgIBM037EncodingString[];
    static const XMLCh fgIBM1047EncodingString[];
    static const XMLCh fgIESString[];
    static const XMLCh fgIDString[];
    static const XMLCh fgIDRefString[];
    static const XMLCh fgIDRefsString[];
    static const XMLCh fgImpliedString[];
    static const XMLCh fgIgnoreString[];
    static const XMLCh fgIncludeString[];
    static const XMLCh fgISO88591EncodingString[];
    static const XMLCh fgISO88591EncodingString2[];
    static const XMLCh fgISO88591EncodingString3[];
    static const XMLCh fgISO88591EncodingString4[];
    static const XMLCh fgISO88591EncodingString5[];
    static const XMLCh fgISO88591EncodingString6[];
    static const XMLCh fgISO88591EncodingString7[];
    static const XMLCh fgISO88591EncodingString8[];
    static const XMLCh fgLocalHostString[];
    static const XMLCh fgNoString[];
    static const XMLCh fgNotationString[];
    static const XMLCh fgNDATAString[];
    static const XMLCh fgNmTokenString[];
    static const XMLCh fgNmTokensString[];
    static const XMLCh fgOtherEncodingStr[];
    static const XMLCh fgPCDATAString[];
    static const XMLCh fgPIString[];
    static const XMLCh fgPubIDString[];
    static const XMLCh fgRefString[];
    static const XMLCh fgRequiredString[];
    static const XMLCh fgStandaloneString[];
    static const XMLCh fgSupportedVersion[];
    static const XMLCh fgSysIDString[];
    static const XMLCh fgUnknownURIName[];
    static const XMLCh fgUCS4EncodingString[];
    static const XMLCh fgUCS4EncodingString2[];
    static const XMLCh fgUCS4EncodingString3[];
    static const XMLCh fgUCS4BEncodingString[];
    static const XMLCh fgUCS4BEncodingString2[];
    static const XMLCh fgUCS4LEncodingString[];
    static const XMLCh fgUCS4LEncodingString2[];
    static const XMLCh fgUSASCIIEncodingString[];
    static const XMLCh fgUSASCIIEncodingString2[];
    static const XMLCh fgUSASCIIEncodingString3[];
    static const XMLCh fgUSASCIIEncodingString4[];
    static const XMLCh fgUTF8EncodingString[];
    static const XMLCh fgUTF8EncodingString2[];
    static const XMLCh fgUTF16EncodingString[];
    static const XMLCh fgUTF16EncodingString2[];
    static const XMLCh fgUTF16EncodingString3[];
    static const XMLCh fgUTF16EncodingString4[];
    static const XMLCh fgUTF16BEncodingString[];
    static const XMLCh fgUTF16BEncodingString2[];
    static const XMLCh fgUTF16LEncodingString[];
    static const XMLCh fgUTF16LEncodingString2[];
    static const XMLCh fgVersionString[];
    static const XMLCh fgValidityDomain[];
    static const XMLCh fgXMLDeclString[];
    static const XMLCh fgXMLString[];
    static const XMLCh fgXMLStringSpace[];
    static const XMLCh fgXMLStringSpaceU[];
    static const XMLCh fgXMLDeclStringSpace[];
    static const XMLCh fgXMLNSString[];
    static const XMLCh fgXMLNSColonString[];
    static const XMLCh fgXMLNSURIName[];
    static const XMLCh fgXMLErrDomain[];
    static const XMLCh fgXMLURIName[];
    static const XMLCh fgYesString[];
    static const XMLCh fgZeroLenString[];
};

#endif
<commit_msg>Removed fgOtherEncodingStr<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.7  2000/02/09 23:06:03  abagchi
 * Removed fgOtherEncodingStr
 *
 * Revision 1.6  2000/02/08 00:59:19  roddey
 * Support for new intrinsic encoder for IBM-1047 code page.
 *
 * Revision 1.5  2000/02/06 07:48:06  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.4  2000/01/12 20:44:50  roddey
 * Ooops, I checked in the URL.cpp file with a L"localhost" style string in it. This is not legal for
 * some of our compilers, so a new string was added XMLUni and used in its place.
 *
 * Revision 1.3  1999/12/18 00:18:10  roddey
 * More changes to support the new, completely orthagonal support for
 * intrinsic encodings.
 *
 * Revision 1.2  1999/12/15 19:41:29  roddey
 * Support for the new transcoder system, where even intrinsic encodings are
 * done via the same transcoder abstraction as external ones.
 *
 * Revision 1.1.1.1  1999/11/09 01:05:56  twl
 * Initial checkin
 *
 * Revision 1.4  1999/11/08 20:45:21  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
//  This file contains the grunt work constants for Unicode characters and
//  common Unicode constant strings. These cannot be created normally because
//  we have to compile on systems that cannot do the L"" style prefix. So
//  they must be created as constant values for Unicode code points and the
//  strings built up as arrays of those constants.
// ---------------------------------------------------------------------------

#if !defined(XMLUNI_HPP)
#define XMLUNI_HPP

#include <util/XML4CDefs.hpp>

// ---------------------------------------------------------------------------
//  Constants for the Unicode characters of interest to us in an XML parser
//  We don't put these inside the class because then they could not be const
//  inline values, which would have significant performance ramifications.
//
//  We cannot use a namespace because of the requirement to support old
//  compilers.
// ---------------------------------------------------------------------------
const XMLCh chNull                  = 0x00;
const XMLCh chHTab                  = 0x09;
const XMLCh chLF                    = 0x0A;
const XMLCh chCR                    = 0x0D;
const XMLCh chAmpersand             = 0x26;
const XMLCh chAsterisk              = 0x2A;
const XMLCh chAt                    = 0x40;
const XMLCh chBackSlash             = 0x5C;
const XMLCh chBang                  = 0x21;
const XMLCh chCloseAngle            = 0x3E;
const XMLCh chCloseCurly            = 0x7D;
const XMLCh chCloseParen            = 0x29;
const XMLCh chCloseSquare           = 0x5D;
const XMLCh chColon                 = 0x3A;
const XMLCh chComma                 = 0x2C;
const XMLCh chDash                  = 0x2D;
const XMLCh chDollarSign            = 0x24;
const XMLCh chDoubleQuote           = 0x22;
const XMLCh chEqual                 = 0x3D;
const XMLCh chForwardSlash          = 0x2F;
const XMLCh chGrave                 = 0x60;
const XMLCh chOpenAngle             = 0x3C;
const XMLCh chOpenCurly             = 0x7B;
const XMLCh chOpenParen             = 0x28;
const XMLCh chOpenSquare            = 0x5B;
const XMLCh chPercent               = 0x25;
const XMLCh chPeriod                = 0x2E;
const XMLCh chPipe                  = 0x7C;
const XMLCh chPlus                  = 0x2B;
const XMLCh chPound                 = 0x23;
const XMLCh chQuestion              = 0x3F;
const XMLCh chSingleQuote           = 0x27;
const XMLCh chSpace                 = 0x20;
const XMLCh chSemiColon             = 0x3B;
const XMLCh chTilde                 = 0x7E;
const XMLCh chUnderscore            = 0x5F;

const XMLCh chSwappedUnicodeMarker  = XMLCh(0xFFFE);
const XMLCh chUnicodeMarker         = XMLCh(0xFEFF);

const XMLCh chDigit_0               = 0x30;
const XMLCh chDigit_1               = 0x31;
const XMLCh chDigit_2               = 0x32;
const XMLCh chDigit_3               = 0x33;
const XMLCh chDigit_4               = 0x34;
const XMLCh chDigit_5               = 0x35;
const XMLCh chDigit_6               = 0x36;
const XMLCh chDigit_7               = 0x37;
const XMLCh chDigit_8               = 0x38;
const XMLCh chDigit_9               = 0x39;

const XMLCh chLatin_A               = 0x41;
const XMLCh chLatin_B               = 0x42;
const XMLCh chLatin_C               = 0x43;
const XMLCh chLatin_D               = 0x44;
const XMLCh chLatin_E               = 0x45;
const XMLCh chLatin_F               = 0x46;
const XMLCh chLatin_G               = 0x47;
const XMLCh chLatin_H               = 0x48;
const XMLCh chLatin_I               = 0x49;
const XMLCh chLatin_J               = 0x4A;
const XMLCh chLatin_K               = 0x4B;
const XMLCh chLatin_L               = 0x4C;
const XMLCh chLatin_M               = 0x4D;
const XMLCh chLatin_N               = 0x4E;
const XMLCh chLatin_O               = 0x4F;
const XMLCh chLatin_P               = 0x50;
const XMLCh chLatin_Q               = 0x51;
const XMLCh chLatin_R               = 0x52;
const XMLCh chLatin_S               = 0x53;
const XMLCh chLatin_T               = 0x54;
const XMLCh chLatin_U               = 0x55;
const XMLCh chLatin_V               = 0x56;
const XMLCh chLatin_W               = 0x57;
const XMLCh chLatin_X               = 0x58;
const XMLCh chLatin_Y               = 0x59;
const XMLCh chLatin_Z               = 0x5A;

const XMLCh chLatin_a               = 0x61;
const XMLCh chLatin_b               = 0x62;
const XMLCh chLatin_c               = 0x63;
const XMLCh chLatin_d               = 0x64;
const XMLCh chLatin_e               = 0x65;
const XMLCh chLatin_f               = 0x66;
const XMLCh chLatin_g               = 0x67;
const XMLCh chLatin_h               = 0x68;
const XMLCh chLatin_i               = 0x69;
const XMLCh chLatin_j               = 0x6A;
const XMLCh chLatin_k               = 0x6B;
const XMLCh chLatin_l               = 0x6C;
const XMLCh chLatin_m               = 0x6D;
const XMLCh chLatin_n               = 0x6E;
const XMLCh chLatin_o               = 0x6F;
const XMLCh chLatin_p               = 0x70;
const XMLCh chLatin_q               = 0x71;
const XMLCh chLatin_r               = 0x72;
const XMLCh chLatin_s               = 0x73;
const XMLCh chLatin_t               = 0x74;
const XMLCh chLatin_u               = 0x75;
const XMLCh chLatin_v               = 0x76;
const XMLCh chLatin_w               = 0x77;
const XMLCh chLatin_x               = 0x78;
const XMLCh chLatin_y               = 0x79;
const XMLCh chLatin_z               = 0x7A;

class XMLUTIL_EXPORT XMLUni
{
public :
    // -----------------------------------------------------------------------
    //  These are constant strings that are common in XML data. Because
    //  of the limitation of the compilers we have to work with, these are
    //  done as arrays of XMLCh characters, not as constant strings.
    // -----------------------------------------------------------------------
    static const XMLCh fgAnyString[];
    static const XMLCh fgAttListString[];
    static const XMLCh fgCommentString[];
    static const XMLCh fgCDATAString[];
    static const XMLCh fgDefaultString[];
    static const XMLCh fgDocTypeString[];
    static const XMLCh fgDefaultEBCDICEncodingString[];
    static const XMLCh fgEBCDICEncodingString[];
    static const XMLCh fgEBCDICEncodingString2[];
    static const XMLCh fgElemString[];
    static const XMLCh fgEmptyString[];
    static const XMLCh fgEncodingString[];
    static const XMLCh fgEntitString[];
    static const XMLCh fgEntityString[];
    static const XMLCh fgEntitiesString[];
    static const XMLCh fgEnumerationString[];
    static const XMLCh fgExceptDomain[];
    static const XMLCh fgFixedString[];
    static const XMLCh fgGlobalNSURIName[];
    static const XMLCh fgIBM037EncodingString[];
    static const XMLCh fgIBM1047EncodingString[];
    static const XMLCh fgIESString[];
    static const XMLCh fgIDString[];
    static const XMLCh fgIDRefString[];
    static const XMLCh fgIDRefsString[];
    static const XMLCh fgImpliedString[];
    static const XMLCh fgIgnoreString[];
    static const XMLCh fgIncludeString[];
    static const XMLCh fgISO88591EncodingString[];
    static const XMLCh fgISO88591EncodingString2[];
    static const XMLCh fgISO88591EncodingString3[];
    static const XMLCh fgISO88591EncodingString4[];
    static const XMLCh fgISO88591EncodingString5[];
    static const XMLCh fgISO88591EncodingString6[];
    static const XMLCh fgISO88591EncodingString7[];
    static const XMLCh fgISO88591EncodingString8[];
    static const XMLCh fgLocalHostString[];
    static const XMLCh fgNoString[];
    static const XMLCh fgNotationString[];
    static const XMLCh fgNDATAString[];
    static const XMLCh fgNmTokenString[];
    static const XMLCh fgNmTokensString[];
    static const XMLCh fgPCDATAString[];
    static const XMLCh fgPIString[];
    static const XMLCh fgPubIDString[];
    static const XMLCh fgRefString[];
    static const XMLCh fgRequiredString[];
    static const XMLCh fgStandaloneString[];
    static const XMLCh fgSupportedVersion[];
    static const XMLCh fgSysIDString[];
    static const XMLCh fgUnknownURIName[];
    static const XMLCh fgUCS4EncodingString[];
    static const XMLCh fgUCS4EncodingString2[];
    static const XMLCh fgUCS4EncodingString3[];
    static const XMLCh fgUCS4BEncodingString[];
    static const XMLCh fgUCS4BEncodingString2[];
    static const XMLCh fgUCS4LEncodingString[];
    static const XMLCh fgUCS4LEncodingString2[];
    static const XMLCh fgUSASCIIEncodingString[];
    static const XMLCh fgUSASCIIEncodingString2[];
    static const XMLCh fgUSASCIIEncodingString3[];
    static const XMLCh fgUSASCIIEncodingString4[];
    static const XMLCh fgUTF8EncodingString[];
    static const XMLCh fgUTF8EncodingString2[];
    static const XMLCh fgUTF16EncodingString[];
    static const XMLCh fgUTF16EncodingString2[];
    static const XMLCh fgUTF16EncodingString3[];
    static const XMLCh fgUTF16EncodingString4[];
    static const XMLCh fgUTF16BEncodingString[];
    static const XMLCh fgUTF16BEncodingString2[];
    static const XMLCh fgUTF16LEncodingString[];
    static const XMLCh fgUTF16LEncodingString2[];
    static const XMLCh fgVersionString[];
    static const XMLCh fgValidityDomain[];
    static const XMLCh fgXMLDeclString[];
    static const XMLCh fgXMLString[];
    static const XMLCh fgXMLStringSpace[];
    static const XMLCh fgXMLStringSpaceU[];
    static const XMLCh fgXMLDeclStringSpace[];
    static const XMLCh fgXMLNSString[];
    static const XMLCh fgXMLNSColonString[];
    static const XMLCh fgXMLNSURIName[];
    static const XMLCh fgXMLErrDomain[];
    static const XMLCh fgXMLURIName[];
    static const XMLCh fgYesString[];
    static const XMLCh fgZeroLenString[];
};

#endif
<|endoftext|>


<commit_before>/*
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include <new>
#include <cstdlib>
#include <iostream>
#include "util/exception.h"
#include "util/memory.h"

namespace lean {
void set_max_memory_megabyte(unsigned max) {
    size_t m = max;
    m *= 1024 * 1024;
    set_max_memory(m);
}
}

#if !defined(LEAN_TRACK_MEMORY)
namespace lean {
size_t     get_allocated_memory() {
    return 0;
}

void set_max_memory(size_t) {
    throw exception("Lean was compiled without memory consumption tracking "
                    "(possible solution: compile using LEAN_TRACK_MEMORY)");
}

void check_memory(char const * component_name) {
    // do nothing when LEAN_TRACK_MEMORY is not defined
}

void * malloc(size_t sz, bool use_ex)  {
    void * r = ::malloc(sz);
    if (r || sz == 0)
        return r;
    else if (use_ex)
        throw std::bad_alloc();
    else
        return nullptr;
}

void * malloc(size_t sz) {
    return malloc(sz, true);
}

void * realloc(void * ptr, size_t sz) {
    void * r = ::realloc(ptr, sz);
    if (r || sz == 0)
        return r;
    else
        throw std::bad_alloc();
}

void free(void * ptr) {
    ::free(ptr);
}
}

#else
#include "util/thread.h"

#if defined(HAS_MALLOC_USABLE_SIZE)
#include <malloc.h> // NOLINT
namespace lean {
inline size_t malloc_size(void * ptr)             { return malloc_usable_size(ptr); }
inline void * malloc_core(size_t sz)              { return ::malloc(sz); }
inline void * realloc_core(void * ptr, size_t sz) { return ::realloc(ptr, sz); }
inline void   free_core(void * ptr)               { ::free(ptr); }
}
// REMARK: We commented the following piece of code because tc_malloc_size is hanging

// #elif defined(HAS_TCMALLOC)
// #include <gperftools/tcmalloc.h>
// namespace lean {
// inline size_t malloc_size(void * ptr)             { return tc_malloc_size(ptr); }
// inline void * malloc_core(size_t sz)              { return tc_malloc(sz); }
// inline void * realloc_core(void * ptr, size_t sz) { return tc_realloc(ptr, sz); }
// inline void   free_core(void * ptr)               { tc_free(ptr); }
// }
#elif defined(HAS_MALLOCSIZE)
#include <malloc/malloc.h> // NOLINT
namespace lean {
inline size_t malloc_size(void * ptr)             { return ::malloc_size(ptr); }
inline void * malloc_core(size_t sz)              { return ::malloc(sz); }
inline void * realloc_core(void * ptr, size_t sz) { return ::realloc(ptr, sz); }
inline void   free_core(void * ptr)               { ::free(ptr); }
}
#elif defined(HAS_MSIZE)
#include <malloc.h> // NOLINT
namespace lean {
inline size_t malloc_size(void * ptr)             { return _msize(ptr); }
inline void * malloc_core(size_t sz)              { return ::malloc(sz); }
inline void * realloc_core(void * ptr, size_t sz) { return ::realloc(ptr, sz); }
inline void   free_core(void * ptr)               { ::free(ptr); }
}
#else
namespace lean {
void * save_alloc_size(void * ptr, size_t sz) {
    if (ptr) {
        size_t * r = static_cast<size_t*>(ptr);
        *r = sz;
        return r + 1;
    } else {
        return ptr;
    }
}
inline size_t malloc_size(void * ptr)             { return static_cast<size_t*>(ptr)[-1]; }
inline void * malloc_core(size_t sz)              { return save_alloc_size(::malloc(sz + sizeof(sz)), sz); }
inline void * realloc_core(void * ptr, size_t sz) { return save_alloc_size(::realloc(static_cast<size_t*>(ptr) - 1, sz + sizeof(sz)), sz); }
inline void   free_core(void * ptr)               { ::free(static_cast<size_t*>(ptr) - 1); }
}
#endif

namespace lean {
class alloc_info {
    atomic<size_t> m_size;
public:
    alloc_info():m_size(0) {}
    ~alloc_info() {}
    void inc(size_t sz) { m_size += sz; }
    void dec(size_t sz) { m_size -= sz; }
    size_t size() const { return m_size; }
};

// TODO(Leo): use explicit initialization?
static alloc_info g_global_memory;
static size_t     g_max_memory = 0;

void set_max_memory(size_t max) {
    g_max_memory = max;
}

size_t get_allocated_memory() {
    return g_global_memory.size();
}

void check_memory(char const * component_name) {
    if (g_max_memory != 0 && get_allocated_memory() > g_max_memory)
        throw memory_exception(component_name);
}

void * malloc(size_t sz, bool use_ex)  {
    void * r = malloc_core(sz);
    if (r || sz == 0) {
        size_t rsz = malloc_size(r);
        g_global_memory.inc(rsz);
        return r;
    } else if (use_ex) {
        throw std::bad_alloc();
    } else {
        return nullptr;
    }
}

void * malloc(size_t sz) {
    return malloc(sz, true);
}

void * realloc(void * ptr, size_t sz) {
    if (ptr == nullptr)
        return malloc(sz);
    if (sz == 0) {
        free(ptr);
        return nullptr;
    }
    size_t old_sz = malloc_size(ptr);
    g_global_memory.dec(old_sz);
    void * r = realloc_core(ptr, sz);
    size_t new_sz = malloc_size(r);
    g_global_memory.inc(new_sz);
    if (r || sz == 0)
        return r;
    else
        throw std::bad_alloc();
}

void free(void * ptr) {
    if (ptr) {
        size_t sz = malloc_size(ptr);
        g_global_memory.dec(sz);
    }
    free_core(ptr);
}
}

void* operator new(std::size_t sz) throw(std::bad_alloc) { return lean::malloc(sz, true); }
void  operator delete(void * ptr) throw() { return lean::free(ptr); }
void* operator new[](std::size_t sz) throw(std::bad_alloc) { return lean::malloc(sz, true); }
void  operator delete[](void * ptr) throw() { return lean::free(ptr); }
void* operator new(std::size_t sz, std::nothrow_t const &) noexcept { return lean::malloc(sz, false); }
void* operator new[](std::size_t sz, std::nothrow_t const &) noexcept { return lean::malloc(sz, false); }

#pragma GCC diagnostic ignored "-Wc++14-compat"
void operator delete(void * ptr, size_t _size) throw() { return lean::free(ptr); }
void operator delete[](void * ptr, size_t _size) throw() { return lean::free(ptr); }
#endif
<commit_msg>feat(util/memory.cpp): use COMP_HAS_SIZED_DEALLOCATION macro<commit_after>/*
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include <new>
#include <cstdlib>
#include <iostream>
#include "./compatibility.h"
#include "util/exception.h"
#include "util/memory.h"

namespace lean {
void set_max_memory_megabyte(unsigned max) {
    size_t m = max;
    m *= 1024 * 1024;
    set_max_memory(m);
}
}

#if !defined(LEAN_TRACK_MEMORY)
namespace lean {
size_t     get_allocated_memory() {
    return 0;
}

void set_max_memory(size_t) {
    throw exception("Lean was compiled without memory consumption tracking "
                    "(possible solution: compile using LEAN_TRACK_MEMORY)");
}

void check_memory(char const * component_name) {
    // do nothing when LEAN_TRACK_MEMORY is not defined
}

void * malloc(size_t sz, bool use_ex)  {
    void * r = ::malloc(sz);
    if (r || sz == 0)
        return r;
    else if (use_ex)
        throw std::bad_alloc();
    else
        return nullptr;
}

void * malloc(size_t sz) {
    return malloc(sz, true);
}

void * realloc(void * ptr, size_t sz) {
    void * r = ::realloc(ptr, sz);
    if (r || sz == 0)
        return r;
    else
        throw std::bad_alloc();
}

void free(void * ptr) {
    ::free(ptr);
}
}

#else
#include "util/thread.h"

#if defined(HAS_MALLOC_USABLE_SIZE)
#include <malloc.h> // NOLINT
namespace lean {
inline size_t malloc_size(void * ptr)             { return malloc_usable_size(ptr); }
inline void * malloc_core(size_t sz)              { return ::malloc(sz); }
inline void * realloc_core(void * ptr, size_t sz) { return ::realloc(ptr, sz); }
inline void   free_core(void * ptr)               { ::free(ptr); }
}
// REMARK: We commented the following piece of code because tc_malloc_size is hanging

// #elif defined(HAS_TCMALLOC)
// #include <gperftools/tcmalloc.h>
// namespace lean {
// inline size_t malloc_size(void * ptr)             { return tc_malloc_size(ptr); }
// inline void * malloc_core(size_t sz)              { return tc_malloc(sz); }
// inline void * realloc_core(void * ptr, size_t sz) { return tc_realloc(ptr, sz); }
// inline void   free_core(void * ptr)               { tc_free(ptr); }
// }
#elif defined(HAS_MALLOCSIZE)
#include <malloc/malloc.h> // NOLINT
namespace lean {
inline size_t malloc_size(void * ptr)             { return ::malloc_size(ptr); }
inline void * malloc_core(size_t sz)              { return ::malloc(sz); }
inline void * realloc_core(void * ptr, size_t sz) { return ::realloc(ptr, sz); }
inline void   free_core(void * ptr)               { ::free(ptr); }
}
#elif defined(HAS_MSIZE)
#include <malloc.h> // NOLINT
namespace lean {
inline size_t malloc_size(void * ptr)             { return _msize(ptr); }
inline void * malloc_core(size_t sz)              { return ::malloc(sz); }
inline void * realloc_core(void * ptr, size_t sz) { return ::realloc(ptr, sz); }
inline void   free_core(void * ptr)               { ::free(ptr); }
}
#else
namespace lean {
void * save_alloc_size(void * ptr, size_t sz) {
    if (ptr) {
        size_t * r = static_cast<size_t*>(ptr);
        *r = sz;
        return r + 1;
    } else {
        return ptr;
    }
}
inline size_t malloc_size(void * ptr)             { return static_cast<size_t*>(ptr)[-1]; }
inline void * malloc_core(size_t sz)              { return save_alloc_size(::malloc(sz + sizeof(sz)), sz); }
inline void * realloc_core(void * ptr, size_t sz) { return save_alloc_size(::realloc(static_cast<size_t*>(ptr) - 1, sz + sizeof(sz)), sz); }
inline void   free_core(void * ptr)               { ::free(static_cast<size_t*>(ptr) - 1); }
}
#endif

namespace lean {
class alloc_info {
    atomic<size_t> m_size;
public:
    alloc_info():m_size(0) {}
    ~alloc_info() {}
    void inc(size_t sz) { m_size += sz; }
    void dec(size_t sz) { m_size -= sz; }
    size_t size() const { return m_size; }
};

// TODO(Leo): use explicit initialization?
static alloc_info g_global_memory;
static size_t     g_max_memory = 0;

void set_max_memory(size_t max) {
    g_max_memory = max;
}

size_t get_allocated_memory() {
    return g_global_memory.size();
}

void check_memory(char const * component_name) {
    if (g_max_memory != 0 && get_allocated_memory() > g_max_memory)
        throw memory_exception(component_name);
}

void * malloc(size_t sz, bool use_ex)  {
    void * r = malloc_core(sz);
    if (r || sz == 0) {
        size_t rsz = malloc_size(r);
        g_global_memory.inc(rsz);
        return r;
    } else if (use_ex) {
        throw std::bad_alloc();
    } else {
        return nullptr;
    }
}

void * malloc(size_t sz) {
    return malloc(sz, true);
}

void * realloc(void * ptr, size_t sz) {
    if (ptr == nullptr)
        return malloc(sz);
    if (sz == 0) {
        free(ptr);
        return nullptr;
    }
    size_t old_sz = malloc_size(ptr);
    g_global_memory.dec(old_sz);
    void * r = realloc_core(ptr, sz);
    size_t new_sz = malloc_size(r);
    g_global_memory.inc(new_sz);
    if (r || sz == 0)
        return r;
    else
        throw std::bad_alloc();
}

void free(void * ptr) {
    if (ptr) {
        size_t sz = malloc_size(ptr);
        g_global_memory.dec(sz);
    }
    free_core(ptr);
}
}

void* operator new(std::size_t sz) throw(std::bad_alloc) { return lean::malloc(sz, true); }
void  operator delete(void * ptr) throw() { return lean::free(ptr); }
void* operator new[](std::size_t sz) throw(std::bad_alloc) { return lean::malloc(sz, true); }
void  operator delete[](void * ptr) throw() { return lean::free(ptr); }
void* operator new(std::size_t sz, std::nothrow_t const &) noexcept { return lean::malloc(sz, false); }
void* operator new[](std::size_t sz, std::nothrow_t const &) noexcept { return lean::malloc(sz, false); }

#ifdef COMP_HAS_SIZED_DEALLOCATION
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++14-compat"
void operator delete(void * ptr, size_t) throw() { return lean::free(ptr); }
void operator delete[](void * ptr, size_t) throw() { return lean::free(ptr); }
#pragma GCC diagnostic pop
#endif
#endif
<|endoftext|>