<commit_before>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009-2010 Bastian Holst <bastianholst@gmx.de>
//

// Self
#include "ScreenGraphicsItem.h"
#include "ScreenGraphicsItem_p.h"

// Marble
#include "MarbleDebug.h"
#include "MarbleWidget.h"

// Qt
#include <QtGui/QMouseEvent>

using namespace Marble;

ScreenGraphicsItem::ScreenGraphicsItem( MarbleGraphicsItem *parent )
    : MarbleGraphicsItem( new ScreenGraphicsItemPrivate( this, parent ) )
{
}

ScreenGraphicsItem::ScreenGraphicsItem( ScreenGraphicsItemPrivate *d_ptr )
    : MarbleGraphicsItem( d_ptr )
{
}

ScreenGraphicsItem::~ScreenGraphicsItem()
{
}

QPointF ScreenGraphicsItem::position() const
{
    return p()->m_position;
}

void ScreenGraphicsItem::setPosition( const QPointF& position )
{
    p()->m_position = position;
}

QPointF ScreenGraphicsItem::positivePosition() const
{
    return p()->positivePosition();
}

QList<QPointF> ScreenGraphicsItem::absolutePositions() const
{
    return p()->absolutePositions();
}

ScreenGraphicsItem::GraphicsItemFlags ScreenGraphicsItem::flags() const
{
    return p()->m_flags;
}

void ScreenGraphicsItem::setFlags( ScreenGraphicsItem::GraphicsItemFlags flags )
{
    p()->m_flags = flags;
}

void ScreenGraphicsItem::changeViewport( ViewportParams *viewport )
{
    Q_UNUSED( viewport );
}

bool ScreenGraphicsItem::eventFilter( QObject *object, QEvent *e )
{
    MarbleWidget *widget = dynamic_cast<MarbleWidget*>(object);
    if ( !widget ) {
        return MarbleGraphicsItem::eventFilter( object, e );
    }

    if ( !p()->m_floatItemMoving ) {
        if ( MarbleGraphicsItem::eventFilter( object, e ) ) {
            return true;
        }

        if ( !visible() || !p()->isMovable() ) {
            return false;
        }

        if ( e->type() == QEvent::MouseMove ) {
            return false;
        }

        // Move ScreenGraphicsItem
        if ( e->type() == QEvent::MouseButtonPress )
        {
            QMouseEvent *event = static_cast<QMouseEvent*>(e);

            // Click and move above a float item triggers moving the float item
            if ( contains( event->pos() ) ) {
                if ( event->button() == Qt::LeftButton ) {
                    p()->m_floatItemMoveStartPos = event->pos();
                    p()->m_floatItemMoving = true;
                    return true;
                }
            }
        }

        return false;
    }
    else {
        // Move ScreenGraphicsItem
        if ( e->type() == QEvent::MouseMove
            || e->type() == QEvent::MouseButtonPress
            || e->type() == QEvent::MouseButtonRelease )
        {
            QMouseEvent *event = static_cast<QMouseEvent*>( e );
            // The rect the item was painted on before. We add one pixel as antialiasing could
            // result into painting on these pixels to.
            QRectF floatItemRect = QRectF( positivePosition() - QPoint( 1, 1 ),
                                           size() + QSize( 2, 2 ) );

            const bool cursorAboveFloatItem = contains( event->pos() );

            // Click and move above a float item triggers moving the float item
            if ( e->type() == QEvent::MouseButtonPress && event->button() == Qt::LeftButton ) {
                if ( cursorAboveFloatItem ) {
                    p()->m_floatItemMoveStartPos = event->pos();
                    return true;
                }
            }

            if ( e->type() == QEvent::MouseMove && event->buttons() & Qt::LeftButton ) {
                if ( p()->isMovable() ) {
                    p()->m_floatItemMoving = true;
                    const QPoint &point = event->pos();
                    QPointF position = positivePosition();
                    qreal newX = qMax( 0., position.x()+point.x()-p()->m_floatItemMoveStartPos.x() );
                    qreal newY = qMax( 0., position.y()+point.y()-p()->m_floatItemMoveStartPos.y() );

                    // docking behavior
                    const qreal dockArea = 60.0; // Alignment area width/height
                    const qreal dockJump = 30.0; // Alignment indicator jump size
                    if ( widget->width()-size().width()-newX < dockArea ) {
                        newX = qMin( qreal( -1.0 ), size().width() + newX-widget->width() );
                        if ( p()->m_floatItemMoveStartPos.x() < event->pos().x() ) {
                            // Indicate change to right alignment with a short jump
                            newX = qMax( newX, -(dockArea-dockJump) );
                        }
                    }
                    if ( widget->height()-size().height()-newY < dockArea ) {
                        newY = qMin( qreal( -1.0 ), size().height() + newY-widget->height() );
                        if (p()->m_floatItemMoveStartPos.y()<event->pos().y()) {
                        // Indicate change to bottom alignment with a short jump
                        newY = qMax( newY, -( dockArea - dockJump ) );
                        }
                    }

                    setPosition( QPointF( newX,newY ) );
                    // The rect the item will be painted on now. We add one pixel as
                    // antialiasing could result into painting on these pixels to.
                    QRect newFloatItemRect = QRectF( positivePosition() - QPoint( 1, 1 ),
                                                     size() + QSize( 2, 2 ) ).toRect();
                    p()->m_floatItemMoveStartPos = event->pos();
                    QRegion dirtyRegion( floatItemRect.toRect() );
                    dirtyRegion = dirtyRegion.united( newFloatItemRect );

                    widget->setAttribute( Qt::WA_NoSystemBackground,  false );
                    widget->update(dirtyRegion);
                    widget->setAttribute( Qt::WA_NoSystemBackground, widget->viewport()->mapCoversViewport() );
                    return true;
                }
            }

            if ( e->type() == QEvent::MouseButtonRelease ) {
                p()->m_floatItemMoving = false;
            }

            // Adjusting Cursor shape
            if ( cursorAboveFloatItem || p()->m_floatItemMoving ) {
                widget->setCursor(QCursor(Qt::SizeAllCursor));
                return true;
            }
        }

        return MarbleGraphicsItem::eventFilter( object, e );
    }
}

ScreenGraphicsItemPrivate *ScreenGraphicsItem::p() const
{
    return reinterpret_cast<ScreenGraphicsItemPrivate *>( d );
}
<commit_msg>mark ScreenGraphicsItem as moving as soon as the mouse button is pressed<commit_after>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009-2010 Bastian Holst <bastianholst@gmx.de>
//

// Self
#include "ScreenGraphicsItem.h"
#include "ScreenGraphicsItem_p.h"

// Marble
#include "MarbleDebug.h"
#include "MarbleWidget.h"

// Qt
#include <QtGui/QMouseEvent>

using namespace Marble;

ScreenGraphicsItem::ScreenGraphicsItem( MarbleGraphicsItem *parent )
    : MarbleGraphicsItem( new ScreenGraphicsItemPrivate( this, parent ) )
{
}

ScreenGraphicsItem::ScreenGraphicsItem( ScreenGraphicsItemPrivate *d_ptr )
    : MarbleGraphicsItem( d_ptr )
{
}

ScreenGraphicsItem::~ScreenGraphicsItem()
{
}

QPointF ScreenGraphicsItem::position() const
{
    return p()->m_position;
}

void ScreenGraphicsItem::setPosition( const QPointF& position )
{
    p()->m_position = position;
}

QPointF ScreenGraphicsItem::positivePosition() const
{
    return p()->positivePosition();
}

QList<QPointF> ScreenGraphicsItem::absolutePositions() const
{
    return p()->absolutePositions();
}

ScreenGraphicsItem::GraphicsItemFlags ScreenGraphicsItem::flags() const
{
    return p()->m_flags;
}

void ScreenGraphicsItem::setFlags( ScreenGraphicsItem::GraphicsItemFlags flags )
{
    p()->m_flags = flags;
}

void ScreenGraphicsItem::changeViewport( ViewportParams *viewport )
{
    Q_UNUSED( viewport );
}

bool ScreenGraphicsItem::eventFilter( QObject *object, QEvent *e )
{
    MarbleWidget *widget = dynamic_cast<MarbleWidget*>(object);
    if ( !widget ) {
        return MarbleGraphicsItem::eventFilter( object, e );
    }

    if ( !p()->m_floatItemMoving ) {
        if ( MarbleGraphicsItem::eventFilter( object, e ) ) {
            return true;
        }

        if ( !visible() || !p()->isMovable() ) {
            return false;
        }

        if ( e->type() == QEvent::MouseMove ) {
            return false;
        }

        // Move ScreenGraphicsItem
        if ( e->type() == QEvent::MouseButtonPress )
        {
            QMouseEvent *event = static_cast<QMouseEvent*>(e);

            // Click and move above a float item triggers moving the float item
            if ( contains( event->pos() ) ) {
                if ( event->button() == Qt::LeftButton ) {
                    p()->m_floatItemMoveStartPos = event->pos();
                    p()->m_floatItemMoving = true;
                    return true;
                }
            }
        }

        return false;
    }
    else {
        // Move ScreenGraphicsItem
        if ( e->type() == QEvent::MouseMove
            || e->type() == QEvent::MouseButtonPress
            || e->type() == QEvent::MouseButtonRelease )
        {
            QMouseEvent *event = static_cast<QMouseEvent*>( e );
            // The rect the item was painted on before. We add one pixel as antialiasing could
            // result into painting on these pixels to.
            QRectF floatItemRect = QRectF( positivePosition() - QPoint( 1, 1 ),
                                           size() + QSize( 2, 2 ) );

            const bool cursorAboveFloatItem = contains( event->pos() );

            // Click and move above a float item triggers moving the float item
            if ( e->type() == QEvent::MouseButtonPress && event->button() == Qt::LeftButton ) {
                if ( cursorAboveFloatItem && p()->isMovable() ) {
                    p()->m_floatItemMoving = true;
                    p()->m_floatItemMoveStartPos = event->pos();
                    return true;
                }
            }

            if ( e->type() == QEvent::MouseMove && event->buttons() & Qt::LeftButton ) {
                if ( p()->m_floatItemMoving ) {
                    const QPoint &point = event->pos();
                    QPointF position = positivePosition();
                    qreal newX = qMax( 0., position.x()+point.x()-p()->m_floatItemMoveStartPos.x() );
                    qreal newY = qMax( 0., position.y()+point.y()-p()->m_floatItemMoveStartPos.y() );

                    // docking behavior
                    const qreal dockArea = 60.0; // Alignment area width/height
                    const qreal dockJump = 30.0; // Alignment indicator jump size
                    if ( widget->width()-size().width()-newX < dockArea ) {
                        newX = qMin( qreal( -1.0 ), size().width() + newX-widget->width() );
                        if ( p()->m_floatItemMoveStartPos.x() < event->pos().x() ) {
                            // Indicate change to right alignment with a short jump
                            newX = qMax( newX, -(dockArea-dockJump) );
                        }
                    }
                    if ( widget->height()-size().height()-newY < dockArea ) {
                        newY = qMin( qreal( -1.0 ), size().height() + newY-widget->height() );
                        if (p()->m_floatItemMoveStartPos.y()<event->pos().y()) {
                        // Indicate change to bottom alignment with a short jump
                        newY = qMax( newY, -( dockArea - dockJump ) );
                        }
                    }

                    setPosition( QPointF( newX,newY ) );
                    // The rect the item will be painted on now. We add one pixel as
                    // antialiasing could result into painting on these pixels to.
                    QRect newFloatItemRect = QRectF( positivePosition() - QPoint( 1, 1 ),
                                                     size() + QSize( 2, 2 ) ).toRect();
                    p()->m_floatItemMoveStartPos = event->pos();
                    QRegion dirtyRegion( floatItemRect.toRect() );
                    dirtyRegion = dirtyRegion.united( newFloatItemRect );

                    widget->setAttribute( Qt::WA_NoSystemBackground,  false );
                    widget->update(dirtyRegion);
                    widget->setAttribute( Qt::WA_NoSystemBackground, widget->viewport()->mapCoversViewport() );
                    return true;
                }
            }

            if ( e->type() == QEvent::MouseButtonRelease ) {
                p()->m_floatItemMoving = false;
            }

            // Adjusting Cursor shape
            if ( cursorAboveFloatItem || p()->m_floatItemMoving ) {
                widget->setCursor(QCursor(Qt::SizeAllCursor));
                return true;
            }
        }

        return MarbleGraphicsItem::eventFilter( object, e );
    }
}

