<commit_before>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2010 Arjen Hiemstra <ahiemstra@heimr.nl>
 * Copyright (C) 2010 Keith Rusler <xzekecomax@gmail.com>
 * Copyright (C) 2010 Laszlo Papp <djszapi@archlinux.us>
 *
 * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "newprojectdialogpage.h"

#include "engine/gameproject.h"
#include "engine/scene.h"
#include "engine/game.h"
#include "engine/gameobject.h"
#include "engine/component.h"

#include <KDE/KLocalizedString>
#include <KDE/KIcon>
#include <KDE/KLineEdit>
#include <KDE/KUrlRequester>
#include <KDE/KMessageBox>
#include <KDE/KSqueezedTextLabel>

#include <QtGui/QWidget>
#include <QtGui/QGroupBox>
#include <QtGui/QVBoxLayout>
#include <QtGui/QFormLayout>
#include <QtGui/QLabel>
#include <QtCore/QScopedPointer>

using namespace GluonCreator;

class NewProjectDialogPage::NewProjectDialogPagePrivate
{
    public:
        NewProjectDialogPagePrivate( NewProjectDialogPage* qq )
            : name( 0 )
            , location( 0 )
            , locationValidLabel( 0 )
            , q( qq )
        {
        }

    public:
        KLineEdit* name;
        KUrlRequester* location;
        KSqueezedTextLabel *locationValidLabel;

    private:
        NewProjectDialogPage* q;
};

NewProjectDialogPage::NewProjectDialogPage()
    : KPageWidgetItem( new QWidget, i18n( "New Project" ) ),
      d( new NewProjectDialogPagePrivate( this ) )
{
    setIcon( KIcon( "document-new" ) );

    QVBoxLayout* layout = new QVBoxLayout( widget() );
    QGroupBox* box = new QGroupBox( i18n( "General Information" ), widget() );

    widget()->setLayout( layout );
    layout->addWidget( box );

    QFormLayout* boxLayout = new QFormLayout( box );
    box->setLayout( boxLayout );

    d->name = new KLineEdit( box );
    d->name->setPlaceholderText( i18n( "Enter the name for a new game project" ) );
    boxLayout->addRow( i18n( "Project Name" ), d->name );

    d->location = new KUrlRequester( box );
    d->location->setMode( KFile::Directory );
    QFileInfo locInfo(QDir::currentPath());
    if( locInfo.isWritable() )
        d->location->setUrl( KUrl( QDir::current().absolutePath() ) );
    else
        d->location->setUrl( KUrl( QDir::homePath() ) );
    boxLayout->addRow( i18n( "Project Location" ), d->location );

    d->locationValidLabel = new KSqueezedTextLabel( box );
    boxLayout->addRow( QString(), d->locationValidLabel );

    connect( d->location->lineEdit(), SIGNAL(textEdited(const QString&)), SLOT(urlEdited() ));

}

NewProjectDialogPage::~NewProjectDialogPage()
{
    delete d;
}

QString NewProjectDialogPage::createProject() const
{
    if( d->name->text().isEmpty() || d->location->url().isEmpty() )
    {
        KMessageBox::error( 0, i18n( "You need to enter a name and location to continue" ) );
        return QString();
    }

    QScopedPointer<GluonEngine::GameProject> project( new GluonEngine::GameProject( GluonEngine::Game::instance() ) );
    if( project.isNull() )
    {
        return QString();
    }

    project->setName( d->name->text() );

    GluonEngine::Scene* root = new GluonEngine::Scene( project.data() );
    root->setName( i18n( "New Scene" ) );
    root->savableDirty = true;

    project->addChild( root );
    project->setEntryPoint( root );

    GluonEngine::GameObject* camera = new GluonEngine::GameObject( root );
    camera->setName( i18n( "Camera" ) );
    camera->setPosition( 0.0f, 0.0f, 50.0f );
    root->sceneContents()->addChild( camera );

    GluonCore::GluonObject* cameraController =
        GluonCore::GluonObjectFactory::instance()->instantiateObjectByName( "GluonEngine::CameraControllerComponent" );
    cameraController->setName( "CameraController" );
    camera->addComponent( qobject_cast<GluonEngine::Component*>( cameraController ) );

    GluonEngine::GameObject* sprite = new GluonEngine::GameObject( root );
    sprite->setName( i18n( "Sprite" ) );
    sprite->setScale( 10.f, 10.f, 0.f );
    root->sceneContents()->addChild( sprite );

    GluonCore::GluonObject* spriteComponent =
        GluonCore::GluonObjectFactory::instance()->instantiateObjectByName( "GluonEngine::SpriteRendererComponent" );
	spriteComponent->setName( "SpriteRenderer" );
	sprite->addComponent( qobject_cast<GluonEngine::Component*>( spriteComponent ) );

	KUrl location = d->location->url();
	QString gameBundleDir = project->fullyQualifiedFileName() + GluonEngine::projectSuffix;
	location.addPath( gameBundleDir );
	project->setDirname( location );
	location.addPath( GluonEngine::projectFilename );
	project->setFilename( location );

	KUrl currentLocation = d->location->url();
	currentLocation.addPath( gameBundleDir );
	QDir dir = QDir(d->location->text());
	dir.mkpath( gameBundleDir );
	QDir::setCurrent( currentLocation.toLocalFile() );
	project->saveToFile();

	return location.toLocalFile();
}

void NewProjectDialogPage::urlEdited()
{
    validateData();
}

void NewProjectDialogPage::setForeground(QLabel* label, KColorScheme::ForegroundRole role)
{
    QPalette p = label->palette();
    KColorScheme::adjustForeground(p, role, label->foregroundRole(), KColorScheme::Window);
    label->setPalette(p);
}

void NewProjectDialogPage::validateData()
{
    KUrl url = d->location->url();
    if( !url.isLocalFile() || url.isEmpty() )
    {
        d->locationValidLabel->setText( i18n("Invalid location") );
        setForeground(d->locationValidLabel, KColorScheme::NegativeText);
        emit validationFinished( false );
        return;
    }

    QString appName = d->name->text();

    if( appName.isEmpty() )
    {
        d->locationValidLabel->setText( i18n("Empty project name") );
        setForeground(d->locationValidLabel, KColorScheme::NegativeText);
        emit validationFinished( false );
        return;
    }

    if( appName == "." || appName == "..")
    {
        d->locationValidLabel->setText( i18n("Invalid project name") );
        setForeground(d->locationValidLabel, KColorScheme::NegativeText);
        emit validationFinished( false );
        return;
    }

    QDir tDir(url.toLocalFile( KUrl::RemoveTrailingSlash ));
    while (!tDir.exists() && !tDir.isRoot())
        tDir.setPath( pathUp( tDir.absolutePath() ));

    if (tDir.exists())
    {
        QFileInfo tFileInfo(tDir.absolutePath());
        if (!tFileInfo.isWritable() || !tFileInfo.isExecutable())
        {
            d->locationValidLabel->setText( i18n("Unable to create subdirectories, "
                                                  "missing permissions on: %1", tDir.absolutePath()) );
            setForeground(d->locationValidLabel, KColorScheme::NegativeText);
            emit validationFinished( false );
            return;
        }
    }

    d->locationValidLabel->setText( QString(" ") );
    setForeground(d->locationValidLabel, KColorScheme::NormalText);
    emit validationFinished( true );

    // Check for non-empty target directory. Not an error, but need to display a warning.
    url.addPath( encodedAppName() );
    QFileInfo fi( url.toLocalFile( KUrl::RemoveTrailingSlash ) );
    if( fi.exists() && fi.isDir() )
    {
        if( !QDir( fi.absoluteFilePath()).entryList( QDir::NoDotAndDotDot | QDir::AllEntries ).isEmpty() )
        {
            d->locationValidLabel->setText( i18n("Path already exists and contains files") );
            setForeground(d->locationValidLabel, KColorScheme::NegativeText);
        }
    }
}

bool NewProjectDialogPage::isModified() const
{
    return ( !d->name->text().isEmpty() || !d->location->url().isEmpty() );
}

QByteArray NewProjectDialogPage::encodedAppName()
{
    // : < > * ? / \ | " are invalid on windows
    QByteArray tEncodedName = d->name->text().toUtf8();
    for (int i = 0; i < tEncodedName.size(); ++i)
    {
        QChar tChar(tEncodedName.at( i ));
        if (tChar.isDigit() || tChar.isSpace() || tChar.isLetter() || tChar == '%')
            continue;

        QByteArray tReplace = QUrl::toPercentEncoding( tChar );
        tEncodedName.replace( tEncodedName.at( i ) ,tReplace );
        i =  i + tReplace.size() - 1;
    }
    return tEncodedName;
}

QString NewProjectDialogPage::pathUp(const QString& aPath)
{
    QString tPath = aPath;
    int tIndex = tPath.lastIndexOf( QDir::separator() );
    tPath = tPath.remove(tIndex, tPath.length() - tIndex);
    return tPath;
}

<commit_msg>Add Scenes, Assets, Prefabs folders by default.<commit_after>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2010 Arjen Hiemstra <ahiemstra@heimr.nl>
 * Copyright (C) 2010 Keith Rusler <xzekecomax@gmail.com>
 * Copyright (C) 2010 Laszlo Papp <djszapi@archlinux.us>
 *
 * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "newprojectdialogpage.h"

#include "core/gluon_global.h"
#include "engine/gameproject.h"
#include "engine/scene.h"
#include "engine/game.h"
#include "engine/gameobject.h"
#include "engine/component.h"

#include <KDE/KLocalizedString>
#include <KDE/KIcon>
#include <KDE/KLineEdit>
#include <KDE/KUrlRequester>
#include <KDE/KMessageBox>
#include <KDE/KSqueezedTextLabel>

#include <QtGui/QWidget>
#include <QtGui/QGroupBox>
#include <QtGui/QVBoxLayout>
#include <QtGui/QFormLayout>
#include <QtGui/QLabel>
#include <QtCore/QScopedPointer>

using namespace GluonCreator;

class NewProjectDialogPage::NewProjectDialogPagePrivate
{
    public:
        NewProjectDialogPagePrivate( NewProjectDialogPage* qq )
            : name( 0 )
            , location( 0 )
            , locationValidLabel( 0 )
            , q( qq )
        {
        }

