<commit_before>// Copyright (c) 2016, Joseph Mirabel
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
//
// This file is part of gepetto-viewer-corba.
// gepetto-viewer-corba 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
// 3 of the License, or (at your option) any later version.
//
// gepetto-viewer-corba 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 Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// gepetto-viewer-corba. If not, see <http://www.gnu.org/licenses/>.

#include <gepetto/viewer/blender-geom-writer.h>

#include <algorithm>
#include <sys/stat.h>

#include <gepetto/viewer/node.h>
#include <gepetto/viewer/group-node.h>
#include <gepetto/viewer/leaf-node-arrow.h>
#include <gepetto/viewer/leaf-node-box.h>
#include <gepetto/viewer/leaf-node-capsule.h>
#include <gepetto/viewer/leaf-node-collada.h>
#include <gepetto/viewer/leaf-node-cone.h>
#include <gepetto/viewer/leaf-node-cylinder.h>
#include <gepetto/viewer/leaf-node-face.h>
#include <gepetto/viewer/leaf-node-ground.h>
#include <gepetto/viewer/leaf-node-light.h>
#include <gepetto/viewer/leaf-node-line.h>
#include <gepetto/viewer/leaf-node-sphere.h>
#include <gepetto/viewer/leaf-node-xyzaxis.h>
//#include <gepetto/viewer/node-rod.h>

namespace graphics {
  namespace {
    const char indent[] = "  ";
    const char end = '\n';
    const char group[] = "##";
    const char node[] = "#";

    template <typename Vector>
      std::ostream& writeVectorAsList (std::ostream& os, const Vector& v)
    {
      os << "( ";
      for (int i = 0; i < Vector::num_components; ++i)
        os << v[i] << ", ";
      os << ")";
      return os;
    }

    template <>
      std::ostream& writeVectorAsList<osg::Quat> (std::ostream& os, const osg::Quat& q)
    {
      os << "( " << q.w() << ", " << q.x() << ", " << q.y() << ", " << q.z() << ", )";
      return os;
    }
  }

  BlenderGeomWriterVisitor::BlenderGeomWriterVisitor (const std::string& filename)
    : filename_ (filename)
  {
    bool isNew = !openFile();
    const std::string comment = (isNew ? "" : "# ");
    out() << comment << "import bpy" << end << end
      << comment << "## Start convenient functions" << end
      << comment << "taggedObjects = list()" << end
      << comment << "def tagObjects ():" << end
      << comment << "  global taggedObjects" << end
      << comment << "  taggedObjects = list ()" << end
      << comment << "  for obj in bpy.data.objects:" << end
      << comment << "    taggedObjects.append (obj.name)" << end
      << comment << "" << end
      << comment << "def getNonTaggedObjects ():" << end
      << comment << "  global taggedObjects" << end
      << comment << "  return [obj for obj in bpy.data.objects if obj.name not in taggedObjects]" << end
      << comment << "" << end
      << comment << "def setParent (children, parent):" << end
      << comment << "  for child in children:" << end
      << comment << "    child.parent = parent" << end << end
      << comment << "## End of convenient functions" << end;
  }

  bool BlenderGeomWriterVisitor::openFile () {
    struct stat buffer;
    bool ret = (stat (filename_.c_str(), &buffer) == 0);
    file_.open (filename_.c_str(),
        std::ofstream::out | std::ofstream::app);
    if (!file_.is_open ())
      throw std::ios_base::failure ("Unable to open file " + filename_);
    return ret;
  }

