<commit_before>//  File   : SMESH_NumberFilter.cxx
//  Module : SMESH

#include "SMESH_NumberFilter.hxx"

#include "GEOMBase.h"

#include "SUIT_Application.h"
#include "SUIT_Session.h"

#include "SalomeApp_Study.h"
#include "SalomeApp_DataOwner.h"

#include "SALOME_InteractiveObject.hxx"
#include "SALOMEDSClient_SObject.hxx"
#include "SALOMEDS_SObject.hxx"

#include <TopTools_MapOfShape.hxx>
#include <TopExp_Explorer.hxx>

/*!
 *  Class       : SMESH_NumberFilter
 *  Description : Filter for geom objects.
 *                Filter geom objects by number of subshapes of the given type
 */

//=======================================================================
// name    : SMESH_NumberFilter::SMESH_NumberFilter
// Purpose : Constructor
//=======================================================================
SMESH_NumberFilter::SMESH_NumberFilter (const char*            theKind,
                                        const TopAbs_ShapeEnum theSubShapeType,
                                        const int              theNumber,
                                        const TopAbs_ShapeEnum theShapeType,
                                        GEOM::GEOM_Object_ptr  theMainObj,
                                        const bool             theIsClosedOnly)
{
  myKind = (char*)theKind;
  mySubShapeType = theSubShapeType;
  myNumber = theNumber;
  myIsClosedOnly = theIsClosedOnly;
  myShapeTypes.Add(theShapeType);
  myMainObj = GEOM::GEOM_Object::_duplicate(theMainObj);
}

//=======================================================================
// name    : SMESH_NumberFilter::SMESH_NumberFilter
// Purpose : Constructor
//=======================================================================
SMESH_NumberFilter::SMESH_NumberFilter (const char*                 theKind,
                                        const TopAbs_ShapeEnum      theSubShapeType,
                                        const int                   theNumber,
                                        const TColStd_MapOfInteger& theShapeTypes,
                                        GEOM::GEOM_Object_ptr       theMainObj,
                                        const bool                  theIsClosedOnly )
{
  myKind = (char*)theKind;
  mySubShapeType = theSubShapeType;
  myNumber = theNumber;
  myIsClosedOnly = theIsClosedOnly;
  myShapeTypes = theShapeTypes;
  myMainObj = GEOM::GEOM_Object::_duplicate(theMainObj);
}

SMESH_NumberFilter::~SMESH_NumberFilter()
{
}

//=======================================================================
// name    : SMESH_NumberFilter::SMESH_NumberFilter
// Purpose : Verify validity of entry object
//=======================================================================
bool SMESH_NumberFilter::isOk (const SUIT_DataOwner* theDataOwner) const
{
  if (!theDataOwner)
    return false;

  // Get geom object from IO
  GEOM::GEOM_Object_var aGeomObj = getGeom(theDataOwner);
  if (aGeomObj->_is_nil())
    return false;

  // Get shape from geom object and verify its parameters
  TopoDS_Shape aShape;
  if (!GEOMBase::GetShape(aGeomObj, aShape) ||
      aShape.IsNull() ||
      !myShapeTypes.Contains(aShape.ShapeType()))
    return false;

  if (myIsClosedOnly && aShape.ShapeType() == TopAbs_SHELL && !aShape.Closed())
    return false;

  // Verify whether shape of entry object is sub-shape of myMainObj
  if (!myMainObj->_is_nil()) {
    TopoDS_Shape aMainShape;
    if (!GEOMBase::GetShape(myMainObj, aMainShape))
      return false;

    bool isFound = false;
    TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
    TopExp_Explorer anExp (aMainShape, aShapeType);
    for (; anExp.More(); anExp.Next()) {
      if (anExp.Current() == aShape) {
        isFound = true;
        break;
      }
    }
    if (!isFound)
      return false;
  }

  // Verify number of sub-shapes
  if (mySubShapeType == TopAbs_SHAPE);
    return true;

  TopExp_Explorer anExp2 (aShape, mySubShapeType);
  TopTools_MapOfShape aMap;
  for (; anExp2.More(); anExp2.Next())
    aMap.Add(anExp2.Current());

  return myNumber == aMap.Extent();
}

//=======================================================================
// name    : SMESH_NumberFilter::getGeom
// Purpose : Retrieve geom object from SALOME_InteractiveObject
//=======================================================================
GEOM::GEOM_Object_ptr SMESH_NumberFilter::getGeom
  (const SUIT_DataOwner* theDataOwner) const
{
  const SalomeApp_DataOwner* owner =
    dynamic_cast<const SalomeApp_DataOwner*>(theDataOwner);
  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>
    (SUIT_Session::session()->activeApplication()->activeStudy());

  GEOM::GEOM_Object_var anObj;

  if (!owner || !appStudy)
    return GEOM::GEOM_Object::_nil();

  _PTR(Study) study = appStudy->studyDS();
  QString entry = owner->entry();

  _PTR(SObject) aSO(study->FindObjectID(entry.latin1()));
  if (!aSO)
    return GEOM::GEOM_Object::_nil();

  CORBA::Object_var anObject = _CAST(SObject,aSO)->GetObject();
  anObj = GEOM::GEOM_Object::_narrow(anObject);
  if (!CORBA::is_nil(anObj))
    return anObj._retn();

  // Get geom object corresponding to the mesh
  _PTR(ChildIterator) anIter = study->NewChildIterator(aSO);
  for (; anIter->More(); anIter->Next()) {
    _PTR(SObject) aSO = anIter->Value();
    if (!aSO)
      continue;
    _PTR(SObject) aRefSO;
    _PTR(SObject) anObj;
    if (aSO->ReferencedObject(aRefSO))
      anObj = aRefSO;

    if (!anObj)
      anObj = aSO;

    anObject = _CAST(SObject,anObj)->GetObject();
    GEOM::GEOM_Object_var aMeshShape = GEOM::GEOM_Object::_narrow(anObject);

    if (!aMeshShape->_is_nil())
      return aMeshShape._retn();
  }

  return GEOM::GEOM_Object::_nil();
}

void SMESH_NumberFilter::SetSubShapeType (const TopAbs_ShapeEnum theSubShapeType)
{
  mySubShapeType = theSubShapeType;
}

void SMESH_NumberFilter::SetNumber (const int theNumber)
{
  myNumber = theNumber;
}

void SMESH_NumberFilter::SetClosedOnly (const bool theIsClosedOnly)
{
  myIsClosedOnly = theIsClosedOnly;
}

void SMESH_NumberFilter::SetShapeType (const TopAbs_ShapeEnum theShapeType)
{
  myShapeTypes.Add( theShapeType );
}

void SMESH_NumberFilter::SetMainShape (GEOM::GEOM_Object_ptr theMainObj)
{
  myMainObj = GEOM::GEOM_Object::_duplicate(theMainObj);
}
<commit_msg>Improve NumberFilter: retrieve selected and main shape with the same instance of GEOM_Client()<commit_after>//  File   : SMESH_NumberFilter.cxx
//  Module : SMESH

#include "SMESH_NumberFilter.hxx"

#include "GEOM_Client.hxx"
#include "GeometryGUI.h"

#include "SUIT_Application.h"
#include "SUIT_Session.h"

#include "SalomeApp_Study.h"
#include "SalomeApp_DataOwner.h"

#include "SALOME_InteractiveObject.hxx"
#include "SALOMEDSClient_SObject.hxx"
#include "SALOMEDS_SObject.hxx"

#include <TopTools_MapOfShape.hxx>
#include <TopExp_Explorer.hxx>

/*!
 *  Class       : SMESH_NumberFilter
 *  Description : Filter for geom objects.
 *                Filter geom objects by number of subshapes of the given type
 */

//=======================================================================
// name    : SMESH_NumberFilter::SMESH_NumberFilter
// Purpose : Constructor
//=======================================================================
SMESH_NumberFilter::SMESH_NumberFilter (const char*            theKind,
                                        const TopAbs_ShapeEnum theSubShapeType,
                                        const int              theNumber,
                                        const TopAbs_ShapeEnum theShapeType,
                                        GEOM::GEOM_Object_ptr  theMainObj,
                                        const bool             theIsClosedOnly)
{
  myKind = (char*)theKind;
  mySubShapeType = theSubShapeType;
  myNumber = theNumber;
  myIsClosedOnly = theIsClosedOnly;
  myShapeTypes.Add(theShapeType);
  myMainObj = GEOM::GEOM_Object::_duplicate(theMainObj);
}

//=======================================================================
// name    : SMESH_NumberFilter::SMESH_NumberFilter
// Purpose : Constructor
//=======================================================================
SMESH_NumberFilter::SMESH_NumberFilter (const char*                 theKind,
                                        const TopAbs_ShapeEnum      theSubShapeType,
                                        const int                   theNumber,
                                        const TColStd_MapOfInteger& theShapeTypes,
                                        GEOM::GEOM_Object_ptr       theMainObj,
                                        const bool                  theIsClosedOnly )
{
  myKind = (char*)theKind;
  mySubShapeType = theSubShapeType;
  myNumber = theNumber;
  myIsClosedOnly = theIsClosedOnly;
  myShapeTypes = theShapeTypes;
  myMainObj = GEOM::GEOM_Object::_duplicate(theMainObj);
}

SMESH_NumberFilter::~SMESH_NumberFilter()
{
}

//=======================================================================
// name    : SMESH_NumberFilter::SMESH_NumberFilter
// Purpose : Verify validity of entry object
//=======================================================================
bool SMESH_NumberFilter::isOk (const SUIT_DataOwner* theDataOwner) const
{
  if (!theDataOwner)
    return false;

  // Get geom object from IO
  GEOM::GEOM_Object_var aGeomObj = getGeom(theDataOwner);
  if (aGeomObj->_is_nil())
    return false;

  // Get shape from geom object and verify its parameters
  GEOM_Client aGeomClient;
  TopoDS_Shape aShape = aGeomClient.GetShape(GeometryGUI::GetGeomGen(), aGeomObj);
  if (aShape.IsNull() ||
      !myShapeTypes.Contains(aShape.ShapeType()))
    return false;

  if (myIsClosedOnly && aShape.ShapeType() == TopAbs_SHELL && !aShape.Closed())
    return false;

  // Verify whether shape of entry object is sub-shape of myMainObj
  if (!myMainObj->_is_nil()) {
    TopoDS_Shape aMainShape = aGeomClient.GetShape(GeometryGUI::GetGeomGen(), myMainObj);
    if (aMainShape.IsNull())
      return false;

    bool isFound = false;
    TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
    TopExp_Explorer anExp (aMainShape, aShapeType);
    for (; anExp.More(); anExp.Next()) {
      if (anExp.Current() == aShape) {
        isFound = true;
        break;
      }
    }
    if (!isFound)
      return false;
  }

  // Verify number of sub-shapes
  if (mySubShapeType == TopAbs_SHAPE);
    return true;

  TopExp_Explorer anExp2 (aShape, mySubShapeType);
  TopTools_MapOfShape aMap;
  for (; anExp2.More(); anExp2.Next())
    aMap.Add(anExp2.Current());

  return myNumber == aMap.Extent();
}

//=======================================================================
// name    : SMESH_NumberFilter::getGeom
// Purpose : Retrieve geom object from SALOME_InteractiveObject
//=======================================================================
GEOM::GEOM_Object_ptr SMESH_NumberFilter::getGeom
  (const SUIT_DataOwner* theDataOwner) const
{
  const SalomeApp_DataOwner* owner =
    dynamic_cast<const SalomeApp_DataOwner*>(theDataOwner);
  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>
    (SUIT_Session::session()->activeApplication()->activeStudy());

  GEOM::GEOM_Object_var anObj;

  if (!owner || !appStudy)
    return GEOM::GEOM_Object::_nil();

  _PTR(Study) study = appStudy->studyDS();
  QString entry = owner->entry();

  _PTR(SObject) aSO(study->FindObjectID(entry.latin1()));
  if (!aSO)
    return GEOM::GEOM_Object::_nil();

  CORBA::Object_var anObject = _CAST(SObject,aSO)->GetObject();
  anObj = GEOM::GEOM_Object::_narrow(anObject);
  if (!CORBA::is_nil(anObj))
    return anObj._retn();

  // Get geom object corresponding to the mesh
  _PTR(ChildIterator) anIter = study->NewChildIterator(aSO);
  for (; anIter->More(); anIter->Next()) {
    _PTR(SObject) aSO = anIter->Value();
    if (!aSO)
      continue;
    _PTR(SObject) aRefSO;
    _PTR(SObject) anObj;
    if (aSO->ReferencedObject(aRefSO))
      anObj = aRefSO;

    if (!anObj)
      anObj = aSO;

    anObject = _CAST(SObject,anObj)->GetObject();
    GEOM::GEOM_Object_var aMeshShape = GEOM::GEOM_Object::_narrow(anObject);

    if (!aMeshShape->_is_nil())
      return aMeshShape._retn();
  }

  return GEOM::GEOM_Object::_nil();
}