    public:
        KLineEdit* name;
        KUrlRequester* location;
        KSqueezedTextLabel *locationValidLabel;

    private:
        NewProjectDialogPage* q;
};

NewProjectDialogPage::NewProjectDialogPage()
    : KPageWidgetItem( new QWidget, i18n( "New Project" ) ),
      d( new NewProjectDialogPagePrivate( this ) )
{
    setIcon( KIcon( "document-new" ) );

    QVBoxLayout* layout = new QVBoxLayout( widget() );
    QGroupBox* box = new QGroupBox( i18n( "General Information" ), widget() );

    widget()->setLayout( layout );
    layout->addWidget( box );

    QFormLayout* boxLayout = new QFormLayout( box );
    box->setLayout( boxLayout );

    d->name = new KLineEdit( box );
    d->name->setPlaceholderText( i18n( "Enter the name for a new game project" ) );
    boxLayout->addRow( i18n( "Project Name" ), d->name );

    d->location = new KUrlRequester( box );
    d->location->setMode( KFile::Directory );
    QFileInfo locInfo(QDir::currentPath());
    if( locInfo.isWritable() )
        d->location->setUrl( KUrl( QDir::current().absolutePath() ) );
    else
        d->location->setUrl( KUrl( QDir::homePath() ) );
    boxLayout->addRow( i18n( "Project Location" ), d->location );

    d->locationValidLabel = new KSqueezedTextLabel( box );
    boxLayout->addRow( QString(), d->locationValidLabel );

    connect( d->location->lineEdit(), SIGNAL(textEdited(const QString&)), SLOT(urlEdited() ));

}

NewProjectDialogPage::~NewProjectDialogPage()
{
    delete d;
}

QString NewProjectDialogPage::createProject() const
{
    if( d->name->text().isEmpty() || d->location->url().isEmpty() )
    {
        KMessageBox::error( 0, i18n( "You need to enter a name and location to continue" ) );
        return QString();
    }

    QScopedPointer<GluonEngine::GameProject> project( new GluonEngine::GameProject( GluonEngine::Game::instance() ) );
    if( project.isNull() )
    {
        return QString();
    }

    project->setName( d->name->text() );

    GluonCore::GluonObject* scenesFolder = new GluonCore::GluonObject("Scenes");

    GluonEngine::Scene* root = new GluonEngine::Scene( project.data() );
    root->setGameProject(project.data());
    root->setName( i18n( "New Scene" ) );
    root->savableDirty = true;

    scenesFolder->addChild(root);
    project->setEntryPoint( root );
    project->addChild(scenesFolder);

    GluonEngine::GameObject* camera = new GluonEngine::GameObject( root );
    camera->setName( i18n( "Camera" ) );
    camera->setPosition( 0.0f, 0.0f, 50.0f );
    root->sceneContents()->addChild( camera );

    GluonCore::GluonObject* cameraController =
        GluonCore::GluonObjectFactory::instance()->instantiateObjectByName( "GluonEngine::CameraControllerComponent" );
    cameraController->setName( "CameraController" );
    camera->addComponent( qobject_cast<GluonEngine::Component*>( cameraController ) );

    GluonEngine::GameObject* sprite = new GluonEngine::GameObject( root );
    sprite->setName( i18n( "Sprite" ) );
    sprite->setScale( 10.f, 10.f, 0.f );
    root->sceneContents()->addChild( sprite );

    GluonCore::GluonObject* spriteComponent =
    GluonCore::GluonObjectFactory::instance()->instantiateObjectByName( "GluonEngine::SpriteRendererComponent" );
    spriteComponent->setName( "SpriteRenderer" );
    sprite->addComponent( qobject_cast<GluonEngine::Component*>( spriteComponent ) );

    project->addChild(new GluonCore::GluonObject("Assets"));
    project->addChild(new GluonCore::GluonObject("Prefabs"));

    KUrl location = d->location->url();
    QString gameBundleDir = project->name().toLower().replace(GluonCore::Global::filenameFilter(), "") + GluonEngine::projectSuffix;
    location.addPath( gameBundleDir );
    project->setDirname( location );
    location.addPath( GluonEngine::projectFilename );
    project->setFilename( location );

    KUrl currentLocation = d->location->url();
    currentLocation.addPath( gameBundleDir );
    QDir dir = QDir(d->location->text());
    dir.mkpath( gameBundleDir );
    QDir::setCurrent( currentLocation.toLocalFile() );
    project->saveToFile();

    return location.toLocalFile();
}

void NewProjectDialogPage::urlEdited()
{
    validateData();
}

void NewProjectDialogPage::setForeground(QLabel* label, KColorScheme::ForegroundRole role)
{
    QPalette p = label->palette();
    KColorScheme::adjustForeground(p, role, label->foregroundRole(), KColorScheme::Window);
    label->setPalette(p);
}

void NewProjectDialogPage::validateData()
{
    KUrl url = d->location->url();
    if( !url.isLocalFile() || url.isEmpty() )
    {
        d->locationValidLabel->setText( i18n("Invalid location") );
        setForeground(d->locationValidLabel, KColorScheme::NegativeText);
        emit validationFinished( false );
        return;
    }

    QString appName = d->name->text();

    if( appName.isEmpty() )
    {
        d->locationValidLabel->setText( i18n("Empty project name") );
        setForeground(d->locationValidLabel, KColorScheme::NegativeText);
        emit validationFinished( false );
        return;
    }

    if( appName == "." || appName == "..")
    {
        d->locationValidLabel->setText( i18n("Invalid project name") );
        setForeground(d->locationValidLabel, KColorScheme::NegativeText);
        emit validationFinished( false );
        return;
    }

    QDir tDir(url.toLocalFile( KUrl::RemoveTrailingSlash ));
    while (!tDir.exists() && !tDir.isRoot())
        tDir.setPath( pathUp( tDir.absolutePath() ));

    if (tDir.exists())
    {
        QFileInfo tFileInfo(tDir.absolutePath());
        if (!tFileInfo.isWritable() || !tFileInfo.isExecutable())
        {
            d->locationValidLabel->setText( i18n("Unable to create subdirectories, "
                                                  "missing permissions on: %1", tDir.absolutePath()) );
            setForeground(d->locationValidLabel, KColorScheme::NegativeText);
            emit validationFinished( false );
            return;
        }
    }

    d->locationValidLabel->setText( QString(" ") );
    setForeground(d->locationValidLabel, KColorScheme::NormalText);
    emit validationFinished( true );

    // Check for non-empty target directory. Not an error, but need to display a warning.
    url.addPath( encodedAppName() );
    QFileInfo fi( url.toLocalFile( KUrl::RemoveTrailingSlash ) );
    if( fi.exists() && fi.isDir() )
    {
        if( !QDir( fi.absoluteFilePath()).entryList( QDir::NoDotAndDotDot | QDir::AllEntries ).isEmpty() )
        {
            d->locationValidLabel->setText( i18n("Path already exists and contains files") );
            setForeground(d->locationValidLabel, KColorScheme::NegativeText);
        }
    }
}

bool NewProjectDialogPage::isModified() const
{
    return ( !d->name->text().isEmpty() || !d->location->url().isEmpty() );
}

QByteArray NewProjectDialogPage::encodedAppName()
{
    // : < > * ? / \ | " are invalid on windows
    QByteArray tEncodedName = d->name->text().toUtf8();
    for (int i = 0; i < tEncodedName.size(); ++i)
    {
        QChar tChar(tEncodedName.at( i ));
        if (tChar.isDigit() || tChar.isSpace() || tChar.isLetter() || tChar == '%')
            continue;

        QByteArray tReplace = QUrl::toPercentEncoding( tChar );
        tEncodedName.replace( tEncodedName.at( i ) ,tReplace );
        i =  i + tReplace.size() - 1;
    }
    return tEncodedName;
}

QString NewProjectDialogPage::pathUp(const QString& aPath)
{
    QString tPath = aPath;
    int tIndex = tPath.lastIndexOf( QDir::separator() );
    tPath = tPath.remove(tIndex, tPath.length() - tIndex);
    return tPath;
}

<|endoftext|>


<commit_before>/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

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 "tensorflow/lite/kernels/internal/reference/softmax.h"

#include "arm_nnfunctions.h"
#include "tensorflow/lite/kernels/internal/tensor_ctypes.h"
#include "tensorflow/lite/kernels/kernel_util.h"

namespace tflite {
namespace ops {
namespace micro {
namespace activations {
namespace {

TfLiteStatus CalculateSoftmaxParams(TfLiteContext* context,
                                    const TfLiteTensor* input,
                                    TfLiteTensor* output,
                                    const TfLiteSoftmaxParams* params,
                                    SoftmaxParams* op_data) {
  if (input->type == kTfLiteUInt8 || input->type == kTfLiteInt8) {
    if (input->type == kTfLiteUInt8) {
      TF_LITE_ENSURE_TYPES_EQ(context, output->type, kTfLiteUInt8);
      TF_LITE_ENSURE_EQ(context, output->params.zero_point, 0);
    } else {
      TF_LITE_ENSURE_TYPES_EQ(context, input->type, kTfLiteInt8);
      TF_LITE_ENSURE_TYPES_EQ(context, output->type, kTfLiteInt8);
      TF_LITE_ENSURE_EQ(context, output->params.zero_point, -128);
    }
    TF_LITE_ENSURE(context, (output->params.scale == 1.f / 256) ||
                                (output->params.scale == 1.f / 255));

    static const int kScaledDiffIntegerBits = 5;

    int input_left_shift;
    tflite::PreprocessSoftmaxScaling(
        params->beta, input->params.scale, kScaledDiffIntegerBits,
        &op_data->input_multiplier, &input_left_shift);
    op_data->input_left_shift = input_left_shift;
    op_data->diff_min =
        -1.0 * tflite::CalculateInputRadius(kScaledDiffIntegerBits,
                                            op_data->input_left_shift);
  } else {
    TF_LITE_ENSURE_TYPES_EQ(context, input->type, kTfLiteFloat32);
    TF_LITE_ENSURE_TYPES_EQ(context, output->type, kTfLiteFloat32);
    op_data->beta = static_cast<double>(params->beta);
  }
  return kTfLiteOk;
}

}  // namespace

void* Init(TfLiteContext* context, const char* buffer, size_t length) {
  return nullptr;
}

void Free(TfLiteContext* context, void* buffer) {}

TfLiteStatus SoftmaxPrepare(TfLiteContext* context, TfLiteNode* node) {
  TF_LITE_ENSURE_EQ(context, NumInputs(node), 1);
  TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1);
  const TfLiteTensor* input = GetInput(context, node, 0);
  TF_LITE_ENSURE(context, NumDimensions(input) >= 1);