ScreenGraphicsItemPrivate *ScreenGraphicsItem::p() const
{
    return reinterpret_cast<ScreenGraphicsItemPrivate *>( d );
}
<|endoftext|>


<commit_before>/* Copyright 2016 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/contrib/session_bundle/bundle_shim.h"

#include "tensorflow/cc/saved_model/loader.h"
#include "tensorflow/cc/saved_model/signature_constants.h"
#include "tensorflow/contrib/session_bundle/manifest.pb.h"
#include "tensorflow/contrib/session_bundle/session_bundle.h"
#include "tensorflow/contrib/session_bundle/signature.h"
#include "tensorflow/core/graph/graph_constructor.h"
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/core/status.h"
#include "tensorflow/core/lib/core/stringpiece.h"
#include "tensorflow/core/protobuf/meta_graph.pb.h"
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/public/session_options.h"

namespace tensorflow {
namespace serving {
namespace {
///////////////////////////////////////////////////////////////////////////////
// Helper functions to check Signature type.

bool IsClassificationSignature(const Signature& signature) {
  return signature.type_case() == Signature::kClassificationSignature;
}

bool IsRegressionSignature(const Signature& signature) {
  return signature.type_case() == Signature::kRegressionSignature;
}

///////////////////////////////////////////////////////////////////////////////
// Helper functions to build `Classification`, `Regression` and `Predict`
// SignatureDefs.

SignatureDef BuildRegressionSignatureDef(
    const RegressionSignature& regression_signature,
    const std::unordered_map<string, DataType>& tensor_name_to_dtype) {
  SignatureDef signature_def;
  signature_def.set_method_name(kRegressMethodName);
  internal::AddInputToSignatureDef(regression_signature.input().tensor_name(),
                                   tensor_name_to_dtype, kRegressInputs,
                                   &signature_def);
  internal::AddOutputToSignatureDef(regression_signature.output().tensor_name(),
                                    tensor_name_to_dtype, kRegressOutputs,
                                    &signature_def);
  return signature_def;
}

SignatureDef BuildClassificationSignatureDef(
    const ClassificationSignature& classification_signature,
    const std::unordered_map<string, DataType>& tensor_name_to_dtype) {
  SignatureDef signature_def;
  signature_def.set_method_name(kClassifyMethodName);
  internal::AddInputToSignatureDef(
      classification_signature.input().tensor_name(), tensor_name_to_dtype,
      kClassifyInputs, &signature_def);
  internal::AddOutputToSignatureDef(
      classification_signature.classes().tensor_name(), tensor_name_to_dtype,
      kClassifyOutputClasses, &signature_def);
  internal::AddOutputToSignatureDef(
      classification_signature.scores().tensor_name(), tensor_name_to_dtype,
      kClassifyOutputScores, &signature_def);
  return signature_def;
}

Status MaybeBuildPredictSignatureDef(
    const std::unordered_map<string, DataType>& tensor_name_to_dtype,
    MetaGraphDef* meta_graph_def) {
  Signature input_signature, output_signature;
  // Ensure that named signatures corresponding to `inputs` and `outputs` keys
  // exist.
  if (!GetNamedSignature(kPredictInputs, *meta_graph_def, &input_signature)
           .ok() ||
      !GetNamedSignature(kPredictOutputs, *meta_graph_def, &output_signature)
           .ok()) {
    return Status(error::Code::INVALID_ARGUMENT,
                  "Named signatures can only be up-converted if entries "
                  "corresponding to both `inputs` and `outputs` exist.");
  }
  // Ensure the `inputs` and `outputs` named signatures are generic signatures.
  if (input_signature.type_case() != Signature::TypeCase::kGenericSignature ||
      output_signature.type_case() != Signature::TypeCase::kGenericSignature) {
    return Status(error::Code::INVALID_ARGUMENT,
                  "Named signatures corresponding to `inputs` and `outputs` "
                  "can only be up-converted if they are GenericSignatures.");
  }
  SignatureDef signature_def;
  signature_def.set_method_name(kPredictMethodName);
  // Add map entries from the `inputs` generic signature to the input map in the
  // signature def.
  for (const auto& map_entry : input_signature.generic_signature().map()) {
    internal::AddInputToSignatureDef(map_entry.second.tensor_name(),
                                     tensor_name_to_dtype, map_entry.first,
                                     &signature_def);
  }
  // Add map entries from the `outputs` generic signature to the output map in
  // the signature def.
  for (const auto& map_entry : output_signature.generic_signature().map()) {
    internal::AddOutputToSignatureDef(map_entry.second.tensor_name(),
                                      tensor_name_to_dtype, map_entry.first,
                                      &signature_def);
  }
  // Add the constructed signature def to the signature def map of the meta
  // graph def. Use the default key if it isn't already in use.
  const bool already_has_default_signature =
      meta_graph_def->signature_def().find(kDefaultServingSignatureDefKey) !=
      meta_graph_def->signature_def().end();
  const string signature_def_key =
      already_has_default_signature
          ? strings::StrCat(kDefaultServingSignatureDefKey, "_from_named")
          : kDefaultServingSignatureDefKey;
  (*meta_graph_def->mutable_signature_def())[signature_def_key] = signature_def;
  return Status::OK();
}

Status LoadSavedModelFromLegacySessionBundlePath(
    const SessionOptions& session_options, const RunOptions& run_options,
    const StringPiece session_bundle_export_dir,
    SavedModelBundle* saved_model_bundle) {
  if (session_bundle_export_dir.empty()) {
    return Status(error::Code::NOT_FOUND, "Export directory path is empty.");
  }
  if (!IsPossibleExportDirectory(session_bundle_export_dir)) {
    return Status(
        error::Code::NOT_FOUND,
        "Export directory does not contain a valid SessionBundle export.");
  }

  // Build the session-bundle.
  SessionBundle session_bundle;
  TF_RETURN_IF_ERROR(LoadSessionBundleFromPathUsingRunOptions(
      session_options, run_options, session_bundle_export_dir,
      &session_bundle));

  // Convert the session-bundle to a saved-model-bundle.
  return internal::ConvertSessionBundleToSavedModelBundle(session_bundle,
                                                          saved_model_bundle);
}

///////////////////////////////////////////////////////////////////////////////
// Helper functions to convert `Default` and `Named` signatures to
// SignatureDefs.

// Up-conversion of default signatures is supported for classification and
// regression.
Status ConvertDefaultSignatureToSignatureDef(
    const Signatures& signatures,
    const std::unordered_map<string, DataType>& tensor_name_to_dtype,
    MetaGraphDef* meta_graph_def) {
  if (!signatures.has_default_signature()) {
    return Status::OK();
  }
  const bool already_has_default_signature =
      meta_graph_def->signature_def().find(kDefaultServingSignatureDefKey) !=
      meta_graph_def->signature_def().end();
  if (already_has_default_signature) {
    return Status(error::Code::ALREADY_EXISTS,
                  strings::StrCat(
                      "Default signature cannot be up-converted since ",
                      kDefaultServingSignatureDefKey, " key already exists."));
  }
  const Signature& signature = signatures.default_signature();
  if (IsRegressionSignature(signature)) {
    (*meta_graph_def->mutable_signature_def())[kDefaultServingSignatureDefKey] =
        BuildRegressionSignatureDef(signature.regression_signature(),
                                    tensor_name_to_dtype);
  } else if (IsClassificationSignature(signature)) {
    (*meta_graph_def->mutable_signature_def())[kDefaultServingSignatureDefKey] =
        BuildClassificationSignatureDef(signature.classification_signature(),
                                        tensor_name_to_dtype);
  } else {
    LOG(WARNING) << "Default signature up-conversion to SignatureDef is only "
                    "supported for `Classification` and `Regression`. Could "
                    "not up-convert signature: "
                 << signature.DebugString()
                 << ". (If using SessionRun with the SessionBundle export "
                    "format please ignore this warning.)";
  }
  return Status::OK();
}

Status ConvertNamedSignaturesToSignatureDef(
    const Signatures& signatures,
    const std::unordered_map<string, DataType>& tensor_name_to_dtype,
    MetaGraphDef* meta_graph_def) {
  if (signatures.named_signatures().empty()) {
    return Status::OK();
  }
  // Check for a Predict signature for up-conversion.
  Status predict_signature_def_status =
      MaybeBuildPredictSignatureDef(tensor_name_to_dtype, meta_graph_def);
  for (const auto& it_named_signature : signatures.named_signatures()) {
    const string key = it_named_signature.first;
    // If a Predict SignatureDef was successfully constructed, skip the entries
    // corresponding to `inputs` and `outputs`.
    if (predict_signature_def_status.ok()) {
      if (key == kPredictInputs || key == kPredictOutputs) {
        continue;
      }
    }
    const Signature signature = it_named_signature.second;
    if (IsRegressionSignature(signature)) {
      (*meta_graph_def->mutable_signature_def())[key] =
          BuildRegressionSignatureDef(signature.regression_signature(),
                                      tensor_name_to_dtype);
    } else if (IsClassificationSignature(signature)) {
      (*meta_graph_def->mutable_signature_def())[key] =
          BuildClassificationSignatureDef(signature.classification_signature(),
                                          tensor_name_to_dtype);
    } else {
      LOG(WARNING)
          << "Named signature up-conversion to SignatureDef is only supported "
             "for `Classification`, `Regression` or if two `GenericSignatures` "
             "signatures  called `inputs` and `outputs` exist, corresponding "
             "to the `Prediction` API. Could not up-convert signature: "
          << signature.DebugString();
    }
  }
  return Status::OK();
}

}  // namespace

namespace internal {
///////////////////////////////////////////////////////////////////////////////
// Helper functions to populate SignatureDef fields.

// Adds an entry to the `inputs` map of the supplied SignatureDef.
void AddInputToSignatureDef(
    const string& tensor_name,
    const std::unordered_map<string, DataType>& tensor_name_to_dtype,
    const string& input_key, SignatureDef* signature_def) {
  if (tensor_name.empty()) {
    LOG(WARNING) << "Tensor name not provided. Cannot add TensorInfo to "
                    "SignatureDef inputs.";
    return;
  }
  // Extract the tensor-name in case the supplied string is a tensor-reference.
  // Example: Extract "x" from "x:0".
  std::size_t pos = tensor_name.find(":");
  const string key =
      (pos != std::string::npos) ? tensor_name.substr(0, pos) : tensor_name;
  const auto it_tensor_info = tensor_name_to_dtype.find(key);
  TensorInfo tensor_info;
  tensor_info.set_name(tensor_name);
  if (it_tensor_info != tensor_name_to_dtype.end()) {
    tensor_info.set_dtype(it_tensor_info->second);
  } else {
    LOG(WARNING)
        << "No dtype found for tensor with name: " << tensor_name << ". "
        << "Building TensorInfo with only name for SignatureDef inputs. "
        << "Downstream functionality including validation may be "
        << "impacted.";
  }
  (*signature_def->mutable_inputs())[input_key] = tensor_info;
}

// Adds an entry to the `outputs` map of the supplied SignatureDef.
void AddOutputToSignatureDef(
    const string& tensor_name,
    const std::unordered_map<string, DataType>& tensor_name_to_dtype,
    const string& output_key, SignatureDef* signature_def) {
  if (tensor_name.empty()) {
    LOG(WARNING) << "Tensor name not provided. Cannot add TensorInfo to "
                    "SignatureDef outputs.";
    return;
  }
  // Extract the tensor-name in case the supplied string is a tensor-reference.
  // Example: Extract "x" from "x:0".
  std::size_t pos = tensor_name.find(":");
  const string key =
      (pos != std::string::npos) ? tensor_name.substr(0, pos) : tensor_name;
  const auto it_tensor_info = tensor_name_to_dtype.find(key);
  TensorInfo tensor_info;
  tensor_info.set_name(tensor_name);
  if (it_tensor_info != tensor_name_to_dtype.end()) {
    tensor_info.set_dtype(it_tensor_info->second);
  } else {
    LOG(WARNING)
        << "No dtype found for tensor with name: " << tensor_name << ". "
        << "Building TensorInfo with only name for SignatureDef outputs."
        << " Downstream functionality including validation may be "
        << "impacted.";
  }
  (*signature_def->mutable_outputs())[output_key] = tensor_info;
}

// Builds a map from tensor name to the corresponding datatype, by parsing the
// MetaGraphDef.
Status BuildTensorNameToDtypeMap(
    const MetaGraphDef& meta_graph_def,
    std::unordered_map<string, DataType>* tensor_name_to_dtype) {
  GraphConstructorOptions opts;
  Graph graph(OpRegistry::Global());
  TF_RETURN_IF_ERROR(
      ConvertGraphDefToGraph(opts, meta_graph_def.graph_def(), &graph));
  for (Node* node : graph.nodes()) {
    for (auto dt : node->output_types()) {
      tensor_name_to_dtype->insert(std::make_pair(node->name(), dt));
    }
  }
  return Status::OK();
}

// Converts SessionBundle signatures to SavedModel signature-defs.
Status ConvertSignaturesToSignatureDefs(MetaGraphDef* meta_graph_def) {
  Signatures signatures;
  GetSignatures(*meta_graph_def, &signatures).IgnoreError();

  // Build a map of tensor-names to the corresponding tensor-info with `name`
  // and `dtype` fields.
  std::unordered_map<string, DataType> tensor_name_to_dtype;
  TF_RETURN_IF_ERROR(
      BuildTensorNameToDtypeMap(*meta_graph_def, &tensor_name_to_dtype));

  TF_RETURN_IF_ERROR(ConvertDefaultSignatureToSignatureDef(
      signatures, tensor_name_to_dtype, meta_graph_def));
  TF_RETURN_IF_ERROR(ConvertNamedSignaturesToSignatureDef(
      signatures, tensor_name_to_dtype, meta_graph_def));
  return Status::OK();
}

// Converts a SessionBundle to a SavedModelBundle.
Status ConvertSessionBundleToSavedModelBundle(
    SessionBundle& session_bundle, SavedModelBundle* saved_model_bundle) {
  // Transfer ownership of the session from old to new.
  saved_model_bundle->session = std::move(session_bundle.session);

  // Copy the meta graph def from the SessionBundle to the SavedModelBundle.
  saved_model_bundle->meta_graph_def.CopyFrom(session_bundle.meta_graph_def);

  // Convert signatures from session-bundle to signature-defs in
  // saved-model-bundle.
  return internal::ConvertSignaturesToSignatureDefs(
      &saved_model_bundle->meta_graph_def);
}

}  // namespace internal

Status LoadSessionBundleOrSavedModelBundle(
    const SessionOptions& session_options, const RunOptions& run_options,
    const string& export_dir,
    const std::unordered_set<string>& saved_model_tags,
    SavedModelBundle* saved_model_bundle) {
  if (MaybeSavedModelDirectory(export_dir)) {
    LOG(INFO)
        << "Attempting to load native SavedModelBundle in bundle-shim from: "
        << export_dir;
    return LoadSavedModel(session_options, run_options, export_dir,
                          saved_model_tags, saved_model_bundle);
  } else if (IsPossibleExportDirectory(export_dir)) {
    LOG(INFO) << "Attempting to up-convert SessionBundle to SavedModelBundle "
                 "in bundle-shim from: "
              << export_dir;
    return LoadSavedModelFromLegacySessionBundlePath(
        session_options, run_options, export_dir, saved_model_bundle);
  }
  return Status(error::Code::NOT_FOUND,
                "Session bundle or SavedModel bundle not found at specified "
                "export location");
}

}  // namespace serving
}  // namespace tensorflow
<commit_msg>Add an error message to the bundle-shim for SessionBundle deprecation.<commit_after>/* Copyright 2016 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/contrib/session_bundle/bundle_shim.h"

#include "tensorflow/cc/saved_model/loader.h"
#include "tensorflow/cc/saved_model/signature_constants.h"
#include "tensorflow/contrib/session_bundle/manifest.pb.h"
#include "tensorflow/contrib/session_bundle/session_bundle.h"
#include "tensorflow/contrib/session_bundle/signature.h"
#include "tensorflow/core/graph/graph_constructor.h"
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/core/status.h"
#include "tensorflow/core/lib/core/stringpiece.h"
#include "tensorflow/core/protobuf/meta_graph.pb.h"
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/public/session_options.h"

namespace tensorflow {
namespace serving {
namespace {
///////////////////////////////////////////////////////////////////////////////
// Helper functions to check Signature type.

bool IsClassificationSignature(const Signature& signature) {
  return signature.type_case() == Signature::kClassificationSignature;
}

bool IsRegressionSignature(const Signature& signature) {
  return signature.type_case() == Signature::kRegressionSignature;
}

///////////////////////////////////////////////////////////////////////////////
// Helper functions to build `Classification`, `Regression` and `Predict`
// SignatureDefs.

SignatureDef BuildRegressionSignatureDef(
    const RegressionSignature& regression_signature,
    const std::unordered_map<string, DataType>& tensor_name_to_dtype) {
  SignatureDef signature_def;
  signature_def.set_method_name(kRegressMethodName);
  internal::AddInputToSignatureDef(regression_signature.input().tensor_name(),
                                   tensor_name_to_dtype, kRegressInputs,
                                   &signature_def);
  internal::AddOutputToSignatureDef(regression_signature.output().tensor_name(),
                                    tensor_name_to_dtype, kRegressOutputs,
                                    &signature_def);
  return signature_def;
}

SignatureDef BuildClassificationSignatureDef(
    const ClassificationSignature& classification_signature,
    const std::unordered_map<string, DataType>& tensor_name_to_dtype) {
  SignatureDef signature_def;
  signature_def.set_method_name(kClassifyMethodName);
  internal::AddInputToSignatureDef(
      classification_signature.input().tensor_name(), tensor_name_to_dtype,
      kClassifyInputs, &signature_def);
  internal::AddOutputToSignatureDef(
      classification_signature.classes().tensor_name(), tensor_name_to_dtype,
      kClassifyOutputClasses, &signature_def);
  internal::AddOutputToSignatureDef(
      classification_signature.scores().tensor_name(), tensor_name_to_dtype,
      kClassifyOutputScores, &signature_def);
  return signature_def;
}

Status MaybeBuildPredictSignatureDef(
    const std::unordered_map<string, DataType>& tensor_name_to_dtype,
    MetaGraphDef* meta_graph_def) {
  Signature input_signature, output_signature;
  // Ensure that named signatures corresponding to `inputs` and `outputs` keys
  // exist.
  if (!GetNamedSignature(kPredictInputs, *meta_graph_def, &input_signature)
           .ok() ||
      !GetNamedSignature(kPredictOutputs, *meta_graph_def, &output_signature)
           .ok()) {
    return Status(error::Code::INVALID_ARGUMENT,
                  "Named signatures can only be up-converted if entries "
                  "corresponding to both `inputs` and `outputs` exist.");
  }
  // Ensure the `inputs` and `outputs` named signatures are generic signatures.
  if (input_signature.type_case() != Signature::TypeCase::kGenericSignature ||
      output_signature.type_case() != Signature::TypeCase::kGenericSignature) {
    return Status(error::Code::INVALID_ARGUMENT,
                  "Named signatures corresponding to `inputs` and `outputs` "
                  "can only be up-converted if they are GenericSignatures.");
  }
  SignatureDef signature_def;
  signature_def.set_method_name(kPredictMethodName);
  // Add map entries from the `inputs` generic signature to the input map in the
  // signature def.
  for (const auto& map_entry : input_signature.generic_signature().map()) {
    internal::AddInputToSignatureDef(map_entry.second.tensor_name(),
                                     tensor_name_to_dtype, map_entry.first,
                                     &signature_def);
  }
  // Add map entries from the `outputs` generic signature to the output map in
  // the signature def.
  for (const auto& map_entry : output_signature.generic_signature().map()) {
    internal::AddOutputToSignatureDef(map_entry.second.tensor_name(),
                                      tensor_name_to_dtype, map_entry.first,
                                      &signature_def);
  }
  // Add the constructed signature def to the signature def map of the meta
  // graph def. Use the default key if it isn't already in use.
  const bool already_has_default_signature =
      meta_graph_def->signature_def().find(kDefaultServingSignatureDefKey) !=
      meta_graph_def->signature_def().end();
  const string signature_def_key =
      already_has_default_signature
          ? strings::StrCat(kDefaultServingSignatureDefKey, "_from_named")
          : kDefaultServingSignatureDefKey;
  (*meta_graph_def->mutable_signature_def())[signature_def_key] = signature_def;
  return Status::OK();
}

Status LoadSavedModelFromLegacySessionBundlePath(
    const SessionOptions& session_options, const RunOptions& run_options,
    const StringPiece session_bundle_export_dir,
    SavedModelBundle* saved_model_bundle) {
  if (session_bundle_export_dir.empty()) {
    return Status(error::Code::NOT_FOUND, "Export directory path is empty.");
  }
  if (!IsPossibleExportDirectory(session_bundle_export_dir)) {
    return Status(
        error::Code::NOT_FOUND,
        "Export directory does not contain a valid SessionBundle export.");
  }

  // Build the session-bundle.
  SessionBundle session_bundle;
  TF_RETURN_IF_ERROR(LoadSessionBundleFromPathUsingRunOptions(
      session_options, run_options, session_bundle_export_dir,
      &session_bundle));

  // Convert the session-bundle to a saved-model-bundle.
  return internal::ConvertSessionBundleToSavedModelBundle(session_bundle,
                                                          saved_model_bundle);
}

///////////////////////////////////////////////////////////////////////////////
// Helper functions to convert `Default` and `Named` signatures to
// SignatureDefs.

// Up-conversion of default signatures is supported for classification and
// regression.
Status ConvertDefaultSignatureToSignatureDef(
    const Signatures& signatures,
    const std::unordered_map<string, DataType>& tensor_name_to_dtype,
    MetaGraphDef* meta_graph_def) {
  if (!signatures.has_default_signature()) {
    return Status::OK();
  }
  const bool already_has_default_signature =
      meta_graph_def->signature_def().find(kDefaultServingSignatureDefKey) !=
      meta_graph_def->signature_def().end();
  if (already_has_default_signature) {
    return Status(error::Code::ALREADY_EXISTS,
                  strings::StrCat(
                      "Default signature cannot be up-converted since ",
                      kDefaultServingSignatureDefKey, " key already exists."));
  }
  const Signature& signature = signatures.default_signature();
  if (IsRegressionSignature(signature)) {
    (*meta_graph_def->mutable_signature_def())[kDefaultServingSignatureDefKey] =
        BuildRegressionSignatureDef(signature.regression_signature(),
                                    tensor_name_to_dtype);
  } else if (IsClassificationSignature(signature)) {
    (*meta_graph_def->mutable_signature_def())[kDefaultServingSignatureDefKey] =
        BuildClassificationSignatureDef(signature.classification_signature(),
                                        tensor_name_to_dtype);
  } else {
    LOG(WARNING) << "Default signature up-conversion to SignatureDef is only "
                    "supported for `Classification` and `Regression`. Could "
                    "not up-convert signature: "
                 << signature.DebugString()
                 << ". (If using SessionRun with the SessionBundle export "
                    "format please ignore this warning.)";
  }
  return Status::OK();
}

Status ConvertNamedSignaturesToSignatureDef(
    const Signatures& signatures,
    const std::unordered_map<string, DataType>& tensor_name_to_dtype,
    MetaGraphDef* meta_graph_def) {
  if (signatures.named_signatures().empty()) {
    return Status::OK();
  }
  // Check for a Predict signature for up-conversion.
  Status predict_signature_def_status =
      MaybeBuildPredictSignatureDef(tensor_name_to_dtype, meta_graph_def);
  for (const auto& it_named_signature : signatures.named_signatures()) {
    const string key = it_named_signature.first;
    // If a Predict SignatureDef was successfully constructed, skip the entries
    // corresponding to `inputs` and `outputs`.
    if (predict_signature_def_status.ok()) {
      if (key == kPredictInputs || key == kPredictOutputs) {
        continue;
      }
    }
    const Signature signature = it_named_signature.second;
    if (IsRegressionSignature(signature)) {
      (*meta_graph_def->mutable_signature_def())[key] =
          BuildRegressionSignatureDef(signature.regression_signature(),
                                      tensor_name_to_dtype);
    } else if (IsClassificationSignature(signature)) {
      (*meta_graph_def->mutable_signature_def())[key] =
          BuildClassificationSignatureDef(signature.classification_signature(),
                                          tensor_name_to_dtype);
    } else {
      LOG(WARNING)
          << "Named signature up-conversion to SignatureDef is only supported "
             "for `Classification`, `Regression` or if two `GenericSignatures` "
             "signatures  called `inputs` and `outputs` exist, corresponding "
             "to the `Prediction` API. Could not up-convert signature: "
          << signature.DebugString();
    }
  }
  return Status::OK();
}

}  // namespace

namespace internal {
///////////////////////////////////////////////////////////////////////////////
// Helper functions to populate SignatureDef fields.

// Adds an entry to the `inputs` map of the supplied SignatureDef.
void AddInputToSignatureDef(
    const string& tensor_name,
    const std::unordered_map<string, DataType>& tensor_name_to_dtype,
    const string& input_key, SignatureDef* signature_def) {
  if (tensor_name.empty()) {
    LOG(WARNING) << "Tensor name not provided. Cannot add TensorInfo to "
                    "SignatureDef inputs.";
    return;
  }
  // Extract the tensor-name in case the supplied string is a tensor-reference.
  // Example: Extract "x" from "x:0".
  std::size_t pos = tensor_name.find(":");
  const string key =
      (pos != std::string::npos) ? tensor_name.substr(0, pos) : tensor_name;
  const auto it_tensor_info = tensor_name_to_dtype.find(key);
  TensorInfo tensor_info;
  tensor_info.set_name(tensor_name);
  if (it_tensor_info != tensor_name_to_dtype.end()) {
    tensor_info.set_dtype(it_tensor_info->second);
  } else {
    LOG(WARNING)
        << "No dtype found for tensor with name: " << tensor_name << ". "
        << "Building TensorInfo with only name for SignatureDef inputs. "
        << "Downstream functionality including validation may be "
        << "impacted.";
  }
  (*signature_def->mutable_inputs())[input_key] = tensor_info;
}

// Adds an entry to the `outputs` map of the supplied SignatureDef.
void AddOutputToSignatureDef(
    const string& tensor_name,
    const std::unordered_map<string, DataType>& tensor_name_to_dtype,
    const string& output_key, SignatureDef* signature_def) {
  if (tensor_name.empty()) {
    LOG(WARNING) << "Tensor name not provided. Cannot add TensorInfo to "
                    "SignatureDef outputs.";
    return;
  }
  // Extract the tensor-name in case the supplied string is a tensor-reference.
  // Example: Extract "x" from "x:0".
  std::size_t pos = tensor_name.find(":");
  const string key =
      (pos != std::string::npos) ? tensor_name.substr(0, pos) : tensor_name;
  const auto it_tensor_info = tensor_name_to_dtype.find(key);
  TensorInfo tensor_info;
  tensor_info.set_name(tensor_name);
  if (it_tensor_info != tensor_name_to_dtype.end()) {
    tensor_info.set_dtype(it_tensor_info->second);
  } else {
    LOG(WARNING)
        << "No dtype found for tensor with name: " << tensor_name << ". "
        << "Building TensorInfo with only name for SignatureDef outputs."
        << " Downstream functionality including validation may be "
        << "impacted.";
  }
  (*signature_def->mutable_outputs())[output_key] = tensor_info;
}

// Builds a map from tensor name to the corresponding datatype, by parsing the
// MetaGraphDef.
Status BuildTensorNameToDtypeMap(
    const MetaGraphDef& meta_graph_def,
    std::unordered_map<string, DataType>* tensor_name_to_dtype) {
  GraphConstructorOptions opts;
  Graph graph(OpRegistry::Global());
  TF_RETURN_IF_ERROR(
      ConvertGraphDefToGraph(opts, meta_graph_def.graph_def(), &graph));
  for (Node* node : graph.nodes()) {
    for (auto dt : node->output_types()) {
      tensor_name_to_dtype->insert(std::make_pair(node->name(), dt));
    }
  }
  return Status::OK();
}

// Converts SessionBundle signatures to SavedModel signature-defs.
Status ConvertSignaturesToSignatureDefs(MetaGraphDef* meta_graph_def) {
  Signatures signatures;
  GetSignatures(*meta_graph_def, &signatures).IgnoreError();

  // Build a map of tensor-names to the corresponding tensor-info with `name`
  // and `dtype` fields.
  std::unordered_map<string, DataType> tensor_name_to_dtype;
  TF_RETURN_IF_ERROR(
      BuildTensorNameToDtypeMap(*meta_graph_def, &tensor_name_to_dtype));

  TF_RETURN_IF_ERROR(ConvertDefaultSignatureToSignatureDef(
      signatures, tensor_name_to_dtype, meta_graph_def));
  TF_RETURN_IF_ERROR(ConvertNamedSignaturesToSignatureDef(
      signatures, tensor_name_to_dtype, meta_graph_def));
  return Status::OK();
}

// Converts a SessionBundle to a SavedModelBundle.
Status ConvertSessionBundleToSavedModelBundle(
    SessionBundle& session_bundle, SavedModelBundle* saved_model_bundle) {
  // Transfer ownership of the session from old to new.
  saved_model_bundle->session = std::move(session_bundle.session);

  // Copy the meta graph def from the SessionBundle to the SavedModelBundle.
  saved_model_bundle->meta_graph_def.CopyFrom(session_bundle.meta_graph_def);

  // Convert signatures from session-bundle to signature-defs in
  // saved-model-bundle.
  return internal::ConvertSignaturesToSignatureDefs(
      &saved_model_bundle->meta_graph_def);
}

}  // namespace internal

Status LoadSessionBundleOrSavedModelBundle(
    const SessionOptions& session_options, const RunOptions& run_options,
    const string& export_dir,
    const std::unordered_set<string>& saved_model_tags,
    SavedModelBundle* saved_model_bundle) {
  if (MaybeSavedModelDirectory(export_dir)) {
    LOG(INFO)
        << "Attempting to load native SavedModelBundle in bundle-shim from: "
        << export_dir;
    return LoadSavedModel(session_options, run_options, export_dir,
                          saved_model_tags, saved_model_bundle);
  } else if (IsPossibleExportDirectory(export_dir)) {
    LOG(ERROR) << "Found possible SessionBundle in export directory. "
                  "SessionBundle is deprecated. Use SavedModel instead.";
    LOG(INFO) << "Attempting to up-convert SessionBundle to SavedModelBundle "
                 "in bundle-shim from: "
              << export_dir;
    return LoadSavedModelFromLegacySessionBundlePath(
        session_options, run_options, export_dir, saved_model_bundle);
  }
  return Status(error::Code::NOT_FOUND,
                "Session bundle or SavedModel bundle not found at specified "
                "export location");
}

}  // namespace serving
}  // namespace tensorflow
<|endoftext|>


<commit_before>// Virvo - Virtual Reality Volume Rendering
// Copyright (C) 1999-2003 University of Stuttgart, 2004-2005 Brown University
// Contact: Jurgen P. Schulze, jschulze@ucsd.edu
//
// This file is part of Virvo.
//
// Virvo 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 (see license.txt); if not, write to the
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

#define GLX_GLXEXT_LEGACY

#include <iostream>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#undef USE_NEXTSTEP

#ifdef USE_NEXTSTEP
#  include <mach-o/dyld.h>
#elif defined(__linux__) || defined(LINUX) || defined(__hpux) || defined(__APPLE__) || defined(__sun)
#include <dlfcn.h>
#endif

#include "vvopengl.h"
#if defined(HAVE_X11) && defined(USE_X11)
#include <GL/glx.h>
#endif

#include "vvdynlib.h"

using namespace std;

int vvDynLib::close(VV_SHLIB_HANDLE handle)
{
#ifdef _WIN32
  FreeLibrary (handle);
  return 1;

#elif __hpux
  // HP-UX 10.x and 32-bit 11.00 do not pay attention to the ref count when
  // unloading a dynamic lib.  So, if the ref count is more than 1, do not
  // unload the lib.  This will cause a library loaded more than once to
  // not be unloaded until the process runs down, but that's life.  It's
  // better than unloading a library that's in use.
  // So far as I know, there's no way to decrement the refcnt that the kernel
  // is looking at - the shl_descriptor is a copy of what the kernel has, not
  // the actual struct.
  // On 64-bit HP-UX using dlopen, this problem has been fixed.
  struct shl_descriptor  desc;
  if (shl_gethandle_r(handle, &desc) == -1)
    return -1;
  if (desc.ref_count > 1)
    return 1;
#if defined(__GNUC__) || __cplusplus >= 199707L
  shl_unload(handle);
#else
  cxxshl_unload(handle);
#endif                                          /* aC++ vs. Hp C++ */
  return 1;