void SMESH_NumberFilter::SetSubShapeType (const TopAbs_ShapeEnum theSubShapeType)
{
  mySubShapeType = theSubShapeType;
}

void SMESH_NumberFilter::SetNumber (const int theNumber)
{
  myNumber = theNumber;
}

void SMESH_NumberFilter::SetClosedOnly (const bool theIsClosedOnly)
{
  myIsClosedOnly = theIsClosedOnly;
}

void SMESH_NumberFilter::SetShapeType (const TopAbs_ShapeEnum theShapeType)
{
  myShapeTypes.Add( theShapeType );
}

void SMESH_NumberFilter::SetMainShape (GEOM::GEOM_Object_ptr theMainObj)
{
  myMainObj = GEOM::GEOM_Object::_duplicate(theMainObj);
}
<|endoftext|>


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

#ifndef REALM_OS_OBJECT_ACCESSOR_HPP
#define REALM_OS_OBJECT_ACCESSOR_HPP

#include "object.hpp"

#include "list.hpp"
#include "object_schema.hpp"
#include "object_store.hpp"
#include "results.hpp"
#include "schema.hpp"
#include "util/format.hpp"

#include <realm/link_view.hpp>
#include <realm/util/assert.hpp>
#include <realm/table_view.hpp>

#include <string>

namespace realm {
//
// Value converters - template specializations must be implemented for each platform in order to call templated methods on Object
//
template<typename ValueType, typename ContextType>
class NativeAccessor {
public:
    static bool dict_has_value_for_key(ContextType ctx, ValueType dict, const std::string &prop_name);
    static ValueType dict_value_for_key(ContextType ctx, ValueType dict, const std::string &prop_name);

    static bool has_default_value_for_property(ContextType ctx, Realm *realm, const ObjectSchema &object_schema, const std::string &prop_name);
    static ValueType default_value_for_property(ContextType ctx, Realm *realm, const ObjectSchema &object_schema, const std::string &prop_name);

    static bool to_bool(ContextType, ValueType &);
    static ValueType from_bool(ContextType, bool);
    static long long to_long(ContextType, ValueType &);
    static ValueType from_long(ContextType, long long);
    static float to_float(ContextType, ValueType &);
    static ValueType from_float(ContextType, float);
    static double to_double(ContextType, ValueType &);
    static ValueType from_double(ContextType, double);
    static std::string to_string(ContextType, ValueType &);
    static ValueType from_string(ContextType, StringData);
    static std::string to_binary(ContextType, ValueType &);
    static ValueType from_binary(ContextType, BinaryData);
    static Timestamp to_timestamp(ContextType, ValueType &);
    static ValueType from_timestamp(ContextType, Timestamp);

    static bool is_null(ContextType, ValueType &);
    static ValueType null_value(ContextType);

    // convert value to persisted object
    // for existing objects return the existing row index
    // for new/updated objects return the row index
    static size_t to_object_index(ContextType ctx, SharedRealm realm, ValueType &val, const std::string &type, bool try_update);
    static ValueType from_object(ContextType ctx, Object);

    // object index for an existing object
    static size_t to_existing_object_index(ContextType ctx, SharedRealm realm, ValueType &val);

    // list value accessors
    static size_t list_size(ContextType ctx, ValueType &val);
    static ValueType list_value_at_index(ContextType ctx, ValueType &val, size_t index);
    static ValueType from_list(ContextType ctx, List);

    // results value accessors
    static ValueType from_results(ContextType ctx, Results);

    //
    // Deprecated
    //
    static Mixed to_mixed(ContextType, ValueType&);
};

//
// template method implementations
//
template <typename ValueType, typename ContextType>
void Object::set_property_value(ContextType ctx, std::string prop_name, ValueType value, bool try_update)
{
    verify_attached();
    m_realm->verify_in_write();
    auto& property = property_for_name(prop_name);
    if (property.is_primary)
        throw std::logic_error("Cannot modify primary key after creation");

    set_property_value_impl(ctx, property, value, try_update);
}

template <typename ValueType, typename ContextType>
ValueType Object::get_property_value(ContextType ctx, std::string prop_name)
{
    return get_property_value_impl<ValueType>(ctx, property_for_name(prop_name));
}

template <typename ValueType, typename ContextType>
void Object::set_property_value_impl(ContextType ctx, const Property &property, ValueType value, bool try_update, bool is_default)
{
    using Accessor = NativeAccessor<ValueType, ContextType>;

    auto& table = *m_row.get_table();
    size_t column = property.table_column;
    size_t row = m_row.get_index();
    if (property.is_nullable && Accessor::is_null(ctx, value)) {
        if (property.type == PropertyType::Object) {
            if (!is_default)
                table.nullify_link(column, row);
        }
        else {
            table.set_null(column, row, is_default);
        }
        return;
    }

    switch (property.type) {
        case PropertyType::Bool:
            table.set_bool(column, row, Accessor::to_bool(ctx, value), is_default);
            break;
        case PropertyType::Int:
            table.set_int(column, row, Accessor::to_long(ctx, value), is_default);
            break;
        case PropertyType::Float:
            table.set_float(column, row, Accessor::to_float(ctx, value), is_default);
            break;
        case PropertyType::Double:
            table.set_double(column, row, Accessor::to_double(ctx, value), is_default);
            break;
        case PropertyType::String: {
            auto str = Accessor::to_string(ctx, value);
            table.set_string(column, row, str, is_default);
            break;
        }
        case PropertyType::Data: {
            auto data = Accessor::to_binary(ctx, value);
            table.set_binary(column, row, BinaryData(data), is_default);
            break;
        }
        case PropertyType::Any:
            table.set_mixed(column, row, Accessor::to_mixed(ctx, value), is_default);
            break;
        case PropertyType::Date:
            table.set_timestamp(column, row, Accessor::to_timestamp(ctx, value), is_default);
            break;
        case PropertyType::Object: {
            table.set_link(column, row, Accessor::to_object_index(ctx, m_realm, value, property.object_type, try_update), is_default);
            break;
        }
        case PropertyType::Array: {
            LinkViewRef link_view = m_row.get_linklist(column);
            link_view->clear();
            if (!Accessor::is_null(ctx, value)) {
                size_t count = Accessor::list_size(ctx, value);
                for (size_t i = 0; i < count; i++) {
                    ValueType element = Accessor::list_value_at_index(ctx, value, i);
                    link_view->add(Accessor::to_object_index(ctx, m_realm, element, property.object_type, try_update));
                }
            }
            break;
        }
        case PropertyType::LinkingObjects:
            throw ReadOnlyPropertyException(m_object_schema->name, property.name);
    }
}

template <typename ValueType, typename ContextType>
ValueType Object::get_property_value_impl(ContextType ctx, const Property &property)
{
    verify_attached();

    using Accessor = NativeAccessor<ValueType, ContextType>;

    size_t column = property.table_column;
    if (property.is_nullable && m_row.is_null(column)) {
        return Accessor::null_value(ctx);
    }

    switch (property.type) {
        case PropertyType::Bool:
            return Accessor::from_bool(ctx, m_row.get_bool(column));
        case PropertyType::Int:
            return Accessor::from_long(ctx, m_row.get_int(column));
        case PropertyType::Float:
            return Accessor::from_float(ctx, m_row.get_float(column));
        case PropertyType::Double:
            return Accessor::from_double(ctx, m_row.get_double(column));
        case PropertyType::String:
            return Accessor::from_string(ctx, m_row.get_string(column));
        case PropertyType::Data:
            return Accessor::from_binary(ctx, m_row.get_binary(column));
        case PropertyType::Any:
            throw "Any not supported";
        case PropertyType::Date:
            return Accessor::from_timestamp(ctx, m_row.get_timestamp(column));
        case PropertyType::Object: {
            auto linkObjectSchema = m_realm->schema().find(property.object_type);
            TableRef table = ObjectStore::table_for_object_type(m_realm->read_group(), linkObjectSchema->name);
            return Accessor::from_object(ctx, Object(m_realm, *linkObjectSchema, table->get(m_row.get_link(column))));
        }
        case PropertyType::Array:
            return Accessor::from_list(ctx, List(m_realm, m_row.get_linklist(column)));
        case PropertyType::LinkingObjects: {
            auto target_object_schema = m_realm->schema().find(property.object_type);
            auto link_property = target_object_schema->property_for_name(property.link_origin_property_name);
            TableRef table = ObjectStore::table_for_object_type(m_realm->read_group(), target_object_schema->name);
            auto tv = m_row.get_table()->get_backlink_view(m_row.get_index(), table.get(), link_property->table_column);
            return Accessor::from_results(ctx, Results(m_realm, std::move(tv)));
        }
    }
    REALM_UNREACHABLE();
}

template<typename ValueType, typename ContextType>
Object Object::create(ContextType ctx, SharedRealm realm, const ObjectSchema &object_schema, ValueType value, bool try_update)
{
    realm->verify_in_write();

    using Accessor = NativeAccessor<ValueType, ContextType>;

    // get or create our accessor
    bool created = false;

    // try to get existing row if updating
    size_t row_index = realm::not_found;
    realm::TableRef table = ObjectStore::table_for_object_type(realm->read_group(), object_schema.name);

    if (auto primary_prop = object_schema.primary_key_property()) {
        // search for existing object based on primary key type
        ValueType primary_value = Accessor::dict_value_for_key(ctx, value, object_schema.primary_key);
        row_index = get_for_primary_key_impl(ctx, *table, *primary_prop, primary_value);

        if (row_index == realm::not_found) {
            row_index = table->add_empty_row();
            created = true;
            if (primary_prop->type == PropertyType::Int)
                table->set_int_unique(primary_prop->table_column, row_index, Accessor::to_long(ctx, primary_value));
            else if (primary_prop->type == PropertyType::String) {
                auto value = Accessor::to_string(ctx, primary_value);
                table->set_string_unique(primary_prop->table_column, row_index, value);
            }
            else
                REALM_UNREACHABLE();
        }
        else if (!try_update) {
            throw std::logic_error(util::format("Attempting to create an object of type '%1' with an existing primary key value.", object_schema.name));
        }
    }
    else {
        row_index = table->add_empty_row();
        created = true;
    }

    // populate
    Object object(realm, object_schema, table->get(row_index));
    for (const Property& prop : object_schema.persisted_properties) {
        if (prop.is_primary)
            continue;

        if (Accessor::dict_has_value_for_key(ctx, value, prop.name)) {
            object.set_property_value_impl(ctx, prop, Accessor::dict_value_for_key(ctx, value, prop.name), try_update);
        }
        else if (created) {
            if (Accessor::has_default_value_for_property(ctx, realm.get(), object_schema, prop.name)) {
                object.set_property_value_impl(ctx, prop, Accessor::default_value_for_property(ctx, realm.get(), object_schema, prop.name), try_update, true);
            }
            else if (prop.is_nullable || prop.type == PropertyType::Array) {
                object.set_property_value_impl(ctx, prop, Accessor::null_value(ctx), try_update);
            }
            else {
                throw MissingPropertyValueException(object_schema.name, prop.name);
            }
        }
    }
    return object;
}

template<typename ValueType, typename ContextType>
Object Object::get_for_primary_key(ContextType ctx, SharedRealm realm, const ObjectSchema &object_schema, ValueType primary_value)
{
    auto primary_prop = object_schema.primary_key_property();
    if (!primary_prop) {
        throw MissingPrimaryKeyException(object_schema.name);
    }

    auto table = ObjectStore::table_for_object_type(realm->read_group(), object_schema.name);
    auto row_index = get_for_primary_key_impl(ctx, *table, *primary_prop, primary_value);

    return Object(realm, object_schema, row_index == realm::not_found ? Row() : table->get(row_index));
}

template<typename ValueType, typename ContextType>
size_t Object::get_for_primary_key_impl(ContextType ctx, Table const& table, const Property &primary_prop, ValueType primary_value) {
    using Accessor = NativeAccessor<ValueType, ContextType>;

    if (primary_prop.type == PropertyType::String) {
        auto primary_string = Accessor::to_string(ctx, primary_value);
        return table.find_first_string(primary_prop.table_column, primary_string);
    }
    else {
        return table.find_first_int(primary_prop.table_column, Accessor::to_long(ctx, primary_value));
    }
}

//
// List implementation
//
template<typename ValueType, typename ContextType>
void List::add(ContextType ctx, ValueType value)
{
    add(NativeAccessor<ValueType, ContextType>::to_object_index(ctx, m_realm, value, get_object_schema().name, false));
}

template<typename ValueType, typename ContextType>
void List::insert(ContextType ctx, ValueType value, size_t list_ndx)
{
    insert(list_ndx, NativeAccessor<ValueType, ContextType>::to_object_index(ctx, m_realm, value, get_object_schema().name, false));
}

template<typename ValueType, typename ContextType>
void List::set(ContextType ctx, ValueType value, size_t list_ndx)
{
    set(list_ndx, NativeAccessor<ValueType, ContextType>::to_object_index(ctx, m_realm, value, get_object_schema().name, false));
}
} // namespace realm

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