  return kTfLiteOk;
}

// Takes a tensor and performs softmax along the last dimension.
void SoftmaxFloat(const TfLiteTensor* input, TfLiteTensor* output,
                  const SoftmaxParams& op_data) {
  tflite::reference_ops::Softmax(
      op_data, GetTensorShape(input), GetTensorData<float>(input),
      GetTensorShape(output), GetTensorData<float>(output));
}

void SoftmaxQuantized(const TfLiteTensor* input, TfLiteTensor* output,
                      const SoftmaxParams& op_data) {
  if (input->type == kTfLiteUInt8) {
    tflite::reference_ops::Softmax(
        op_data, GetTensorShape(input), GetTensorData<uint8_t>(input),
        GetTensorShape(output), GetTensorData<uint8_t>(output));
  } else {
    const unsigned int num_dims = NumDimensions(input);

    const int trailing_dim = input_shape.DimensionsCount() - 1;
    const int outer_size =
        MatchingFlatSizeSkipDim(input_shape, trailing_dim, output_shape);
    const int depth =
        MatchingDim(input_shape, trailing_dim, output_shape, trailing_dim);

    arm_softmax_s8(GetTensorData<int8_t>(input), outer_size, depth,
                   op_data.input_multiplier, op_data.input_left_shift,
                   op_data.diff_min, GetTensorData<int8_t>(output));
  }
}

TfLiteStatus SoftmaxEval(TfLiteContext* context, TfLiteNode* node) {
  auto* params = static_cast<TfLiteSoftmaxParams*>(node->builtin_data);

  const TfLiteTensor* input = GetInput(context, node, 0);
  TfLiteTensor* output = GetOutput(context, node, 0);

  SoftmaxParams op_data;
  TF_LITE_ENSURE_STATUS(
      CalculateSoftmaxParams(context, input, output, params, &op_data));

  switch (input->type) {
    case kTfLiteFloat32: {
      SoftmaxFloat(input, output, op_data);
      return kTfLiteOk;
    }
    case kTfLiteInt8:
    case kTfLiteUInt8: {
      SoftmaxQuantized(input, output, params, op_data);
      return kTfLiteOk;
    }
    default:
      TF_LITE_KERNEL_LOG(
          context,
          "Only float32, uint8_t and int8_t input supported currently, got %d.",
          input->type);
      return kTfLiteError;
  }
}
}  // namespace activations

TfLiteRegistration* Register_SOFTMAX() {
  static TfLiteRegistration r = {activations::Init, activations::Free,
                                 activations::SoftmaxPrepare,
                                 activations::SoftmaxEval};
  return &r;
}

}  // namespace micro
}  // namespace ops
}  // namespace tflite
<commit_msg>TFLu: Fix compilation errors for cmsis-nn/softmax.cc<commit_after>/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

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 "tensorflow/lite/kernels/internal/reference/softmax.h"

#include "arm_nnfunctions.h"
#include "tensorflow/lite/kernels/internal/tensor_ctypes.h"
#include "tensorflow/lite/kernels/kernel_util.h"

namespace tflite {
namespace ops {
namespace micro {
namespace activations {
namespace {

TfLiteStatus CalculateSoftmaxParams(TfLiteContext* context,
                                    const TfLiteTensor* input,
                                    TfLiteTensor* output,
                                    const TfLiteSoftmaxParams* params,
                                    SoftmaxParams* op_data) {
  if (input->type == kTfLiteUInt8 || input->type == kTfLiteInt8) {
    if (input->type == kTfLiteUInt8) {
      TF_LITE_ENSURE_TYPES_EQ(context, output->type, kTfLiteUInt8);
      TF_LITE_ENSURE_EQ(context, output->params.zero_point, 0);
    } else {
      TF_LITE_ENSURE_TYPES_EQ(context, input->type, kTfLiteInt8);
      TF_LITE_ENSURE_TYPES_EQ(context, output->type, kTfLiteInt8);
      TF_LITE_ENSURE_EQ(context, output->params.zero_point, -128);
    }
    TF_LITE_ENSURE(context, (output->params.scale == 1.f / 256) ||
                                (output->params.scale == 1.f / 255));

    static const int kScaledDiffIntegerBits = 5;

    int input_left_shift;
    tflite::PreprocessSoftmaxScaling(
        params->beta, input->params.scale, kScaledDiffIntegerBits,
        &op_data->input_multiplier, &input_left_shift);
    op_data->input_left_shift = input_left_shift;
    op_data->diff_min =
        -1.0 * tflite::CalculateInputRadius(kScaledDiffIntegerBits,
                                            op_data->input_left_shift);
  } else {
    TF_LITE_ENSURE_TYPES_EQ(context, input->type, kTfLiteFloat32);
    TF_LITE_ENSURE_TYPES_EQ(context, output->type, kTfLiteFloat32);
    op_data->beta = static_cast<double>(params->beta);
  }
  return kTfLiteOk;
}

}  // namespace

void* Init(TfLiteContext* context, const char* buffer, size_t length) {
  return nullptr;
}

void Free(TfLiteContext* context, void* buffer) {}

TfLiteStatus SoftmaxPrepare(TfLiteContext* context, TfLiteNode* node) {
  TF_LITE_ENSURE_EQ(context, NumInputs(node), 1);
  TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1);
  const TfLiteTensor* input = GetInput(context, node, 0);
  TF_LITE_ENSURE(context, NumDimensions(input) >= 1);

  return kTfLiteOk;
}

// Takes a tensor and performs softmax along the last dimension.
void SoftmaxFloat(const TfLiteTensor* input, TfLiteTensor* output,
                  const SoftmaxParams& op_data) {
  tflite::reference_ops::Softmax(
      op_data, GetTensorShape(input), GetTensorData<float>(input),
      GetTensorShape(output), GetTensorData<float>(output));
}

void SoftmaxQuantized(const TfLiteTensor* input, TfLiteTensor* output,
                      const SoftmaxParams& op_data) {
  const auto input_shape = GetTensorShape(input);
  const auto output_shape = GetTensorShape(output);

  if (input->type == kTfLiteUInt8) {
    tflite::reference_ops::Softmax(op_data, input_shape,
                                   GetTensorData<uint8_t>(input), output_shape,
                                   GetTensorData<uint8_t>(output));
  } else {
    const unsigned int num_dims = NumDimensions(input);

    const int trailing_dim = input_shape.DimensionsCount() - 1;
    const int outer_size =
        MatchingFlatSizeSkipDim(input_shape, trailing_dim, output_shape);
    const int depth =
        MatchingDim(input_shape, trailing_dim, output_shape, trailing_dim);

    arm_softmax_s8(GetTensorData<int8_t>(input), outer_size, depth,
                   op_data.input_multiplier, op_data.input_left_shift,
                   op_data.diff_min, GetTensorData<int8_t>(output));
  }
}

TfLiteStatus SoftmaxEval(TfLiteContext* context, TfLiteNode* node) {
  auto* params = static_cast<TfLiteSoftmaxParams*>(node->builtin_data);

  const TfLiteTensor* input = GetInput(context, node, 0);
  TfLiteTensor* output = GetOutput(context, node, 0);

  SoftmaxParams op_data;
  TF_LITE_ENSURE_STATUS(
      CalculateSoftmaxParams(context, input, output, params, &op_data));

  switch (input->type) {
    case kTfLiteFloat32: {
      SoftmaxFloat(input, output, op_data);
      return kTfLiteOk;
    }
    case kTfLiteInt8:
    case kTfLiteUInt8: {
      SoftmaxQuantized(input, output, op_data);
      return kTfLiteOk;
    }
    default:
      TF_LITE_KERNEL_LOG(
          context,
          "Only float32, uint8_t and int8_t input supported currently, got %d.",
          input->type);
      return kTfLiteError;
  }
}
}  // namespace activations

TfLiteRegistration* Register_SOFTMAX() {
  static TfLiteRegistration r = {activations::Init, activations::Free,
                                 activations::SoftmaxPrepare,
                                 activations::SoftmaxEval};
  return &r;
}

}  // namespace micro
}  // namespace ops
}  // namespace tflite
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: cusshow.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: pjunck $ $Date: 2004-11-03 08:52:59 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif

#include "sdiocmpt.hxx"
#include "cusshow.hxx"
#include "sdpage.hxx"
#include "drawdoc.hxx"

// #90477#
#ifndef _TOOLS_TENCCVT_HXX
#include <tools/tenccvt.hxx>
#endif

using namespace ::com::sun::star;

/*************************************************************************
|*
|* Ctor
|*
\************************************************************************/
SdCustomShow::SdCustomShow(SdDrawDocument* pDrawDoc)
  : List(),
  pDoc(pDrawDoc)
{
}

/*************************************************************************
|*
|* Copy-Ctor
|*
\************************************************************************/
SdCustomShow::SdCustomShow( const SdCustomShow& rShow )
    : List( rShow )
{
    aName = rShow.GetName();
    pDoc = rShow.GetDoc();
}

SdCustomShow::SdCustomShow(SdDrawDocument* pDrawDoc, ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xShow )
  : List(),
  pDoc(pDrawDoc),
  mxUnoCustomShow( xShow )
{
}

/*************************************************************************
|*
|* Dtor
|*
\************************************************************************/
SdCustomShow::~SdCustomShow()
{
    uno::Reference< uno::XInterface > xShow( mxUnoCustomShow );
    uno::Reference< lang::XComponent > xComponent( xShow, uno::UNO_QUERY );
    if( xComponent.is() )
        xComponent->dispose();
}