  void BlenderGeomWriterVisitor::apply (Node& node)
  {
    std::cerr << "This function should not be called. Type of node " << node.getID() << " may be unknown" << std::endl;
    standardApply(node);
  }
  void BlenderGeomWriterVisitor::apply (GroupNode& node)
  {
    for (std::size_t i = 0; i < groupStack_.size() + 1; ++i)
      out() << group;
    out() << " Group " << node.getID() << end;

    out() << "bpy.ops.object.empty_add()" << end
      << "bpy.context.object.name = \"" << node.getID() << '"' << end;
    // Set parent of this group
    if (!groupStack_.empty())
      out() << "bpy.context.object.parent = bpy.data.objects[\""
        << groupStack_.top() << "\"]" << end;

    groupStack_.push(node.getID());
    NodeVisitor::apply(static_cast<Node&>(node));
    groupStack_.pop();

    for (std::size_t i = 0; i < groupStack_.size() + 1; ++i)
      out() << group;
    out() << end;
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeArrow& node)
  {
    unimplemented("LeafNodeArrow", node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeBox& node)
  {
    out()
      << "bpy.ops.mesh.primitive_cube_add ()" << end
      << "bpy.context.object.dimensions = ";
    writeVectorAsList(out(), node.getHalfAxis()*2) << end;
    standardApply(static_cast<Node&>(node));
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeCapsule& node)
  {
    unimplemented("LeafNodeCapsule", node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeCollada& node)
  {
    out() << "tagObjects()" << end;

    const std::string& mesh = node.meshFilePath();

    std::string ext = mesh.substr(mesh.find_last_of(".")+1,mesh.size());
    std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
    if(ext == "obj") {
      out() << "bpy.ops.import_scene.obj (filepath=\"" << mesh << "\")" << end;
    } else if (ext == "dae") {
      out() << "bpy.ops.wm.collada_import (filepath=\"" << mesh << "\")" << end;
    } else if (ext == "stl") {
      out() << "bpy.ops.import_mesh.stl (filepath=\"" << mesh << "\")" << end;
    } else {
      std::cout << "Extension of file " << mesh << " with name " << node.getID()
        << " is not known." << end
        << "You can load the file manually and add it to the empty object called " << node.getID() << end
        << "To fix the issue, upate" __FILE__ ":" << __LINE__ << std::endl;
      out() << "# Here goes the content of file " << mesh << end;
      out() << "# To fix it, upate" __FILE__ ":" << __LINE__ << end;
    }

    out ()
      << "imported_objects = getNonTaggedObjects ()" << end
      << "print(imported_objects)" << end
      << "bpy.ops.object.empty_add ()" << end
      << "setParent (imported_objects, bpy.context.object)" << end;
    standardApply(node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeCone& node)
  {
    out() << "bpy.ops.mesh.primitive_cone_add (radius1="
      << node.getRadius() << ", depth=" << node.getHeight() << ')' << end;
    standardApply(node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeCylinder& node)
  {
    out() << "bpy.ops.mesh.primitive_cylinder_add (radius="
      << node.getRadius() << ", depth=" << node.getHeight() << ')' << end;
    standardApply(node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeFace& node)
  {
    unimplemented("LeafNodeFace", node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeGround& node)
  {
    unimplemented("LeafNodeGround", node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeLight& node)
  {
    unimplemented("LeafNodeLight", node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeLine& node)
  {
    unimplemented("LeafNodeLine", node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeSphere& node)
  {
    out () << "bpy.ops.mesh.primitive_ico_sphere_add (size="
      << node.getRadius() << ")" << end;
    standardApply(node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeXYZAxis& node)
  {
    unimplemented("LeafNodeXYZAxis", node);
  }

  void BlenderGeomWriterVisitor::standardApply (Node& node)
  {
    const std::string& id = node.getID ();
    // Set name
    out()
      << "bpy.context.object.name = \"" << id << "__shape\"" << end
      << "bpy.context.object.location = ";
    writeVectorAsList(out(), node.getStaticPosition()) << end;
    out()
      << "bpy.context.object.rotation_mode = 'QUATERNION'" << end
      << "bpy.context.object.rotation_quaternion = ";
    writeVectorAsList(out(), node.getStaticRotation()) << end;
    out()
      << "bpy.ops.object.empty_add ()" << end
      << "bpy.context.object.name = \"" << id << '"' << end
      << "bpy.data.objects[\"" << id << "__shape\"].parent = "
      << "bpy.data.objects[\"" << id << "\"]" << end;
    // Set parent group
    if (!groupStack_.empty())
      out() << "bpy.context.object.parent = bpy.data.objects[\""
        << groupStack_.top() << "\"]" << end;

    NodeVisitor::apply (node);
  }

  void BlenderGeomWriterVisitor::unimplemented(const char* type, Node& node)
  {
    std::cout << type << " is not implemented. " << node.getID()
      << " not added" << std::endl;
    out() << "bpy.ops.object.empty_add()" << end;
    standardApply(node);
  }
} // namespace graphics

<commit_msg>Write color for Box and Collada when exporting for blender<commit_after>// Copyright (c) 2016, Joseph Mirabel
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
//
// This file is part of gepetto-viewer-corba.
// gepetto-viewer-corba 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
// 3 of the License, or (at your option) any later version.
//
// gepetto-viewer-corba 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 Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// gepetto-viewer-corba. If not, see <http://www.gnu.org/licenses/>.

#include <gepetto/viewer/blender-geom-writer.h>

#include <algorithm>
#include <sys/stat.h>

#include <gepetto/viewer/node.h>
#include <gepetto/viewer/group-node.h>
#include <gepetto/viewer/leaf-node-arrow.h>
#include <gepetto/viewer/leaf-node-box.h>
#include <gepetto/viewer/leaf-node-capsule.h>
#include <gepetto/viewer/leaf-node-collada.h>
#include <gepetto/viewer/leaf-node-cone.h>
#include <gepetto/viewer/leaf-node-cylinder.h>
#include <gepetto/viewer/leaf-node-face.h>
#include <gepetto/viewer/leaf-node-ground.h>
#include <gepetto/viewer/leaf-node-light.h>
#include <gepetto/viewer/leaf-node-line.h>
#include <gepetto/viewer/leaf-node-sphere.h>
#include <gepetto/viewer/leaf-node-xyzaxis.h>
//#include <gepetto/viewer/node-rod.h>

namespace graphics {
  namespace {
    const char indent[] = "  ";
    const char end = '\n';
    const char group[] = "##";
    const char node[] = "#";

    template <typename Vector>
      std::ostream& writeVectorAsList (std::ostream& os, const Vector& v)
    {
      os << "( ";
      for (int i = 0; i < Vector::num_components; ++i)
        os << v[i] << ", ";
      os << ")";
      return os;
    }

    template <>
      std::ostream& writeVectorAsList<osg::Quat> (std::ostream& os, const osg::Quat& q)
    {
      os << "( " << q.w() << ", " << q.x() << ", " << q.y() << ", " << q.z() << ", )";
      return os;
    }

    std::ostream& writeRGB(std::ostream& os, const osgVector4& rgba)
    {
      return os << "( " << rgba.r() << ", " << rgba.g() << ", " << rgba.b() << ", )";
    }

    std::string writeMaterial(std::ostream& os, const std::string& name, const osg::Material* mat,
        bool diffuse = true, bool ambient = false, bool specular = false) {
      const std::string var = "material";
      const osg::Material::Face face = osg::Material::FRONT;
      os << var << " = bpy.data.materials.new(\"" << name << "\")" << end;
      if (diffuse)
        writeRGB (os << var << ".diffuse_color = ", mat->getDiffuse(face)) << end
          << var << ".diffuse_intensity = " << mat->getDiffuse(face).a() << end;
      if (ambient)
        writeRGB (os << var << ".ambient_color = ", mat->getAmbient(face)) << end
          << var << ".ambient_intensity = " << mat->getAmbient(face).a() << end;
      if (specular)
        writeRGB (os << var << ".specular_color = ", mat->getSpecular(face)) << end
          << var << ".specular_intensity = " << mat->getSpecular(face).a() << end;
      return var;
    }

    std::string writeMaterial(std::ostream& os, const std::string& name, const osgVector4& rgbaDiffuse)
    {
      const std::string var = "material";
      os << var << " = bpy.data.materials.new(\"" << name << "\")" << end;
      writeRGB (os << var << ".diffuse_color = ", rgbaDiffuse) << end
        << var << ".diffuse_intensity = " << rgbaDiffuse.a() << end;
      return var;
    }
  }

  BlenderGeomWriterVisitor::BlenderGeomWriterVisitor (const std::string& filename)
    : filename_ (filename)
  {
    bool isNew = !openFile();
    const std::string comment = (isNew ? "" : "# ");
    out() << comment << "import bpy" << end << end
      << comment << "## Start convenient functions" << end
      << comment << "def checkConf():" << end
      << comment << "  if bpy.app.version[0:2] != (2, 75):" << end
      << comment << "    print \"Using blender version\", bpy.app.version" << end
      << comment << "    print \"Developed under version 2.75.0.\"" << end
      << comment << "    return False" << end
      << comment << "  if bpy.context.scene.render.engine != 'CYCLES':" << end
      << comment << "    print \"Cycles renderer is prefered\"" << end
      << comment << "    return False" << end
      << comment << "  return True" << end
      << comment << end
      << comment << "taggedObjects = list()" << end
      << comment << "def tagObjects ():" << end
      << comment << "  global taggedObjects" << end
      << comment << "  taggedObjects = list ()" << end
      << comment << "  for obj in bpy.data.objects:" << end
      << comment << "    taggedObjects.append (obj.name)" << end
      << comment << "" << end
      << comment << "def getNonTaggedObjects ():" << end
      << comment << "  global taggedObjects" << end
      << comment << "  return [obj for obj in bpy.data.objects if obj.name not in taggedObjects]" << end
      << comment << "" << end
      << comment << "def setParent (children, parent):" << end
      << comment << "  for child in children:" << end
      << comment << "    child.parent = parent" << end << end
      << comment << "" << end
      << comment << "def setMaterial (children, mat):" << end
      << comment << "  for child in children:" << end
      << comment << "    child.data.materials.append(mat)" << end << end
      << comment << "checkConf()" << end << end
      << comment << "## End of convenient functions" << end;
  }

  bool BlenderGeomWriterVisitor::openFile () {
    struct stat buffer;
    bool ret = (stat (filename_.c_str(), &buffer) == 0);
    file_.open (filename_.c_str(),
        std::ofstream::out | std::ofstream::app);
    if (!file_.is_open ())
      throw std::ios_base::failure ("Unable to open file " + filename_);
    return ret;
  }

  void BlenderGeomWriterVisitor::apply (Node& node)
  {
    std::cerr << "This function should not be called. Type of node " << node.getID() << " may be unknown" << std::endl;
    standardApply(node);
  }
  void BlenderGeomWriterVisitor::apply (GroupNode& node)
  {
    for (std::size_t i = 0; i < groupStack_.size() + 1; ++i)
      out() << group;
    out() << " Group " << node.getID() << end;

    out() << "bpy.ops.object.empty_add()" << end
      << "bpy.context.object.name = \"" << node.getID() << '"' << end;
    // Set parent of this group
    if (!groupStack_.empty())
      out() << "bpy.context.object.parent = bpy.data.objects[\""
        << groupStack_.top() << "\"]" << end;

    groupStack_.push(node.getID());
    NodeVisitor::apply(static_cast<Node&>(node));
    groupStack_.pop();

    for (std::size_t i = 0; i < groupStack_.size() + 1; ++i)
      out() << group;
    out() << end;
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeArrow& node)
  {
    unimplemented("LeafNodeArrow", node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeBox& node)
  {
    out()
      << "bpy.ops.mesh.primitive_cube_add ()" << end
      << "bpy.context.object.dimensions = ";
    writeVectorAsList(out(), node.getHalfAxis()*2) << end;

    const std::string var_mat = writeMaterial(out(), node.getID() + "__mat", node.getColor());
    out () << "bpy.context.object.data.materials.append(" << var_mat << ')' << end;

    standardApply(static_cast<Node&>(node));
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeCapsule& node)
  {
    unimplemented("LeafNodeCapsule", node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeCollada& node)
  {
    out() << "tagObjects()" << end;

    const std::string& mesh = node.meshFilePath();

    std::string ext = mesh.substr(mesh.find_last_of(".")+1,mesh.size());
    std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
    if(ext == "obj") {
      out() << "bpy.ops.import_scene.obj (filepath=\"" << mesh << "\")" << end;
    } else if (ext == "dae") {
      out() << "bpy.ops.wm.collada_import (filepath=\"" << mesh << "\")" << end;
    } else if (ext == "stl") {
      out() << "bpy.ops.import_mesh.stl (filepath=\"" << mesh << "\")" << end;
    } else {
      std::cout << "Extension of file " << mesh << " with name " << node.getID()
        << " is not known." << end
        << "You can load the file manually and add it to the empty object called " << node.getID() << end
        << "To fix the issue, upate" __FILE__ ":" << __LINE__ << std::endl;
      out() << "# Here goes the content of file " << mesh << end;
      out() << "# To fix it, upate" __FILE__ ":" << __LINE__ << end;
    }

    out ()
      << "imported_objects = getNonTaggedObjects ()" << end
      << "print(imported_objects)" << end
      << "bpy.ops.object.empty_add ()" << end
      << "setParent (imported_objects, bpy.context.object)" << end;

    osg::Material* mat_ptr = dynamic_cast<osg::Material*> (
        node.getOsgNode()->getStateSet()->getAttribute(osg::StateAttribute::MATERIAL));
    if (mat_ptr != NULL) { // Color was set by URDF
      const std::string var_mat = writeMaterial(out(), node.getID() + "__mat", mat_ptr, true, false, false);
      out () << "setMaterial (imported_objects, " << var_mat << ')' << end;
    }

    standardApply(node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeCone& node)
  {
    out() << "bpy.ops.mesh.primitive_cone_add (radius1="
      << node.getRadius() << ", depth=" << node.getHeight() << ')' << end;
    standardApply(node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeCylinder& node)
  {
    out() << "bpy.ops.mesh.primitive_cylinder_add (radius="
      << node.getRadius() << ", depth=" << node.getHeight() << ')' << end;
    standardApply(node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeFace& node)
  {
    unimplemented("LeafNodeFace", node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeGround& node)
  {
    unimplemented("LeafNodeGround", node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeLight& node)
  {
    unimplemented("LeafNodeLight", node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeLine& node)
  {
    unimplemented("LeafNodeLine", node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeSphere& node)
  {
    out () << "bpy.ops.mesh.primitive_ico_sphere_add (size="
      << node.getRadius() << ")" << end;
    standardApply(node);
  }
  void BlenderGeomWriterVisitor::apply (LeafNodeXYZAxis& node)
  {
    unimplemented("LeafNodeXYZAxis", node);
  }

  void BlenderGeomWriterVisitor::standardApply (Node& node)
  {
    const std::string& id = node.getID ();
    // Set name
    out()
      << "bpy.context.object.name = \"" << id << "__shape\"" << end
      << "bpy.context.object.location = ";
    writeVectorAsList(out(), node.getStaticPosition()) << end;
    out()
      << "bpy.context.object.rotation_mode = 'QUATERNION'" << end
      << "bpy.context.object.rotation_quaternion = ";
    writeVectorAsList(out(), node.getStaticRotation()) << end;
    out()
      << "bpy.ops.object.empty_add ()" << end
      << "bpy.context.object.name = \"" << id << '"' << end
      << "bpy.data.objects[\"" << id << "__shape\"].parent = "
      << "bpy.data.objects[\"" << id << "\"]" << end;
    // Set parent group
    if (!groupStack_.empty())
      out() << "bpy.context.object.parent = bpy.data.objects[\""
        << groupStack_.top() << "\"]" << end;

    NodeVisitor::apply (node);
  }

  void BlenderGeomWriterVisitor::unimplemented(const char* type, Node& node)
  {
    std::cout << type << " is not implemented. " << node.getID()
      << " not added" << std::endl;
    out() << "bpy.ops.object.empty_add()" << end;
    standardApply(node);
  }
} // namespace graphics

<|endoftext|>


<commit_before>// Copyright (C) 2010 and 2011 Marcin Arkadiusz Skrobiranda.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. Neither the name of the project nor the names of its contributors
//    may be used to endorse or promote products derived from this software
//    without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.

#include <GameServer/Building/Operators/BuildBuilding/BuildBuildingOperator.hpp>
#include <GameServer/Configuration/Configurator/Building/ConfiguratorBuilding.hpp>

using namespace GameServer::Common;
using namespace GameServer::Configuration;
using namespace GameServer::Persistence;
using namespace GameServer::Resource;

namespace GameServer
{
namespace Building
{

BuildBuildingOperator::BuildBuildingOperator(
    IContextShrPtr                   const a_context,
    IBuildingPersistenceFacadeShrPtr       a_building_persistence_facade,
    IResourcePersistenceFacadeShrPtr       a_resource_persistence_facade
)
    : m_context(a_context),
      m_building_persistence_facade(a_building_persistence_facade),
      m_resource_persistence_facade(a_resource_persistence_facade)
{
}

BuildBuildingOperatorExitCode BuildBuildingOperator::buildBuilding(
    ITransactionShrPtr         a_transaction,
    IDHolder           const & a_id_holder,
    IBuildingKey       const & a_key,
    Volume             const & a_volume
) const
{
    try
    {
        // Trying to build zero buildings.
        if (a_volume == 0)
        {
            return BuildBuildingOperatorExitCode(BUILD_BUILDING_OPERATOR_EXIT_CODE_TRYING_TO_BUILD_ZERO_BUILDINGS);
        }

        // Get available resources.
        ResourceSet resource_set = m_resource_persistence_facade->getResources(a_transaction, a_id_holder);

        // Get total cost.
        // TODO: Consider handling invalid key: coding by contract / verification.
        ResourceSet cost = m_context->getConfiguratorBuilding()->getBuilding(a_key)->getCostsToBuild();

        // Multiply total cost.
        cost *= a_volume;

        // Verify if there is enough resources.
        if (!(resource_set >= cost))
        {
            return BuildBuildingOperatorExitCode(BUILD_BUILDING_OPERATOR_EXIT_CODE_NOT_ENOUGH_RESOURCES);
        }

        // Subtract the resources.
        bool const result = m_resource_persistence_facade->subtractResourceSet(a_transaction, a_id_holder, cost);

        // There is a possible situation (in multithreaded application) of a race condition between checking if
        // there is enough resources and trying to subtract it.
        // As it is not an error (just a result of another action) the appropriate exit code is returned.
        if (!result)
        {
            return BuildBuildingOperatorExitCode(BUILD_BUILDING_OPERATOR_EXIT_CODE_RESOURCES_MISSING_IN_THE_MEANTIME);
        }

        // Add the building.
        m_building_persistence_facade->addBuilding(a_transaction, a_id_holder, a_key, a_volume);

        return BuildBuildingOperatorExitCode(BUILD_BUILDING_OPERATOR_EXIT_CODE_BUILDING_HAS_BEEN_BUILT);
    }
    catch (...)
    {
        return BuildBuildingOperatorExitCode(BUILD_BUILDING_OPERATOR_EXIT_CODE_UNEXPECTED_ERROR);
    }
}

} // namespace Building
} // namespace GameServer
<commit_msg>Less data included.<commit_after>// Copyright (C) 2010 and 2011 Marcin Arkadiusz Skrobiranda.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. Neither the name of the project nor the names of its contributors
//    may be used to endorse or promote products derived from this software
//    without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.

#include <GameServer/Building/Operators/BuildBuilding/BuildBuildingOperator.hpp>
#include <GameServer/Configuration/Configurator/Building/IBuilding.hpp>

using namespace GameServer::Common;
using namespace GameServer::Configuration;
using namespace GameServer::Persistence;
using namespace GameServer::Resource;

namespace GameServer
{
namespace Building
{

BuildBuildingOperator::BuildBuildingOperator(
    IContextShrPtr                   const a_context,
    IBuildingPersistenceFacadeShrPtr       a_building_persistence_facade,
    IResourcePersistenceFacadeShrPtr       a_resource_persistence_facade
)
    : m_context(a_context),
      m_building_persistence_facade(a_building_persistence_facade),
      m_resource_persistence_facade(a_resource_persistence_facade)
{
}

BuildBuildingOperatorExitCode BuildBuildingOperator::buildBuilding(
    ITransactionShrPtr         a_transaction,
    IDHolder           const & a_id_holder,
    IBuildingKey       const & a_key,
    Volume             const & a_volume
) const
{
    try
    {
        // Trying to build zero buildings.
        if (a_volume == 0)
        {
            return BuildBuildingOperatorExitCode(BUILD_BUILDING_OPERATOR_EXIT_CODE_TRYING_TO_BUILD_ZERO_BUILDINGS);
        }

        // Get available resources.
        ResourceSet resource_set = m_resource_persistence_facade->getResources(a_transaction, a_id_holder);

        // Get total cost.
        // TODO: Consider handling invalid key: coding by contract / verification.
        ResourceSet cost = m_context->getConfiguratorBuilding()->getBuilding(a_key)->getCostsToBuild();

        // Multiply total cost.
        cost *= a_volume;

        // Verify if there is enough resources.
        if (!(resource_set >= cost))
        {
            return BuildBuildingOperatorExitCode(BUILD_BUILDING_OPERATOR_EXIT_CODE_NOT_ENOUGH_RESOURCES);
        }

        // Subtract the resources.
        bool const result = m_resource_persistence_facade->subtractResourceSet(a_transaction, a_id_holder, cost);

        // There is a possible situation (in multithreaded application) of a race condition between checking if
        // there is enough resources and trying to subtract it.
        // As it is not an error (just a result of another action) the appropriate exit code is returned.
        if (!result)
        {
            return BuildBuildingOperatorExitCode(BUILD_BUILDING_OPERATOR_EXIT_CODE_RESOURCES_MISSING_IN_THE_MEANTIME);
        }

        // Add the building.
        m_building_persistence_facade->addBuilding(a_transaction, a_id_holder, a_key, a_volume);

        return BuildBuildingOperatorExitCode(BUILD_BUILDING_OPERATOR_EXIT_CODE_BUILDING_HAS_BEEN_BUILT);
    }
    catch (...)
    {
        return BuildBuildingOperatorExitCode(BUILD_BUILDING_OPERATOR_EXIT_CODE_UNEXPECTED_ERROR);
    }
}

} // namespace Building
} // namespace GameServer
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkNormalizedCorrelationPointSetToImageMetricTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "itkImageRegionIterator.h"
#include "itkTranslationTransform.h"
#include "itkLinearInterpolateImageFunction.h"
#include "itkNormalizedCorrelationPointSetToImageMetric.h"
#include "itkGaussianImageSource.h"
#include "itkImage.h"
#include "itkPointSet.h"

#include <iostream>

/**
 *  This test uses two 2D-Gaussians (standard deviation RegionSize/2)
 *  One is shifted by 5 pixels from the other.
 *
 *  This test computes the NormalizedCorrelation value and derivatives
 *  for various shift values in (-10,10).
 *
 */

int itkNormalizedCorrelationPointSetToImageMetricTest(int, char* [] )
{

//------------------------------------------------------------
// Create two simple images
//------------------------------------------------------------

  const unsigned int ImageDimension = 2;

  typedef double                   PixelType;

  typedef double                   CoordinateRepresentationType;

  //Allocate Images
  typedef itk::Image<PixelType,ImageDimension>         MovingImageType;
  typedef itk::Image<PixelType,ImageDimension>         FixedImageType;

  // Declare Gaussian Sources
  typedef itk::GaussianImageSource< MovingImageType >  MovingImageSourceType;
  typedef itk::GaussianImageSource< FixedImageType  >  FixedImageSourceType;
  typedef MovingImageSourceType::Pointer               MovingImageSourcePointer;
  typedef FixedImageSourceType::Pointer                FixedImageSourcePointer;

  // Note: the following declarations are classical arrays
  unsigned long fixedImageSize[]     = {  100,  100 };
  unsigned long movingImageSize[]    = {  100,  100 };

  float         fixedImageSpacing[]  = { 1.0f, 1.0f };
  float         movingImageSpacing[] = { 1.0f, 1.0f };

  float         fixedImageOrigin[]   = { 0.0f, 0.0f };
  float         movingImageOrigin[]  = { 0.0f, 0.0f };

  MovingImageSourceType::Pointer movingImageSource = MovingImageSourceType::New();
  FixedImageSourceType::Pointer  fixedImageSource  = FixedImageSourceType::New();

  fixedImageSource->SetSize(    fixedImageSize    );
  fixedImageSource->SetOrigin(  fixedImageOrigin  );
  fixedImageSource->SetSpacing( fixedImageSpacing );
  fixedImageSource->SetNormalized( false );
  fixedImageSource->SetScale( 250.0f );

  movingImageSource->SetSize(    movingImageSize    );
  movingImageSource->SetOrigin(  movingImageOrigin  );
  movingImageSource->SetSpacing( movingImageSpacing );
  movingImageSource->SetNormalized( false );
  movingImageSource->SetScale( 250.0f );

  movingImageSource->Update();  // Force the filter to run
  fixedImageSource->Update();   // Force the filter to run

  MovingImageType::Pointer movingImage = movingImageSource->GetOutput();
  FixedImageType::Pointer  fixedImage  = fixedImageSource->GetOutput();

//-----------------------------------------------------------
// Create the point set and load it with data by sampling
// the fixed image
//-----------------------------------------------------------
  typedef itk::PointSet< float, 2 >   FixedPointSetType;
  FixedPointSetType::Pointer fixedPointSet = FixedPointSetType::New();
  fixedPointSet->GetPoints()->Reserve( 100 );
  fixedPointSet->GetPointData()->Reserve( 100 );

  for(unsigned int y=0; y<100; y+=10)
    {
    for(unsigned int x=0; x<100; x+=10)
      {
      }
    }

//-----------------------------------------------------------
// Set up  the Metric
//-----------------------------------------------------------
  typedef itk::NormalizedCorrelationPointSetToImageMetric<
                                       FixedPointSetType,
                                       MovingImageType >
                                                    MetricType;

  typedef MetricType::TransformType                 TransformBaseType;
  typedef TransformBaseType::ParametersType         ParametersType;
  typedef TransformBaseType::JacobianType           JacobianType;

  MetricType::Pointer  metric = MetricType::New();

//-----------------------------------------------------------
// Plug the Images into the metric
//-----------------------------------------------------------
  metric->SetFixedPointSet( fixedPointSet );
  metric->SetMovingImage( movingImage );

//-----------------------------------------------------------
// Set up a Transform
//-----------------------------------------------------------

  typedef itk::TranslationTransform<
                        CoordinateRepresentationType,
                        ImageDimension >         TransformType;

  TransformType::Pointer transform = TransformType::New();

  metric->SetTransform( transform.GetPointer() );

//------------------------------------------------------------
// Set up an Interpolator
//------------------------------------------------------------
  typedef itk::LinearInterpolateImageFunction<
                    MovingImageType,
                    double > InterpolatorType;

  InterpolatorType::Pointer interpolator = InterpolatorType::New();

  interpolator->SetInputImage( movingImage.GetPointer() );

  metric->SetInterpolator( interpolator.GetPointer() );

//------------------------------------------------------------
// Define the Scale at which the Gradient of the image will be computed
//------------------------------------------------------------
   metric->SetScaleGradient( 1.0 );

  std::cout << metric << std::endl;

//------------------------------------------------------------
// This call is mandatory before start querying the Metric
// This method do all the necesary connections between the
// internal components: Interpolator, Transform and Images
//------------------------------------------------------------
  try {
    metric->Initialize();
    }
  catch( itk::ExceptionObject & e )
    {
    std::cout << "Metric initialization failed" << std::endl;
    std::cout << "Reason " << e.GetDescription() << std::endl;
    return EXIT_FAILURE;
    }

//------------------------------------------------------------
// Set up transform parameters
//------------------------------------------------------------
  ParametersType parameters( transform->GetNumberOfParameters() );

  // initialize the offset/vector part
  for( unsigned int k = 0; k < ImageDimension; k++ )
    {
    parameters[k]= 0.0f;
    }

//---------------------------------------------------------
// Print out metric values
// for parameters[1] = {-10,10}  (arbitrary choice...)
//---------------------------------------------------------

  MetricType::MeasureType     measure;
  MetricType::DerivativeType  derivative;

  std::cout << "param[1]   Metric    d(Metric)/d(param[1] " << std::endl;

  for( double trans = -10; trans <= 5; trans += 0.2 )
    {
    parameters[1] = trans;
    metric->GetValueAndDerivative( parameters, measure, derivative );

    std::cout.width(5);
    std::cout.precision(5);
    std::cout << trans;
    std::cout.width(15);
    std::cout.precision(5);
    std::cout << measure;
    std::cout.width(15);
    std::cout.precision(5);
    std::cout << derivative[1];
    std::cout << std::endl;

    // exercise the other functions
    metric->GetValue( parameters );
    metric->GetDerivative( parameters, derivative );

    }

//-------------------------------------------------------
// exercise misc member functions
//-------------------------------------------------------
  std::cout << "Check case when Target is NULL" << std::endl;
  metric->SetFixedPointSet( NULL );
  try
    {
    std::cout << "Value = " << metric->GetValue( parameters );
    std::cout << "If you are reading this message the Metric " << std::endl;
    std::cout << "is NOT managing exceptions correctly    " << std::endl;
    return EXIT_FAILURE;
    }
  catch( itk::ExceptionObject & e )
    {
    std::cout << "Exception received (as expected) "    << std::endl;
    std::cout << "Description : " << e.GetDescription() << std::endl;
    std::cout << "Location    : " << e.GetLocation()    << std::endl;
    std::cout << "Test for exception throwing... PASSED ! " << std::endl;
    }

  try
    {
    metric->GetValueAndDerivative( parameters, measure, derivative );
    std::cout << "Value = " << measure << std::endl;
    std::cout << "If you are reading this message the Metric " << std::endl;
    std::cout << "is NOT managing exceptions correctly    " << std::endl;
    return EXIT_FAILURE;
    }
  catch( itk::ExceptionObject & e )
    {
    std::cout << "Exception received (as expected) "    << std::endl;
    std::cout << "Description : " << e.GetDescription() << std::endl;
    std::cout << "Location    : " << e.GetLocation()    << std::endl;
    std::cout << "Test for exception throwing... PASSED ! "  << std::endl;
    }

  return EXIT_SUCCESS;

}

<commit_msg>ENH: Sampling of points from the fixed image added. The pointSet was empty      before that.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkNormalizedCorrelationPointSetToImageMetricTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "itkImageRegionIterator.h"
#include "itkTranslationTransform.h"
#include "itkLinearInterpolateImageFunction.h"
#include "itkNormalizedCorrelationPointSetToImageMetric.h"
#include "itkGaussianImageSource.h"
#include "itkImage.h"
#include "itkPointSet.h"
#include "itkImageRegionIterator.h"

#include <iostream>

/**
 *  This test uses two 2D-Gaussians (standard deviation RegionSize/2)
 *  One is shifted by 5 pixels from the other.
 *
 *  This test computes the NormalizedCorrelation value and derivatives
 *  for various shift values in (-10,10).
 *
 */

int itkNormalizedCorrelationPointSetToImageMetricTest(int, char* [] )
{

//------------------------------------------------------------
// Create two simple images
//------------------------------------------------------------

  const unsigned int ImageDimension = 2;

  typedef double                   PixelType;

  typedef double                   CoordinateRepresentationType;

  //Allocate Images
  typedef itk::Image<PixelType,ImageDimension>         MovingImageType;
  typedef itk::Image<PixelType,ImageDimension>         FixedImageType;

  // Declare Gaussian Sources
  typedef itk::GaussianImageSource< MovingImageType >  MovingImageSourceType;
  typedef itk::GaussianImageSource< FixedImageType  >  FixedImageSourceType;
  typedef MovingImageSourceType::Pointer               MovingImageSourcePointer;
  typedef FixedImageSourceType::Pointer                FixedImageSourcePointer;

  // Note: the following declarations are classical arrays
  unsigned long fixedImageSize[]     = {  100,  100 };
  unsigned long movingImageSize[]    = {  100,  100 };

  float         fixedImageSpacing[]  = { 1.0f, 1.0f };
  float         movingImageSpacing[] = { 1.0f, 1.0f };

  float         fixedImageOrigin[]   = { 0.0f, 0.0f };
  float         movingImageOrigin[]  = { 0.0f, 0.0f };

  MovingImageSourceType::Pointer movingImageSource = MovingImageSourceType::New();
  FixedImageSourceType::Pointer  fixedImageSource  = FixedImageSourceType::New();

  fixedImageSource->SetSize(    fixedImageSize    );
  fixedImageSource->SetOrigin(  fixedImageOrigin  );
  fixedImageSource->SetSpacing( fixedImageSpacing );
  fixedImageSource->SetNormalized( false );
  fixedImageSource->SetScale( 250.0f );

  movingImageSource->SetSize(    movingImageSize    );
  movingImageSource->SetOrigin(  movingImageOrigin  );
  movingImageSource->SetSpacing( movingImageSpacing );
  movingImageSource->SetNormalized( false );
  movingImageSource->SetScale( 250.0f );

  movingImageSource->Update();  // Force the filter to run
  fixedImageSource->Update();   // Force the filter to run

  MovingImageType::Pointer movingImage = movingImageSource->GetOutput();
  FixedImageType::Pointer  fixedImage  = fixedImageSource->GetOutput();

//-----------------------------------------------------------
// Create the point set and load it with data by sampling
// the fixed image
//-----------------------------------------------------------
  typedef itk::PointSet< float, 2 >   FixedPointSetType;
  FixedPointSetType::Pointer fixedPointSet = FixedPointSetType::New();

  const unsigned int numberOfPoints = 100;

  fixedPointSet->GetPoints()->Reserve( numberOfPoints );
  fixedPointSet->GetPointData()->Reserve( numberOfPoints );

  itk::ImageRegionIterator< FixedImageType > it( fixedImage,
                                            fixedImage->GetBufferedRegion() );

  const unsigned int skip =
      fixedImage->GetBufferedRegion().GetNumberOfPixels() / numberOfPoints;

  unsigned int counter = skip;

  FixedPointSetType::PointIdentifier pointId = 0;
  FixedPointSetType::PointType  point;

  it.GoToBegin();
  while( !it.IsAtEnd() )
    {
    if( counter==0 )
      {
      fixedImage->TransformIndexToPhysicalPoint( it.GetIndex(), point );
      fixedPointSet->SetPoint( pointId, point );
      fixedPointSet->SetPointData( pointId, it.Get() );
      ++pointId;
      if( pointId == numberOfPoints )
        {
        break;
        }
      counter = skip;
      }
    --counter;
    ++it;
    }

//-----------------------------------------------------------
// Set up  the Metric
//-----------------------------------------------------------
  typedef itk::NormalizedCorrelationPointSetToImageMetric<
                                       FixedPointSetType,
                                       MovingImageType >
                                                    MetricType;

  typedef MetricType::TransformType                 TransformBaseType;
  typedef TransformBaseType::ParametersType         ParametersType;
  typedef TransformBaseType::JacobianType           JacobianType;

  MetricType::Pointer  metric = MetricType::New();

//-----------------------------------------------------------
// Plug the Images into the metric
//-----------------------------------------------------------
  metric->SetFixedPointSet( fixedPointSet );
  metric->SetMovingImage( movingImage );

//-----------------------------------------------------------
// Set up a Transform
//-----------------------------------------------------------

  typedef itk::TranslationTransform<
                        CoordinateRepresentationType,
                        ImageDimension >         TransformType;

  TransformType::Pointer transform = TransformType::New();

  metric->SetTransform( transform.GetPointer() );

//------------------------------------------------------------
// Set up an Interpolator
//------------------------------------------------------------
  typedef itk::LinearInterpolateImageFunction<
                    MovingImageType,
                    double > InterpolatorType;

  InterpolatorType::Pointer interpolator = InterpolatorType::New();

  interpolator->SetInputImage( movingImage.GetPointer() );

  metric->SetInterpolator( interpolator.GetPointer() );

//------------------------------------------------------------
// Define the Scale at which the Gradient of the image will be computed
//------------------------------------------------------------
   metric->SetScaleGradient( 1.0 );

  std::cout << metric << std::endl;

//------------------------------------------------------------
// This call is mandatory before start querying the Metric
// This method do all the necesary connections between the
// internal components: Interpolator, Transform and Images
//------------------------------------------------------------
  try {
    metric->Initialize();
    }
  catch( itk::ExceptionObject & e )
    {
    std::cout << "Metric initialization failed" << std::endl;
    std::cout << "Reason " << e.GetDescription() << std::endl;
    return EXIT_FAILURE;
    }

//------------------------------------------------------------
// Set up transform parameters
//------------------------------------------------------------
  ParametersType parameters( transform->GetNumberOfParameters() );

  // initialize the offset/vector part
  for( unsigned int k = 0; k < ImageDimension; k++ )
    {
    parameters[k]= 0.0f;
    }

//---------------------------------------------------------
// Print out metric values
// for parameters[1] = {-10,10}  (arbitrary choice...)
//---------------------------------------------------------

  MetricType::MeasureType     measure;
  MetricType::DerivativeType  derivative;

  std::cout << "param[1]   Metric    d(Metric)/d(param[1] " << std::endl;

  for( double trans = -10; trans <= 5; trans += 0.2 )
    {
    parameters[1] = trans;
    metric->GetValueAndDerivative( parameters, measure, derivative );

    std::cout.width(5);
    std::cout.precision(5);
    std::cout << trans;
    std::cout.width(15);
    std::cout.precision(5);
    std::cout << measure;
    std::cout.width(15);
    std::cout.precision(5);
    std::cout << derivative[1];
    std::cout << std::endl;

    // exercise the other functions
    metric->GetValue( parameters );
    metric->GetDerivative( parameters, derivative );

    }

//-------------------------------------------------------
// exercise misc member functions
//-------------------------------------------------------
  std::cout << "Check case when Target is NULL" << std::endl;
  metric->SetFixedPointSet( NULL );
  try
    {
    std::cout << "Value = " << metric->GetValue( parameters );
    std::cout << "If you are reading this message the Metric " << std::endl;
    std::cout << "is NOT managing exceptions correctly    " << std::endl;
    return EXIT_FAILURE;
    }
  catch( itk::ExceptionObject & e )
    {
    std::cout << "Exception received (as expected) "    << std::endl;
    std::cout << "Description : " << e.GetDescription() << std::endl;
    std::cout << "Location    : " << e.GetLocation()    << std::endl;
    std::cout << "Test for exception throwing... PASSED ! " << std::endl;
    }

  try
    {
    metric->GetValueAndDerivative( parameters, measure, derivative );
    std::cout << "Value = " << measure << std::endl;
    std::cout << "If you are reading this message the Metric " << std::endl;
    std::cout << "is NOT managing exceptions correctly    " << std::endl;
    return EXIT_FAILURE;
    }
  catch( itk::ExceptionObject & e )
    {
    std::cout << "Exception received (as expected) "    << std::endl;
    std::cout << "Description : " << e.GetDescription() << std::endl;
    std::cout << "Location    : " << e.GetLocation()    << std::endl;
    std::cout << "Test for exception throwing... PASSED ! "  << std::endl;
    }

  return EXIT_SUCCESS;

}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 ARM Limited. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 * 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 "lwm2mtest.h"
#include "ns_types.h"
#include "ns_cmdline.h"

M2MLWClient::M2MLWClient()
: _security(NULL),
  _interface(NULL),
  _device(NULL),
  _bootstrapped(false),
  _error(false),
  _registered(false),
  _unregistered(false),
  _registration_updated(false)
{
}

M2MLWClient::~M2MLWClient()
{
    if(_interface) {
        delete _interface;
    }
    if(_security) {
        delete _security;
    }
    if( _register_security){
        delete _register_security;
    }
}

bool M2MLWClient::create_interface(int32_t param_count,
					  const char *endpoint,
                      const char *resource_type,
                      const int32_t lifetime,
                      const uint16_t listen_port,
                      const char *domain,
                      const uint8_t binding_mode,
                      const uint8_t network_interface)
{
    if(_interface) {
        delete _interface;
        _interface = NULL;
    }
    String ep;
    String rt;
    String dmn;
    if(endpoint) {
        ep += endpoint;
    }
    if(resource_type) {
        rt += resource_type;
    }
    if(domain) {
        dmn += domain;
    }

    // Binding mode cannot be higher than 0x07 since it is an enum, check M2MInterface::BindingMode
    if(binding_mode > 0x07) {
        return false;
    }

    switch (param_count) {
		case 0:
			_interface = M2MInterfaceFactory::create_interface(*this, ep, rt);
			break;
		case 1:
			_interface = M2MInterfaceFactory::create_interface(*this, ep, rt, lifetime);
			break;
		case 2:
			_interface = M2MInterfaceFactory::create_interface(*this, ep, rt, lifetime, listen_port);
			break;
		case 3:
			_interface = M2MInterfaceFactory::create_interface(*this, ep, rt, lifetime, listen_port, dmn);
			break;
		case 4:
			_interface = M2MInterfaceFactory::create_interface(*this, ep, rt, lifetime, listen_port, dmn, (M2MInterface::BindingMode)binding_mode);
			break;
		case 5:
			_interface = M2MInterfaceFactory::create_interface(*this, ep, rt, lifetime, listen_port, dmn, (M2MInterface::BindingMode)binding_mode, (M2MInterface::NetworkStack)network_interface);
			break;
	}
    return (_interface == NULL) ? false : true;
}

bool M2MLWClient::create_bootstrap_object(const char *coap_bootstrap_address)
{
    bool success = false;
    String address;
    if(coap_bootstrap_address) {
        address += coap_bootstrap_address;
    }
    if(_security) {
        delete _security;
    }
    _security = M2MInterfaceFactory::create_security(M2MSecurity::Bootstrap);
    if(_security) {
        if(_security->set_resource_value(M2MSecurity::M2MServerUri, address) &&
           _security->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::NoSecurity)) {
            success = true;
        }
    }
    return success;
}

bool M2MLWClient::create_register_object(const char *coap_register_address)
{
    bool success = false;
    String address;
    if(coap_register_address) {
        address += coap_register_address;
    }
    if(_register_security) {
        delete _register_security;
    }
    _register_security = M2MInterfaceFactory::create_security(M2MSecurity::M2MServer);
    if(_register_security) {
        if(_register_security->set_resource_value(M2MSecurity::M2MServerUri, address) &&
           _register_security->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::NoSecurity)) {
            success = true;
        }
    }
    return success;
}

bool M2MLWClient::test_bootstrap()
{
    bool success = false;
    if(_interface) {
        _interface->bootstrap(_security);
        success = true;
    }
    return success;
}

bool M2MLWClient::create_device_object(M2MDevice::DeviceResource resource,
                                       const char *value)
{
    bool success = false;
    String value_string;
    if(value) {
        value_string += value;
    }
    if(!_device) {
        _device = M2MInterfaceFactory::create_device();
    }
    if(_device) {

        if(_device->create_resource(resource,value_string)){
            success = true;
        } else {
            success = _device->set_resource_value(resource,value);
        }
    }
    return success;
}

bool M2MLWClient::create_device_object()
{
    bool success = false;
    if(!_device) {
        _device = M2MInterfaceFactory::create_device();
        success = true;
    }
    return success;
}

bool M2MLWClient::create_device_object(M2MDevice::DeviceResource resource,
                          uint32_t value)
{
    bool success = false;
    if(!_device) {
        _device = M2MInterfaceFactory::create_device();
    }
    if(_device) {
        if(_device->create_resource(resource,value)) {
            success = true;
        } else {
            success = _device->set_resource_value(resource,value);
        }
    }
    return success;
}

bool M2MLWClient::create_object(const char *name, bool new_instance)
{
    bool success = false;
    if(!_object) {
        _object = M2MInterfaceFactory::create_object(name);
        if(_object) {
            if(_object->create_object_instance()) {
                success = true;
            }
        }
    } else {
        if(new_instance) {
            if(_object->create_object_instance()) {
                success = true;
            }
        }
    }
    return success;
}

bool M2MLWClient::create_static_resource_string(const char *name,
                                                const char *value,
                                                bool multiple_instance,
                                                uint16_t object_instance)
{
    bool success = false;
    String name_string;
    if(name) {
        name_string += name;
    }
    String value_string;
    if(value) {
        value_string += value;
    }
    if(_object) {
        M2MObjectInstance *inst = _object->object_instance(object_instance);
        if(inst) {
            if(inst->create_static_resource(name,"resource",
                                            M2MResourceInstance::STRING,
                                            (const uint8_t*)value_string.c_str(),
                                            value_string.size()) != NULL) {
                success = true;
            }
        }
    }
    return success;
}

bool M2MLWClient::create_static_resource_int(const char *name,
                                             uint32_t value,
                                             bool multiple_instance,
                                             uint16_t object_instance)
{
    bool success = false;
    String name_string;
    String value_string;

    if(name) {
        name_string += name;
    }

    char value_buffer[20];
    sprintf(value_buffer,"%d",value);
    value_string += value_buffer;

    if(_object) {
        M2MObjectInstance *inst = _object->object_instance(object_instance);
        if(inst) {
            if(inst->create_static_resource(name,"resource",
                                            M2MResourceInstance::INTEGER,
                                            (const uint8_t*)value_string.c_str(),
                                            value_string.size()) != NULL) {
                success = true;
            }
        }
    }
    return success;
}

bool M2MLWClient::create_dynamic_resource(const char *name,
                                          bool observable,
                                          bool multiple_instance,
                                          uint16_t object_instance)
{
    bool success = false;
    String name_string;
    if(name) {
        name_string += name;
    }
    if(_object) {
        M2MObjectInstance *inst = _object->object_instance(object_instance);
        if(inst) {
            if(inst->create_dynamic_resource(name,"resource",
                                             M2MResourceInstance::OPAQUE,
                                             observable) != NULL) {
                success = true;
            }
        }
    }
    return success;
}

bool M2MLWClient::set_resource_value(const char *name,
                                          int32_t value,
                                          uint16_t object_instance)
{
    bool success = false;
    String name_string;
    String value_string;
    if(name) {
        name_string += name;
    }

    char value_buffer[20];
    sprintf(value_buffer,"%d",value);
    value_string += value_buffer;

    if(_object && name_string.length() > 0) {
        M2MObjectInstance *inst = _object->object_instance(object_instance);
        if(inst) {
            M2MResource *res = inst->resource(name_string);
            if (res) {
                if (res->set_value((const uint8_t*)value_string.c_str(), value_string.size())) {
                    success = true;
                }
            }
        }
    }
    return success;
}

bool M2MLWClient::test_register()
{
    bool success = false;
    M2MObjectList object_list;
    if(_device) {
        object_list.push_back(_device);
    }
    if(_object) {
        object_list.push_back(_object);
    }
    if(_interface) {
        _interface->register_object(_register_security,object_list);
        success = true;
    }
    return success;
}

bool M2MLWClient::test_update_register(const uint32_t lifetime)
{
    bool success = false;
    if(_interface && _register_security) {
        success = true;
        _interface->update_registration(_register_security,lifetime);
    }
    return success;
}

bool M2MLWClient::test_unregister()
{
    bool success = false;
    if(_interface) {
         success = true;
        _interface->unregister_object(_register_security);
    }
    return success;
}

void M2MLWClient::bootstrap_done(M2MSecurity *server_object)
{
    if(server_object) {
        _register_security = server_object;
        _bootstrapped = true;
        cmd_printf("\nBootstrapped\n");
        cmd_ready( CMDLINE_RETCODE_SUCCESS );
    }
}

void M2MLWClient::object_registered(M2MSecurity *security_object, const M2MServer &server_object)
{
    _registered = true;
    cmd_printf("\nRegistered\n");
    cmd_ready( CMDLINE_RETCODE_SUCCESS );
}

void M2MLWClient::object_unregistered(M2MSecurity *server_object)
{
    _unregistered = true;
    if(_device) {
        M2MDevice::delete_instance();
        _device = NULL;
    }
    if(_object) {
        delete _object;
        _object = NULL;
    }
    if(_security) {
        delete _security;
        _security = NULL;
    }
    if(_register_security) {
        delete _register_security;
        _register_security = NULL;
    }
    cmd_printf("\nUnregistered\n");
    cmd_ready( CMDLINE_RETCODE_SUCCESS );
}

void M2MLWClient::registration_updated(M2MSecurity *security_object,
                                       const M2MServer &server_object)
{
    _registration_updated = true;
    cmd_printf("\nregistration updated\n");
    cmd_ready( CMDLINE_RETCODE_SUCCESS );
}

void M2MLWClient::error(M2MInterface::Error error)
{
    _error = true;
    cmd_printf("\nError occured Error Code : %d\n", (int8_t)error);
    cmd_ready( CMDLINE_RETCODE_SUCCESS );
}

void M2MLWClient::value_updated(M2MBase *base, M2MBase::BaseType type)
{
    cmd_printf("\nValue updated of Object name %s and Type \n",
               base->name().c_str(), type);
}
<commit_msg>Fixed test app device object creation<commit_after>/*
 * Copyright (c) 2015 ARM Limited. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 * 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 "lwm2mtest.h"
#include "ns_types.h"
#include "ns_cmdline.h"

M2MLWClient::M2MLWClient()
: _security(NULL),
  _interface(NULL),
  _device(NULL),
  _bootstrapped(false),
  _error(false),
  _registered(false),
  _unregistered(false),
  _registration_updated(false)
{
}

M2MLWClient::~M2MLWClient()
{
    if(_interface) {
        delete _interface;
    }
    if(_security) {
        delete _security;
    }
    if( _register_security){
        delete _register_security;
    }
}

bool M2MLWClient::create_interface(int32_t param_count,
					  const char *endpoint,
                      const char *resource_type,
                      const int32_t lifetime,
                      const uint16_t listen_port,
                      const char *domain,
                      const uint8_t binding_mode,
                      const uint8_t network_interface)
{
    if(_interface) {
        delete _interface;
        _interface = NULL;
    }
    String ep;
    String rt;
    String dmn;
    if(endpoint) {
        ep += endpoint;
    }
    if(resource_type) {
        rt += resource_type;
    }
    if(domain) {
        dmn += domain;
    }

    // Binding mode cannot be higher than 0x07 since it is an enum, check M2MInterface::BindingMode
    if(binding_mode > 0x07) {
        return false;
    }

    switch (param_count) {
		case 0:
			_interface = M2MInterfaceFactory::create_interface(*this, ep, rt);
			break;
		case 1:
			_interface = M2MInterfaceFactory::create_interface(*this, ep, rt, lifetime);
			break;
		case 2:
			_interface = M2MInterfaceFactory::create_interface(*this, ep, rt, lifetime, listen_port);
			break;
		case 3:
			_interface = M2MInterfaceFactory::create_interface(*this, ep, rt, lifetime, listen_port, dmn);
			break;
		case 4:
			_interface = M2MInterfaceFactory::create_interface(*this, ep, rt, lifetime, listen_port, dmn, (M2MInterface::BindingMode)binding_mode);
			break;
		case 5:
			_interface = M2MInterfaceFactory::create_interface(*this, ep, rt, lifetime, listen_port, dmn, (M2MInterface::BindingMode)binding_mode, (M2MInterface::NetworkStack)network_interface);
			break;
	}
    return (_interface == NULL) ? false : true;
}

bool M2MLWClient::create_bootstrap_object(const char *coap_bootstrap_address)
{
    bool success = false;
    String address;
    if(coap_bootstrap_address) {
        address += coap_bootstrap_address;
    }
    if(_security) {
        delete _security;
    }
    _security = M2MInterfaceFactory::create_security(M2MSecurity::Bootstrap);
    if(_security) {
        if(_security->set_resource_value(M2MSecurity::M2MServerUri, address) &&
           _security->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::NoSecurity)) {
            success = true;
        }
    }
    return success;
}

bool M2MLWClient::create_register_object(const char *coap_register_address)
{
    bool success = false;
    String address;
    if(coap_register_address) {
        address += coap_register_address;
    }
    if(_register_security) {
        delete _register_security;
    }
    _register_security = M2MInterfaceFactory::create_security(M2MSecurity::M2MServer);
    if(_register_security) {
        if(_register_security->set_resource_value(M2MSecurity::M2MServerUri, address) &&
           _register_security->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::NoSecurity)) {
            success = true;
        }
    }
    return success;
}

bool M2MLWClient::test_bootstrap()
{
    bool success = false;
    if(_interface) {
        _interface->bootstrap(_security);
        success = true;
    }
    return success;
}

bool M2MLWClient::create_device_object(M2MDevice::DeviceResource resource,
                                       const char *value)
{
    bool success = false;
    String value_string;
    if(value) {
        value_string += value;
    }
    if(!_device) {
        _device = M2MInterfaceFactory::create_device();
    }
    if(_device) {

        if(_device->create_resource(resource,value_string)){
            success = true;
        } else {
            success = _device->set_resource_value(resource,value);
        }
    }
    return success;
}

bool M2MLWClient::create_device_object()
{
    bool success = false;
    if(!_device) {
        _device = M2MInterfaceFactory::create_device();
        success = true;
    }
    return success;
}

bool M2MLWClient::create_device_object(M2MDevice::DeviceResource resource,
                          uint32_t value)
{
    bool success = false;
    if(!_device) {
        _device = M2MInterfaceFactory::create_device();
    }
    if(_device) {
        if(_device->create_resource(resource,value)) {
            success = true;
        } else {
            if (_device->create_resource_instance(resource, value, 0)) {
                success = true;
            }
            else {
                success = _device->set_resource_value(resource, value);
            }
        }
    }
    return success;
}

bool M2MLWClient::create_object(const char *name, bool new_instance)
{
    bool success = false;
    if(!_object) {
        _object = M2MInterfaceFactory::create_object(name);
        if(_object) {
            if(_object->create_object_instance()) {
                success = true;
            }
        }
    } else {
        if(new_instance) {
            if(_object->create_object_instance()) {
                success = true;
            }
        }
    }
    return success;
}

bool M2MLWClient::create_static_resource_string(const char *name,
                                                const char *value,
                                                bool multiple_instance,
                                                uint16_t object_instance)
{
    bool success = false;
    String name_string;
    if(name) {
        name_string += name;
    }
    String value_string;
    if(value) {
        value_string += value;
    }
    if(_object) {
        M2MObjectInstance *inst = _object->object_instance(object_instance);
        if(inst) {
            if(inst->create_static_resource(name,"resource",
                                            M2MResourceInstance::STRING,
                                            (const uint8_t*)value_string.c_str(),
                                            value_string.size()) != NULL) {
                success = true;
            }
        }
    }
    return success;
}

bool M2MLWClient::create_static_resource_int(const char *name,
                                             uint32_t value,
                                             bool multiple_instance,
                                             uint16_t object_instance)
{
    bool success = false;
    String name_string;
    String value_string;

    if(name) {
        name_string += name;
    }

    char value_buffer[20];
    sprintf(value_buffer,"%d",value);
    value_string += value_buffer;

    if(_object) {
        M2MObjectInstance *inst = _object->object_instance(object_instance);
        if(inst) {
            if(inst->create_static_resource(name,"resource",
                                            M2MResourceInstance::INTEGER,
                                            (const uint8_t*)value_string.c_str(),
                                            value_string.size()) != NULL) {
                success = true;
            }
        }
    }
    return success;
}

bool M2MLWClient::create_dynamic_resource(const char *name,
                                          bool observable,
                                          bool multiple_instance,
                                          uint16_t object_instance)
{
    bool success = false;
    String name_string;
    if(name) {
        name_string += name;
    }
    if(_object) {
        M2MObjectInstance *inst = _object->object_instance(object_instance);
        if(inst) {
            if(inst->create_dynamic_resource(name,"resource",
                                             M2MResourceInstance::OPAQUE,
                                             observable) != NULL) {
                success = true;
            }
        }
    }
    return success;
}

bool M2MLWClient::set_resource_value(const char *name,
                                          int32_t value,
                                          uint16_t object_instance)
{
    bool success = false;
    String name_string;
    String value_string;
    if(name) {
        name_string += name;
    }

    char value_buffer[20];
    sprintf(value_buffer,"%d",value);
    value_string += value_buffer;

    if(_object && name_string.length() > 0) {
        M2MObjectInstance *inst = _object->object_instance(object_instance);
        if(inst) {
            M2MResource *res = inst->resource(name_string);
            if (res) {
                if (res->set_value((const uint8_t*)value_string.c_str(), value_string.size())) {
                    success = true;
                }
            }
        }
    }
    return success;
}

bool M2MLWClient::test_register()
{
    bool success = false;
    M2MObjectList object_list;
    if(_device) {
        object_list.push_back(_device);
    }
    if(_object) {
        object_list.push_back(_object);
    }
    if(_interface) {
        _interface->register_object(_register_security,object_list);
        success = true;
    }
    return success;
}

bool M2MLWClient::test_update_register(const uint32_t lifetime)
{
    bool success = false;
    if(_interface && _register_security) {
        success = true;
        _interface->update_registration(_register_security,lifetime);
    }
    return success;
}

bool M2MLWClient::test_unregister()
{
    bool success = false;
    if(_interface) {
         success = true;
        _interface->unregister_object(_register_security);
    }
    return success;
}

void M2MLWClient::bootstrap_done(M2MSecurity *server_object)
{
    if(server_object) {
        _register_security = server_object;
        _bootstrapped = true;
        cmd_printf("\nBootstrapped\n");
        cmd_ready( CMDLINE_RETCODE_SUCCESS );
    }
}

void M2MLWClient::object_registered(M2MSecurity *security_object, const M2MServer &server_object)
{
    _registered = true;
    cmd_printf("\nRegistered\n");
    cmd_ready( CMDLINE_RETCODE_SUCCESS );
}

void M2MLWClient::object_unregistered(M2MSecurity *server_object)
{
    _unregistered = true;
    if(_device) {
        M2MDevice::delete_instance();
        _device = NULL;
    }
    if(_object) {
        delete _object;
        _object = NULL;
    }
    if(_security) {
        delete _security;
        _security = NULL;
    }
    if(_register_security) {
        delete _register_security;
        _register_security = NULL;
    }
    cmd_printf("\nUnregistered\n");
    cmd_ready( CMDLINE_RETCODE_SUCCESS );
}

void M2MLWClient::registration_updated(M2MSecurity *security_object,
                                       const M2MServer &server_object)
{
    _registration_updated = true;
    cmd_printf("\nregistration updated\n");
    cmd_ready( CMDLINE_RETCODE_SUCCESS );
}

void M2MLWClient::error(M2MInterface::Error error)
{
    _error = true;
    cmd_printf("\nError occured Error Code : %d\n", (int8_t)error);
    cmd_ready( CMDLINE_RETCODE_SUCCESS );
}

void M2MLWClient::value_updated(M2MBase *base, M2MBase::BaseType type)
{
    cmd_printf("\nValue updated of Object name %s and Type \n",
               base->name().c_str(), type);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#define BOOST_TEST_MODULE core

#include "vint-serialization.hh"

#include "bytes.hh"

#include <boost/test/unit_test.hpp>

#include <array>
#include <cstdint>
#include <random>

using namespace seastar;

namespace {

typename bytes::value_type operator "" _b(unsigned long long value) {
    return static_cast<bytes::value_type>(value);
}

// Check that the encoded value decodes back to the value. Also allows inspecting the encoded bytes.
template <class Vint, class BytesInspector>
void check_bytes_and_roundtrip(typename Vint::value_type value, BytesInspector&& f) {
    static std::array<int8_t, 9> encoding_buffer({});

    const auto size = Vint::serialize(value, encoding_buffer.begin());
    const auto view = bytes_view(encoding_buffer.data(), size);
    f(view);

    const auto deserialized = Vint::deserialize(view);
    BOOST_REQUIRE_EQUAL(deserialized.value, value);
    BOOST_REQUIRE_EQUAL(deserialized.size, size);
};

// Check that the encoded value decodes back to the value.
template <class Vint>
void check_roundtrip(typename Vint::value_type value) {
    check_bytes_and_roundtrip<Vint>(value, [](const bytes_view&) {});
}

template <class Integer, class RandomEngine, class Callback>
void with_random_samples(RandomEngine& rng, std::size_t count, Callback&& f) {
    std::uniform_int_distribution<Integer> distribution;

    for (std::size_t i = 0; i < count; ++i) {
        f(distribution(rng));
    }
}

template <class Vint, class RandomEngine>
void check_roundtrip_sweep(std::size_t count, RandomEngine& rng) {
    with_random_samples<typename Vint::value_type>(rng, count, &check_roundtrip<Vint>);
};

auto& random_engine() {
    static std::random_device rd;
    static std::mt19937 rng(rd());
    return rng;
}

}

BOOST_AUTO_TEST_CASE(sanity_unsigned_examples) {
    using vint = unsigned_vint;

    check_bytes_and_roundtrip<vint>(0, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0_b}));
    });

    check_bytes_and_roundtrip<vint>(5, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0b0000'0101_b}));
    });

    check_bytes_and_roundtrip<vint>(1111, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0b1000'0100_b, 0b0101'0111_b}));
    });

    check_bytes_and_roundtrip<vint>(256'000, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0b1100'0011_b, 0b1110'1000_b, 0b0000'0000_b}));
    });

    check_bytes_and_roundtrip<vint>(0xff'ee'dd'cc'bb'aa'99'88, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0xff_b, 0xff_b, 0xee_b, 0xdd_b, 0xcc_b, 0xbb_b, 0xaa_b, 0x99_b, 0x88_b}));
    });
}

BOOST_AUTO_TEST_CASE(sanity_unsigned_sweep) {
    check_roundtrip_sweep<unsigned_vint>(100'000, random_engine());
}

BOOST_AUTO_TEST_CASE(sanity_signed_examples) {
    using vint = signed_vint;

    check_bytes_and_roundtrip<vint>(0, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0_b}));
    });

    check_bytes_and_roundtrip<vint>(-1, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0b0000'0001_b}));
    });

    check_bytes_and_roundtrip<vint>(1, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0b0000'0010_b}));
    });

    check_bytes_and_roundtrip<vint>(-2, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0b0000'0011_b}));
    });

    check_bytes_and_roundtrip<vint>(2, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0b0000'0100_b}));
    });

    check_bytes_and_roundtrip<vint>(-256'000, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0b1100'0111_b, 0b1100'1111_b, 0b1111'1111_b}));
    });
}

BOOST_AUTO_TEST_CASE(sanity_signed_sweep) {
    check_roundtrip_sweep<signed_vint>(100'000, random_engine());
}
<commit_msg>Cover serialized_size_from_first_byte in tests<commit_after>/*
 * Copyright (C) 2017 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#define BOOST_TEST_MODULE core

#include "vint-serialization.hh"

#include "bytes.hh"

#include <boost/test/unit_test.hpp>

#include <array>
#include <cstdint>
#include <random>

using namespace seastar;

namespace {

typename bytes::value_type operator "" _b(unsigned long long value) {
    return static_cast<bytes::value_type>(value);
}

template <class Vint>
void test_serialized_size_from_first_byte(vint_size_type size, bytes_view bytes) {
}

template <>
void test_serialized_size_from_first_byte<unsigned_vint>(vint_size_type size, bytes_view bytes) {
    BOOST_REQUIRE_EQUAL(size, unsigned_vint::serialized_size_from_first_byte(bytes[0]));
}

// Check that the encoded value decodes back to the value. Also allows inspecting the encoded bytes.
template <class Vint, class BytesInspector>
void check_bytes_and_roundtrip(typename Vint::value_type value, BytesInspector&& f) {
    static std::array<int8_t, 9> encoding_buffer({});

    const auto size = Vint::serialize(value, encoding_buffer.begin());
    const auto view = bytes_view(encoding_buffer.data(), size);
    f(view);

    const auto deserialized = Vint::deserialize(view);
    BOOST_REQUIRE_EQUAL(deserialized.value, value);
    BOOST_REQUIRE_EQUAL(deserialized.size, size);
    test_serialized_size_from_first_byte<Vint>(size, view);
};

// Check that the encoded value decodes back to the value.
template <class Vint>
void check_roundtrip(typename Vint::value_type value) {
    check_bytes_and_roundtrip<Vint>(value, [](const bytes_view&) {});
}

template <class Integer, class RandomEngine, class Callback>
void with_random_samples(RandomEngine& rng, std::size_t count, Callback&& f) {
    std::uniform_int_distribution<Integer> distribution;

    for (std::size_t i = 0; i < count; ++i) {
        f(distribution(rng));
    }
}

template <class Vint, class RandomEngine>
void check_roundtrip_sweep(std::size_t count, RandomEngine& rng) {
    with_random_samples<typename Vint::value_type>(rng, count, &check_roundtrip<Vint>);
};

auto& random_engine() {
    static std::random_device rd;
    static std::mt19937 rng(rd());
    return rng;
}

}

BOOST_AUTO_TEST_CASE(sanity_unsigned_examples) {
    using vint = unsigned_vint;

    check_bytes_and_roundtrip<vint>(0, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0_b}));
    });

    check_bytes_and_roundtrip<vint>(5, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0b0000'0101_b}));
    });

    check_bytes_and_roundtrip<vint>(1111, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0b1000'0100_b, 0b0101'0111_b}));
    });

    check_bytes_and_roundtrip<vint>(256'000, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0b1100'0011_b, 0b1110'1000_b, 0b0000'0000_b}));
    });

    check_bytes_and_roundtrip<vint>(0xff'ee'dd'cc'bb'aa'99'88, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0xff_b, 0xff_b, 0xee_b, 0xdd_b, 0xcc_b, 0xbb_b, 0xaa_b, 0x99_b, 0x88_b}));
    });
}

BOOST_AUTO_TEST_CASE(sanity_unsigned_sweep) {
    check_roundtrip_sweep<unsigned_vint>(100'000, random_engine());
}

BOOST_AUTO_TEST_CASE(sanity_signed_examples) {
    using vint = signed_vint;

    check_bytes_and_roundtrip<vint>(0, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0_b}));
    });

    check_bytes_and_roundtrip<vint>(-1, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0b0000'0001_b}));
    });

    check_bytes_and_roundtrip<vint>(1, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0b0000'0010_b}));
    });

    check_bytes_and_roundtrip<vint>(-2, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0b0000'0011_b}));
    });

    check_bytes_and_roundtrip<vint>(2, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0b0000'0100_b}));
    });

    check_bytes_and_roundtrip<vint>(-256'000, [](bytes_view v) {
        BOOST_REQUIRE_EQUAL(v, (bytes{0b1100'0111_b, 0b1100'1111_b, 0b1111'1111_b}));
    });
}

BOOST_AUTO_TEST_CASE(sanity_signed_sweep) {
    check_roundtrip_sweep<signed_vint>(100'000, random_engine());
}
<|endoftext|>


<commit_before>
// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of cdf-handler, a C++ server of OPeNDAP for access to cdf
// data

// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: Patrick West <pwest@ucar.edu>
//
// 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

// Implementation for CDFRequestHandler.
//
// pwest 05/08/03

#ifdef __GNUG__
#pragma implementation
#endif

#include <iostream>
#include <fstream>

using std::ifstream ;
using std::cerr ;
using std::endl ;

#include "CDFRequestHandler.h"
#include "CDFTypeFactory.h"
#include "BESResponseHandler.h"
#include "BESResponseNames.h"
#include "CDFreadAttributes.h"
#include "DAS.h"
#include "CDFreadDescriptors.h"
#include "DDS.h"
#include "BESConstraintFuncs.h"
#include "BESVersionInfo.h"
#include "TheBESKeys.h"
#include "BESResponseException.h"
#include "config_cdf.h"

CDFRequestHandler::CDFRequestHandler( string name )
    : BESRequestHandler( name )
{
    add_handler( DAS_RESPONSE, CDFRequestHandler::cdf_build_das ) ;
    add_handler( DDS_RESPONSE, CDFRequestHandler::cdf_build_dds ) ;
    add_handler( DATA_RESPONSE, CDFRequestHandler::cdf_build_data ) ;
    add_handler( HELP_RESPONSE, CDFRequestHandler::cdf_build_help ) ;
    add_handler( VERS_RESPONSE, CDFRequestHandler::cdf_build_version ) ;
}

CDFRequestHandler::~CDFRequestHandler()
{
}

bool
CDFRequestHandler::cdf_build_das( BESDataHandlerInterface &dhi )
{
    DAS *das = (DAS *)dhi.response_handler->get_response_object() ;
    if( !readAttributes( *das, dhi.container->get_real_name() ) )
    {
	string s = "CDF could not build the DAS response" ;
	throw BESResponseException( s, __FILE__, __LINE__ ) ;
    }
    return true ;
}

bool
CDFRequestHandler::cdf_build_dds( BESDataHandlerInterface &dhi )
{
    DDS *dds = (DDS *)dhi.response_handler->get_response_object() ;
    CDFTypeFactory *factory = new CDFTypeFactory ;
    dds->set_factory( factory ) ;
    if( !readDescriptors( *dds, dhi.container->get_real_name(),
			  dhi.container->get_symbolic_name() ) )
    {
	string s = "CDF could not build the DDS response" ;
	throw BESResponseException( s, __FILE__, __LINE__ ) ;
    }
    BESConstraintFuncs::post_append( dhi ) ;

    return true ;
}

bool
CDFRequestHandler::cdf_build_data( BESDataHandlerInterface &dhi )
{
    DDS *dds = (DDS *)dhi.response_handler->get_response_object() ;
    CDFTypeFactory *factory = new CDFTypeFactory ;
    dds->set_factory( factory ) ;
    if( !readDescriptors( *dds, dhi.container->get_real_name(),
			  dhi.container->get_symbolic_name() ) )
    {
	string s = "CDF could not build the Data DDS response" ;
	throw BESResponseException( s, __FILE__, __LINE__ ) ;
    }
    BESConstraintFuncs::post_append( dhi ) ;

    return true ;
}

bool
CDFRequestHandler::cdf_build_help( BESDataHandlerInterface &dhi )
{
    BESInfo *info = dynamic_cast<BESInfo *>(dhi.response_handler->get_response_object());
    string handles = (string)DAS_RESPONSE
                     + "," + DDS_RESPONSE
                     + "," + DATA_RESPONSE
                     + "," + HELP_RESPONSE
                     + "," + VERS_RESPONSE ;
    info->add_tag( "handles", handles ) ;
    info->add_tag( "version", PACKAGE_STRING ) ;
    return true ;
}

bool
CDFRequestHandler::cdf_build_version( BESDataHandlerInterface &dhi )
{
    BESVersionInfo *info = dynamic_cast<BESVersionInfo *>(dhi.response_handler->get_response_object() ) ;
    info->addHandlerVersion( PACKAGE_NAME, PACKAGE_VERSION ) ;
    return true ;
}

<commit_msg>In the help response added begin and end tags called handler to separate the different hander help responses and added a tag called name within the handler tag to say which handler this help is for<commit_after>
// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of cdf-handler, a C++ server of OPeNDAP for access to cdf
// data

// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: Patrick West <pwest@ucar.edu>
//
// 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

// Implementation for CDFRequestHandler.
//
// pwest 05/08/03

#ifdef __GNUG__
#pragma implementation
#endif

#include <iostream>
#include <fstream>

using std::ifstream ;
using std::cerr ;
using std::endl ;

#include "CDFRequestHandler.h"
#include "CDFTypeFactory.h"
#include "BESResponseHandler.h"
#include "BESResponseNames.h"
#include "CDFreadAttributes.h"
#include "DAS.h"
#include "CDFreadDescriptors.h"
#include "DDS.h"
#include "BESConstraintFuncs.h"
#include "BESVersionInfo.h"
#include "TheBESKeys.h"
#include "BESResponseException.h"
#include "config_cdf.h"

CDFRequestHandler::CDFRequestHandler( string name )
    : BESRequestHandler( name )
{
    add_handler( DAS_RESPONSE, CDFRequestHandler::cdf_build_das ) ;
    add_handler( DDS_RESPONSE, CDFRequestHandler::cdf_build_dds ) ;
    add_handler( DATA_RESPONSE, CDFRequestHandler::cdf_build_data ) ;
    add_handler( HELP_RESPONSE, CDFRequestHandler::cdf_build_help ) ;
    add_handler( VERS_RESPONSE, CDFRequestHandler::cdf_build_version ) ;
}

CDFRequestHandler::~CDFRequestHandler()
{
}

bool
CDFRequestHandler::cdf_build_das( BESDataHandlerInterface &dhi )
{
    DAS *das = (DAS *)dhi.response_handler->get_response_object() ;
    if( !readAttributes( *das, dhi.container->get_real_name() ) )
    {
	string s = "CDF could not build the DAS response" ;
	throw BESResponseException( s, __FILE__, __LINE__ ) ;
    }
    return true ;
}

bool
CDFRequestHandler::cdf_build_dds( BESDataHandlerInterface &dhi )
{
    DDS *dds = (DDS *)dhi.response_handler->get_response_object() ;
    CDFTypeFactory *factory = new CDFTypeFactory ;
    dds->set_factory( factory ) ;
    if( !readDescriptors( *dds, dhi.container->get_real_name(),
			  dhi.container->get_symbolic_name() ) )
    {
	string s = "CDF could not build the DDS response" ;
	throw BESResponseException( s, __FILE__, __LINE__ ) ;
    }
    BESConstraintFuncs::post_append( dhi ) ;

    return true ;
}

bool
CDFRequestHandler::cdf_build_data( BESDataHandlerInterface &dhi )
{
    DDS *dds = (DDS *)dhi.response_handler->get_response_object() ;
    CDFTypeFactory *factory = new CDFTypeFactory ;
    dds->set_factory( factory ) ;
    if( !readDescriptors( *dds, dhi.container->get_real_name(),
			  dhi.container->get_symbolic_name() ) )
    {
	string s = "CDF could not build the Data DDS response" ;
	throw BESResponseException( s, __FILE__, __LINE__ ) ;
    }
    BESConstraintFuncs::post_append( dhi ) ;

    return true ;
}

bool
CDFRequestHandler::cdf_build_help( BESDataHandlerInterface &dhi )
{
    BESInfo *info = dynamic_cast<BESInfo *>(dhi.response_handler->get_response_object());
    info->begin_tag( "Handler" ) ;
    info->add_tag( "name", PACKAGE_NAME ) ;
    string handles = (string)DAS_RESPONSE
                     + "," + DDS_RESPONSE
                     + "," + DATA_RESPONSE
                     + "," + HELP_RESPONSE
                     + "," + VERS_RESPONSE ;
    info->add_tag( "handles", handles ) ;
    info->add_tag( "version", PACKAGE_STRING ) ;
    info->end_tag( "Handler" ) ;
    return true ;
}

bool
CDFRequestHandler::cdf_build_version( BESDataHandlerInterface &dhi )
{
    BESVersionInfo *info = dynamic_cast<BESVersionInfo *>(dhi.response_handler->get_response_object() ) ;
    info->addHandlerVersion( PACKAGE_NAME, PACKAGE_VERSION ) ;
    return true ;
}

<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 <activemq/connector/openwire/commands/WireFormatInfo.h>
#include <activemq/exceptions/NullPointerException.h>

using namespace std;
using namespace activemq;
using namespace activemq::exceptions;
using namespace activemq::connector;
using namespace activemq::connector::openwire;
using namespace activemq::connector::openwire::commands;

////////////////////////////////////////////////////////////////////////////////
std::vector<char> WireFormatInfo::MAGIC;

////////////////////////////////////////////////////////////////////////////////
WireFormatInfo::WireFormatInfo()
{
    if( MAGIC.empty() ) {
        MAGIC.push_back( 'A' );
        MAGIC.push_back( 'c' );
        MAGIC.push_back( 't' );
        MAGIC.push_back( 'i' );
        MAGIC.push_back( 'v' );
        MAGIC.push_back( 'e' );
        MAGIC.push_back( 'M' );
        MAGIC.push_back( 'Q' );
    }
}

////////////////////////////////////////////////////////////////////////////////
WireFormatInfo::~WireFormatInfo()
{
}

////////////////////////////////////////////////////////////////////////////////
DataStructure* WireFormatInfo::cloneDataStructure() const {
    WireFormatInfo* wireFormatInfo = new WireFormatInfo();

    // Copy the data from the base class or classes
    wireFormatInfo->copyDataStructure( this );

    return wireFormatInfo;
}

////////////////////////////////////////////////////////////////////////////////
void WireFormatInfo::copyDataStructure( const DataStructure* src ) {

    // Copy the data of the base class or classes
    BaseDataStructure::copyDataStructure( src );

    const WireFormatInfo* srcPtr = dynamic_cast<const WireFormatInfo*>( src );

    if( srcPtr == NULL || src == NULL ) {

        throw exceptions::NullPointerException(
            __FILE__, __LINE__,
            "WireFormatInfo::copyDataStructure - src is NULL or invalid" );
    }
}

////////////////////////////////////////////////////////////////////////////////
unsigned char WireFormatInfo::getDataStructureType() const {
    return WireFormatInfo::ID_WIREFORMATINFO;
}

////////////////////////////////////////////////////////////////////////////////
bool WireFormatInfo::isValid() const {

    if( magic.size() != MAGIC.size() ) {
        return false;
    }

    for( size_t i = 0; i < magic.size(); i++ ) {
        if( magic[i] != MAGIC[i] ) {
            return false;
        }
    }

    return true;
}
<commit_msg>[AMQCPP-30] Fixed initialization of magic member in OpenwireFormatInfo<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 <activemq/connector/openwire/commands/WireFormatInfo.h>
#include <activemq/exceptions/NullPointerException.h>

using namespace std;
using namespace activemq;
using namespace activemq::exceptions;
using namespace activemq::connector;
using namespace activemq::connector::openwire;
using namespace activemq::connector::openwire::commands;

////////////////////////////////////////////////////////////////////////////////
std::vector<char> WireFormatInfo::MAGIC;

////////////////////////////////////////////////////////////////////////////////
WireFormatInfo::WireFormatInfo()
{
    // Initialize the static MAGIC buffer.
    if( MAGIC.empty() ) {
        MAGIC.push_back( 'A' );
        MAGIC.push_back( 'c' );
        MAGIC.push_back( 't' );
        MAGIC.push_back( 'i' );
        MAGIC.push_back( 'v' );
        MAGIC.push_back( 'e' );
        MAGIC.push_back( 'M' );
        MAGIC.push_back( 'Q' );
    }

    // Initialize member magic buffer to the static buffer.
    magic.resize( MAGIC.size() );
    for( int ix=0; ix<MAGIC.size(); ++ix ){
        magic[ix] = MAGIC[ix];
    }
}

////////////////////////////////////////////////////////////////////////////////
WireFormatInfo::~WireFormatInfo()
{
}

////////////////////////////////////////////////////////////////////////////////
DataStructure* WireFormatInfo::cloneDataStructure() const {
    WireFormatInfo* wireFormatInfo = new WireFormatInfo();

    // Copy the data from the base class or classes
    wireFormatInfo->copyDataStructure( this );

    return wireFormatInfo;
}

////////////////////////////////////////////////////////////////////////////////
void WireFormatInfo::copyDataStructure( const DataStructure* src ) {

    // Copy the data of the base class or classes
    BaseDataStructure::copyDataStructure( src );

    const WireFormatInfo* srcPtr = dynamic_cast<const WireFormatInfo*>( src );

    if( srcPtr == NULL || src == NULL ) {

        throw exceptions::NullPointerException(
            __FILE__, __LINE__,
            "WireFormatInfo::copyDataStructure - src is NULL or invalid" );
    }
}

////////////////////////////////////////////////////////////////////////////////
unsigned char WireFormatInfo::getDataStructureType() const {
    return WireFormatInfo::ID_WIREFORMATINFO;
}

////////////////////////////////////////////////////////////////////////////////
bool WireFormatInfo::isValid() const {

    if( magic.size() != MAGIC.size() ) {
        return false;
    }

    for( size_t i = 0; i < magic.size(); i++ ) {
        if( magic[i] != MAGIC[i] ) {
            return false;
        }
    }

    return true;
}
<|endoftext|>