#ifndef REALM_OS_OBJECT_ACCESSOR_HPP
#define REALM_OS_OBJECT_ACCESSOR_HPP

#include "object.hpp"

#include "list.hpp"
#include "object_schema.hpp"
#include "object_store.hpp"
#include "results.hpp"
#include "schema.hpp"
#include "util/format.hpp"

#include <realm/link_view.hpp>
#include <realm/util/assert.hpp>
#include <realm/table_view.hpp>

#include <string>

namespace realm {
//
// Value converters - template specializations must be implemented for each platform in order to call templated methods on Object
//
template<typename ValueType, typename ContextType>
class NativeAccessor {
public:
    static bool dict_has_value_for_key(ContextType ctx, ValueType dict, const std::string &prop_name);
    static ValueType dict_value_for_key(ContextType ctx, ValueType dict, const std::string &prop_name);

    static bool has_default_value_for_property(ContextType ctx, Realm *realm, const ObjectSchema &object_schema, const std::string &prop_name);
    static ValueType default_value_for_property(ContextType ctx, Realm *realm, const ObjectSchema &object_schema, const std::string &prop_name);

    static bool to_bool(ContextType, ValueType &);
    static ValueType from_bool(ContextType, bool);
    static long long to_long(ContextType, ValueType &);
    static ValueType from_long(ContextType, long long);
    static float to_float(ContextType, ValueType &);
    static ValueType from_float(ContextType, float);
    static double to_double(ContextType, ValueType &);
    static ValueType from_double(ContextType, double);
    static std::string to_string(ContextType, ValueType &);
    static ValueType from_string(ContextType, StringData);
    static std::string to_binary(ContextType, ValueType &);
    static ValueType from_binary(ContextType, BinaryData);
    static Timestamp to_timestamp(ContextType, ValueType &);
    static ValueType from_timestamp(ContextType, Timestamp);

    static bool is_null(ContextType, ValueType &);
    static ValueType null_value(ContextType);

    // convert value to persisted object
    // for existing objects return the existing row index
    // for new/updated objects return the row index
    static size_t to_object_index(ContextType ctx, SharedRealm realm, ValueType &val, const std::string &type, bool try_update);
    static ValueType from_object(ContextType ctx, Object);

    // object index for an existing object
    static size_t to_existing_object_index(ContextType ctx, SharedRealm realm, ValueType &val);

    // list value accessors
    static size_t list_size(ContextType ctx, ValueType &val);
    static ValueType list_value_at_index(ContextType ctx, ValueType &val, size_t index);
    static ValueType from_list(ContextType ctx, List);

    // results value accessors
    static ValueType from_results(ContextType ctx, Results);

    //
    // Deprecated
    //
    static Mixed to_mixed(ContextType, ValueType&);
};

//
// template method implementations
//
template <typename ValueType, typename ContextType>
void Object::set_property_value(ContextType ctx, std::string prop_name, ValueType value, bool try_update)
{
    verify_attached();
    m_realm->verify_in_write();
    auto& property = property_for_name(prop_name);
    if (property.is_primary)
        throw std::logic_error("Cannot modify primary key after creation");

    set_property_value_impl(ctx, property, value, try_update);
}

template <typename ValueType, typename ContextType>
ValueType Object::get_property_value(ContextType ctx, std::string prop_name)
{
    return get_property_value_impl<ValueType>(ctx, property_for_name(prop_name));
}

template <typename ValueType, typename ContextType>
void Object::set_property_value_impl(ContextType ctx, const Property &property, ValueType value, bool try_update, bool is_default)
{
    using Accessor = NativeAccessor<ValueType, ContextType>;

    auto& table = *m_row.get_table();
    size_t column = property.table_column;
    size_t row = m_row.get_index();
    if (property.is_nullable && Accessor::is_null(ctx, value)) {
        if (property.type == PropertyType::Object) {
            if (!is_default)
                table.nullify_link(column, row);
        }
        else {
            table.set_null(column, row, is_default);
        }
        return;
    }

    switch (property.type) {
        case PropertyType::Bool:
            table.set_bool(column, row, Accessor::to_bool(ctx, value), is_default);
            break;
        case PropertyType::Int:
            table.set_int(column, row, Accessor::to_long(ctx, value), is_default);
            break;
        case PropertyType::Float:
            table.set_float(column, row, Accessor::to_float(ctx, value), is_default);
            break;
        case PropertyType::Double:
            table.set_double(column, row, Accessor::to_double(ctx, value), is_default);
            break;
        case PropertyType::String: {
            auto str = Accessor::to_string(ctx, value);
            table.set_string(column, row, str, is_default);
            break;
        }
        case PropertyType::Data: {
            auto data = Accessor::to_binary(ctx, value);
            table.set_binary(column, row, BinaryData(data), is_default);
            break;
        }
        case PropertyType::Any:
            table.set_mixed(column, row, Accessor::to_mixed(ctx, value), is_default);
            break;
        case PropertyType::Date:
            table.set_timestamp(column, row, Accessor::to_timestamp(ctx, value), is_default);
            break;
        case PropertyType::Object: {
            table.set_link(column, row, Accessor::to_object_index(ctx, m_realm, value, property.object_type, try_update), is_default);
            break;
        }
        case PropertyType::Array: {
            LinkViewRef link_view = m_row.get_linklist(column);
            link_view->clear();
            if (!Accessor::is_null(ctx, value)) {
                size_t count = Accessor::list_size(ctx, value);
                for (size_t i = 0; i < count; i++) {
                    ValueType element = Accessor::list_value_at_index(ctx, value, i);
                    link_view->add(Accessor::to_object_index(ctx, m_realm, element, property.object_type, try_update));
                }
            }
            break;
        }
        case PropertyType::LinkingObjects:
            throw ReadOnlyPropertyException(m_object_schema->name, property.name);
    }
}

template <typename ValueType, typename ContextType>
ValueType Object::get_property_value_impl(ContextType ctx, const Property &property)
{
    verify_attached();

    using Accessor = NativeAccessor<ValueType, ContextType>;

    size_t column = property.table_column;
    if (property.is_nullable && m_row.is_null(column)) {
        return Accessor::null_value(ctx);
    }

    switch (property.type) {
        case PropertyType::Bool:
            return Accessor::from_bool(ctx, m_row.get_bool(column));
        case PropertyType::Int:
            return Accessor::from_long(ctx, m_row.get_int(column));
        case PropertyType::Float:
            return Accessor::from_float(ctx, m_row.get_float(column));
        case PropertyType::Double:
            return Accessor::from_double(ctx, m_row.get_double(column));
        case PropertyType::String:
            return Accessor::from_string(ctx, m_row.get_string(column));
        case PropertyType::Data:
            return Accessor::from_binary(ctx, m_row.get_binary(column));
        case PropertyType::Any:
            throw "Any not supported";
        case PropertyType::Date:
            return Accessor::from_timestamp(ctx, m_row.get_timestamp(column));
        case PropertyType::Object: {
            auto linkObjectSchema = m_realm->schema().find(property.object_type);
            TableRef table = ObjectStore::table_for_object_type(m_realm->read_group(), linkObjectSchema->name);
            return Accessor::from_object(ctx, Object(m_realm, *linkObjectSchema, table->get(m_row.get_link(column))));
        }
        case PropertyType::Array:
            return Accessor::from_list(ctx, List(m_realm, m_row.get_linklist(column)));
        case PropertyType::LinkingObjects: {
            auto target_object_schema = m_realm->schema().find(property.object_type);
            auto link_property = target_object_schema->property_for_name(property.link_origin_property_name);
            TableRef table = ObjectStore::table_for_object_type(m_realm->read_group(), target_object_schema->name);
            auto tv = m_row.get_table()->get_backlink_view(m_row.get_index(), table.get(), link_property->table_column);
            return Accessor::from_results(ctx, Results(m_realm, std::move(tv)));
        }
    }
    REALM_UNREACHABLE();
}

template<typename ValueType, typename ContextType>
Object Object::create(ContextType ctx, SharedRealm realm, const ObjectSchema &object_schema, ValueType value, bool try_update)
{
    realm->verify_in_write();

    using Accessor = NativeAccessor<ValueType, ContextType>;

    // get or create our accessor
    bool created = false;

    // try to get existing row if updating
    size_t row_index = realm::not_found;
    realm::TableRef table = ObjectStore::table_for_object_type(realm->read_group(), object_schema.name);

    if (auto primary_prop = object_schema.primary_key_property()) {
        // search for existing object based on primary key type
        ValueType primary_value = Accessor::dict_value_for_key(ctx, value, object_schema.primary_key);
        row_index = get_for_primary_key_impl(ctx, *table, *primary_prop, primary_value);

        if (row_index == realm::not_found) {
            row_index = table->add_empty_row();
            created = true;
            if (primary_prop->type == PropertyType::Int)
                table->set_int_unique(primary_prop->table_column, row_index, Accessor::to_long(ctx, primary_value));
            else if (primary_prop->type == PropertyType::String) {
                auto value = Accessor::to_string(ctx, primary_value);
                table->set_string_unique(primary_prop->table_column, row_index, value);
            }
            else
                REALM_UNREACHABLE();
        }
        else if (!try_update) {
            throw std::logic_error(util::format("Attempting to create an object of type '%1' with an existing primary key value.", object_schema.name));
        }
    }
    else {
        row_index = table->add_empty_row();
        created = true;
    }

    // populate
    Object object(realm, object_schema, table->get(row_index));
    for (const Property& prop : object_schema.persisted_properties) {
        if (prop.is_primary)
            continue;

        if (Accessor::dict_has_value_for_key(ctx, value, prop.name)) {
            object.set_property_value_impl(ctx, prop, Accessor::dict_value_for_key(ctx, value, prop.name), try_update);
        }
        else if (created) {
            if (Accessor::has_default_value_for_property(ctx, realm.get(), object_schema, prop.name)) {
                object.set_property_value_impl(ctx, prop, Accessor::default_value_for_property(ctx, realm.get(), object_schema, prop.name), try_update, true);
            }
            else if (prop.is_nullable || prop.type == PropertyType::Array) {
                object.set_property_value_impl(ctx, prop, Accessor::null_value(ctx), try_update);
            }
            else {
                throw MissingPropertyValueException(object_schema.name, prop.name);
            }
        }
    }
    return object;
}

template<typename ValueType, typename ContextType>
Object Object::get_for_primary_key(ContextType ctx, SharedRealm realm, const ObjectSchema &object_schema, ValueType primary_value)
{
    auto primary_prop = object_schema.primary_key_property();
    if (!primary_prop) {
        throw MissingPrimaryKeyException(object_schema.name);
    }

    auto table = ObjectStore::table_for_object_type(realm->read_group(), object_schema.name);
    auto row_index = get_for_primary_key_impl(ctx, *table, *primary_prop, primary_value);

    return Object(realm, object_schema, row_index == realm::not_found ? Row() : Row(table->get(row_index)));
}

template<typename ValueType, typename ContextType>
size_t Object::get_for_primary_key_impl(ContextType ctx, Table const& table, const Property &primary_prop, ValueType primary_value) {
    using Accessor = NativeAccessor<ValueType, ContextType>;

    if (primary_prop.type == PropertyType::String) {
        auto primary_string = Accessor::to_string(ctx, primary_value);
        return table.find_first_string(primary_prop.table_column, primary_string);
    }
    else {
        return table.find_first_int(primary_prop.table_column, Accessor::to_long(ctx, primary_value));
    }
}

//
// List implementation
//
template<typename ValueType, typename ContextType>
void List::add(ContextType ctx, ValueType value)
{
    add(NativeAccessor<ValueType, ContextType>::to_object_index(ctx, m_realm, value, get_object_schema().name, false));
}

template<typename ValueType, typename ContextType>
void List::insert(ContextType ctx, ValueType value, size_t list_ndx)
{
    insert(list_ndx, NativeAccessor<ValueType, ContextType>::to_object_index(ctx, m_realm, value, get_object_schema().name, false));
}

template<typename ValueType, typename ContextType>
void List::set(ContextType ctx, ValueType value, size_t list_ndx)
{
    set(list_ndx, NativeAccessor<ValueType, ContextType>::to_object_index(ctx, m_realm, value, get_object_schema().name, false));
}
} // namespace realm