/*************************************************************************
|*
|* Inserter fuer SvStream zum Speichern
|*
\************************************************************************/
//BFS02SvStream& operator << (SvStream& rOut, const SdCustomShow& rCustomShow)
//BFS02{
//BFS02 // Letzter Parameter ist die aktuelle Versionsnummer des Codes
//BFS02 SdIOCompat aIO(rOut, STREAM_WRITE, 0);
//BFS02
//BFS02 // Name
//BFS02 // #90477# rOut.WriteByteString( rCustomShow.aName, ::GetStoreCharSet( gsl_getSystemTextEncoding() ) );
//BFS02 rOut.WriteByteString(rCustomShow.aName,
//BFS02     GetSOStoreTextEncoding(gsl_getSystemTextEncoding(), (sal_uInt16)rOut.GetVersion()));
//BFS02
//BFS02 // Anzahl Seiten
//BFS02 UINT32 nCount = rCustomShow.Count();
//BFS02 rOut << nCount;
//BFS02
//BFS02 for (UINT32 i = 0; i < nCount; i++)
//BFS02 {
//BFS02     // Seite aus Liste holen
//BFS02     SdPage* pPage = (SdPage*) rCustomShow.GetObject(i);
//BFS02
//BFS02     if (pPage)
//BFS02     {
//BFS02         // SdPage-Seitennummer
//BFS02         UINT16 nPageNum = (pPage->GetPageNum() - 1) / 2;
//BFS02         rOut << nPageNum;
//BFS02     }
//BFS02 }
//BFS02
//BFS02 return rOut;
//BFS02}

/*************************************************************************
|*
|* Extractor fuer SvStream zum Laden
|*
\************************************************************************/
//BFS02SvStream& operator >> (SvStream& rIn, SdCustomShow& rCustomShow)
//BFS02{
//BFS02 SdIOCompat aIO(rIn, STREAM_READ);
//BFS02
//BFS02 // Name
//BFS02 // #90477# rIn.ReadByteString( rCustomShow.aName, ::GetStoreCharSet( gsl_getSystemTextEncoding() ) );
//BFS02 rIn.ReadByteString(rCustomShow.aName,
//BFS02     GetSOLoadTextEncoding(gsl_getSystemTextEncoding(), (sal_uInt16)rIn.GetVersion()));
//BFS02
//BFS02 // Anzahl Seiten
//BFS02 UINT32 nCount = 0;
//BFS02 rIn >> nCount;
//BFS02
//BFS02 rCustomShow.Clear();
//BFS02
//BFS02 for (UINT32 i = 0; i < nCount; i++)
//BFS02 {
//BFS02     // Seitennummer
//BFS02     UINT16 nPageNum;
//BFS02     rIn >> nPageNum;
//BFS02
//BFS02     // Seite in Liste einfuegen
//BFS02     SdPage* pPage = (SdPage*) rCustomShow.pDoc->GetSdPage(nPageNum, PK_STANDARD);
//BFS02     rCustomShow.Insert(pPage, LIST_APPEND);
//BFS02 }
//BFS02
//BFS02 return rIn;
//BFS02}

extern uno::Reference< uno::XInterface > createUnoCustomShow( SdCustomShow* pShow );

uno::Reference< uno::XInterface > SdCustomShow::getUnoCustomShow()
{
    // try weak reference first
    uno::Reference< uno::XInterface > xShow( mxUnoCustomShow );

    if( !xShow.is() )
    {
        xShow = createUnoCustomShow( this );
    }

    return xShow;
}
<commit_msg>INTEGRATION: CWS ooo19126 (1.5.310); FILE MERGED 2005/09/05 13:20:14 rt 1.5.310.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cusshow.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 03:10:37 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif

#include "sdiocmpt.hxx"
#include "cusshow.hxx"
#include "sdpage.hxx"
#include "drawdoc.hxx"

// #90477#
#ifndef _TOOLS_TENCCVT_HXX
#include <tools/tenccvt.hxx>
#endif

using namespace ::com::sun::star;

/*************************************************************************
|*
|* Ctor
|*
\************************************************************************/
SdCustomShow::SdCustomShow(SdDrawDocument* pDrawDoc)
  : List(),
  pDoc(pDrawDoc)
{
}

/*************************************************************************
|*
|* Copy-Ctor
|*
\************************************************************************/
SdCustomShow::SdCustomShow( const SdCustomShow& rShow )
    : List( rShow )
{
    aName = rShow.GetName();
    pDoc = rShow.GetDoc();
}

SdCustomShow::SdCustomShow(SdDrawDocument* pDrawDoc, ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xShow )
  : List(),
  pDoc(pDrawDoc),
  mxUnoCustomShow( xShow )
{
}

/*************************************************************************
|*
|* Dtor
|*
\************************************************************************/
SdCustomShow::~SdCustomShow()
{
    uno::Reference< uno::XInterface > xShow( mxUnoCustomShow );
    uno::Reference< lang::XComponent > xComponent( xShow, uno::UNO_QUERY );
    if( xComponent.is() )
        xComponent->dispose();
}

/*************************************************************************
|*
|* Inserter fuer SvStream zum Speichern
|*
\************************************************************************/
//BFS02SvStream& operator << (SvStream& rOut, const SdCustomShow& rCustomShow)
//BFS02{
//BFS02 // Letzter Parameter ist die aktuelle Versionsnummer des Codes
//BFS02 SdIOCompat aIO(rOut, STREAM_WRITE, 0);
//BFS02
//BFS02 // Name
//BFS02 // #90477# rOut.WriteByteString( rCustomShow.aName, ::GetStoreCharSet( gsl_getSystemTextEncoding() ) );
//BFS02 rOut.WriteByteString(rCustomShow.aName,
//BFS02     GetSOStoreTextEncoding(gsl_getSystemTextEncoding(), (sal_uInt16)rOut.GetVersion()));
//BFS02
//BFS02 // Anzahl Seiten
//BFS02 UINT32 nCount = rCustomShow.Count();
//BFS02 rOut << nCount;
//BFS02
//BFS02 for (UINT32 i = 0; i < nCount; i++)
//BFS02 {
//BFS02     // Seite aus Liste holen
//BFS02     SdPage* pPage = (SdPage*) rCustomShow.GetObject(i);
//BFS02
//BFS02     if (pPage)
//BFS02     {
//BFS02         // SdPage-Seitennummer
//BFS02         UINT16 nPageNum = (pPage->GetPageNum() - 1) / 2;
//BFS02         rOut << nPageNum;
//BFS02     }
//BFS02 }
//BFS02
//BFS02 return rOut;
//BFS02}

/*************************************************************************
|*
|* Extractor fuer SvStream zum Laden
|*
\************************************************************************/
//BFS02SvStream& operator >> (SvStream& rIn, SdCustomShow& rCustomShow)
//BFS02{
//BFS02 SdIOCompat aIO(rIn, STREAM_READ);
//BFS02
//BFS02 // Name
//BFS02 // #90477# rIn.ReadByteString( rCustomShow.aName, ::GetStoreCharSet( gsl_getSystemTextEncoding() ) );
//BFS02 rIn.ReadByteString(rCustomShow.aName,
//BFS02     GetSOLoadTextEncoding(gsl_getSystemTextEncoding(), (sal_uInt16)rIn.GetVersion()));
//BFS02
//BFS02 // Anzahl Seiten
//BFS02 UINT32 nCount = 0;
//BFS02 rIn >> nCount;
//BFS02
//BFS02 rCustomShow.Clear();
//BFS02
//BFS02 for (UINT32 i = 0; i < nCount; i++)
//BFS02 {
//BFS02     // Seitennummer
//BFS02     UINT16 nPageNum;
//BFS02     rIn >> nPageNum;
//BFS02
//BFS02     // Seite in Liste einfuegen
//BFS02     SdPage* pPage = (SdPage*) rCustomShow.pDoc->GetSdPage(nPageNum, PK_STANDARD);
//BFS02     rCustomShow.Insert(pPage, LIST_APPEND);
//BFS02 }
//BFS02
//BFS02 return rIn;
//BFS02}

extern uno::Reference< uno::XInterface > createUnoCustomShow( SdCustomShow* pShow );

uno::Reference< uno::XInterface > SdCustomShow::getUnoCustomShow()
{
    // try weak reference first
    uno::Reference< uno::XInterface > xShow( mxUnoCustomShow );

    if( !xShow.is() )
    {
        xShow = createUnoCustomShow( this );
    }

    return xShow;
}
<|endoftext|>


<commit_before>#include "point_series_xy.h"
#include <cmath>
#include <cstdlib>

PointSeriesXY::PointSeriesXY(const PlotData *y_axis, const PlotData *x_axis):
    DataSeriesBase( &_cached_curve ),
    _x_axis(x_axis),
    _y_axis(y_axis),
    _cached_curve("")
{
    updateCache();
}

PlotData::RangeTimeOpt PointSeriesXY::getVisualizationRangeX()
{
    if( this->size() < 2 )
        return  PlotData::RangeTimeOpt();
    else{
        return PlotData::RangeTimeOpt( { _bounding_box.left() ,
                                         _bounding_box.right()} );
    }
}

nonstd::optional<QPointF> PointSeriesXY::sampleFromTime(double t)
{
    if( _cached_curve.size() == 0 )
    {
        return {};
    }

    int index = _y_axis->getIndexFromX(t);
    if(index <0)
    {
        return {};
    }
    const auto& p = _cached_curve.at( size_t(index) );
    return QPointF(p.x, p.y);
}

PlotData::RangeValueOpt PointSeriesXY::getVisualizationRangeY(PlotData::RangeTime range_X)
{
    //TODO: improve?
    return PlotData::RangeValueOpt( { _bounding_box.bottom(),
                                      _bounding_box.top() } );
}