#else

#ifdef __sun4
  // SunOS4 does not automatically call _fini()!
  void *ptr;
  ptr = sym(handle, "_fini");

  if (ptr != 0)
    (*((int (*)(void)) ptr)) ();                  // Call _fini hook explicitly.
#endif

  dlclose(handle);
  return 1;
#endif
}

char* vvDynLib::error()
{
#ifdef __hpux
  return strerror(errno);
#elif _WIN32
  static char buf[128];
  FormatMessageA (FORMAT_MESSAGE_FROM_SYSTEM,
    NULL,
    GetLastError (),
    0,
    buf,
    sizeof buf,
    NULL);
  return buf;
#else
  return dlerror();
#endif
}

VV_SHLIB_HANDLE vvDynLib::open(const char* filename, int mode)
{
  void* handle;

#ifdef _WIN32
  handle = LoadLibraryA (filename);
#elif __hpux
#if defined(__GNUC__) || __cplusplus >= 199707L
  handle = shl_load(filename, mode, 0L);
#else
  handle = cxxshl_load(filename, mode, 0L);
#endif
#else
  handle = dlopen(filename, mode);
#endif

  if(handle == NULL)
  {
    cerr << error() << endl;
  }

#ifdef __sun4
  if (handle != 0)
  {
    void *ptr;
    // Some systems (e.g., SunOS4) do not automatically call _init(), so
    // we'll have to call it manually.

    ptr = sym(handle, "_init");

                                                  // Call _init hook explicitly.
    if (ptr != 0 && (*((int (*)(void)) ptr)) () == -1)
    {
      // Close down the handle to prevent leaks.
      close(handle);
      return 0;
    }
  }
#endif

#ifdef _WIN32
  mode = mode;                                    // prevent warning
#endif

  return (VV_SHLIB_HANDLE)handle;
}