#endif /* defined(REALM_OS_OBJECT_ACCESSOR_HPP) */
<|endoftext|>


<commit_before>#include "spline.hpp"

namespace m2
{

Spline::Spline(vector<PointF> const & path)
{
  ASSERT(path.size() > 1, ("Wrong path size!"));
  m_position.assign(path.begin(), path.end());
  int cnt = m_position.size() - 1;
  m_direction = vector<PointF>(cnt);
  m_length = vector<float>(cnt);

  for(int i = 0; i < cnt; ++i)
  {
    m_direction[i] = path[i+1] - path[i];
    m_length[i] = m_direction[i].Length();
    m_direction[i] = m_direction[i].Normalize();
    m_lengthAll += m_length[i];
  }
}

void Spline::AddPoint(PointF const & pt)
{
  if(m_position.empty())
    m_position.push_back(pt);
  else
  {
    PointF dir = pt - m_position.back();
    m_position.push_back(pt);
    m_direction.push_back(dir.Normalize());
    m_length.push_back(dir.Length());
    m_lengthAll += m_length.back();
  }
}

Spline const & Spline::operator = (Spline const & spl)
{
  if(&spl != this)
  {
    m_lengthAll = spl.m_lengthAll;
    m_position = spl.m_position;
    m_direction = spl.m_direction;
    m_length = spl.m_length;
  }
  return *this;
}

Spline::iterator::iterator()
  : m_checker(false)
  , m_spl(NULL)
  , m_index(0)
  , m_dist(0) {}

void Spline::iterator::Attach(Spline const & S)
{
  m_spl = &S;
  m_index = 0;
  m_dist = 0;
  m_checker = false;
  m_dir = m_spl->m_direction[m_index];
  m_avrDir = m_spl->m_direction[m_index];
  m_pos = m_spl->m_position[m_index] + m_dir * m_dist;
}

void Spline::iterator::Step(float speed)
{
  m_dist += speed;
  while(m_dist > m_spl->m_length[m_index])
  {
    m_dist -= m_spl->m_length[m_index];
    m_index++;
    if(m_index >= m_spl->m_direction.size())
    {
      m_index = 0;
      m_checker = true;
    }
  }
  m_dir = m_spl->m_direction[m_index];
  m_avrDir = -m_pos;
  m_pos = m_spl->m_position[m_index] + m_dir * m_dist;
  m_avrDir += m_pos;
}

bool Spline::iterator::BeginAgain()
{
  return m_checker;
}

SharedSpline::SharedSpline(vector<PointF> const & path)
{
  m_spline.reset(new Spline(path));
}

SharedSpline::SharedSpline(SharedSpline const & other)
{
  if (this != &other)
    m_spline = other.m_spline;
}

SharedSpline const & SharedSpline::operator= (SharedSpline const & spl)
{
  if (this != &spl)
    m_spline = spl.m_spline;
  return *this;
}

float SharedSpline::GetLength() const
{
  return m_spline->GetLength();
}

Spline::iterator SharedSpline::CreateIterator()
{
  Spline::iterator result;
  result.Attach(*m_spline.get());
  return result;
}

}

<commit_msg>small fix<commit_after>#include "spline.hpp"

namespace m2
{

Spline::Spline(vector<PointF> const & path) : m_lengthAll(0.0f)
{
  ASSERT(path.size() > 1, ("Wrong path size!"));
  m_position.assign(path.begin(), path.end());
  int cnt = m_position.size() - 1;
  m_direction = vector<PointF>(cnt);
  m_length = vector<float>(cnt);

  for(int i = 0; i < cnt; ++i)
  {
    m_direction[i] = path[i+1] - path[i];
    m_length[i] = m_direction[i].Length();
    m_direction[i] = m_direction[i].Normalize();
    m_lengthAll += m_length[i];
  }
}

void Spline::AddPoint(PointF const & pt)
{
  if(m_position.empty())
    m_position.push_back(pt);
  else
  {
    PointF dir = pt - m_position.back();
    m_position.push_back(pt);
    m_length.push_back(dir.Length());
    m_direction.push_back(dir.Normalize());
    m_lengthAll += m_length.back();
  }
}

Spline const & Spline::operator = (Spline const & spl)
{
  if(&spl != this)
  {
    m_lengthAll = spl.m_lengthAll;
    m_position = spl.m_position;
    m_direction = spl.m_direction;
    m_length = spl.m_length;
  }
  return *this;
}

Spline::iterator::iterator()
  : m_checker(false)
  , m_spl(NULL)
  , m_index(0)
  , m_dist(0) {}

void Spline::iterator::Attach(Spline const & S)
{
  m_spl = &S;
  m_index = 0;
  m_dist = 0;
  m_checker = false;
  m_dir = m_spl->m_direction[m_index];
  m_avrDir = m_spl->m_direction[m_index];
  m_pos = m_spl->m_position[m_index] + m_dir * m_dist;
}

void Spline::iterator::Step(float speed)
{
  m_dist += speed;
  while(m_dist > m_spl->m_length[m_index])
  {
    m_dist -= m_spl->m_length[m_index];
    m_index++;
    if(m_index >= m_spl->m_direction.size())
    {
      m_index = 0;
      m_checker = true;
    }
  }
  m_dir = m_spl->m_direction[m_index];
  m_avrDir = -m_pos;
  m_pos = m_spl->m_position[m_index] + m_dir * m_dist;
  m_avrDir += m_pos;
}

bool Spline::iterator::BeginAgain()
{
  return m_checker;
}

SharedSpline::SharedSpline(vector<PointF> const & path)
{
  m_spline.reset(new Spline(path));
}

SharedSpline::SharedSpline(SharedSpline const & other)
{
  if (this != &other)
    m_spline = other.m_spline;
}

SharedSpline const & SharedSpline::operator= (SharedSpline const & spl)
{
  if (this != &spl)
    m_spline = spl.m_spline;
  return *this;
}

float SharedSpline::GetLength() const
{
  return m_spline->GetLength();
}

Spline::iterator SharedSpline::CreateIterator()
{
  Spline::iterator result;
  result.Attach(*m_spline.get());
  return result;
}

}

<|endoftext|>


<commit_before>#pragma once

#include "threaded_list.hpp"
#include "logging.hpp"
#include "../std/bind.hpp"
#include "../std/scoped_ptr.hpp"

struct BasePoolElemFactory
{
  string m_resName;
  size_t m_elemSize;
  size_t m_batchSize;

  BasePoolElemFactory(char const * resName, size_t elemSize, size_t batchSize);

  size_t BatchSize() const;
  char const * ResName() const;
  size_t ElemSize() const;
};

/// basic traits maintains a list of free resources.
template <typename TElem, typename TElemFactory>
struct BasePoolTraits
{
  TElemFactory m_factory;
  ThreadedList<TElem> m_pool;
  bool m_IsDebugging;

  typedef TElem elem_t;

  BasePoolTraits(TElemFactory const & factory)
    : m_factory(factory), m_IsDebugging(false)
  {
    m_pool.SetName(factory.ResName());
  }

  virtual ~BasePoolTraits()
  {}

  virtual void Init()
  {
    Free(Reserve());
  }

  virtual void Free(TElem const & elem)
  {
    m_pool.PushBack(elem);
  }

  virtual TElem const Reserve()
  {
    return m_pool.Front(true);
  }

  virtual size_t Size() const
  {
    return m_pool.Size();
  }

  virtual void Cancel()
  {
    m_pool.Cancel();
  }

  virtual bool IsCancelled() const
  {
    return m_pool.IsCancelled();
  }

  virtual void UpdateState()
  {
  }
};

/// This traits stores the free elements in a separate pool and has
/// a separate method to merge them all into a main pool.
/// For example should be used for resources where a certain preparation operation
/// should be performed on main thread before returning resource
/// to a free pool(p.e. @see resource_manager.cpp StorageFactory)
template <typename TElemFactory, typename TBase>
struct SeparateFreePoolTraits : TBase
{
  typedef TBase base_t;
  typedef typename base_t::elem_t elem_t;

  ThreadedList<elem_t> m_freePool;
  int m_maxFreePoolSize;

  SeparateFreePoolTraits(TElemFactory const & factory)
    : base_t(factory), m_maxFreePoolSize(0)
  {}

  void Free(elem_t const & elem)
  {
    m_freePool.PushBack(elem);
/*    if (base_t::m_IsDebugging)
    {
      int oldMaxFreePoolSize = m_maxFreePoolSize;
      m_maxFreePoolSize = max(m_maxFreePoolSize, (int)m_freePool.Size());
      if (oldMaxFreePoolSize != m_maxFreePoolSize)
        LOG(LINFO, (base_t::m_pool.GetName(), "freePool maximum size has reached", m_maxFreePoolSize, "elements"));
    }*/
  }

  void UpdateStateImpl(list<elem_t> & l)
  {
    for (typename list<elem_t>::const_iterator it = l.begin();
         it != l.end();
         ++it)
    {
      base_t::m_factory.BeforeMerge(*it);
      base_t::m_pool.PushBack(*it);
    }

//    if ((base_t::m_IsDebugging) && (!base_t::m_pool.GetName().empty()))
//      LOG(LINFO, ("pool for", base_t::m_pool.GetName(), "has", base_t::m_pool.Size(), "elements"));

    l.clear();
  }

  void UpdateState()
  {
    m_freePool.ProcessList(bind(&SeparateFreePoolTraits<TElemFactory, TBase>::UpdateStateImpl, this, _1));
  }
};

/// This traits maintains a fixed-size of pre-allocated resources.
template <typename TElemFactory, typename TBase >
struct FixedSizePoolTraits : TBase
{
  typedef TBase base_t;
  typedef typename base_t::elem_t elem_t;

  size_t m_count;
  bool m_isAllocated;

  FixedSizePoolTraits(TElemFactory const & factory, size_t count)
    : base_t(factory),
      m_count(count),
      m_isAllocated(false)
  {}

  elem_t const Reserve()
  {
    if (!m_isAllocated)
    {
      m_isAllocated = true;

      LOG(LDEBUG, ("allocating ", base_t::m_factory.ElemSize() * m_count, "bytes for ", base_t::m_factory.ResName()));

      for (size_t i = 0; i < m_count; ++i)
        base_t::m_pool.PushBack(base_t::m_factory.Create());
    }

    return base_t::Reserve();
  }
};

/// This traits allocates resources on demand.
template <typename TElemFactory, typename TBase>
struct AllocateOnDemandMultiThreadedPoolTraits : TBase
{
  typedef TBase base_t;
  typedef typename base_t::elem_t elem_t;
  typedef AllocateOnDemandMultiThreadedPoolTraits<TElemFactory, base_t> self_t;

  size_t m_poolSize;
  AllocateOnDemandMultiThreadedPoolTraits(TElemFactory const & factory, size_t )
    : base_t(factory),
      m_poolSize(0)
  {}

  void AllocateIfNeeded(list<elem_t> & l)
  {
    if (l.empty())
    {
      m_poolSize += base_t::m_factory.ElemSize() * base_t::m_factory.BatchSize();
      LOG(LDEBUG, ("allocating ", base_t::m_factory.ElemSize(), "bytes for ", base_t::m_factory.ResName(), " on-demand, poolSize=", m_poolSize / base_t::m_factory.ElemSize(), ", totalMemory=", m_poolSize));
      for (unsigned i = 0; i < base_t::m_factory.BatchSize(); ++i)
        l.push_back(base_t::m_factory.Create());
    }
  }

  elem_t const Reserve()
  {
    base_t::m_pool.ProcessList(bind(&self_t::AllocateIfNeeded, this, _1));
    return base_t::Reserve();
  }
};