bool PointSeriesXY::updateCache()
{
    if( _x_axis == nullptr )
    {
        throw std::runtime_error("the X axis is null");
    }

    const size_t data_size =  _x_axis->size();

    if( data_size != _x_axis->size() )
    {
        _bounding_box = QRectF();
        _cached_curve.clear();
        throw std::runtime_error("X and Y axis don't share the same time axis");
    }

    if(data_size == 0)
    {
        _bounding_box = QRectF();
        _cached_curve.clear();
        return true;
    }

    double min_y =( std::numeric_limits<double>::max() );
    double max_y =(-std::numeric_limits<double>::max() );
    double min_x =( std::numeric_limits<double>::max() );
    double max_x =(-std::numeric_limits<double>::max() );

    _cached_curve.resize( data_size );

    const double EPS = std::numeric_limits<double>::epsilon();

    for (size_t i=0; i<data_size; i++ )
    {
        if( Abs( _x_axis->at(i).x  - _y_axis->at(i).x ) >  EPS)
        {
            _bounding_box = QRectF();
            _cached_curve.clear();
            throw std::runtime_error("X and Y axis don't share the same time axis");
        }

        const QPointF p(_x_axis->at(i).y,
                        _y_axis->at(i).y );

        _cached_curve.at(i) = { p.x(), p.y() };

        min_x = std::min( min_x, p.x() );
        max_x = std::max( max_x, p.x() );
        min_y = std::min( min_y, p.y() );
        max_y = std::max( max_y, p.y() );
    }

    _bounding_box.setLeft(  min_x );
    _bounding_box.setRight( max_x );
    _bounding_box.setBottom( min_y );
    _bounding_box.setTop( max_y );

    return true;
}
<commit_msg>fixed bug reported in issue #177<commit_after>#include "point_series_xy.h"
#include <cmath>
#include <cstdlib>

PointSeriesXY::PointSeriesXY(const PlotData *y_axis, const PlotData *x_axis):
    DataSeriesBase( &_cached_curve ),
    _x_axis(x_axis),
    _y_axis(y_axis),
    _cached_curve("")
{
    updateCache();
}

PlotData::RangeTimeOpt PointSeriesXY::getVisualizationRangeX()
{
    if( this->size() < 2 )
        return  PlotData::RangeTimeOpt();
    else{
        return PlotData::RangeTimeOpt( { _bounding_box.left() ,
                                         _bounding_box.right()} );
    }
}

nonstd::optional<QPointF> PointSeriesXY::sampleFromTime(double t)
{
    if( _cached_curve.size() == 0 )
    {
        return {};
    }

    int index = _y_axis->getIndexFromX(t);
    if(index <0)
    {
        return {};
    }
    const auto& p = _cached_curve.at( size_t(index) );
    return QPointF(p.x, p.y);
}

PlotData::RangeValueOpt PointSeriesXY::getVisualizationRangeY(PlotData::RangeTime range_X)
{
    //TODO: improve?
    return PlotData::RangeValueOpt( { _bounding_box.bottom(),
                                      _bounding_box.top() } );
}

bool PointSeriesXY::updateCache()
{
    if( _x_axis == nullptr )
    {
        throw std::runtime_error("the X axis is null");
    }

    const size_t data_size =  _x_axis->size();

    if( data_size != _y_axis->size() )
    {
        _bounding_box = QRectF();
        _cached_curve.clear();
        throw std::runtime_error("X and Y axis don't share the same time axis");
    }

    if(data_size == 0)
    {
        _bounding_box = QRectF();
        _cached_curve.clear();
        return true;
    }

    double min_y =( std::numeric_limits<double>::max() );
    double max_y =(-std::numeric_limits<double>::max() );
    double min_x =( std::numeric_limits<double>::max() );
    double max_x =(-std::numeric_limits<double>::max() );

    _cached_curve.resize( data_size );

    const double EPS = std::numeric_limits<double>::epsilon();

    for (size_t i=0; i<data_size; i++ )
    {
        if( Abs( _x_axis->at(i).x  - _y_axis->at(i).x ) >  EPS)
        {
            _bounding_box = QRectF();
            _cached_curve.clear();
            throw std::runtime_error("X and Y axis don't share the same time axis");
        }

        const QPointF p(_x_axis->at(i).y,
                        _y_axis->at(i).y );

        _cached_curve.at(i) = { p.x(), p.y() };

        min_x = std::min( min_x, p.x() );
        max_x = std::max( max_x, p.x() );
        min_y = std::min( min_y, p.y() );
        max_y = std::max( max_y, p.y() );
    }

    _bounding_box.setLeft(  min_x );
    _bounding_box.setRight( max_x );
    _bounding_box.setBottom( min_y );
    _bounding_box.setTop( max_y );

    return true;
}
<|endoftext|>


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

#include "remoting/host/capturer_gdi.h"
#include "remoting/host/differ.h"

#include "gfx/rect.h"

namespace remoting {

// 3780 pixels per meter is equivalent to 96 DPI, typical on desktop monitors.
static const int kPixelsPerMeter = 3780;
// 32 bit RGBA is 4 bytes per pixel.
static const int kBytesPerPixel = 4;

CapturerGdi::CapturerGdi(MessageLoop* message_loop)
    : Capturer(message_loop),
      desktop_dc_(NULL),
      memory_dc_(NULL),
      capture_fullscreen_(true) {
  memset(target_bitmap_, 0, sizeof(target_bitmap_));
  memset(buffers_, 0, sizeof(buffers_));
}

CapturerGdi::~CapturerGdi() {
  ReleaseBuffers();
}

void CapturerGdi::ReleaseBuffers() {
  for (int i = kNumBuffers - 1; i >= 0; i--) {
    if (target_bitmap_[i]) {
      DeleteObject(target_bitmap_[i]);
      target_bitmap_[i] = NULL;
    }
    if (buffers_[i]) {
      DeleteObject(buffers_[i]);
      buffers_[i] = NULL;
    }
  }

  desktop_dc_ = NULL;
  if (memory_dc_) {
    DeleteDC(memory_dc_);
    memory_dc_ = NULL;
  }
}

void CapturerGdi::ScreenConfigurationChanged() {
  ReleaseBuffers();

  desktop_dc_ = GetDC(GetDesktopWindow());
  memory_dc_ = CreateCompatibleDC(desktop_dc_);

  // Create a bitmap to keep the desktop image.
  width_ = GetSystemMetrics(SM_CXSCREEN);
  height_ = GetSystemMetrics(SM_CYSCREEN);
  int rounded_width = (width_ + 3) & (~3);

  // Dimensions of screen.
  pixel_format_ = media::VideoFrame::RGB32;
  bytes_per_row_ = rounded_width * kBytesPerPixel;

  // Create a differ for this screen size.
  differ_.reset(new Differ(width_, height_, 4, bytes_per_row_));

  // Create a device independant bitmap (DIB) that is the same size.
  BITMAPINFO bmi;
  memset(&bmi, 0, sizeof(bmi));
  bmi.bmiHeader.biHeight = height_;
  bmi.bmiHeader.biWidth = width_;
  bmi.bmiHeader.biPlanes = 1;
  bmi.bmiHeader.biBitCount = kBytesPerPixel * 8;
  bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
  bmi.bmiHeader.biSizeImage = bytes_per_row_ * height_;
  bmi.bmiHeader.biXPelsPerMeter = kPixelsPerMeter;
  bmi.bmiHeader.biYPelsPerMeter = kPixelsPerMeter;

  // Create memory for the buffers.
  for (int i = 0; i < kNumBuffers; i++) {
    target_bitmap_[i] = CreateDIBSection(desktop_dc_, &bmi, DIB_RGB_COLORS,
                                         static_cast<void**>(&buffers_[i]),
                                         NULL, 0);
  }

  capture_fullscreen_ = true;
}

void CapturerGdi::CalculateInvalidRects() {
  ClearInvalidRects();
  CaptureImage();

  if (capture_fullscreen_) {
    InvalidateFullScreen();
  } else {
    // Calculate the difference between the previous and current screen.
    int prev_buffer_id = current_buffer_ - 1;
    if (prev_buffer_id < 0) {
      prev_buffer_id = kNumBuffers - 1;
    }

    void* prev_buffer = buffers_[prev_buffer_id];
    void* curr_buffer = buffers_[current_buffer_];

    InvalidRects rects;
    differ_->CalcDirtyRects(prev_buffer, curr_buffer, &rects);

    InvalidateRects(rects);
  }

  capture_fullscreen_ = false;
}

void CapturerGdi::CaptureRects(const InvalidRects& rects,
                               CaptureCompletedCallback* callback) {
  DataPlanes planes;
  planes.data[0] = static_cast<uint8*>(buffers_[current_buffer_]);
  planes.strides[0] = bytes_per_row_;

  scoped_refptr<CaptureData> data(new CaptureData(planes,
                                                  width(),
                                                  height(),
                                                  pixel_format()));
  data->mutable_dirty_rects() = rects;

  FinishCapture(data, callback);
}

void CapturerGdi::CaptureImage() {
  // Select the target bitmap into the memory dc.
  SelectObject(memory_dc_, target_bitmap_[current_buffer_]);

  // And then copy the rect from desktop to memory.
  BitBlt(memory_dc_, 0, 0, width_, height_, desktop_dc_, 0, 0,
      SRCCOPY | CAPTUREBLT);
}

}  // namespace remoting
<commit_msg>Fix GDI capturer initialization.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/host/capturer_gdi.h"
#include "remoting/host/differ.h"

#include "gfx/rect.h"