void* vvDynLib::sym(VV_SHLIB_HANDLE handle, const char* symbolname)
{
#ifdef _WIN32
  return (void *)GetProcAddress(handle, symbolname);
#elif __hpux
  void *value;
  int status;
  shl_t _handle = handle;
  status = shl_findsym(&_handle, symbolname, TYPE_UNDEFINED, &value);
  return status == 0 ? value : NULL;
#else
  return dlsym (handle, symbolname);
#endif
}

// #define USE_DYNLIB_FOR_GL // this has problems
void (*vvDynLib::glSym(const char *symbolname))(void)
{
#if defined(_WIN32)
  return (void (*)()) wglGetProcAddress(symbolname);
#elif defined(USE_DYNLIB_FOR_GL) || defined(__sgi)
  VV_SHLIB_HANDLE dynLib = open("libGL.so", RTLD_NOW);
  void (*func)() = (void (*)()) sym(dynLib, symbolname);
  close(dynLib);
  return func;
#elif defined(__APPLE__)
#ifndef USE_NEXTSTEP
  VV_SHLIB_HANDLE dynLib = open(NULL, RTLD_NOW);
  void (*func)() = (void (*)()) sym(dynLib, symbolname);
  close(dynLib);
  return func;
#else
  NSSymbol symbol;
  // Prepend a '_' for the Unix C symbol mangling convention
  char *mangledSymbolName = new char[strlen(symbolname) + 2];
  strcpy(mangledSymbolName + 1, symbolname);
  mangledSymbolName[0] = '_';
  symbol = NULL;
  if (NSIsSymbolNameDefined (mangledSymbolName))
    symbol = NSLookupAndBindSymbol (mangledSymbolName);
  delete[] (mangledSymbolName);
  return symbol ? (void (*)(void))NSAddressOfSymbol (symbol) : NULL;
#endif
#elif defined(GLX_ARB_get_proc_address)
  return (void (*)())  glXGetProcAddressARB((const GLubyte *)symbolname);
#else
  return (void (*)()) glXGetProcAddress((const GLubyte *)symbolname);
#endif
}
// vim: sw=2:expandtab:softtabstop=2:ts=2:cino=\:0g0t0
<commit_msg>another compile fix<commit_after>// Virvo - Virtual Reality Volume Rendering
// Copyright (C) 1999-2003 University of Stuttgart, 2004-2005 Brown University
// Contact: Jurgen P. Schulze, jschulze@ucsd.edu
//
// This file is part of Virvo.
//
// Virvo 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 (see license.txt); if not, write to the
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