template <typename TElemFactory, typename TBase>
struct AllocateOnDemandSingleThreadedPoolTraits : TBase
{
  typedef TBase base_t;
  typedef typename TBase::elem_t elem_t;
  typedef AllocateOnDemandSingleThreadedPoolTraits<TElemFactory, TBase> self_t;

  size_t m_poolSize;
  AllocateOnDemandSingleThreadedPoolTraits(TElemFactory const & factory, size_t )
    : base_t(factory),
      m_poolSize(0)
  {}

  void Init()
  {}

  void AllocateIfNeeded(list<elem_t> & l)
  {
    if (l.empty())
    {
      m_poolSize += base_t::m_factory.ElemSize() * base_t::m_factory.BatchSize();
      LOG(LDEBUG, ("allocating", base_t::m_factory.BatchSize(), "elements for ", base_t::m_factory.ResName(), "on-demand, poolSize=", m_poolSize / base_t::m_factory.ElemSize(), ", totalMemory=", m_poolSize));
      for (unsigned i = 0; i < base_t::m_factory.BatchSize(); ++i)
        l.push_back(base_t::m_factory.Create());
    }
  }

  void UpdateState()
  {
    base_t::UpdateState();
    base_t::m_pool.ProcessList(bind(&self_t::AllocateIfNeeded, this, _1));
  }
};

/// resource pool interface
template <typename TElem>
class ResourcePool
{
public:
  virtual ~ResourcePool(){}
  virtual TElem const Reserve() = 0;
  virtual void Free(TElem const & elem) = 0;
  virtual size_t Size() const = 0;
  virtual void EnterForeground() = 0;
  virtual void EnterBackground() = 0;
  virtual void Cancel() = 0;
  virtual bool IsCancelled() const = 0;
  virtual void UpdateState() = 0;
  virtual void SetIsDebugging(bool flag) = 0;
};

// This class tracks OpenGL resources allocation in
// a multithreaded environment.
template <typename TPoolTraits>
class ResourcePoolImpl : public ResourcePool<typename TPoolTraits::elem_t>
{
private:

  scoped_ptr<TPoolTraits> m_traits;

public:

  typedef typename TPoolTraits::elem_t elem_t;

  ResourcePoolImpl(TPoolTraits * traits)
    : m_traits(traits)
  {
    /// quick trick to perform lazy initialization
    /// on the same thread the pool was created.
    m_traits->Init();
  }

  elem_t const Reserve()
  {
    return m_traits->Reserve();
  }

  void Free(elem_t const & elem)
  {
    m_traits->Free(elem);
  }

  size_t Size() const
  {
    return m_traits->Size();
  }

  void EnterForeground()
  {}

  void EnterBackground()
  {}

  void Cancel()
  {
    return m_traits->Cancel();
  }

  bool IsCancelled() const
  {
    return m_traits->IsCancelled();
  }

  void UpdateState()
  {
    m_traits->UpdateState();
  }

  void SetIsDebugging(bool isDebugging)
  {
    m_traits->m_IsDebugging = isDebugging;
  }
};
<commit_msg>added ResourcePool::ResName for the purpose of logging.<commit_after>#pragma once

#include "threaded_list.hpp"
#include "logging.hpp"
#include "../std/bind.hpp"
#include "../std/scoped_ptr.hpp"

struct BasePoolElemFactory
{
  string m_resName;
  size_t m_elemSize;
  size_t m_batchSize;

  BasePoolElemFactory(char const * resName, size_t elemSize, size_t batchSize);

  size_t BatchSize() const;
  char const * ResName() const;
  size_t ElemSize() const;
};

/// basic traits maintains a list of free resources.
template <typename TElem, typename TElemFactory>
struct BasePoolTraits
{
  TElemFactory m_factory;
  ThreadedList<TElem> m_pool;
  bool m_IsDebugging;

  typedef TElem elem_t;

  BasePoolTraits(TElemFactory const & factory)
    : m_factory(factory), m_IsDebugging(false)
  {
    m_pool.SetName(factory.ResName());
  }

  virtual ~BasePoolTraits()
  {}

  virtual void Init()
  {
    Free(Reserve());
  }

  virtual void Free(TElem const & elem)
  {
    m_pool.PushBack(elem);
  }

  virtual TElem const Reserve()
  {
    return m_pool.Front(true);
  }

  virtual size_t Size() const
  {
    return m_pool.Size();
  }

  virtual void Cancel()
  {
    m_pool.Cancel();
  }

  virtual bool IsCancelled() const
  {
    return m_pool.IsCancelled();
  }

  virtual void UpdateState()
  {
  }

  char const * ResName() const
  {
    return m_factory.ResName();
  }
};

/// This traits stores the free elements in a separate pool and has
/// a separate method to merge them all into a main pool.
/// For example should be used for resources where a certain preparation operation
/// should be performed on main thread before returning resource
/// to a free pool(p.e. @see resource_manager.cpp StorageFactory)
template <typename TElemFactory, typename TBase>
struct SeparateFreePoolTraits : TBase
{
  typedef TBase base_t;
  typedef typename base_t::elem_t elem_t;

  ThreadedList<elem_t> m_freePool;
  int m_maxFreePoolSize;

  SeparateFreePoolTraits(TElemFactory const & factory)
    : base_t(factory), m_maxFreePoolSize(0)
  {}

  void Free(elem_t const & elem)
  {
    m_freePool.PushBack(elem);
/*    if (base_t::m_IsDebugging)
    {
      int oldMaxFreePoolSize = m_maxFreePoolSize;
      m_maxFreePoolSize = max(m_maxFreePoolSize, (int)m_freePool.Size());
      if (oldMaxFreePoolSize != m_maxFreePoolSize)
        LOG(LINFO, (base_t::m_pool.GetName(), "freePool maximum size has reached", m_maxFreePoolSize, "elements"));
    }*/
  }

  void UpdateStateImpl(list<elem_t> & l)
  {
    for (typename list<elem_t>::const_iterator it = l.begin();
         it != l.end();
         ++it)
    {
      base_t::m_factory.BeforeMerge(*it);
      base_t::m_pool.PushBack(*it);
    }

//    if ((base_t::m_IsDebugging) && (!base_t::m_pool.GetName().empty()))
//      LOG(LINFO, ("pool for", base_t::m_pool.GetName(), "has", base_t::m_pool.Size(), "elements"));

    l.clear();
  }

  void UpdateState()
  {
    m_freePool.ProcessList(bind(&SeparateFreePoolTraits<TElemFactory, TBase>::UpdateStateImpl, this, _1));
  }
};

/// This traits maintains a fixed-size of pre-allocated resources.
template <typename TElemFactory, typename TBase >
struct FixedSizePoolTraits : TBase
{
  typedef TBase base_t;
  typedef typename base_t::elem_t elem_t;

  size_t m_count;
  bool m_isAllocated;

  FixedSizePoolTraits(TElemFactory const & factory, size_t count)
    : base_t(factory),
      m_count(count),
      m_isAllocated(false)
  {}

  elem_t const Reserve()
  {
    if (!m_isAllocated)
    {
      m_isAllocated = true;

      LOG(LDEBUG, ("allocating ", base_t::m_factory.ElemSize() * m_count, "bytes for ", base_t::m_factory.ResName()));

      for (size_t i = 0; i < m_count; ++i)
        base_t::m_pool.PushBack(base_t::m_factory.Create());
    }

    return base_t::Reserve();
  }
};

/// This traits allocates resources on demand.
template <typename TElemFactory, typename TBase>
struct AllocateOnDemandMultiThreadedPoolTraits : TBase
{
  typedef TBase base_t;
  typedef typename base_t::elem_t elem_t;
  typedef AllocateOnDemandMultiThreadedPoolTraits<TElemFactory, base_t> self_t;

  size_t m_poolSize;
  AllocateOnDemandMultiThreadedPoolTraits(TElemFactory const & factory, size_t )
    : base_t(factory),
      m_poolSize(0)
  {}

  void AllocateIfNeeded(list<elem_t> & l)
  {
    if (l.empty())
    {
      m_poolSize += base_t::m_factory.ElemSize() * base_t::m_factory.BatchSize();
      LOG(LDEBUG, ("allocating ", base_t::m_factory.ElemSize(), "bytes for ", base_t::m_factory.ResName(), " on-demand, poolSize=", m_poolSize / base_t::m_factory.ElemSize(), ", totalMemory=", m_poolSize));
      for (unsigned i = 0; i < base_t::m_factory.BatchSize(); ++i)
        l.push_back(base_t::m_factory.Create());
    }
  }

  elem_t const Reserve()
  {
    base_t::m_pool.ProcessList(bind(&self_t::AllocateIfNeeded, this, _1));
    return base_t::Reserve();
  }
};

template <typename TElemFactory, typename TBase>
struct AllocateOnDemandSingleThreadedPoolTraits : TBase
{
  typedef TBase base_t;
  typedef typename TBase::elem_t elem_t;
  typedef AllocateOnDemandSingleThreadedPoolTraits<TElemFactory, TBase> self_t;

  size_t m_poolSize;
  AllocateOnDemandSingleThreadedPoolTraits(TElemFactory const & factory, size_t )
    : base_t(factory),
      m_poolSize(0)
  {}

  void Init()
  {}

  void AllocateIfNeeded(list<elem_t> & l)
  {
    if (l.empty())
    {
      m_poolSize += base_t::m_factory.ElemSize() * base_t::m_factory.BatchSize();
      LOG(LDEBUG, ("allocating", base_t::m_factory.BatchSize(), "elements for ", base_t::m_factory.ResName(), "on-demand, poolSize=", m_poolSize / base_t::m_factory.ElemSize(), ", totalMemory=", m_poolSize));
      for (unsigned i = 0; i < base_t::m_factory.BatchSize(); ++i)
        l.push_back(base_t::m_factory.Create());
    }
  }

  void UpdateState()
  {
    base_t::UpdateState();
    base_t::m_pool.ProcessList(bind(&self_t::AllocateIfNeeded, this, _1));
  }
};

/// resource pool interface
template <typename TElem>
class ResourcePool
{
public:
  virtual ~ResourcePool(){}
  virtual TElem const Reserve() = 0;
  virtual void Free(TElem const & elem) = 0;
  virtual size_t Size() const = 0;
  virtual void EnterForeground() = 0;
  virtual void EnterBackground() = 0;
  virtual void Cancel() = 0;
  virtual bool IsCancelled() const = 0;
  virtual void UpdateState() = 0;
  virtual void SetIsDebugging(bool flag) = 0;
  virtual char const * ResName() const = 0;
};

// This class tracks OpenGL resources allocation in
// a multithreaded environment.
template <typename TPoolTraits>
class ResourcePoolImpl : public ResourcePool<typename TPoolTraits::elem_t>
{
private:

  scoped_ptr<TPoolTraits> m_traits;

public:

  typedef typename TPoolTraits::elem_t elem_t;

  ResourcePoolImpl(TPoolTraits * traits)
    : m_traits(traits)
  {
    /// quick trick to perform lazy initialization
    /// on the same thread the pool was created.
    m_traits->Init();
  }

  elem_t const Reserve()
  {
    return m_traits->Reserve();
  }

  void Free(elem_t const & elem)
  {
    m_traits->Free(elem);
  }

  size_t Size() const
  {
    return m_traits->Size();
  }

  void EnterForeground()
  {}

  void EnterBackground()
  {}

  void Cancel()
  {
    return m_traits->Cancel();
  }

  bool IsCancelled() const
  {
    return m_traits->IsCancelled();
  }

  void UpdateState()
  {
    m_traits->UpdateState();
  }

  void SetIsDebugging(bool isDebugging)
  {
    m_traits->m_IsDebugging = isDebugging;
  }

  char const * ResName() const
  {
    return m_traits->ResName();
  }
};
<|endoftext|>


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

#include "update_engine/dbus_service.h"

#include <string>

#include <base/logging.h>

#include "update_engine/marshal.glibmarshal.h"
#include "update_engine/omaha_request_params.h"
#include "update_engine/utils.h"

using std::string;

G_DEFINE_TYPE(UpdateEngineService, update_engine_service, G_TYPE_OBJECT)

static void update_engine_service_finalize(GObject* object) {
  G_OBJECT_CLASS(update_engine_service_parent_class)->finalize(object);
}

static guint status_update_signal = 0;