namespace remoting {

// 3780 pixels per meter is equivalent to 96 DPI, typical on desktop monitors.
static const int kPixelsPerMeter = 3780;
// 32 bit RGBA is 4 bytes per pixel.
static const int kBytesPerPixel = 4;

CapturerGdi::CapturerGdi(MessageLoop* message_loop)
    : Capturer(message_loop),
      desktop_dc_(NULL),
      memory_dc_(NULL),
      capture_fullscreen_(true) {
  memset(target_bitmap_, 0, sizeof(target_bitmap_));
  memset(buffers_, 0, sizeof(buffers_));
  ScreenConfigurationChanged();
}

CapturerGdi::~CapturerGdi() {
  ReleaseBuffers();
}

void CapturerGdi::ReleaseBuffers() {
  for (int i = kNumBuffers - 1; i >= 0; i--) {
    if (target_bitmap_[i]) {
      DeleteObject(target_bitmap_[i]);
      target_bitmap_[i] = NULL;
    }
    if (buffers_[i]) {
      DeleteObject(buffers_[i]);
      buffers_[i] = NULL;
    }
  }

  desktop_dc_ = NULL;
  if (memory_dc_) {
    DeleteDC(memory_dc_);
    memory_dc_ = NULL;
  }
}

void CapturerGdi::ScreenConfigurationChanged() {
  ReleaseBuffers();

  desktop_dc_ = GetDC(GetDesktopWindow());
  memory_dc_ = CreateCompatibleDC(desktop_dc_);

  // Create a bitmap to keep the desktop image.
  width_ = GetSystemMetrics(SM_CXSCREEN);
  height_ = GetSystemMetrics(SM_CYSCREEN);
  int rounded_width = (width_ + 3) & (~3);

  // Dimensions of screen.
  pixel_format_ = media::VideoFrame::RGB32;
  bytes_per_row_ = rounded_width * kBytesPerPixel;

  // Create a differ for this screen size.
  differ_.reset(new Differ(width_, height_, 4, bytes_per_row_));

  // Create a device independant bitmap (DIB) that is the same size.
  BITMAPINFO bmi;
  memset(&bmi, 0, sizeof(bmi));
  bmi.bmiHeader.biHeight = height_;
  bmi.bmiHeader.biWidth = width_;
  bmi.bmiHeader.biPlanes = 1;
  bmi.bmiHeader.biBitCount = kBytesPerPixel * 8;
  bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
  bmi.bmiHeader.biSizeImage = bytes_per_row_ * height_;
  bmi.bmiHeader.biXPelsPerMeter = kPixelsPerMeter;
  bmi.bmiHeader.biYPelsPerMeter = kPixelsPerMeter;

  // Create memory for the buffers.
  for (int i = 0; i < kNumBuffers; i++) {
    target_bitmap_[i] = CreateDIBSection(desktop_dc_, &bmi, DIB_RGB_COLORS,
                                         static_cast<void**>(&buffers_[i]),
                                         NULL, 0);
  }

  capture_fullscreen_ = true;
}

void CapturerGdi::CalculateInvalidRects() {
  ClearInvalidRects();
  CaptureImage();

  if (capture_fullscreen_) {
    InvalidateFullScreen();
  } else {
    // Calculate the difference between the previous and current screen.
    int prev_buffer_id = current_buffer_ - 1;
    if (prev_buffer_id < 0) {
      prev_buffer_id = kNumBuffers - 1;
    }

    void* prev_buffer = buffers_[prev_buffer_id];
    void* curr_buffer = buffers_[current_buffer_];

    InvalidRects rects;
    differ_->CalcDirtyRects(prev_buffer, curr_buffer, &rects);

    InvalidateRects(rects);
  }

  capture_fullscreen_ = false;
}

void CapturerGdi::CaptureRects(const InvalidRects& rects,
                               CaptureCompletedCallback* callback) {
  DataPlanes planes;
  planes.data[0] = static_cast<uint8*>(buffers_[current_buffer_]);
  planes.strides[0] = bytes_per_row_;

  scoped_refptr<CaptureData> data(new CaptureData(planes,
                                                  width(),
                                                  height(),
                                                  pixel_format()));
  data->mutable_dirty_rects() = rects;

  FinishCapture(data, callback);
}

void CapturerGdi::CaptureImage() {
  // Select the target bitmap into the memory dc.
  SelectObject(memory_dc_, target_bitmap_[current_buffer_]);

  // And then copy the rect from desktop to memory.
  BitBlt(memory_dc_, 0, 0, width_, height_, desktop_dc_, 0, 0,
      SRCCOPY | CAPTUREBLT);
}

}  // namespace remoting
<|endoftext|>


<commit_before>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * Razor - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2012 Razor team
 * Authors:
 *   Kuzma Shapran <kuzma.shapran@gmail.com>
 *   Luís Pereira <luis.artur.pereira@gmail.com>
 *
 * This program or 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 Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include "calendar_utils.h"
#include "config.h"

#include <QtCore/QtGlobal>

#if QT_VERSION >= 0x040800

Qt::DayOfWeek firstDayOfWeek(void)
{
    return QLocale::system().firstDayOfWeek();
}

#else
#ifdef CAN_USE_BOOST

#include <boost/locale/date_time.hpp>

Qt::DayOfWeek firstDayOfWeek(void)
{
    return (boost::locale::calendar().first_day_of_week() + 6) % 7;
}

#else // use C
#ifdef HAVE__NL_TIME_FIRST_WEEKDAY

#include <langinfo.h>
#include <QtCore/QDebug>

Qt::DayOfWeek firstDayOfWeek(void)
{
    static char *locale = NULL;
    if (!locale)
        locale = setlocale(LC_TIME, "");

    // firstWeekDay: Specifies the offset of the first day-of-week in the day
    // list.

    // weekFirstDay: Some date that corresponds to the beginning of a week.
    // Specifies the base of the day list. It is (in glibc) either
    // 19971130 (Sunday) or 19971201 (Monday)

    int firstWeekDay = nl_langinfo(_NL_TIME_FIRST_WEEKDAY)[0];

    int weekFirstDay = 0;
    long weekFirstDayLong = (long) nl_langinfo(_NL_TIME_WEEK_1STDAY);
    if (weekFirstDayLong == 19971130L)  // Sunday
    {
        weekFirstDay = 0;
    }
    else if (weekFirstDayLong == 19971201L) // Monday
    {
        weekFirstDay = 1;
    }
    else
    {
        qDebug() << Q_FUNC_INFO <<
            "nl_langinfo(_NL_TIME_WEEK_1STDAY) returned an unknown value.";
    }

    int weekStart = (weekFirstDay + firstWeekDay - 1) % 7;
    if (weekStart == 0)
    {
        return Qt::Sunday;
    }
    else
    {
        return static_cast<Qt::DayOfWeek>(weekStart);
    }
}

#else