#define GLX_GLXEXT_LEGACY

#include <iostream>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#undef USE_NEXTSTEP

#ifdef USE_NEXTSTEP
#  include <mach-o/dyld.h>
#elif defined(__linux__) || defined(LINUX) || defined(__hpux) || defined(__APPLE__) || defined(__sun)
#include <dlfcn.h>
#endif

#include "vvopengl.h"

#include "vvconfig.h"
#if defined(HAVE_X11) && defined(USE_X11)
#include <GL/glx.h>
#endif

#include "vvdynlib.h"

using namespace std;

int vvDynLib::close(VV_SHLIB_HANDLE handle)
{
#ifdef _WIN32
  FreeLibrary (handle);
  return 1;

#elif __hpux
  // HP-UX 10.x and 32-bit 11.00 do not pay attention to the ref count when
  // unloading a dynamic lib.  So, if the ref count is more than 1, do not
  // unload the lib.  This will cause a library loaded more than once to
  // not be unloaded until the process runs down, but that's life.  It's
  // better than unloading a library that's in use.
  // So far as I know, there's no way to decrement the refcnt that the kernel
  // is looking at - the shl_descriptor is a copy of what the kernel has, not
  // the actual struct.
  // On 64-bit HP-UX using dlopen, this problem has been fixed.
  struct shl_descriptor  desc;
  if (shl_gethandle_r(handle, &desc) == -1)
    return -1;
  if (desc.ref_count > 1)
    return 1;
#if defined(__GNUC__) || __cplusplus >= 199707L
  shl_unload(handle);
#else
  cxxshl_unload(handle);
#endif                                          /* aC++ vs. Hp C++ */
  return 1;

#else

#ifdef __sun4
  // SunOS4 does not automatically call _fini()!
  void *ptr;
  ptr = sym(handle, "_fini");

  if (ptr != 0)
    (*((int (*)(void)) ptr)) ();                  // Call _fini hook explicitly.
#endif

  dlclose(handle);
  return 1;
#endif
}