static void update_engine_service_class_init(UpdateEngineServiceClass* klass) {
  GObjectClass *object_class;
  object_class = G_OBJECT_CLASS(klass);
  object_class->finalize = update_engine_service_finalize;

  status_update_signal = g_signal_new(
      "status_update",
      G_OBJECT_CLASS_TYPE(klass),
      G_SIGNAL_RUN_LAST,
      0,  // 0 == no class method associated
      NULL,  // Accumulator
      NULL,  // Accumulator data
      update_engine_VOID__INT64_DOUBLE_STRING_STRING_INT64,
      G_TYPE_NONE,  // Return type
      5,  // param count:
      G_TYPE_INT64,
      G_TYPE_DOUBLE,
      G_TYPE_STRING,
      G_TYPE_STRING,
      G_TYPE_INT64);
}

static void update_engine_service_init(UpdateEngineService* object) {
}

UpdateEngineService* update_engine_service_new(void) {
  return reinterpret_cast<UpdateEngineService*>(
      g_object_new(UPDATE_ENGINE_TYPE_SERVICE, NULL));
}

gboolean update_engine_service_attempt_update(UpdateEngineService* self,
                                              gchar* app_version,
                                              gchar* omaha_url,
                                              GError **error) {
  string update_app_version;
  string update_omaha_url;
  // Only non-official (e.g., dev and test) builds can override the current
  // version and update server URL over D-Bus.
  if (!chromeos_update_engine::utils::IsOfficialBuild()) {
    if (app_version) {
      update_app_version = app_version;
    }
    if (omaha_url) {
      update_omaha_url = omaha_url;
    }
  }
  LOG(INFO) << "Attempt update: app_version=\"" << update_app_version << "\" "
            << "omaha_url=\"" << update_omaha_url << "\"";
  self->update_attempter_->CheckForUpdate(update_app_version, update_omaha_url);
  return TRUE;
}

gboolean update_engine_service_get_status(UpdateEngineService* self,
                                          int64_t* last_checked_time,
                                          double* progress,
                                          gchar** current_operation,
                                          gchar** new_version,
                                          int64_t* new_size,
                                          GError **error) {
  string current_op;
  string new_version_str;

  CHECK(self->update_attempter_->GetStatus(last_checked_time,
                                           progress,
                                           &current_op,
                                           &new_version_str,
                                           new_size));

  *current_operation = g_strdup(current_op.c_str());
  *new_version = g_strdup(new_version_str.c_str());
  if (!(*current_operation && *new_version)) {
    *error = NULL;
    return FALSE;
  }
  return TRUE;
}

gboolean update_engine_service_get_track(UpdateEngineService* self,
                                         gchar** track,
                                         GError **error) {
  string track_str =
      chromeos_update_engine::OmahaRequestDeviceParams::GetDeviceTrack();
  *track = g_strdup(track_str.c_str());
  return TRUE;
}

gboolean update_engine_service_reboot_if_needed(UpdateEngineService* self,
                                                GError **error) {
  if (!self->update_attempter_->RebootIfNeeded()) {
    *error = NULL;
    return FALSE;
  }
  return TRUE;
}

gboolean update_engine_service_set_track(UpdateEngineService* self,
                                         gchar* track,
                                         GError **error) {
  if (track) {
    LOG(INFO) << "Setting track to: " << track;
    if (!chromeos_update_engine::OmahaRequestDeviceParams::SetDeviceTrack(
            track)) {
      *error = NULL;
      return FALSE;
    }
  }
  return TRUE;
}

gboolean update_engine_service_emit_status_update(
    UpdateEngineService* self,
    gint64 last_checked_time,
    gdouble progress,
    const gchar* current_operation,
    const gchar* new_version,
    gint64 new_size) {
  g_signal_emit(self,
                status_update_signal,
                0,
                last_checked_time,
                progress,
                current_operation,
                new_version,
                new_size);
  return TRUE;
}
<commit_msg>If the Omaha URL is 'autest', point to the hardcoded test server.<commit_after>// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "update_engine/dbus_service.h"

#include <string>

#include <base/logging.h>

#include "update_engine/marshal.glibmarshal.h"
#include "update_engine/omaha_request_params.h"
#include "update_engine/utils.h"

using std::string;

static const char kAUTestURLRequest[] = "autest";
static const char kAUTestURL[] =
    "https://omaha.corp.google.com:8082/service/update2";

G_DEFINE_TYPE(UpdateEngineService, update_engine_service, G_TYPE_OBJECT)

static void update_engine_service_finalize(GObject* object) {
  G_OBJECT_CLASS(update_engine_service_parent_class)->finalize(object);
}

static guint status_update_signal = 0;

static void update_engine_service_class_init(UpdateEngineServiceClass* klass) {
  GObjectClass *object_class;
  object_class = G_OBJECT_CLASS(klass);
  object_class->finalize = update_engine_service_finalize;

  status_update_signal = g_signal_new(
      "status_update",
      G_OBJECT_CLASS_TYPE(klass),
      G_SIGNAL_RUN_LAST,
      0,  // 0 == no class method associated
      NULL,  // Accumulator
      NULL,  // Accumulator data
      update_engine_VOID__INT64_DOUBLE_STRING_STRING_INT64,
      G_TYPE_NONE,  // Return type
      5,  // param count:
      G_TYPE_INT64,
      G_TYPE_DOUBLE,
      G_TYPE_STRING,
      G_TYPE_STRING,
      G_TYPE_INT64);
}

static void update_engine_service_init(UpdateEngineService* object) {
}

UpdateEngineService* update_engine_service_new(void) {
  return reinterpret_cast<UpdateEngineService*>(
      g_object_new(UPDATE_ENGINE_TYPE_SERVICE, NULL));
}

gboolean update_engine_service_attempt_update(UpdateEngineService* self,
                                              gchar* app_version,
                                              gchar* omaha_url,
                                              GError **error) {
  string update_app_version;
  string update_omaha_url;
  // Only non-official (e.g., dev and test) builds can override the current
  // version and update server URL over D-Bus. However, pointing to the
  // hardcoded test update server URL is always allowed.
  if (!chromeos_update_engine::utils::IsOfficialBuild()) {
    if (app_version) {
      update_app_version = app_version;
    }
    if (omaha_url) {
      update_omaha_url = omaha_url;
    }
  }
  if (omaha_url && strcmp(omaha_url, kAUTestURLRequest) == 0) {
    update_omaha_url = kAUTestURL;
  }
  LOG(INFO) << "Attempt update: app_version=\"" << update_app_version << "\" "
            << "omaha_url=\"" << update_omaha_url << "\"";
  self->update_attempter_->CheckForUpdate(update_app_version, update_omaha_url);
  return TRUE;
}

gboolean update_engine_service_get_status(UpdateEngineService* self,
                                          int64_t* last_checked_time,
                                          double* progress,
                                          gchar** current_operation,
                                          gchar** new_version,
                                          int64_t* new_size,
                                          GError **error) {
  string current_op;
  string new_version_str;

  CHECK(self->update_attempter_->GetStatus(last_checked_time,
                                           progress,
                                           &current_op,
                                           &new_version_str,
                                           new_size));

  *current_operation = g_strdup(current_op.c_str());
  *new_version = g_strdup(new_version_str.c_str());
  if (!(*current_operation && *new_version)) {
    *error = NULL;
    return FALSE;
  }
  return TRUE;
}

gboolean update_engine_service_get_track(UpdateEngineService* self,
                                         gchar** track,
                                         GError **error) {
  string track_str =
      chromeos_update_engine::OmahaRequestDeviceParams::GetDeviceTrack();
  *track = g_strdup(track_str.c_str());
  return TRUE;
}

gboolean update_engine_service_reboot_if_needed(UpdateEngineService* self,
                                                GError **error) {
  if (!self->update_attempter_->RebootIfNeeded()) {
    *error = NULL;
    return FALSE;
  }
  return TRUE;
}

gboolean update_engine_service_set_track(UpdateEngineService* self,
                                         gchar* track,
                                         GError **error) {
  if (track) {
    LOG(INFO) << "Setting track to: " << track;
    if (!chromeos_update_engine::OmahaRequestDeviceParams::SetDeviceTrack(
            track)) {
      *error = NULL;
      return FALSE;
    }
  }
  return TRUE;
}

gboolean update_engine_service_emit_status_update(
    UpdateEngineService* self,
    gint64 last_checked_time,
    gdouble progress,
    const gchar* current_operation,
    const gchar* new_version,
    gint64 new_size) {
  g_signal_emit(self,
                status_update_signal,
                0,
                last_checked_time,
                progress,
                current_operation,
                new_version,
                new_size);
  return TRUE;
}
<|endoftext|>


<commit_before><commit_msg>Update OrbitLinuxTracing/TracerThread.cpp<commit_after><|endoftext|>


<commit_before>#include "omnicore/script.h"

#include "amount.h"
#include "script/script.h"
#include "script/standard.h"
#include "serialize.h"
#include "utilstrencodings.h"

#include <boost/foreach.hpp>

#include <string>
#include <utility>
#include <vector>

/** The minimum transaction relay fee. */
extern CFeeRate minRelayTxFee;

/**
 * Determines the minimum output amount to be spent by an output, based on the
 * scriptPubKey size in relation to the minimum relay fee.
 *
 * @param scriptPubKey[in]  The scriptPubKey
 * @return The dust threshold value
 */
int64_t GetDustThreshold(const CScript& scriptPubKey)
{
    CTxOut txOut(0, scriptPubKey);

    return txOut.GetDustThreshold(minRelayTxFee);
}

/**
 * Identifies standard output types based on a scriptPubKey.
 *
 * Note: whichTypeRet is set to TX_NONSTANDARD, if no standard script was found.
 *
 * @param scriptPubKey[in]   The script
 * @param whichTypeRet[out]  The output type
 * @return True if a standard script was found
 */
bool GetOutputType(const CScript& scriptPubKey, txnouttype& whichTypeRet)
{
    std::vector<std::vector<unsigned char> > vSolutions;

    if (SafeSolver(scriptPubKey, whichTypeRet, vSolutions)) {
        return true;
    }
    whichTypeRet = TX_NONSTANDARD;

    return false;
}

/**
 * Extracts the pushed data as hex-encoded string from a script.
 *
 * @param script[in]      The script
 * @param vstrRet[out]    The extracted pushed data as hex-encoded string
 * @param fSkipFirst[in]  Whether the first push operation should be skipped (default: false)
 * @return True if the extraction was successful (result can be empty)
 */
bool GetScriptPushes(const CScript& script, std::vector<std::string>& vstrRet, bool fSkipFirst)
{
    int count = 0;
    CScript::const_iterator pc = script.begin();

    while (pc < script.end()) {
        opcodetype opcode;
        std::vector<unsigned char> data;
        if (!script.GetOp(pc, opcode, data))
            return false;
        if (0x00 <= opcode && opcode <= OP_PUSHDATA4)
            if (count++ || !fSkipFirst) vstrRet.push_back(HexStr(data));
    }

    return true;
}

/**
 * Returns public keys or hashes from scriptPubKey, for standard transaction types.
 *
 * Note: in contrast to the script/standard/Solver, this Solver is not affected by
 * user settings, and in particular any OP_RETURN size is considered as standard.
 *
 * @param scriptPubKey[in]    The script
 * @param typeRet[out]        The output type
 * @param vSolutionsRet[out]  The extracted public keys or hashes
 * @return True if a standard script was found
 */