Qt::DayOfWeek firstDayOfWeek(void)
{
    return Qt::Sunday;

#endif // HAVE__NL_TIME_FIRST_WEEKDAY

#endif // CAN_USE_BOOST

#endif // QT_VERSION >= 0x040800
<commit_msg>Panel Clock plugin: C++-style casting used, multilevel if/else changed to switch/case, conversion formula simplified.<commit_after>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * Razor - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2012 Razor team
 * Authors:
 *   Kuzma Shapran <kuzma.shapran@gmail.com>
 *   Luís Pereira <luis.artur.pereira@gmail.com>
 *
 * This program or 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 Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include "calendar_utils.h"
#include "config.h"

#include <QtCore/QtGlobal>

#if QT_VERSION >= 0x040800

Qt::DayOfWeek firstDayOfWeek(void)
{
    return QLocale::system().firstDayOfWeek();
}

#else
#ifdef CAN_USE_BOOST

#include <boost/locale/date_time.hpp>

Qt::DayOfWeek firstDayOfWeek(void)
{
    return (boost::locale::calendar().first_day_of_week() + 6) % 7;
}

#else // use C
#ifdef HAVE__NL_TIME_FIRST_WEEKDAY

#include <langinfo.h>
#include <QtCore/QDebug>

Qt::DayOfWeek firstDayOfWeek(void)
{
    static char *locale = NULL;
    if (!locale)
        locale = setlocale(LC_TIME, "");

    // firstWeekDay: Specifies the offset of the first day-of-week in the day
    // list.

    // weekFirstDay: Some date that corresponds to the beginning of a week.
    // Specifies the base of the day list. It is (in glibc) either
    // 19971130 (Sunday) or 19971201 (Monday)

    int firstWeekDay = nl_langinfo(_NL_TIME_FIRST_WEEKDAY)[0];

    int weekFirstDay = 0;
    long weekFirstDayLong = reinterpret_cast<long>(nl_langinfo(_NL_TIME_WEEK_1STDAY));
    switch (weekFirstDayLong)
    {
    case 19971130L: // Sunday
        weekFirstDay = 0;
        break;

    case 19971201L: // Monday
        weekFirstDay = 1;
        break;

    default:
        qDebug() << Q_FUNC_INFO <<
            "nl_langinfo(_NL_TIME_WEEK_1STDAY) returned an unknown value.";
    }

    int weekStart = ((weekFirstDay + firstWeekDay + 5) % 7) + 1;

    return static_cast<Qt::DayOfWeek>(weekStart);
}

#else

Qt::DayOfWeek firstDayOfWeek(void)
{
    return Qt::Sunday;

#endif // HAVE__NL_TIME_FIRST_WEEKDAY

#endif // CAN_USE_BOOST

#endif // QT_VERSION >= 0x040800
<|endoftext|>


<commit_before>/**
 * \file   traceroute_results.cc
 * \author Andrea Barberio <insomniac@slackware.it>
 * \copyright 2-clause BSD
 * \date   October 2015
 * \brief  Traceroute results class for dublin-traceroute
 *
 * This file contains the Traceroute results class for dublin-traceroute.
 *
 * This class is a container for a per-flow hops representation, and offers
 * facilities to print the traceroute output and convert it to a JSON
 * representation.
 *
 * \sa traceroute_results.h
 */

#include <random>
#include <future>

#include "dublintraceroute/traceroute_results.h"
#include "dublintraceroute/icmp_messages.h"

TracerouteResults::TracerouteResults(std::shared_ptr<flow_map_t> flows):
		flows_(flows), compressed_(false) {
}

std::shared_ptr<IP> TracerouteResults::match_packet(const Packet &packet) {
	// Is this an IP packet?
	IP ip;
	try {
		ip = packet.pdu()->rfind_pdu<IP>();
	} catch (pdu_not_found) {
		return nullptr;
	}

	// Does it contain an ICMP response?
	ICMP icmp;
	try {
		icmp = ip.rfind_pdu<ICMP>();
	} catch (pdu_not_found) {
		return nullptr;
	}

	// does the ICMP contain an inner IP packet sent by us?
	IP inner_ip;
	try {
		inner_ip = icmp.rfind_pdu<RawPDU>().to<IP>();
	} catch (pdu_not_found) {
		return nullptr;
	}

	// does the inner packet contain our original UDP packet?
	UDP inner_udp;
	try {
		inner_udp = inner_ip.rfind_pdu<UDP>();
	} catch (pdu_not_found) {
		return nullptr;
	}

	// Try to match the received packet against the sent packets. The flow
	// is identified by the UDP destination port
	auto flow_id = inner_udp.dport();
	// FIXME this can throw std::out_of_range
	hops_t hops(flows().at(flow_id));

	unsigned int index = 0;
	for (auto &hop: *hops) {
		auto &sent = hop.sent()->rfind_pdu<IP>();
		if (sent.src_addr() != inner_ip.src_addr())
			continue;
		auto &udp = hop.sent()->rfind_pdu<UDP>();
		/*
		 * The original paris-traceroute would match the checksum, but
		 * this does not work when there is NAT translation. Using the
		 * IP ID to match the packets works through NAT rewriting
		 * instead, and only requires the inner IP layer, which is
		 * guaranteed to return entirely in ICMP ttl-exceeded responses.
		 *
		 * To use the paris-traceroute approach, undefine
		 * USE_IP_ID_MATCHING in common.h .
		 */
#ifdef USE_IP_ID_MATCHING
		if (udp.checksum() == inner_ip.id()) {
#else /* USE_IP_ID_MATCHING */
		 if (udp.checksum() == inner_udp.checksum()) {
#endif /* USE_IP_ID_MATCHING */
			try {
				hop.received(ip, packet.timestamp());
				return std::make_shared<IP>(ip);
			} catch (std::out_of_range) {
				// this should never happen
				throw;
			}
		}
		index++;
	}

	return nullptr;
}

void TracerouteResults::show(std::ostream &stream) {
	compress();
	icmpmessages icmpm;

	for (auto &iter: flows()) {
		unsigned int hopnum = 1;
		unsigned int index = 0;
		uint16_t prev_nat_id = 0;
		stream << "== Flow ID " << iter.first << " ==" << std::endl;
		for (auto &hop: *iter.second) {
			stream << hopnum << "    ";
			if (!hop) {
				stream << "*" << std::endl;
			} else {
				// print the IP address of the hop
				stream << hop.received()->src_addr() << " (" << *hop.name() << ")";

				// print the response IP ID, useful to detect
				// loops due to NATs, fake hops, etc
				stream << ", IP ID: " << hop.received()->id();

				// print the RTT
				std::stringstream rttss;
				rttss << (hop.rtt() / 1000) << "." << (hop.rtt() % 1000) << " ms ";
				stream << " RTT " << rttss.str();

				// print the ICMP type and code
				ICMP icmp;
				try {
					icmp = hop.received()->rfind_pdu<ICMP>();
					stream << " ICMP "
						<< "(type=" << icmp.type() << ", code=" << static_cast<int>(icmp.code()) << ") '"
						<< icmpm.get(icmp.type(), icmp.code()) << "'";
					if (icmp.has_extensions()) {
						for (auto &extension : icmp.extensions().extensions()) {

							if (extension.extension_class() == ICMP_EXTENSION_MPLS_CLASS && extension.extension_type() == ICMP_EXTENSION_MPLS_TYPE) {
								unsigned int label = (extension.payload()[0] << 12) + (extension.payload()[1] << 4) + (extension.payload()[2] >> 4);
								unsigned int experimental = (extension.payload()[2] & 0xf) >> 1;
								unsigned int bottom_of_stack = extension.payload()[2] & 0x1;
								unsigned int ttl = extension.payload()[3];
								stream << ", MPLS(label=" << label << ", experimental=" << experimental << ", bottom_of_stack=" << bottom_of_stack << ", ttl=" << ttl << ")";
							} else {
								stream
									<< ", Extension("
									<< "class=" << static_cast<int>(extension.extension_class())
									<< ", type=" << static_cast<int>(extension.extension_type())
									<< ", payload_size=" << static_cast<int>(extension.payload().size())
									<< ", payload=\"";
								for (auto &byte : extension.payload())
									stream << "\\x" << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>(byte);
								stream << std::dec;
								stream << ")";
							}
						}
					}
				} catch (pdu_not_found) {
				}

				/* NAT detection.
				 * Note that if the previous hop was not
				 * responding, the detected NAT could have been
				 * started before
				 */
				auto inner_ip = hop.received()->rfind_pdu<RawPDU>().to<IP>();
				stream << ", NAT ID: " << hop.nat_id();
				if (hopnum > 1 && hop.nat_id() != prev_nat_id)
					stream << " (NAT detected)";
				prev_nat_id = hop.nat_id();

				stream << std::endl;

			}
			// Break if we reached the target hop
			if (hop.is_last_hop())
				break;
			hopnum++;
			index++;
		}
	}
}

void TracerouteResults::compress() {
	/** \brief compress the traceroute graph
	 *
	 * Compress the traceroute graph in order to remove repetitions of
	 * non-responding hops (i.e. the ones that show a "*" in a traceroute).
	 *
	 * Implementation note: this is not actually a compression, since the
	 * traceroute is not implemented (yet) as a graph, but this will come in
	 * a future release. Currently this method simply marks the first
	 * non-responding hop at the end of a path as last-hop.
	 *
	 * It is safe to call this method multiple times, and there is no
	 * performance penalty.
	 */
	if (compressed_)
		return;
	for (auto &iter: flows()) {
		IPv4Address target = iter.second->at(0).sent()->dst_addr();
		for (auto hop = iter.second->rbegin(); hop != iter.second->rend(); hop++) {
			// TODO also check for ICMP type==3 and code==3
			if (hop->received()) {
				if (hop->received()->src_addr() != target)
					break;
			}
			hop->is_last_hop(true);
		}
	}
	compressed_ = true;
}

std::string TracerouteResults::to_json() {
	std::stringstream json;
	Json::Value root;

	for (auto &iter: flows()) {
		auto flow_id = std::to_string(iter.first);
		Json::Value hops(Json::arrayValue);
		for (auto &hop: *iter.second) {
			hops.append(hop.to_json());
			if (hop.is_last_hop())
				break;
		}
		root["flows"][flow_id] = hops;
	}

	json << root;
	return json.str();
}
<commit_msg>Corrected ICMP extensions printing logic<commit_after>/**
 * \file   traceroute_results.cc
 * \author Andrea Barberio <insomniac@slackware.it>
 * \copyright 2-clause BSD
 * \date   October 2015
 * \brief  Traceroute results class for dublin-traceroute
 *
 * This file contains the Traceroute results class for dublin-traceroute.
 *
 * This class is a container for a per-flow hops representation, and offers
 * facilities to print the traceroute output and convert it to a JSON
 * representation.
 *
 * \sa traceroute_results.h
 */

#include <random>
#include <future>

#include "dublintraceroute/traceroute_results.h"
#include "dublintraceroute/icmp_messages.h"

TracerouteResults::TracerouteResults(std::shared_ptr<flow_map_t> flows):
		flows_(flows), compressed_(false) {
}

std::shared_ptr<IP> TracerouteResults::match_packet(const Packet &packet) {
	// Is this an IP packet?
	IP ip;
	try {
		ip = packet.pdu()->rfind_pdu<IP>();
	} catch (pdu_not_found) {
		return nullptr;
	}

	// Does it contain an ICMP response?
	ICMP icmp;
	try {
		icmp = ip.rfind_pdu<ICMP>();
	} catch (pdu_not_found) {
		return nullptr;
	}

	// does the ICMP contain an inner IP packet sent by us?
	IP inner_ip;
	try {
		inner_ip = icmp.rfind_pdu<RawPDU>().to<IP>();
	} catch (pdu_not_found) {
		return nullptr;
	}

	// does the inner packet contain our original UDP packet?
	UDP inner_udp;
	try {
		inner_udp = inner_ip.rfind_pdu<UDP>();
	} catch (pdu_not_found) {
		return nullptr;
	}

	// Try to match the received packet against the sent packets. The flow
	// is identified by the UDP destination port
	auto flow_id = inner_udp.dport();
	// FIXME this can throw std::out_of_range
	hops_t hops(flows().at(flow_id));

	unsigned int index = 0;
	for (auto &hop: *hops) {
		auto &sent = hop.sent()->rfind_pdu<IP>();
		if (sent.src_addr() != inner_ip.src_addr())
			continue;
		auto &udp = hop.sent()->rfind_pdu<UDP>();
		/*
		 * The original paris-traceroute would match the checksum, but
		 * this does not work when there is NAT translation. Using the
		 * IP ID to match the packets works through NAT rewriting
		 * instead, and only requires the inner IP layer, which is
		 * guaranteed to return entirely in ICMP ttl-exceeded responses.
		 *
		 * To use the paris-traceroute approach, undefine
		 * USE_IP_ID_MATCHING in common.h .
		 */
#ifdef USE_IP_ID_MATCHING
		if (udp.checksum() == inner_ip.id()) {
#else /* USE_IP_ID_MATCHING */
		 if (udp.checksum() == inner_udp.checksum()) {
#endif /* USE_IP_ID_MATCHING */
			try {
				hop.received(ip, packet.timestamp());
				return std::make_shared<IP>(ip);
			} catch (std::out_of_range) {
				// this should never happen
				throw;
			}
		}
		index++;
	}

	return nullptr;
}

void TracerouteResults::show(std::ostream &stream) {
	compress();
	icmpmessages icmpm;

	for (auto &iter: flows()) {
		unsigned int hopnum = 1;
		unsigned int index = 0;
		uint16_t prev_nat_id = 0;
		stream << "== Flow ID " << iter.first << " ==" << std::endl;
		for (auto &hop: *iter.second) {
			stream << hopnum << "    ";
			if (!hop) {
				stream << "*" << std::endl;
			} else {
				// print the IP address of the hop
				stream << hop.received()->src_addr() << " (" << *hop.name() << ")";

				// print the response IP ID, useful to detect
				// loops due to NATs, fake hops, etc
				stream << ", IP ID: " << hop.received()->id();

				// print the RTT
				std::stringstream rttss;
				rttss << (hop.rtt() / 1000) << "." << (hop.rtt() % 1000) << " ms ";
				stream << " RTT " << rttss.str();

				// print the ICMP type and code
				ICMP icmp;
				try {
					icmp = hop.received()->rfind_pdu<ICMP>();
					stream << " ICMP "
						<< "(type=" << icmp.type() << ", code=" << static_cast<int>(icmp.code()) << ") '"
						<< icmpm.get(icmp.type(), icmp.code()) << "'";
					if (icmp.has_extensions()) {
						for (auto &extension : icmp.extensions().extensions()) {

							if (static_cast<int>(extension.extension_class()) == ICMP_EXTENSION_MPLS_CLASS && static_cast<int>(extension.extension_type()) == ICMP_EXTENSION_MPLS_TYPE) {
								stream
									<< ", Extension("
									<< "class=" << static_cast<int>(extension.extension_class())
									<< ", type=" << static_cast<int>(extension.extension_type())
									<< ", payload_size=" << static_cast<int>(extension.payload().size())
									<< ", payload=\"";
								for (auto &byte : extension.payload())
									stream << "\\x" << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>(byte);
								stream << std::dec;
								stream << ")";
							} else {
								unsigned int label = (extension.payload()[0] << 12) + (extension.payload()[1] << 4) + (extension.payload()[2] >> 4);
								unsigned int experimental = (extension.payload()[2] & 0xf) >> 1;
								unsigned int bottom_of_stack = extension.payload()[2] & 0x1;
								unsigned int ttl = extension.payload()[3];
								stream << ", MPLS(label=" << label << ", experimental=" << experimental << ", bottom_of_stack=" << bottom_of_stack << ", ttl=" << ttl << ")";
							}
						}
					}
				} catch (pdu_not_found) {
				}

				/* NAT detection.
				 * Note that if the previous hop was not
				 * responding, the detected NAT could have been
				 * started before
				 */
				auto inner_ip = hop.received()->rfind_pdu<RawPDU>().to<IP>();
				stream << ", NAT ID: " << hop.nat_id();
				if (hopnum > 1 && hop.nat_id() != prev_nat_id)
					stream << " (NAT detected)";
				prev_nat_id = hop.nat_id();

				stream << std::endl;

			}
			// Break if we reached the target hop
			if (hop.is_last_hop())
				break;
			hopnum++;
			index++;
		}
	}
}

void TracerouteResults::compress() {
	/** \brief compress the traceroute graph
	 *
	 * Compress the traceroute graph in order to remove repetitions of
	 * non-responding hops (i.e. the ones that show a "*" in a traceroute).
	 *
	 * Implementation note: this is not actually a compression, since the
	 * traceroute is not implemented (yet) as a graph, but this will come in
	 * a future release. Currently this method simply marks the first
	 * non-responding hop at the end of a path as last-hop.
	 *
	 * It is safe to call this method multiple times, and there is no
	 * performance penalty.
	 */
	if (compressed_)
		return;
	for (auto &iter: flows()) {
		IPv4Address target = iter.second->at(0).sent()->dst_addr();
		for (auto hop = iter.second->rbegin(); hop != iter.second->rend(); hop++) {
			// TODO also check for ICMP type==3 and code==3
			if (hop->received()) {
				if (hop->received()->src_addr() != target)
					break;
			}
			hop->is_last_hop(true);
		}
	}
	compressed_ = true;
}

std::string TracerouteResults::to_json() {
	std::stringstream json;
	Json::Value root;

	for (auto &iter: flows()) {
		auto flow_id = std::to_string(iter.first);
		Json::Value hops(Json::arrayValue);
		for (auto &hop: *iter.second) {
			hops.append(hop.to_json());
			if (hop.is_last_hop())
				break;
		}
		root["flows"][flow_id] = hops;
	}

	json << root;
	return json.str();
}
<|endoftext|>


<commit_before>/*
 * Copyright 2007-2020 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * 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.
 *
 * 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
 * FOUNDATION 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.
 */

#pragma once

#include "Service.hxx"

#include <vector>

/**
 * Wrapper for multiple #TranslationService.  This class implements
 * #TranslationCommand::DEFER.
 */
class MultiTranslationService final : public TranslationService {
	using List = std::vector<TranslationService *>;

	List items;

	class Request;

public:
	void Add(TranslationService *service) noexcept {
		items.push_back(service);
	}

	/* virtual methods from class TranslationService */
	void SendRequest(struct pool &pool,
			 const TranslateRequest &request,
			 const StopwatchPtr &parent_stopwatch,
			 TranslateHandler &handler,
			 CancellablePointer &cancel_ptr) noexcept override;
};
<commit_msg>translation/Multi: add template constructor<commit_after>/*
 * Copyright 2007-2020 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * 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.
 *
 * 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
 * FOUNDATION 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.
 */

#pragma once

#include "Service.hxx"

#include <vector>

/**
 * Wrapper for multiple #TranslationService.  This class implements
 * #TranslationCommand::DEFER.
 */
class MultiTranslationService final : public TranslationService {
	using List = std::vector<TranslationService *>;

	List items;

	class Request;

public:
	MultiTranslationService() = default;

	template<typename T>
	explicit MultiTranslationService(T &&t) noexcept {
		for (auto &i : t)
			Add(&i);
	}

	void Add(TranslationService *service) noexcept {
		items.push_back(service);
	}

	/* virtual methods from class TranslationService */
	void SendRequest(struct pool &pool,
			 const TranslateRequest &request,
			 const StopwatchPtr &parent_stopwatch,
			 TranslateHandler &handler,
			 CancellablePointer &cancel_ptr) noexcept override;
};
<|endoftext|>


<commit_before>/*
===========================================================================

daemon gpl source code
copyright (c) 2013 unvanquished developers

this file is part of the daemon gpl source code (daemon source code).

daemon source code is free software: you can redistribute it and/or modify
it under the terms of the gnu general public license as published by
the free software foundation, either version 3 of the license, or
(at your option) any later version.

daemon source code 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 general public license for more details.

you should have received a copy of the gnu general public license
along with daemon source code.  if not, see <http://www.gnu.org/licenses/>.

===========================================================================
*/

#include "AudioPrivate.h"

namespace Audio {

    // Implementation of Sample

    Sample::Sample(std::string name): HandledResource<Sample>(this), refCount(0), name(std::move(name)) {
    }

    Sample::~Sample() {
    }

    void Sample::Use() {
    }

    AL::Buffer& Sample::GetBuffer() {
        return buffer;
    }

    void Sample::Retain() {
        refCount ++;
    }

    void Sample::Release() {
        refCount --;
    }

    int Sample::GetRefCount() {
        return refCount;
    }

    const std::string& Sample::GetName() {
        return name;
    }

    // Implementation of the sample storage

    static std::unordered_map<std::string, Sample*> samples;

    static Sample* errorSample = nullptr;
    bool initialized = false;

    void InitSamples() {
        if (initialized) {
            return;
        }
        //TODO make an error if it can't register
        //TODO use an aggressive sound instead to know we are missing something?
        errorSample = RegisterSample("sound/feedback/hit.wav");
        initialized = true;
    }

    void ShutdownSamples() {
        if (not initialized) {
            return;
        }

        for (auto it: samples) {
            delete it.second;
        }
        samples.clear();

        initialized = false;
    }

	std::vector<std::string> ListSamples() {
		if (not initialized) {
			return {};
		}

		std::vector<std::string> res;

		for (auto& it : samples) {
			res.push_back(it.first);
		}

		return res;
	}

    Sample* RegisterSample(Str::StringRef filename) {
        auto it = samples.find(filename);
        if (it != samples.end()) {
            return it->second;
        }

        snd_info_t info;
        void* data = S_CodecLoad(filename.c_str(), &info);

        if (data == nullptr) {
            audioLogs.Warn("Couldn't load sound %s", filename);
            return errorSample;
        }

        Sample* sample = new Sample(std::move(filename));
        samples[filename] = sample;

        //TODO handle errors, especially out of memeory errors
        sample->GetBuffer().Feed(info, data);

        if (info.size == 0) {
            audioLogs.Warn("info.size = 0 in RegisterSample, what?");
        }

        Hunk_FreeTempMemory(data);

        return sample;
    }
}
<commit_msg>Audio: error out instead of crashing when the error sample cannot be loaded.<commit_after>/*
===========================================================================

daemon gpl source code
copyright (c) 2013 unvanquished developers

this file is part of the daemon gpl source code (daemon source code).

daemon source code is free software: you can redistribute it and/or modify
it under the terms of the gnu general public license as published by
the free software foundation, either version 3 of the license, or
(at your option) any later version.

daemon source code 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 general public license for more details.

you should have received a copy of the gnu general public license
along with daemon source code.  if not, see <http://www.gnu.org/licenses/>.

===========================================================================
*/

#include "AudioPrivate.h"

namespace Audio {

    // Implementation of Sample

    Sample::Sample(std::string name): HandledResource<Sample>(this), refCount(0), name(std::move(name)) {
    }

    Sample::~Sample() {
    }

    void Sample::Use() {
    }

    AL::Buffer& Sample::GetBuffer() {
        return buffer;
    }

    void Sample::Retain() {
        refCount ++;
    }

    void Sample::Release() {
        refCount --;
    }

    int Sample::GetRefCount() {
        return refCount;
    }

    const std::string& Sample::GetName() {
        return name;
    }

    // Implementation of the sample storage

    static std::unordered_map<std::string, Sample*> samples;

    static const std::string errorSampleName = "sound/feedback/hit.wav";
    static Sample* errorSample = nullptr;
    bool initialized = false;

    void InitSamples() {
        if (initialized) {
            return;
        }
        //TODO use an aggressive sound instead to know we are missing something?
        errorSample = RegisterSample(errorSampleName);

        if (!errorSample) {
            Com_Error(ERR_FATAL, "Couldn't load the error sound sample '%s'", errorSampleName.c_str());
        }

        initialized = true;
    }

    void ShutdownSamples() {
        if (not initialized) {
            return;
        }

        for (auto it: samples) {
            delete it.second;
        }
        samples.clear();

        errorSample = nullptr;

        initialized = false;
    }

	std::vector<std::string> ListSamples() {
		if (not initialized) {
			return {};
		}

		std::vector<std::string> res;

		for (auto& it : samples) {
			res.push_back(it.first);
		}

		return res;
	}

    Sample* RegisterSample(Str::StringRef filename) {
        auto it = samples.find(filename);
        if (it != samples.end()) {
            return it->second;
        }

        snd_info_t info;
        void* data = S_CodecLoad(filename.c_str(), &info);

        if (data == nullptr) {
            audioLogs.Warn("Couldn't load sound %s", filename);
            return errorSample;
        }

        Sample* sample = new Sample(std::move(filename));
        samples[filename] = sample;

        //TODO handle errors, especially out of memeory errors
        sample->GetBuffer().Feed(info, data);

        if (info.size == 0) {
            audioLogs.Warn("info.size = 0 in RegisterSample, what?");
        }

        Hunk_FreeTempMemory(data);

        return sample;
    }
}
<|endoftext|>