char* vvDynLib::error()
{
#ifdef __hpux
  return strerror(errno);
#elif _WIN32
  static char buf[128];
  FormatMessageA (FORMAT_MESSAGE_FROM_SYSTEM,
    NULL,
    GetLastError (),
    0,
    buf,
    sizeof buf,
    NULL);
  return buf;
#else
  return dlerror();
#endif
}

VV_SHLIB_HANDLE vvDynLib::open(const char* filename, int mode)
{
  void* handle;

#ifdef _WIN32
  handle = LoadLibraryA (filename);
#elif __hpux
#if defined(__GNUC__) || __cplusplus >= 199707L
  handle = shl_load(filename, mode, 0L);
#else
  handle = cxxshl_load(filename, mode, 0L);
#endif
#else
  handle = dlopen(filename, mode);
#endif

  if(handle == NULL)
  {
    cerr << error() << endl;
  }

#ifdef __sun4
  if (handle != 0)
  {
    void *ptr;
    // Some systems (e.g., SunOS4) do not automatically call _init(), so
    // we'll have to call it manually.

    ptr = sym(handle, "_init");

                                                  // Call _init hook explicitly.
    if (ptr != 0 && (*((int (*)(void)) ptr)) () == -1)
    {
      // Close down the handle to prevent leaks.
      close(handle);
      return 0;
    }
  }
#endif

#ifdef _WIN32
  mode = mode;                                    // prevent warning
#endif

  return (VV_SHLIB_HANDLE)handle;
}

void* vvDynLib::sym(VV_SHLIB_HANDLE handle, const char* symbolname)
{
#ifdef _WIN32
  return (void *)GetProcAddress(handle, symbolname);
#elif __hpux
  void *value;
  int status;
  shl_t _handle = handle;
  status = shl_findsym(&_handle, symbolname, TYPE_UNDEFINED, &value);
  return status == 0 ? value : NULL;
#else
  return dlsym (handle, symbolname);
#endif
}

// #define USE_DYNLIB_FOR_GL // this has problems
void (*vvDynLib::glSym(const char *symbolname))(void)
{
#if defined(_WIN32)
  return (void (*)()) wglGetProcAddress(symbolname);
#elif defined(USE_DYNLIB_FOR_GL) || defined(__sgi)
  VV_SHLIB_HANDLE dynLib = open("libGL.so", RTLD_NOW);
  void (*func)() = (void (*)()) sym(dynLib, symbolname);
  close(dynLib);
  return func;
#elif defined(__APPLE__)
#ifndef USE_NEXTSTEP
  VV_SHLIB_HANDLE dynLib = open(NULL, RTLD_NOW);
  void (*func)() = (void (*)()) sym(dynLib, symbolname);
  close(dynLib);
  return func;
#else
  NSSymbol symbol;
  // Prepend a '_' for the Unix C symbol mangling convention
  char *mangledSymbolName = new char[strlen(symbolname) + 2];
  strcpy(mangledSymbolName + 1, symbolname);
  mangledSymbolName[0] = '_';
  symbol = NULL;
  if (NSIsSymbolNameDefined (mangledSymbolName))
    symbol = NSLookupAndBindSymbol (mangledSymbolName);
  delete[] (mangledSymbolName);
  return symbol ? (void (*)(void))NSAddressOfSymbol (symbol) : NULL;
#endif
#elif defined(GLX_ARB_get_proc_address)
  return (void (*)())  glXGetProcAddressARB((const GLubyte *)symbolname);
#else
  return (void (*)()) glXGetProcAddress((const GLubyte *)symbolname);
#endif
}
// vim: sw=2:expandtab:softtabstop=2:ts=2:cino=\:0g0t0
<|endoftext|>


<commit_before>/** @file
 *
 * @ingroup dspSoundFileLib
 *
 * @brief Tests for the #TTSoundfileLoader class
 *
 * @details Tests the core functions of the TTSoundfileLoader class in order to ensure that things are working after a build. It also demostrate how to make calls to common methods within the class.@n
 * IMPORTANT NOTE: Because POSIX filepaths will be specific to your system, this test will attempt to find the path to the SoundfileLib extension using the TTFoundationBinaryPath environment variable. If you wish to test with a different sound file, you will need to place in that extension folder and change the relevant macros in the header of this class.
 *
 * @authors Nathan Wolek
 *
 * @copyright Copyright © 2013 by Nathan Wolek @n
 * This code is licensed under the terms of the "New BSD License" @n
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTSoundfileLoader.h"
#include "TTUnitTest.h"

/*

 It is possible to change the target sound file for this test using the macros below.
 Both sound files are included in the Jamoma respository at the following path:
 {JAMOMA_ROOT}/Core/DSP/extensions/SoundfileLib/

 The test should look for the named TESTFILE at this path.

 */

/* */
 #define TESTFILE "geese_clip.aif"
 #define TESTNUMCHANNELS 2
 #define TESTSAMPLERATE 44100
 #define TESTDURATIONINSAMPLES 88202
 #define TESTDURATIONINSECONDS 2.00004535
 #define TESTTITLE ""
 #define TESTARTIST ""
 #define TESTDATE ""
 #define TESTANNOTATION ""
/* */

/*
#define TESTFILE "ding_b2.aiff"
#define TESTNUMCHANNELS 1
#define TESTSAMPLERATE 44100
#define TESTDURATIONINSAMPLES 39493
#define TESTDURATIONINSECONDS 0.89553288
#define TESTTITLE ""
#define TESTARTIST ""
#define TESTDATE ""
#define TESTANNOTATION ""
 */

TTErr TTSoundfileLoader::test(TTValue& returnedTestInfo)
{
    int errorCount = 0;
    int testAssertionCount = 0;

    // assemble the full path of the target sound file

    TTString testSoundPath = TTFoundationBinaryPath;
    int pos = testSoundPath.find_last_of('/');
    testSoundPath = testSoundPath.substr(0,pos+1);
    testSoundPath += TESTFILE;

    std::cout << "We will be using the following path for testing: " << testSoundPath << "\n";

    try {

		TTTestLog("\n");
		TTTestLog("Testing TTSoundfileLoader Basics...");

        // TEST 0: establish our objects & pointers
        TTObject* testTargetMatrix = new TTObject("samplematrix");
        TTObject* testNonSampleMatrix = new TTObject("delay");
        TTObjectBase* objectBasePtrToSampleMatrix;
        TTObjectBase* ptrToNonSampleMatrix;

        // TEST 1: set the filepath
        TTBoolean result1 = { this->setFilePath(TT(testSoundPath)) == kTTErrNone };

        TTTestAssertion("setFilePath operates successfully",
                        result1,
                        testAssertionCount,
                        errorCount);

        // TEST 2: set up the samplematrix first
        int channelsSend = 1;           // compiler complained about TTInt32 being ambiguous here
        int lengthSend = 22050;         // compiler complained about TTInt32 being ambiguous here
        testTargetMatrix->set("numChannels", channelsSend);
        testTargetMatrix->set("lengthInSamples", lengthSend);

        TTInt32 channelsReturn, lengthReturn;

        testTargetMatrix->get("numChannels", channelsReturn);
        testTargetMatrix->get("lengthInSamples", lengthReturn);

        // now for the actual test
        TTBoolean result2a = { channelsSend == channelsReturn };

        TTTestAssertion("numChannels attribute set successfully",
						result2a,
						testAssertionCount,
						errorCount);

        TTBoolean result2b = { lengthSend == lengthReturn };

        TTTestAssertion("lengthInSamples attribute set successfully",
						result2b,
						testAssertionCount,
						errorCount);
        //

        // TEST 3: set the target via an objectBasePtr
        objectBasePtrToSampleMatrix = testTargetMatrix->instance(); // is there a better syntax for this?

        TTBoolean result3 = { this->setTargetMatrix(objectBasePtrToSampleMatrix) == kTTErrNone };

        TTTestAssertion("setTargetMatrix via ObjectBasePtr operates successfully",
						result3,
						testAssertionCount,
						errorCount);

        // TEST 4: set the target to a non-SampleMatrix, should FAIL
        ptrToNonSampleMatrix = testNonSampleMatrix->instance();

        TTBoolean result4 = { this->setTargetMatrix(ptrToNonSampleMatrix) == kTTErrInvalidValue };

        TTTestAssertion("setTargetMatrix returns error when not a SampleMatrix",
						result4,
						testAssertionCount,
						errorCount);

        // TEST 5: copy samplevalues until samplematrix is filled

        TTBoolean result5 = { this->copyUntilFilled() == kTTErrNone };

        TTTestAssertion("copyUntilFilled operates successfully",
						result5,
						testAssertionCount,
						errorCount);

        // TEST 6: compare 5 random sample values for equivalence
        // revealed some potential issues in TTSampleMatrix

        // Can I create a new SampleMatrix this way?
        //TTSampleMatrixPtr newMatrix = NULL;

        TTObject newTargetMatrix("samplematrix");//new TTSampleMatrix(kTTSymEmpty);

        TTValue peekInput(80567);
        peekInput.append(0);
        TTValue peekOutput(0.1);

        newTargetMatrix.send("load", testSoundPath, peekOutput);
        newTargetMatrix.send("peek", peekInput, peekOutput);

        TTFloat32 randomValueSampleMatrix = peekOutput[0];
        TTString outString = "";
        outString += randomValueSampleMatrix;

        std::cout << "I got this value for you: " << outString << "\n";

        // releasing objects
        objectBasePtrToSampleMatrix = NULL;
        ptrToNonSampleMatrix = NULL;
        delete testTargetMatrix;
        delete testNonSampleMatrix;

    } catch (...) {
        TTTestAssertion("FAILED to run tests -- likely that necessary objects did not instantiate",
            0,
            testAssertionCount,
            errorCount);

    }

    return TTTestFinish(testAssertionCount, errorCount, returnedTestInfo);
}
<commit_msg>TTSoundfileLoader::test() - test 6 syntax right now, but now test fails<commit_after>/** @file
 *
 * @ingroup dspSoundFileLib
 *
 * @brief Tests for the #TTSoundfileLoader class
 *
 * @details Tests the core functions of the TTSoundfileLoader class in order to ensure that things are working after a build. It also demostrate how to make calls to common methods within the class.@n
 * IMPORTANT NOTE: Because POSIX filepaths will be specific to your system, this test will attempt to find the path to the SoundfileLib extension using the TTFoundationBinaryPath environment variable. If you wish to test with a different sound file, you will need to place in that extension folder and change the relevant macros in the header of this class.
 *
 * @authors Nathan Wolek
 *
 * @copyright Copyright © 2013 by Nathan Wolek @n
 * This code is licensed under the terms of the "New BSD License" @n
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTSoundfileLoader.h"
#include "TTUnitTest.h"

/*

 It is possible to change the target sound file for this test using the macros below.
 Both sound files are included in the Jamoma respository at the following path:
 {JAMOMA_ROOT}/Core/DSP/extensions/SoundfileLib/

 The test should look for the named TESTFILE at this path.

 */