bool SafeSolver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet)
{
    // Templates
    static std::multimap<txnouttype, CScript> mTemplates;
    if (mTemplates.empty())
    {
        // Standard tx, sender provides pubkey, receiver adds signature
        mTemplates.insert(std::make_pair(TX_PUBKEY, CScript() << OP_PUBKEY << OP_CHECKSIG));

        // Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey
        mTemplates.insert(std::make_pair(TX_PUBKEYHASH, CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG));

        // Sender provides N pubkeys, receivers provides M signatures
        mTemplates.insert(std::make_pair(TX_MULTISIG, CScript() << OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIG));

        // Empty, provably prunable, data-carrying output
        mTemplates.insert(std::make_pair(TX_NULL_DATA, CScript() << OP_RETURN));
    }

    vSolutionsRet.clear();

    // Shortcut for pay-to-script-hash, which are more constrained than the other types:
    // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
    if (scriptPubKey.IsPayToScriptHash())
    {
        typeRet = TX_SCRIPTHASH;
        std::vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22);
        vSolutionsRet.push_back(hashBytes);
        return true;
    }

    // Provably prunable, data-carrying output
    //
    // So long as script passes the IsUnspendable() test and all but the first
    // byte passes the IsPushOnly() test we don't care what exactly is in the
    // script.
    if (scriptPubKey.size() >= 2 && scriptPubKey[0] == OP_RETURN)
    {
        CScript script(scriptPubKey.begin()+1, scriptPubKey.end());
        if (script.IsPushOnly()) {
            typeRet = TX_NULL_DATA;
            return true;
        }
    }

    // Scan templates
    const CScript& script1 = scriptPubKey;
    BOOST_FOREACH(const PAIRTYPE(txnouttype, CScript)& tplate, mTemplates)
    {
        const CScript& script2 = tplate.second;
        vSolutionsRet.clear();

        opcodetype opcode1, opcode2;
        std::vector<unsigned char> vch1, vch2;

        // Compare
        CScript::const_iterator pc1 = script1.begin();
        CScript::const_iterator pc2 = script2.begin();
        while (true)
        {
            if (pc1 == script1.end() && pc2 == script2.end())
            {
                // Found a match
                typeRet = tplate.first;
                if (typeRet == TX_MULTISIG)
                {
                    // Additional checks for TX_MULTISIG:
                    unsigned char m = vSolutionsRet.front()[0];
                    unsigned char n = vSolutionsRet.back()[0];
                    if (m < 1 || n < 1 || m > n || vSolutionsRet.size()-2 != n)
                        return false;
                }
                return true;
            }
            if (!script1.GetOp(pc1, opcode1, vch1))
                break;
            if (!script2.GetOp(pc2, opcode2, vch2))
                break;

            // Template matching opcodes:
            if (opcode2 == OP_PUBKEYS)
            {
                while (vch1.size() >= 33 && vch1.size() <= 65)
                {
                    vSolutionsRet.push_back(vch1);
                    if (!script1.GetOp(pc1, opcode1, vch1))
                        break;
                }
                if (!script2.GetOp(pc2, opcode2, vch2))
                    break;
                // Normal situation is to fall through
                // to other if/else statements
            }

            if (opcode2 == OP_PUBKEY)
            {
                if (vch1.size() < 33 || vch1.size() > 65)
                    break;
                vSolutionsRet.push_back(vch1);
            }
            else if (opcode2 == OP_PUBKEYHASH)
            {
                if (vch1.size() != sizeof(uint160))
                    break;
                vSolutionsRet.push_back(vch1);
            }
            else if (opcode2 == OP_SMALLINTEGER)
            {   // Single-byte small integer pushed onto vSolutions
                if (opcode1 == OP_0 ||
                    (opcode1 >= OP_1 && opcode1 <= OP_16))
                {
                    char n = (char)CScript::DecodeOP_N(opcode1);
                    vSolutionsRet.push_back(std::vector<unsigned char>(1, n));
                }
                else
                    break;
            }
            else if (opcode1 != opcode2 || vch1 != vch2)
            {
                // Others must match exactly
                break;
            }
        }
    }

    vSolutionsRet.clear();
    typeRet = TX_NONSTANDARD;
    return false;
}
<commit_msg>Add support for native SW to safe solver<commit_after>#include "omnicore/script.h"

#include "amount.h"
#include "script/script.h"
#include "script/standard.h"
#include "serialize.h"
#include "utilstrencodings.h"

#include <boost/foreach.hpp>

#include <string>
#include <utility>
#include <vector>

/** The minimum transaction relay fee. */
extern CFeeRate minRelayTxFee;

/**
 * Determines the minimum output amount to be spent by an output, based on the
 * scriptPubKey size in relation to the minimum relay fee.
 *
 * @param scriptPubKey[in]  The scriptPubKey
 * @return The dust threshold value
 */
int64_t GetDustThreshold(const CScript& scriptPubKey)
{
    CTxOut txOut(0, scriptPubKey);

    return txOut.GetDustThreshold(minRelayTxFee);
}

/**
 * Identifies standard output types based on a scriptPubKey.
 *
 * Note: whichTypeRet is set to TX_NONSTANDARD, if no standard script was found.
 *
 * @param scriptPubKey[in]   The script
 * @param whichTypeRet[out]  The output type
 * @return True if a standard script was found
 */
bool GetOutputType(const CScript& scriptPubKey, txnouttype& whichTypeRet)
{
    std::vector<std::vector<unsigned char> > vSolutions;

    if (SafeSolver(scriptPubKey, whichTypeRet, vSolutions)) {
        return true;
    }
    whichTypeRet = TX_NONSTANDARD;

    return false;
}

/**
 * Extracts the pushed data as hex-encoded string from a script.
 *
 * @param script[in]      The script
 * @param vstrRet[out]    The extracted pushed data as hex-encoded string
 * @param fSkipFirst[in]  Whether the first push operation should be skipped (default: false)
 * @return True if the extraction was successful (result can be empty)
 */
bool GetScriptPushes(const CScript& script, std::vector<std::string>& vstrRet, bool fSkipFirst)
{
    int count = 0;
    CScript::const_iterator pc = script.begin();

    while (pc < script.end()) {
        opcodetype opcode;
        std::vector<unsigned char> data;
        if (!script.GetOp(pc, opcode, data))
            return false;
        if (0x00 <= opcode && opcode <= OP_PUSHDATA4)
            if (count++ || !fSkipFirst) vstrRet.push_back(HexStr(data));
    }

    return true;
}

/**
 * Returns public keys or hashes from scriptPubKey, for standard transaction types.
 *
 * Note: in contrast to the script/standard/Solver, this Solver is not affected by
 * user settings, and in particular any OP_RETURN size is considered as standard.
 *
 * @param scriptPubKey[in]    The script
 * @param typeRet[out]        The output type
 * @param vSolutionsRet[out]  The extracted public keys or hashes
 * @return True if a standard script was found
 */
bool SafeSolver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet)
{
    // Templates
    static std::multimap<txnouttype, CScript> mTemplates;
    if (mTemplates.empty())
    {
        // Standard tx, sender provides pubkey, receiver adds signature
        mTemplates.insert(std::make_pair(TX_PUBKEY, CScript() << OP_PUBKEY << OP_CHECKSIG));

        // Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey
        mTemplates.insert(std::make_pair(TX_PUBKEYHASH, CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG));

        // Sender provides N pubkeys, receivers provides M signatures
        mTemplates.insert(std::make_pair(TX_MULTISIG, CScript() << OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIG));

        // Empty, provably prunable, data-carrying output
        mTemplates.insert(std::make_pair(TX_NULL_DATA, CScript() << OP_RETURN));
    }

    vSolutionsRet.clear();

    // Shortcut for pay-to-script-hash, which are more constrained than the other types:
    // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
    if (scriptPubKey.IsPayToScriptHash())
    {
        typeRet = TX_SCRIPTHASH;
        std::vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22);
        vSolutionsRet.push_back(hashBytes);
        return true;
    }

    int witnessversion;
    std::vector<unsigned char> witnessprogram;
    if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
        if (witnessversion == 0 && witnessprogram.size() == 20) {
            typeRet = TX_WITNESS_V0_KEYHASH;
            vSolutionsRet.push_back(witnessprogram);
            return true;
        }
        if (witnessversion == 0 && witnessprogram.size() == 32) {
            typeRet = TX_WITNESS_V0_SCRIPTHASH;
            vSolutionsRet.push_back(witnessprogram);
            return true;
        }
        return false;
    }

    // Provably prunable, data-carrying output
    //
    // So long as script passes the IsUnspendable() test and all but the first
    // byte passes the IsPushOnly() test we don't care what exactly is in the
    // script.
    if (scriptPubKey.size() >= 2 && scriptPubKey[0] == OP_RETURN)
    {
        CScript script(scriptPubKey.begin()+1, scriptPubKey.end());
        if (script.IsPushOnly()) {
            typeRet = TX_NULL_DATA;
            return true;
        }
    }

    // Scan templates
    const CScript& script1 = scriptPubKey;
    BOOST_FOREACH(const PAIRTYPE(txnouttype, CScript)& tplate, mTemplates)
    {
        const CScript& script2 = tplate.second;
        vSolutionsRet.clear();

        opcodetype opcode1, opcode2;
        std::vector<unsigned char> vch1, vch2;

        // Compare
        CScript::const_iterator pc1 = script1.begin();
        CScript::const_iterator pc2 = script2.begin();
        while (true)
        {
            if (pc1 == script1.end() && pc2 == script2.end())
            {
                // Found a match
                typeRet = tplate.first;
                if (typeRet == TX_MULTISIG)
                {
                    // Additional checks for TX_MULTISIG:
                    unsigned char m = vSolutionsRet.front()[0];
                    unsigned char n = vSolutionsRet.back()[0];
                    if (m < 1 || n < 1 || m > n || vSolutionsRet.size()-2 != n)
                        return false;
                }
                return true;
            }
            if (!script1.GetOp(pc1, opcode1, vch1))
                break;
            if (!script2.GetOp(pc2, opcode2, vch2))
                break;

            // Template matching opcodes:
            if (opcode2 == OP_PUBKEYS)
            {
                while (vch1.size() >= 33 && vch1.size() <= 65)
                {
                    vSolutionsRet.push_back(vch1);
                    if (!script1.GetOp(pc1, opcode1, vch1))
                        break;
                }
                if (!script2.GetOp(pc2, opcode2, vch2))
                    break;
                // Normal situation is to fall through
                // to other if/else statements
            }

            if (opcode2 == OP_PUBKEY)
            {
                if (vch1.size() < 33 || vch1.size() > 65)
                    break;
                vSolutionsRet.push_back(vch1);
            }
            else if (opcode2 == OP_PUBKEYHASH)
            {
                if (vch1.size() != sizeof(uint160))
                    break;
                vSolutionsRet.push_back(vch1);
            }
            else if (opcode2 == OP_SMALLINTEGER)
            {   // Single-byte small integer pushed onto vSolutions
                if (opcode1 == OP_0 ||
                    (opcode1 >= OP_1 && opcode1 <= OP_16))
                {
                    char n = (char)CScript::DecodeOP_N(opcode1);
                    vSolutionsRet.push_back(std::vector<unsigned char>(1, n));
                }
                else
                    break;
            }
            else if (opcode1 != opcode2 || vch1 != vch2)
            {
                // Others must match exactly
                break;
            }
        }
    }

    vSolutionsRet.clear();
    typeRet = TX_NONSTANDARD;
    return false;
}
<|endoftext|>


<commit_before>// Parse test application
// Based upon: parsetest.cpp from xmlpp

// needed includes
#include <fstream>
#include <iostream>
#include <ctime>
#include <cppdom/cppdom.h>

// namespace includes
using namespace cppdom;
using namespace std;

// dumps the node
void dump_node( XMLNode &node, int level = 0 )
{
   XMLString name = node.getName();
   XMLNodeType type = node.getType();
   XMLString c_data;

   for(int i=0;i<level;i++) cout << " ";

   char c = ' ';
   switch(type)
   {
   case xml_nt_node:
      c = '+';
      break;
   case xml_nt_leaf:
      c = '-';
      break;
   case xml_nt_document:
      c = '\\';
      break;
   case xml_nt_cdata:
      c = '#';
      c_data = node.getCdata();
      break;
   }

   if(type == xml_nt_cdata)
      cout << c << name.c_str() << "[" << c_data << "]" << endl;
   else
      cout << c << name.c_str() << endl;

   XMLAttributes attr = node.getAttrmap();

   // guru: added output of attributes
   for (XMLAttributes::iterator j = attr.begin(); j!=attr.end(); j++)
   {
      for (int i=0; i<level; i++)
         cout << " ";
      cout << "   ";
      cout << j->first << ": " << j->second << endl;
   }

   XMLNodeList& nlist = node.getChildren();

   XMLNodeList::const_iterator iter, stop;
   iter = nlist.begin();
   stop = nlist.end();

   while (iter != stop)
   {
      XMLNodePtr node = *iter;

      dump_node ( *node, level+1 );

      ++iter;
   }
};