/* */
 #define TESTFILE "geese_clip.aif"
 #define TESTNUMCHANNELS 2
 #define TESTSAMPLERATE 44100
 #define TESTDURATIONINSAMPLES 88202
 #define TESTDURATIONINSECONDS 2.00004535
 #define TESTTITLE ""
 #define TESTARTIST ""
 #define TESTDATE ""
 #define TESTANNOTATION ""
/* */

/*
#define TESTFILE "ding_b2.aiff"
#define TESTNUMCHANNELS 1
#define TESTSAMPLERATE 44100
#define TESTDURATIONINSAMPLES 39493
#define TESTDURATIONINSECONDS 0.89553288
#define TESTTITLE ""
#define TESTARTIST ""
#define TESTDATE ""
#define TESTANNOTATION ""
 */

TTErr TTSoundfileLoader::test(TTValue& returnedTestInfo)
{
    int errorCount = 0;
    int testAssertionCount = 0;

    // assemble the full path of the target sound file

    TTString testSoundPath = TTFoundationBinaryPath;
    int pos = testSoundPath.find_last_of('/');
    testSoundPath = testSoundPath.substr(0,pos+1);
    testSoundPath += TESTFILE;

    std::cout << "We will be using the following path for testing: " << testSoundPath << "\n";

    try {

		TTTestLog("\n");
		TTTestLog("Testing TTSoundfileLoader Basics...");

        // TEST 0: establish our objects & pointers
        TTObject* testTargetMatrix = new TTObject("samplematrix");
        TTObject* testNonSampleMatrix = new TTObject("delay");
        TTObjectBase* objectBasePtrToSampleMatrix;
        TTObjectBase* ptrToNonSampleMatrix;

        // TEST 1: set the filepath
        TTBoolean result1 = { this->setFilePath(TT(testSoundPath)) == kTTErrNone };

        TTTestAssertion("setFilePath operates successfully",
                        result1,
                        testAssertionCount,
                        errorCount);

        // TEST 2: set up the samplematrix first
        int channelsSend = 1;           // compiler complained about TTInt32 being ambiguous here
        int lengthSend = 22050;         // compiler complained about TTInt32 being ambiguous here
        testTargetMatrix->set("numChannels", channelsSend);
        testTargetMatrix->set("lengthInSamples", lengthSend);

        TTInt32 channelsReturn, lengthReturn;

        testTargetMatrix->get("numChannels", channelsReturn);
        testTargetMatrix->get("lengthInSamples", lengthReturn);

        // now for the actual test
        TTBoolean result2a = { channelsSend == channelsReturn };

        TTTestAssertion("numChannels attribute set successfully",
						result2a,
						testAssertionCount,
						errorCount);

        TTBoolean result2b = { lengthSend == lengthReturn };

        TTTestAssertion("lengthInSamples attribute set successfully",
						result2b,
						testAssertionCount,
						errorCount);
        //

        // TEST 3: set the target via an objectBasePtr
        objectBasePtrToSampleMatrix = testTargetMatrix->instance(); // is there a better syntax for this?

        TTBoolean result3 = { this->setTargetMatrix(objectBasePtrToSampleMatrix) == kTTErrNone };

        TTTestAssertion("setTargetMatrix via ObjectBasePtr operates successfully",
						result3,
						testAssertionCount,
						errorCount);

        // TEST 4: set the target to a non-SampleMatrix, should FAIL
        ptrToNonSampleMatrix = testNonSampleMatrix->instance();

        TTBoolean result4 = { this->setTargetMatrix(ptrToNonSampleMatrix) == kTTErrInvalidValue };

        TTTestAssertion("setTargetMatrix returns error when not a SampleMatrix",
						result4,
						testAssertionCount,
						errorCount);

        // TEST 5: copy samplevalues until samplematrix is filled

        TTBoolean result5 = { this->copyUntilFilled() == kTTErrNone };

        TTTestAssertion("copyUntilFilled operates successfully",
						result5,
						testAssertionCount,
						errorCount);

        // TEST 6: compare 5 random sample values for equivalence

        // Can I create a new SampleMatrix this way?
        TTObject newTargetMatrix("samplematrix");//new TTSampleMatrix(kTTSymEmpty);

        int randomIndex;
        TTSampleValue randomValueSoundFile;
        TTBoolean result6 = true;

        for (int i = 0; i<5; i++)
        {
            randomIndex = lengthReturn * TTRandom64();
            //TTTestLog("let's look at index %i", randomIndex);

            TTValue peekInput(randomIndex);
            peekInput.append(0);
            TTValue peekOutput;

            this->peek(randomIndex,0,randomValueSoundFile);
            newTargetMatrix.send("peek",peekInput,peekOutput); //randomIndex,0,randomValueSampleMatrix);
            std::cout << "Does " << randomValueSoundFile << " = " << double(peekOutput) << " ?\n";

            if (result6) // allows test to keep variable false once it is false
                result6 = TTTestFloatEquivalence(randomValueSoundFile, double(peekOutput), true, 0.0000001);
        }

        TTTestAssertion("comparing 5 random values for equivalence",
                        result6,
                        testAssertionCount,
                        errorCount);

        //

        // releasing objects
        objectBasePtrToSampleMatrix = NULL;
        ptrToNonSampleMatrix = NULL;
        delete testTargetMatrix;
        delete testNonSampleMatrix;

    } catch (...) {
        TTTestAssertion("FAILED to run tests -- likely that necessary objects did not instantiate",
            0,
            testAssertionCount,
            errorCount);

    }

    return TTTestFinish(testAssertionCount, errorCount, returnedTestInfo);
}
<|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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.

#ifndef SERVICE_STATISTICS_HPP
#define SERVICE_STATISTICS_HPP

/**
 *
 */
struct Statistics {

  /**
   *
   */
  Statistics& bump_connection_count() noexcept
  { ++number_of_connections_; return *this; }

  /**
   *
   */
  Statistics& bump_data_received(const size_t n) noexcept
  { data_received_ += n; return *this; }

  /**
   *
   */
  Statistics& bump_data_sent(const size_t n) noexcept
  { data_sent_ += n; return *this; }

  /**
   *
   */
  Statistics& bump_request_received() noexcept
  { ++request_received_; return *this; }

  /**
   *
   */
  Statistics& bump_response_sent() noexcept
  { ++response_sent_; return *this; }

  /**
   *
   */
  Statistics& set_active_clients(const size_t n) noexcept
  { active_clients_ = n; return *this; }

  /**
   *
   */
  Statistics& set_memory_usage(const size_t n) noexcept
  { memory_usage_ = n; return *this; }

  /**
   *
   */
  template<typename Writer>
  void serialize(Writer& writer) const;

private:
  uint64_t data_received_         {0U};
  uint64_t data_sent_             {0U};

  uint64_t request_received_      {0U};
  uint64_t response_sent_         {0U};

  uint64_t number_of_connections_ {0U};

  uint64_t active_clients_        {0U};
  uint64_t memory_usage_          {0U};
}; //< struct Statistics

/**--v----------- Implementation Details -----------v--**/

template<typename Writer>
void serialize(Writer& writer) const {
  writer.StartObject();

  writer.Key("DATA_RECV");
  writer.Uint64(data_received_);

  writer.Key("DATA_SENT");
  writer.Uint64(data_sent_);

  writer.Key("REQ_RECV");
  writer.Uint64(request_received_);

  writer.Key("RES_SENT");
  writer.Uint64(response_sent_);

  writer.Key("NO_CONN");
  writer.Uint64(number_of_connections_);

  writer.Key("ACTIVE_CONN");
  writer.Uint(active_clients_);

  writer.Key("MEM_USAGE");
  writer.Uint(memory_usage_);

  writer.EndObject();
}

/**--^----------- Implementation Details -----------^--**/

#endif //< SERVICE_STATISTICS_HPP
<commit_msg>Added scope to method definition<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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.

#ifndef SERVICE_STATISTICS_HPP
#define SERVICE_STATISTICS_HPP

/**
 *
 */
struct Statistics {

  /**
   *
   */
  Statistics& bump_connection_count() noexcept
  { ++number_of_connections_; return *this; }

  /**
   *
   */
  Statistics& bump_data_received(const size_t n) noexcept
  { data_received_ += n; return *this; }

  /**
   *
   */
  Statistics& bump_data_sent(const size_t n) noexcept
  { data_sent_ += n; return *this; }

  /**
   *
   */
  Statistics& bump_request_received() noexcept
  { ++request_received_; return *this; }

  /**
   *
   */
  Statistics& bump_response_sent() noexcept
  { ++response_sent_; return *this; }

  /**
   *
   */
  Statistics& set_active_clients(const size_t n) noexcept
  { active_clients_ = n; return *this; }

  /**
   *
   */
  Statistics& set_memory_usage(const size_t n) noexcept
  { memory_usage_ = n; return *this; }