void process_xml( std::string filename )
{
   cout << "processing [" << filename << "] ..." << endl;

   XMLContextPtr context( new XMLContext );
   XMLDocument node( context );
   ifstream istr( filename.c_str() );

   // Verify that file opened
   if(!istr)
   {
      std::cerr << "Bad file: " << filename << std::endl;
      return;
   }

   try
   {
      clock_t tstart = ::clock();

      node.load( istr, context );

      clock_t tstop = ::clock();
      cout << " needed " <<
         (tstop-tstart)/static_cast<float>(CLOCKS_PER_SEC)
         << " seconds." << endl;

      dump_node( node );

      ofstream ostr( "parsetest.xml" );
      node.save( ostr );
      ostr.close();

   }
   catch (xmlerror e)
   {
      XMLLocation where( context->get_location() );
      XMLString errmsg;
      e.getStrError(errmsg);

      // print out where the error occured
      cout << filename << ":" << where.getLine() << " ";
      cout << "at position " << where.getPos();
      cout << ": error: " << errmsg.c_str();
      cout << endl;

      // print out line where the error occured
      ifstream errfile( filename.c_str() );
      if(!errfile)
      {
         std::cerr << "Can't open file [" << filename << "] to output error" << std::endl;
      }

      int linenr = where.get_line();
      char linebuffer[1024];
      for(int i=0; i<linenr && !errfile.eof(); i++)
         errfile.getline(linebuffer,1024);

      int pos = where.get_pos();
      if (pos>=80)
         pos %= 80;

      std::string err_line( linebuffer + (where.get_pos()-pos) );
      if (err_line.length()>=79)
         err_line.erase(79);
      cout << err_line << std::flush;
      cout << err_line.c_str() << std::endl;
      cout << linebuffer << std::endl;
      for(int j=2;j<pos;j++)
         std::cout << " ";
      cout << '^' << endl;
   }
}

int main(int argc, char* argv[])
{
   for(int i=1;i<argc;i++)
   {
      process_xml( std::string(argv[i]) );
   }

   return 0;
}
<commit_msg>updated to current cppdom api changes<commit_after>// Parse test application
// Based upon: parsetest.cpp from xmlpp

// needed includes
#include <fstream>
#include <iostream>
#include <ctime>
#include <cppdom/cppdom.h>

// namespace includes
using namespace cppdom;
using namespace std;

// dumps the node
void dump_node( XMLNode &node, int level = 0 )
{
   XMLString name = node.getName();
   XMLNodeType type = node.getType();
   XMLString c_data;

   for(int i=0;i<level;i++) cout << " ";

   char c = ' ';
   switch(type)
   {
   case xml_nt_node:
      c = '+';
      break;
   case xml_nt_leaf:
      c = '-';
      break;
   case xml_nt_document:
      c = '\\';
      break;
   case xml_nt_cdata:
      c = '#';
      c_data = node.getCdata();
      break;
   }

   if(type == xml_nt_cdata)
      cout << c << name.c_str() << "[" << c_data << "]" << endl;
   else
      cout << c << name.c_str() << endl;

   XMLAttributes attr = node.getAttrMap();

   // guru: added output of attributes
   for (XMLAttributes::iterator j = attr.begin(); j!=attr.end(); j++)
   {
      for (int i=0; i<level; i++)
         cout << " ";
      cout << "   ";
      cout << j->first << ": " << j->second << endl;
   }

   XMLNodeList& nlist = node.getChildren();

   XMLNodeList::const_iterator iter, stop;
   iter = nlist.begin();
   stop = nlist.end();

   while (iter != stop)
   {
      XMLNodePtr node = *iter;

      dump_node ( *node, level+1 );

      ++iter;
   }
};

void process_xml( std::string filename )
{
   cout << "processing [" << filename << "] ..." << endl;

   XMLContextPtr context( new XMLContext );
   XMLDocument node( context );
   ifstream istr( filename.c_str() );

   // Verify that file opened
   if(!istr)
   {
      std::cerr << "Bad file: " << filename << std::endl;
      return;
   }

   try
   {
      clock_t tstart = ::clock();

      node.load( istr, context );

      clock_t tstop = ::clock();
      cout << " needed " <<
         (tstop-tstart)/static_cast<float>(CLOCKS_PER_SEC)
         << " seconds." << endl;

      dump_node( node );

      ofstream ostr( "parsetest.xml" );
      node.save( ostr );
      ostr.close();

   }
   catch (XMLError e)
   {
      XMLLocation where( context->getLocation() );
      XMLString errmsg;
      e.getStrError(errmsg);

      // print out where the error occured
      cout << filename << ":" << where.getLine() << " ";
      cout << "at position " << where.getPos();
      cout << ": error: " << errmsg.c_str();
      cout << endl;

      // print out line where the error occured
      ifstream errfile( filename.c_str() );
      if(!errfile)
      {
         std::cerr << "Can't open file [" << filename << "] to output error" << std::endl;
      }

      int linenr = where.getLine();
      char linebuffer[1024];
      for(int i=0; i<linenr && !errfile.eof(); i++)
         errfile.getline( linebuffer,1024 );

      int pos = where.getPos();
      if (pos>=80)
         pos %= 80;

      std::string err_line( linebuffer + (where.getPos()-pos) );
      if (err_line.length()>=79)
         err_line.erase(79);
      cout << err_line << std::flush;
      cout << err_line.c_str() << std::endl;
      cout << linebuffer << std::endl;
      for(int j=2;j<pos;j++)
         std::cout << " ";
      cout << '^' << endl;
   }
}

int main(int argc, char* argv[])
{
   for(int i=1;i<argc;i++)
   {
      process_xml( std::string(argv[i]) );
   }

   return 0;
}
<|endoftext|>


<commit_before>#include "../picojson.h"

int main(void)
{
  picojson::value v;

  // read json value from stream
  std::cin >> v;
  if (std::cin.fail()) {
    std::cerr << picojson::get_last_error() << std::endl;
    return 1;
  }

  // dump json object
  std::cout << "---- dump input ----" << std::endl;
  std::cout << v << std::endl;

  // accessors
  std::cout << "---- analyzing input ----" << std::endl;
  if (v.is<picojson::undefined>()) {
    std::cout << "input is undefined" << std::endl;
  } else if (v.is<picojson::null>()) {
    std::cout << "input is null" << std::endl;
  } else if (v.is<bool>()) {
    std::cout << "input is " << (v.get<bool>() ? "true" : "false") << std::endl;
  } else if (v.is<double>()) {
    std::cout << "input is " << v.get<double>() << std::endl;
  } else if (v.is<std::string>()) {
    std::cout << "input is " << v.get<std::string>() << std::endl;
  } else if (v.is<picojson::array>()) {
    std::cout << "input is an array" << std::endl;
    const picojson::array& a = v.get<picojson::array>();
    for (picojson::array::const_iterator i = a.begin(); i != a.end(); ++i) {
      std::cout << "  " << *i << std::endl;
    }
  } else if (v.is<picojson::object>()) {
    std::cout << "input is an object" << std::endl;
    const picojson::object& o = v.get<picojson::object>();
    for (picojson::object::const_iterator i = o.begin(); i != o.end(); ++i) {
      std::cout << i->first << "  " << i->second << std::endl;
    }
  }

  return 0;
}
<commit_msg>remove undefined.<commit_after>#include "../picojson.h"

int main(void)
{
  picojson::value v;

  // read json value from stream
  std::cin >> v;
  if (std::cin.fail()) {
    std::cerr << picojson::get_last_error() << std::endl;
    return 1;
  }

  // dump json object
  std::cout << "---- dump input ----" << std::endl;
  std::cout << v << std::endl;

  // accessors
  std::cout << "---- analyzing input ----" << std::endl;
  if (v.is<picojson::null>()) {
    std::cout << "input is null" << std::endl;
  } else if (v.is<bool>()) {
    std::cout << "input is " << (v.get<bool>() ? "true" : "false") << std::endl;
  } else if (v.is<double>()) {
    std::cout << "input is " << v.get<double>() << std::endl;
  } else if (v.is<std::string>()) {
    std::cout << "input is " << v.get<std::string>() << std::endl;
  } else if (v.is<picojson::array>()) {
    std::cout << "input is an array" << std::endl;
    const picojson::array& a = v.get<picojson::array>();
    for (picojson::array::const_iterator i = a.begin(); i != a.end(); ++i) {
      std::cout << "  " << *i << std::endl;
    }
  } else if (v.is<picojson::object>()) {
    std::cout << "input is an object" << std::endl;
    const picojson::object& o = v.get<picojson::object>();
    for (picojson::object::const_iterator i = o.begin(); i != o.end(); ++i) {
      std::cout << i->first << "  " << i->second << std::endl;
    }
  }

  return 0;
}
<|endoftext|>


<commit_before>void sim(Int_t nev=1) {
  AliSimulation simulator;
  simulator.SetMakeSDigits("TRD TOF PHOS HMPID EMCAL MUON FMD ZDC PMD T0 VZERO");
  simulator.SetMakeDigitsFromHits("ITS TPC");
  simulator.SetWriteRawData("ALL","raw.root",kTRUE);

  simulator.SetDefaultStorage("local://$ALICE_ROOT");
  simulator.SetSpecificStorage("GRP/GRP/Data",
			       Form("local://%s",gSystem->pwd()));
  simulator.SetRunQA("ALL:ALL") ;
  AliQA::SetQARefStorage("local://$ALICE_ROOT") ;

  for (Int_t det = 0 ; det < AliQA::kNDET ; det++) {
    simulator.SetQACycles(det, nev+1) ;
  }

  TStopwatch timer;
  timer.Start();
  simulator.Run(nev);
  timer.Stop();
  timer.Print();
}
<commit_msg>allow to set the number of events throub an env variable<commit_after>void sim(Int_t nev=1) {
  if (gSystem->Getenv("EVENT"))
   nev = atoi(gSystem->Getenv("EVENT")) ;
  AliSimulation simulator;
  simulator.SetMakeSDigits("TRD TOF PHOS HMPID EMCAL MUON FMD ZDC PMD T0 VZERO");
  simulator.SetMakeDigitsFromHits("ITS TPC");
  simulator.SetWriteRawData("ALL","raw.root",kTRUE);

  simulator.SetDefaultStorage("local://$ALICE_ROOT");
  simulator.SetSpecificStorage("GRP/GRP/Data",
			       Form("local://%s",gSystem->pwd()));
  simulator.SetRunQA("ALL:ALL") ;
  AliQA::SetQARefStorage("local://$ALICE_ROOT") ;

  for (Int_t det = 0 ; det < AliQA::kNDET ; det++) {
    simulator.SetQACycles(det, nev+1) ;
  }

  TStopwatch timer;
  timer.Start();
  simulator.Run(nev);
  timer.Stop();
  timer.Print();
}
<|endoftext|>


<commit_before>void sim(Int_t nev=1) {
  if (gSystem->Getenv("EVENT"))
   nev = atoi(gSystem->Getenv("EVENT")) ;

  AliSimulation simulator;
  simulator.SetMakeSDigits("TRD TOF PHOS HMPID EMCAL MUON FMD ZDC PMD T0 VZERO");
  simulator.SetMakeDigitsFromHits("ITS TPC");
  simulator.SetWriteRawData("ALL","raw.root",kTRUE);

  simulator.SetDefaultStorage("local://$ALICE_ROOT/OCDB");
  simulator.SetSpecificStorage("GRP/GRP/Data",
			       Form("local://%s",gSystem->pwd()));

  simulator.SetRunQA("ALL:ALL") ;

  simulator.SetQARefDefaultStorage("local://$ALICE_ROOT/QAref") ;

  for (Int_t det = 0 ; det < AliQA::kNDET ; det++) {
    simulator.SetQACycles(det, nev+1) ;
  }

  TStopwatch timer;
  timer.Start();
  simulator.Run(nev);
  timer.Stop();
  timer.Print();
}
<commit_msg>Revert commit 32313: back to 20 simulated events<commit_after>void sim(Int_t nev=20) {
  if (gSystem->Getenv("EVENT"))
   nev = atoi(gSystem->Getenv("EVENT")) ;

  AliSimulation simulator;
  simulator.SetMakeSDigits("TRD TOF PHOS HMPID EMCAL MUON FMD ZDC PMD T0 VZERO");
  simulator.SetMakeDigitsFromHits("ITS TPC");
  simulator.SetWriteRawData("ALL","raw.root",kTRUE);

  simulator.SetDefaultStorage("local://$ALICE_ROOT/OCDB");
  simulator.SetSpecificStorage("GRP/GRP/Data",
			       Form("local://%s",gSystem->pwd()));

  simulator.SetRunQA("ALL:ALL") ;

  simulator.SetQARefDefaultStorage("local://$ALICE_ROOT/QAref") ;

  for (Int_t det = 0 ; det < AliQA::kNDET ; det++) {
    simulator.SetQACycles(det, nev+1) ;
  }

  TStopwatch timer;
  timer.Start();
  simulator.Run(nev);
  timer.Stop();
  timer.Print();
}
<|endoftext|>