  /**
   *
   */
  template<typename Writer>
  void serialize(Writer& writer) const;

private:
  uint64_t data_received_         {0U};
  uint64_t data_sent_             {0U};

  uint64_t request_received_      {0U};
  uint64_t response_sent_         {0U};

  uint64_t number_of_connections_ {0U};

  uint64_t active_clients_        {0U};
  uint64_t memory_usage_          {0U};
}; //< struct Statistics

/**--v----------- Implementation Details -----------v--**/

template<typename Writer>
void Statistics::serialize(Writer& writer) const {
  writer.StartObject();

  writer.Key("DATA_RECV");
  writer.Uint64(data_received_);

  writer.Key("DATA_SENT");
  writer.Uint64(data_sent_);

  writer.Key("REQ_RECV");
  writer.Uint64(request_received_);

  writer.Key("RES_SENT");
  writer.Uint64(response_sent_);

  writer.Key("NO_CONN");
  writer.Uint64(number_of_connections_);

  writer.Key("ACTIVE_CONN");
  writer.Uint(active_clients_);

  writer.Key("MEM_USAGE");
  writer.Uint(memory_usage_);

  writer.EndObject();
}

/**--^----------- Implementation Details -----------^--**/

#endif //< SERVICE_STATISTICS_HPP
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
//  cpp-compile-test.cc
//  Just check whether (most of) the sokol headers also comppile as C++.
//------------------------------------------------------------------------------
#if defined(__APPLE__)
    #error "This is for non-apple platforms only"
#elif defined(__EMSCRIPTEN__)
    #define SOKOL_GLES2
#elif defined(_WIN32)
    #define SOKOL_D3D11
#else
    #define SOKOL_GLCORE33
#endif
#define SOKOL_IMPL
#include "sokol_app.h"
#include "sokol_args.h"
#include "sokol_audio.h"
#include "sokol_gfx.h"
#include "sokol_time.h"

static sapp_desc desc;

sapp_desc sokol_main(int argc, char* argv[]) {
    /* just interested whether the compilation worked, so force-exit here */
    exit(0);
    return desc;
}
<commit_msg>Fix cpp-compile-test to use CRT main(), not WinMain()<commit_after>//------------------------------------------------------------------------------
//  cpp-compile-test.cc
//  Just check whether (most of) the sokol headers also comppile as C++.
//------------------------------------------------------------------------------
#if defined(__APPLE__)
    #error "This is for non-apple platforms only"
#elif defined(__EMSCRIPTEN__)
    #define SOKOL_GLES2
#elif defined(_WIN32)
    #define SOKOL_D3D11
#else
    #define SOKOL_GLCORE33
#endif
#define SOKOL_IMPL
#define SOKOL_WIN32_FORCE_MAIN
#include "sokol_app.h"
#include "sokol_args.h"
#include "sokol_audio.h"
#include "sokol_gfx.h"
#include "sokol_time.h"

static sapp_desc desc;

sapp_desc sokol_main(int argc, char* argv[]) {
    /* just interested whether the compilation worked, so force-exit here */
    exit(0);
    return desc;
}
<|endoftext|>


<commit_before>#include <QtTest/QtTest>

#include "mainwindow.h"

class TestMainWindow : public QObject
{
    Q_OBJECT

public:
    TestMainWindow();
    ~TestMainWindow();

private slots:
    void about_window();

private:
};

TestMainWindow::TestMainWindow()
{
    QCoreApplication::setOrganizationName(TEST_NAME);
}

TestMainWindow::~TestMainWindow()
{
}

static QAction *get_menubar_about(QMenuBar *menubar)
{
    foreach(QAction *action, menubar->actions())
    {
        if(action->menu())
        {
            foreach(QAction *subaction, action->menu()->actions())
            {
                if(subaction->menuRole() == QAction::AboutRole)
                {
                    return subaction;
                }
            }
        }
    }
    return (nullptr);
}

void TestMainWindow::about_window()
{
    MainWindow *   mainwindow = new MainWindow();
    Ui::MainWindow ui         = mainwindow->_ui;

    // Starts off not visible and the button is not pushed down
    QVERIFY(mainwindow->_aboutWindow.isVisible() == false);
    QVERIFY(ui.aboutButton->isChecked() == false);

    // Becomes visible
    ui.aboutButton->click();
    QVERIFY(mainwindow->_aboutWindow.isVisible() == true);
    QVERIFY(ui.aboutButton->isChecked() == true);

    // Becomes invisible by clicking the button again
    ui.aboutButton->click();
    QVERIFY(mainwindow->_aboutWindow.isVisible() == false);
    QVERIFY(ui.aboutButton->isChecked() == false);

    // Becomes visible
    ui.aboutButton->click();
    QVERIFY(mainwindow->_aboutWindow.isVisible() == true);
    QVERIFY(ui.aboutButton->isChecked() == true);

    // Becomes invisible by closing the About window
    mainwindow->_aboutWindow.close();
    QVERIFY(mainwindow->_aboutWindow.isVisible() == false);
    QVERIFY(ui.aboutButton->isChecked() == false);

    // Test the "About Tarsnap" menubar item, if applicable.
    if(mainwindow->_menuBar != nullptr)
    {
        // find "About Tarsnap" menu item
        QAction *menuAction = get_menubar_about(mainwindow->_menuBar);
        QVERIFY(menuAction != nullptr);

        // Becomes visible using the menu bar action
        menuAction->trigger();
        QVERIFY(mainwindow->_aboutWindow.isVisible() == true);
        QVERIFY(ui.aboutButton->isChecked() == true);

        // Stay visible even when clicking the menu bar action again
        menuAction->trigger();
        QVERIFY(mainwindow->_aboutWindow.isVisible() == true);
        QVERIFY(ui.aboutButton->isChecked() == true);

        // Becomes invisible by clicking the Help->About button
        ui.aboutButton->click();
        QVERIFY(mainwindow->_aboutWindow.isVisible() == false);
        QVERIFY(ui.aboutButton->isChecked() == false);
    }

    delete mainwindow;
}

QTEST_MAIN(TestMainWindow)
#include "main.moc"
<commit_msg>tests/mainwindow: show visually if GUI<commit_after>#include <QtTest/QtTest>

#include "../qtest-platform.h"

#include "mainwindow.h"

#define VISUAL_INIT                                                            \
    IF_VISUAL                                                                  \
    {                                                                          \
        mainwindow->show();                                                    \
        VISUAL_WAIT;                                                           \
    }

class TestMainWindow : public QObject
{
    Q_OBJECT

public:
    TestMainWindow();
    ~TestMainWindow();

private slots:
    void about_window();

private:
};

TestMainWindow::TestMainWindow()
{
    QCoreApplication::setOrganizationName(TEST_NAME);
}

TestMainWindow::~TestMainWindow()
{
}

static QAction *get_menubar_about(QMenuBar *menubar)
{
    foreach(QAction *action, menubar->actions())
    {
        if(action->menu())
        {
            foreach(QAction *subaction, action->menu()->actions())
            {
                if(subaction->menuRole() == QAction::AboutRole)
                {
                    return subaction;
                }
            }
        }
    }
    return (nullptr);
}

void TestMainWindow::about_window()
{
    MainWindow *   mainwindow = new MainWindow();
    Ui::MainWindow ui         = mainwindow->_ui;

    VISUAL_INIT;

    // Starts off not visible and the button is not pushed down
    ui.actionGoHelp->trigger();
    QVERIFY(mainwindow->_aboutWindow.isVisible() == false);
    QVERIFY(ui.aboutButton->isChecked() == false);
    VISUAL_WAIT;

    // Becomes visible
    ui.aboutButton->click();
    QVERIFY(mainwindow->_aboutWindow.isVisible() == true);
    QVERIFY(ui.aboutButton->isChecked() == true);
    VISUAL_WAIT;

    // Becomes invisible by clicking the button again
    ui.aboutButton->click();
    QVERIFY(mainwindow->_aboutWindow.isVisible() == false);
    QVERIFY(ui.aboutButton->isChecked() == false);
    VISUAL_WAIT;

    // Becomes visible
    ui.aboutButton->click();
    QVERIFY(mainwindow->_aboutWindow.isVisible() == true);
    QVERIFY(ui.aboutButton->isChecked() == true);
    VISUAL_WAIT;

    // Becomes invisible by closing the About window
    mainwindow->_aboutWindow.close();
    QVERIFY(mainwindow->_aboutWindow.isVisible() == false);
    QVERIFY(ui.aboutButton->isChecked() == false);
    VISUAL_WAIT;

    // Test the "About Tarsnap" menubar item, if applicable.
    if(mainwindow->_menuBar != nullptr)
    {
        // find "About Tarsnap" menu item
        QAction *menuAction = get_menubar_about(mainwindow->_menuBar);
        QVERIFY(menuAction != nullptr);
        VISUAL_WAIT;

        // Becomes visible using the menu bar action
        menuAction->trigger();
        QVERIFY(mainwindow->_aboutWindow.isVisible() == true);
        QVERIFY(ui.aboutButton->isChecked() == true);
        VISUAL_WAIT;

        // Stay visible even when clicking the menu bar action again
        menuAction->trigger();
        QVERIFY(mainwindow->_aboutWindow.isVisible() == true);
        QVERIFY(ui.aboutButton->isChecked() == true);
        VISUAL_WAIT;

        // Becomes invisible by clicking the Help->About button
        ui.aboutButton->click();
        QVERIFY(mainwindow->_aboutWindow.isVisible() == false);
        QVERIFY(ui.aboutButton->isChecked() == false);
        VISUAL_WAIT;
    }

    delete mainwindow;
}

QTEST_MAIN(TestMainWindow)
#include "main.moc"
<|endoftext|>


<commit_before>#include<iostream>

int main()
{
     int value1 = 0, value2 = 0;
     std::cin >> value1 >> value2;
     std::cout << "The product of " << value1 << " and " << value2 << " equals " << value1 + value2 << std::endl;
     return 0;
}
<commit_msg>Fix * instead of +<commit_after>#include<iostream>

int main()
{
     int value1 = 0, value2 = 0;
     std::cin >> value1 >> value2;
     std::cout << "The product of " << value1 << " and " << value2 << " equals " << value1 * value2 << std::endl;
     return 0;
}
<|endoftext|>