<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ocompinstream.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-10-13 11:49:01 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _INPUTCOMPSTREAM_HXX_
#define _INPUTCOMPSTREAM_HXX_

#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
#include <com/sun/star/io/XInputStream.hpp>
#endif

#ifndef _COM_SUN_STAR_IO_XSTREAM_HPP_
#include <com/sun/star/io/XStream.hpp>
#endif

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

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif

#ifndef _COM_SUN_STAR_EMBED_XEXTENDEDSTORAGESTREAM_HPP_
#include <com/sun/star/embed/XExtendedStorageStream.hpp>
#endif

#ifndef _COM_SUN_STAR_EMBED_XRELATIONSHIPACCESS_HPP_
#include <com/sun/star/embed/XRelationshipAccess.hpp>
#endif

#ifndef _CPPUHELPER_IMPLBASE4_HXX_
#include <cppuhelper/implbase4.hxx>
#endif

#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
#include <cppuhelper/interfacecontainer.h>
#endif

#include "mutexholder.hxx"

struct OWriteStream_Impl;

class OInputCompStream : public cppu::WeakImplHelper4 < ::com::sun::star::io::XInputStream
                                                        ,::com::sun::star::embed::XExtendedStorageStream
                                                        ,::com::sun::star::embed::XRelationshipAccess
                                                        ,::com::sun::star::beans::XPropertySet >
{
protected:
    OWriteStream_Impl* m_pImpl;

    SotMutexHolderRef m_rMutexRef;

    ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > m_xStream;

    ::cppu::OInterfaceContainerHelper* m_pInterfaceContainer;

    ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue > m_aProperties;

    sal_Bool m_bDisposed;

    sal_Int16 m_nStorageType;

    OInputCompStream( sal_Int16 nStorageType );
    OInputCompStream( OWriteStream_Impl& pImpl, sal_Int16 nStorageType );

public:
    OInputCompStream( OWriteStream_Impl& pImpl,
                      ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xStream,
                      const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps,
                      sal_Int16 nStorageType );

    OInputCompStream( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xStream,
                      const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps,
                      sal_Int16 nStorageType );

    virtual ~OInputCompStream();

    void InternalDispose();

    // XInterface
    virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& rType )
        throw( ::com::sun::star::uno::RuntimeException );

    // XInputStream
    virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual sal_Int32 SAL_CALL available(  )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL closeInput(  )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

    //XStream
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream(  ) throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL getOutputStream(  ) throw (::com::sun::star::uno::RuntimeException);

    //XComponent
    virtual void SAL_CALL dispose(  ) throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);

    //XRelationshipAccess
    virtual ::sal_Bool SAL_CALL hasByID( const ::rtl::OUString& sID ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::rtl::OUString SAL_CALL getTargetByID( const ::rtl::OUString& sID ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::rtl::OUString SAL_CALL getTypeByID( const ::rtl::OUString& sID ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > SAL_CALL getRelationshipByID( const ::rtl::OUString& sID ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > SAL_CALL getRelationshipsByType( const ::rtl::OUString& sType ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > SAL_CALL getAllRelationships(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL insertRelationshipByID( const ::rtl::OUString& sID, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair >& aEntry, ::sal_Bool bReplace ) throw (::com::sun::star::container::ElementExistException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeRelationshipByID( const ::rtl::OUString& sID ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL insertRelationships( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > >& aEntries, ::sal_Bool bReplace ) throw (::com::sun::star::container::ElementExistException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL clearRelationships(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

    //XPropertySet
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() throw ( ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
    virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );

};

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.5.54); FILE MERGED 2008/04/01 15:22:22 thb 1.5.54.3: #i85898# Stripping all external header guards 2008/04/01 12:32:12 thb 1.5.54.2: #i85898# Stripping all external header guards 2008/03/31 16:19:07 rt 1.5.54.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: ocompinstream.hxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _INPUTCOMPSTREAM_HXX_
#define _INPUTCOMPSTREAM_HXX_

#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XStream.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/embed/XExtendedStorageStream.hpp>
#include <com/sun/star/embed/XRelationshipAccess.hpp>
#include <cppuhelper/implbase4.hxx>
#include <cppuhelper/interfacecontainer.h>

#include "mutexholder.hxx"

struct OWriteStream_Impl;

class OInputCompStream : public cppu::WeakImplHelper4 < ::com::sun::star::io::XInputStream
                                                        ,::com::sun::star::embed::XExtendedStorageStream
                                                        ,::com::sun::star::embed::XRelationshipAccess
                                                        ,::com::sun::star::beans::XPropertySet >
{
protected:
    OWriteStream_Impl* m_pImpl;

    SotMutexHolderRef m_rMutexRef;

    ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > m_xStream;

    ::cppu::OInterfaceContainerHelper* m_pInterfaceContainer;

    ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue > m_aProperties;

    sal_Bool m_bDisposed;

    sal_Int16 m_nStorageType;

    OInputCompStream( sal_Int16 nStorageType );
    OInputCompStream( OWriteStream_Impl& pImpl, sal_Int16 nStorageType );

public:
    OInputCompStream( OWriteStream_Impl& pImpl,
                      ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xStream,
                      const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps,
                      sal_Int16 nStorageType );

    OInputCompStream( ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xStream,
                      const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps,
                      sal_Int16 nStorageType );

    virtual ~OInputCompStream();

    void InternalDispose();

    // XInterface
    virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& rType )
        throw( ::com::sun::star::uno::RuntimeException );

    // XInputStream
    virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual sal_Int32 SAL_CALL available(  )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL closeInput(  )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

    //XStream
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream(  ) throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL getOutputStream(  ) throw (::com::sun::star::uno::RuntimeException);

    //XComponent
    virtual void SAL_CALL dispose(  ) throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);

    //XRelationshipAccess
    virtual ::sal_Bool SAL_CALL hasByID( const ::rtl::OUString& sID ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::rtl::OUString SAL_CALL getTargetByID( const ::rtl::OUString& sID ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::rtl::OUString SAL_CALL getTypeByID( const ::rtl::OUString& sID ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > SAL_CALL getRelationshipByID( const ::rtl::OUString& sID ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > SAL_CALL getRelationshipsByType( const ::rtl::OUString& sType ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > > SAL_CALL getAllRelationships(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL insertRelationshipByID( const ::rtl::OUString& sID, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair >& aEntry, ::sal_Bool bReplace ) throw (::com::sun::star::container::ElementExistException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeRelationshipByID( const ::rtl::OUString& sID ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL insertRelationships( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > >& aEntries, ::sal_Bool bReplace ) throw (::com::sun::star::container::ElementExistException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL clearRelationships(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

    //XPropertySet
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() throw ( ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
    virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw ( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );

};

#endif

<|endoftext|>


<commit_before>//----------------------------------*-C++-*----------------------------------//
/*!
 * \file   mc/Domain_Transporter.t.hh
 * \author Thomas M. Evans
 * \date   Mon May 12 12:02:13 2014
 * \brief  Domain_Transporter template member definitions.
 * \note   Copyright (C) 2014 Oak Ridge National Laboratory, UT-Battelle, LLC.
 */
//---------------------------------------------------------------------------//

#ifndef mc_Domain_Transporter_t_hh
#define mc_Domain_Transporter_t_hh

#include <cmath>

#include "harness/DBC.hh"
#include "harness/Diagnostics.hh"
#include "geometry/Definitions.hh"
#include "Definitions.hh"
#include "Domain_Transporter.hh"

namespace profugus
{

//---------------------------------------------------------------------------//
// CONSTRUCTOR
//---------------------------------------------------------------------------//
/*!
 * \brief Constructor.
 */
template <class Geometry>
Domain_Transporter<Geometry>::Domain_Transporter()
    : d_sample_fission_sites(false)
    , d_keff(0.0)
{
}

//---------------------------------------------------------------------------//
// PUBLIC FUNCTIONS
//---------------------------------------------------------------------------//
/*!
 * \brief Set the geometry and physics classes.
 *
 * \param geometry
 * \param physics
 */
template <class Geometry>
void Domain_Transporter<Geometry>::set(SP_Geometry geometry,
                                       SP_Physics  physics)
{
    REQUIRE(geometry);
    REQUIRE(physics);

    d_geometry = geometry;
    d_physics  = physics;

    if (d_var_reduction)
    {
        d_var_reduction->set(d_geometry);
        d_var_reduction->set(d_physics);
    }
}

//---------------------------------------------------------------------------//
/*!
 * \brief Set the variance reduction.
 *
 * \param reduction
 */
template <class Geometry>
void Domain_Transporter<Geometry>::set(SP_Variance_Reduction reduction)
{
    REQUIRE(reduction);
    d_var_reduction = reduction;

    if (d_geometry)
        d_var_reduction->set(d_geometry);
    if (d_physics)
        d_var_reduction->set(d_physics);
}

//---------------------------------------------------------------------------//
/*!
 * \brief Set regular tallies.
 *
 * \param tallies
 */
template <class Geometry>
void Domain_Transporter<Geometry>::set(SP_Tallier tallies)
{
    REQUIRE(tallies);
    d_tallier = tallies;
    ENSURE(d_tallier);
}

//---------------------------------------------------------------------------//
/*!
 * \brief Set fission site sampling.
 *
 * \param fission_sites
 * \param keff
 */
template <class Geometry>
void Domain_Transporter<Geometry>::set(SP_Fission_Sites fission_sites,
                                       double           keff)
{
    // assign the container
    d_fission_sites = fission_sites;

    // initialize the sampling flag
    d_sample_fission_sites = false;

    // set the flag indicating whether fission sites should be sampled or not
    if (d_fission_sites)
    {
        d_sample_fission_sites = true;
    }

    // assign current iterate of keff
    d_keff = keff;

    // initialize the number of fission sites to 0
    d_num_fission_sites = 0;
}

//---------------------------------------------------------------------------//
/*!
 * \brief Transport a particle through the domain.
 *
 * \param particle
 * \param bank
 */
template <class Geometry>
void Domain_Transporter<Geometry>::transport(Particle_t &particle,
                                             Bank_t     &bank)
{
    REQUIRE(d_geometry);
    REQUIRE(d_physics);
    REQUIRE(d_var_reduction);
    REQUIRE(d_tallier);
    REQUIRE(particle.alive());
    REQUIRE(particle.rng().assigned());

    // particle state
    Geo_State_t &geo_state = particle.geo_state();

    // step particle through domain while particle is alive; life is relative
    // to the domain, so a particle leaving the domain would be no longer
    // alive wrt the current domain even though the particle might be alive to
    // another domain
    while (particle.alive())
    {
        // calculate distance to collision in mean-free-paths
        d_dist_mfp = -std::log(particle.rng().ran());

        // while we are hitting boundaries, continue to transport until we get
        // to the collision site
        particle.set_event(events::BOUNDARY);

        // process particles through internal boundaries until it hits a
        // collision site or leaves the domain
        //
        // >>>>>>> IMPORTANT <<<<<<<<
        // it is absolutely essential to check the geometry distance first,
        // before the distance to boundary mesh; this naturally takes care of
        // coincident boundary mesh and problem geometry surfaces (you may end
        // up with a small, negative distance to boundary mesh on the
        // subsequent step, but who cares)
        // >>>>>>>>>>>>-<<<<<<<<<<<<<
        while (particle.event() == events::BOUNDARY)
        {
            CHECK(particle.alive());
            CHECK(d_dist_mfp > 0.0);

            // total interaction cross section
            d_xs_tot = d_physics->total(physics::TOTAL, particle);
            CHECK(d_xs_tot >= 0.0);

            // sample distance to next collision
            if (d_xs_tot > 0.0)
                d_dist_col = d_dist_mfp / d_xs_tot;
            else
                d_dist_col = constants::huge;

            // initialize the distance to collision in the step selector
            d_step.initialize(d_dist_col, events::COLLISION);

            // calculate distance to next geometry boundary
            d_dist_bnd = d_geometry->distance_to_boundary(geo_state);
            d_step.submit(d_dist_bnd, events::BOUNDARY);

            // set the next event in the particle
            CHECK(d_step.tag() < events::END_EVENT);
            particle.set_event(static_cast<events::Event>(d_step.tag()));

            // path-length tallies (the actual movement of the particle will
            // take place when we process the various events)
            d_tallier->path_length(d_step.step(), particle);

            // update the mfp distance travelled
            d_dist_mfp -= d_step.step() * d_xs_tot;

            // process a particle through the geometric boundary
            if (particle.event() == events::BOUNDARY)
                process_boundary(particle, bank);
        }

        // we are done moving to a problem boundary, now process the
        // collision; the particle is actually moved from its current position
        // in each of these calls

        // process particle at a collision
        if (particle.event() == events::COLLISION)
            process_collision(particle, bank);

        // any future events go here ...
    }
}

//---------------------------------------------------------------------------//
// PRIVATE FUNCTIONS
//---------------------------------------------------------------------------//

template <class Geometry>
void Domain_Transporter<Geometry>::process_boundary(Particle_t &particle,
                                                    Bank_t     &bank)
{
    REQUIRE(particle.alive());
    REQUIRE(particle.event() == events::BOUNDARY);

    // return if not a boundary event

    // move a particle to the surface and process the event through the surface
    d_geometry->move_to_surface(particle.geo_state());

    // process surface tally events
    d_tallier->surface(particle);

    // get the in/out state of the particle
    int state = d_geometry->boundary_state(particle.geo_state());

    // reflected flag
    bool reflected = false;

    // process the boundary crossing based on the geometric state of the
    // particle
    switch (state)
    {
        case geometry::OUTSIDE:
            // the particle has left the problem geometry
            particle.set_event(events::ESCAPE);
            particle.kill();

            // add a escape diagnostic
            DIAGNOSTICS_TWO(integers["geo_escape"]++);

            ENSURE(particle.event() == events::ESCAPE);
            break;

        case geometry::REFLECT:
            // the particle has hit a reflecting surface
            reflected = d_geometry->reflect(particle.geo_state());
            CHECK(reflected);

            // add a reflecting face diagnostic
            DIAGNOSTICS_TWO(integers["geo_reflect"]++);

            ENSURE(particle.event() == events::BOUNDARY);
            break;

        case geometry::INSIDE:
            // otherwise the particle is at an internal geometry boundary;
            // update the material id of the region the particle has entered
            particle.set_matid(d_geometry->matid(particle.geo_state()));

            // add variance reduction at surface crossings
            d_var_reduction->post_surface(particle, bank);

            // add a boundary crossing diagnostic
            DIAGNOSTICS_TWO(integers["geo_surface"]++);

            ENSURE(particle.event() == events::BOUNDARY);
            break;

        default:
            CHECK(0);
    }
}

//---------------------------------------------------------------------------//

template <class Geometry>
void Domain_Transporter<Geometry>::process_collision(Particle_t &particle,
                                                     Bank_t     &bank)
{
    REQUIRE(d_var_reduction);
    REQUIRE(particle.event() == events::COLLISION);

    // move the particle to the collision site
    d_geometry->move_to_point(d_step.step(), particle.geo_state());

    // sample fission sites
    if (d_sample_fission_sites)
    {
        CHECK(d_fission_sites);
        CHECK(d_keff > 0.0);
        d_num_fission_sites += d_physics->sample_fission_site(
            particle, *d_fission_sites, d_keff);
    }

    // use the physics package to process the collision
    d_physics->collide(particle, bank);

    // apply weight windows
    d_var_reduction->post_collision(particle, bank);
}

} // end namespace profugus

#endif // mc_Domain_Transporter_t_hh

//---------------------------------------------------------------------------//
//                 end of Domain_Transporter.t.hh
//---------------------------------------------------------------------------//
<commit_msg>Changing surface tally to only register on non-reflecting boundaries.<commit_after>//----------------------------------*-C++-*----------------------------------//
/*!
 * \file   mc/Domain_Transporter.t.hh
 * \author Thomas M. Evans
 * \date   Mon May 12 12:02:13 2014
 * \brief  Domain_Transporter template member definitions.
 * \note   Copyright (C) 2014 Oak Ridge National Laboratory, UT-Battelle, LLC.
 */
//---------------------------------------------------------------------------//

#ifndef mc_Domain_Transporter_t_hh
#define mc_Domain_Transporter_t_hh

#include <cmath>

#include "harness/DBC.hh"
#include "harness/Diagnostics.hh"
#include "geometry/Definitions.hh"
#include "Definitions.hh"
#include "Domain_Transporter.hh"

namespace profugus
{

//---------------------------------------------------------------------------//
// CONSTRUCTOR
//---------------------------------------------------------------------------//
/*!
 * \brief Constructor.
 */
template <class Geometry>
Domain_Transporter<Geometry>::Domain_Transporter()
    : d_sample_fission_sites(false)
    , d_keff(0.0)
{
}

//---------------------------------------------------------------------------//
// PUBLIC FUNCTIONS
//---------------------------------------------------------------------------//
/*!
 * \brief Set the geometry and physics classes.
 *
 * \param geometry
 * \param physics
 */
template <class Geometry>
void Domain_Transporter<Geometry>::set(SP_Geometry geometry,
                                       SP_Physics  physics)
{
    REQUIRE(geometry);
    REQUIRE(physics);

    d_geometry = geometry;
    d_physics  = physics;

    if (d_var_reduction)
    {
        d_var_reduction->set(d_geometry);
        d_var_reduction->set(d_physics);
    }
}

//---------------------------------------------------------------------------//
/*!
 * \brief Set the variance reduction.
 *
 * \param reduction
 */
template <class Geometry>
void Domain_Transporter<Geometry>::set(SP_Variance_Reduction reduction)
{
    REQUIRE(reduction);
    d_var_reduction = reduction;

    if (d_geometry)
        d_var_reduction->set(d_geometry);
    if (d_physics)
        d_var_reduction->set(d_physics);
}

//---------------------------------------------------------------------------//
/*!
 * \brief Set regular tallies.
 *
 * \param tallies
 */
template <class Geometry>
void Domain_Transporter<Geometry>::set(SP_Tallier tallies)
{
    REQUIRE(tallies);
    d_tallier = tallies;
    ENSURE(d_tallier);
}

//---------------------------------------------------------------------------//
/*!
 * \brief Set fission site sampling.
 *
 * \param fission_sites
 * \param keff
 */
template <class Geometry>
void Domain_Transporter<Geometry>::set(SP_Fission_Sites fission_sites,
                                       double           keff)
{
    // assign the container
    d_fission_sites = fission_sites;

    // initialize the sampling flag
    d_sample_fission_sites = false;

    // set the flag indicating whether fission sites should be sampled or not
    if (d_fission_sites)
    {
        d_sample_fission_sites = true;
    }

    // assign current iterate of keff
    d_keff = keff;

    // initialize the number of fission sites to 0
    d_num_fission_sites = 0;
}

//---------------------------------------------------------------------------//
/*!
 * \brief Transport a particle through the domain.
 *
 * \param particle
 * \param bank
 */
template <class Geometry>
void Domain_Transporter<Geometry>::transport(Particle_t &particle,
                                             Bank_t     &bank)
{
    REQUIRE(d_geometry);
    REQUIRE(d_physics);
    REQUIRE(d_var_reduction);
    REQUIRE(d_tallier);
    REQUIRE(particle.alive());
    REQUIRE(particle.rng().assigned());

    // particle state
    Geo_State_t &geo_state = particle.geo_state();

    // step particle through domain while particle is alive; life is relative
    // to the domain, so a particle leaving the domain would be no longer
    // alive wrt the current domain even though the particle might be alive to
    // another domain
    while (particle.alive())
    {
        // calculate distance to collision in mean-free-paths
        d_dist_mfp = -std::log(particle.rng().ran());

        // while we are hitting boundaries, continue to transport until we get
        // to the collision site
        particle.set_event(events::BOUNDARY);

        // process particles through internal boundaries until it hits a
        // collision site or leaves the domain
        //
        // >>>>>>> IMPORTANT <<<<<<<<
        // it is absolutely essential to check the geometry distance first,
        // before the distance to boundary mesh; this naturally takes care of
        // coincident boundary mesh and problem geometry surfaces (you may end
        // up with a small, negative distance to boundary mesh on the
        // subsequent step, but who cares)
        // >>>>>>>>>>>>-<<<<<<<<<<<<<
        while (particle.event() == events::BOUNDARY)
        {
            CHECK(particle.alive());
            CHECK(d_dist_mfp > 0.0);

            // total interaction cross section
            d_xs_tot = d_physics->total(physics::TOTAL, particle);
            CHECK(d_xs_tot >= 0.0);

            // sample distance to next collision
            if (d_xs_tot > 0.0)
                d_dist_col = d_dist_mfp / d_xs_tot;
            else
                d_dist_col = constants::huge;

            // initialize the distance to collision in the step selector
            d_step.initialize(d_dist_col, events::COLLISION);

            // calculate distance to next geometry boundary
            d_dist_bnd = d_geometry->distance_to_boundary(geo_state);
            d_step.submit(d_dist_bnd, events::BOUNDARY);

            // set the next event in the particle
            CHECK(d_step.tag() < events::END_EVENT);
            particle.set_event(static_cast<events::Event>(d_step.tag()));

            // path-length tallies (the actual movement of the particle will
            // take place when we process the various events)
            d_tallier->path_length(d_step.step(), particle);

            // update the mfp distance travelled
            d_dist_mfp -= d_step.step() * d_xs_tot;

            // process a particle through the geometric boundary
            if (particle.event() == events::BOUNDARY)
                process_boundary(particle, bank);
        }

        // we are done moving to a problem boundary, now process the
        // collision; the particle is actually moved from its current position
        // in each of these calls

        // process particle at a collision
        if (particle.event() == events::COLLISION)
            process_collision(particle, bank);

        // any future events go here ...
    }
}

//---------------------------------------------------------------------------//
// PRIVATE FUNCTIONS
//---------------------------------------------------------------------------//

template <class Geometry>
void Domain_Transporter<Geometry>::process_boundary(Particle_t &particle,
                                                    Bank_t     &bank)
{
    REQUIRE(particle.alive());
    REQUIRE(particle.event() == events::BOUNDARY);

    // return if not a boundary event

    // move a particle to the surface and process the event through the surface
    d_geometry->move_to_surface(particle.geo_state());

    // get the in/out state of the particle
    int state = d_geometry->boundary_state(particle.geo_state());

    // process surface tally events on non-reflecting surfaces
    if (state != geometry::REFLECT)
        d_tallier->surface(particle);

    // reflected flag
    bool reflected = false;

    // process the boundary crossing based on the geometric state of the
    // particle
    switch (state)
    {
        case geometry::OUTSIDE:
            // the particle has left the problem geometry
            particle.set_event(events::ESCAPE);
            particle.kill();

            // add a escape diagnostic
            DIAGNOSTICS_TWO(integers["geo_escape"]++);

            ENSURE(particle.event() == events::ESCAPE);
            break;

        case geometry::REFLECT:
            // the particle has hit a reflecting surface
            reflected = d_geometry->reflect(particle.geo_state());
            CHECK(reflected);

            // add a reflecting face diagnostic
            DIAGNOSTICS_TWO(integers["geo_reflect"]++);

            ENSURE(particle.event() == events::BOUNDARY);
            break;

        case geometry::INSIDE:
            // otherwise the particle is at an internal geometry boundary;
            // update the material id of the region the particle has entered
            particle.set_matid(d_geometry->matid(particle.geo_state()));

            // add variance reduction at surface crossings
            d_var_reduction->post_surface(particle, bank);

            // add a boundary crossing diagnostic
            DIAGNOSTICS_TWO(integers["geo_surface"]++);

            ENSURE(particle.event() == events::BOUNDARY);
            break;

        default:
            CHECK(0);
    }
}

//---------------------------------------------------------------------------//

template <class Geometry>
void Domain_Transporter<Geometry>::process_collision(Particle_t &particle,
                                                     Bank_t     &bank)
{
    REQUIRE(d_var_reduction);
    REQUIRE(particle.event() == events::COLLISION);

    // move the particle to the collision site
    d_geometry->move_to_point(d_step.step(), particle.geo_state());

    // sample fission sites
    if (d_sample_fission_sites)
    {
        CHECK(d_fission_sites);
        CHECK(d_keff > 0.0);
        d_num_fission_sites += d_physics->sample_fission_site(
            particle, *d_fission_sites, d_keff);
    }

    // use the physics package to process the collision
    d_physics->collide(particle, bank);

    // apply weight windows
    d_var_reduction->post_collision(particle, bank);
}

} // end namespace profugus

#endif // mc_Domain_Transporter_t_hh

//---------------------------------------------------------------------------//
//                 end of Domain_Transporter.t.hh
//---------------------------------------------------------------------------//
<|endoftext|>


<commit_before>/*
* Copyright (C) 2015 deipi.com LLC and contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/

#include "query_dsl.h"

#include "database_utils.h"
#include "exception.h"
#include "multivalue/range.h"

#define RESERVED_TERM "_term"
#define RESERVED_BOOST "_boost"
#define RESERVED_RANGE "_range"
#define RESERVED_FROM "_from"
#define RESERVED_TO "_to"
#define RESERVED_EWKT "_ewkt"

static constexpr auto or_op = const_hash("_or");
static constexpr auto and_op = const_hash("_and");
static constexpr auto xor_op = const_hash("_xor");
static constexpr auto not_op = const_hash("_not");
static constexpr auto reserved_value = const_hash("_value");

static const std::unordered_map<std::string, FieldType> map_type({
	{ FLOAT_STR,       FieldType::FLOAT        }, { INTEGER_STR,     FieldType::INTEGER     },
	{ POSITIVE_STR,    FieldType::POSITIVE     }, { STRING_STR,      FieldType::STRING      },
	{ TEXT_STR,        FieldType::TEXT         }, { DATE_STR,        FieldType::DATE        },
	{ GEO_STR,         FieldType::GEO          }, { BOOLEAN_STR,     FieldType::BOOLEAN     },
	{ UUID_STR,        FieldType::UUID         }
});

/* A domain-specific language (DSL) for query */

QueryDSL::QueryDSL(std::shared_ptr<Schema> schema_) : schema(schema_)
{
	q_flags = Xapian::QueryParser::FLAG_DEFAULT | Xapian::QueryParser::FLAG_WILDCARD;
}

Xapian::Query
QueryDSL::get_query(const MsgPack& obj)
{
	if (obj.is_map() && obj.is_map() == 1) {
		for (auto const& elem : obj) {
			auto str_key = elem.as_string();
			switch (const_hash(lower_string(str_key).c_str())) {
				case or_op:
					return join_queries(obj.at(str_key), Xapian::Query::OP_OR);

				case and_op:
					return join_queries(obj.at(str_key), Xapian::Query::OP_AND);

				case xor_op:
					return join_queries(obj.at(str_key), Xapian::Query::OP_XOR);

				case not_op:
					return join_queries(obj.at(str_key), Xapian::Query::OP_AND_NOT);
				default: {
					auto const& o = obj.at(str_key);
					switch (o.getType()) {
						case MsgPack::Type::ARRAY:
							throw MSG_QueryDslError("Unexpected type %s in %s", MsgPackTypes[static_cast<int>(MsgPack::Type::ARRAY)], str_key.c_str());
						case MsgPack::Type::MAP:
							return process_query(o, str_key);
							break;
						default: {
							return build_query(o, str_key);
						}
					}

				}
			}
		}
	} else {
		throw MSG_QueryDslError("Type error expected map of size one at root level in query dsl");
	}
	return Xapian::Query();
}

Xapian::Query
QueryDSL::build_query(const MsgPack& o, const std::string& field_name,  bool as_term, Xapian::termcount wqf, const std::string& type) {

	auto field_spc = schema->get_data_field(field_name);
	std::string type_s;
	try {
		auto _type = type.empty() ? field_spc.get_type() : map_type.at(type);
		switch (_type) {
			case FieldType::FLOAT:
				type_s = FLOAT_STR;
				if (o.getType() == MsgPack::Type::STR) {
					return Xapian::Query(prefixed(Serialise::_float(o.as_string()), field_spc.prefix), wqf);
				} else {
					return Xapian::Query(prefixed(Serialise::_float(o.as_f64()), field_spc.prefix), wqf);
				}
			case FieldType::INTEGER:
				type_s = INTEGER_STR;
				if (o.getType() == MsgPack::Type::STR) {
					return Xapian::Query(prefixed(Serialise::integer(o.as_string()), field_spc.prefix), wqf);
				} else {
					return Xapian::Query(prefixed(Serialise::integer(o.as_i64()), field_spc.prefix));
				}
			case FieldType::POSITIVE:
				type_s = POSITIVE_STR;
				if (o.getType() == MsgPack::Type::STR) {
					return Xapian::Query(prefixed(Serialise::integer(o.as_string()), field_spc.prefix), wqf);
				} else {
					return Xapian::Query(prefixed(Serialise::integer(o.as_u64()), field_spc.prefix), wqf);
				}
			case FieldType::STRING:
			{
				type_s = STRING_STR;
				auto field_value = o.as_string();
				if (as_term) {
					return Xapian::Query(prefixed(field_spc.bool_term ? field_value : lower_string(field_value), field_spc.prefix), wqf);
				} else {
					Xapian::QueryParser queryString;
					field_spc.bool_term ? queryString.add_boolean_prefix(field_name, field_spc.prefix) : queryString.add_prefix(field_name, field_spc.prefix);
					queryString.set_stemming_strategy(getQueryParserStrategy(field_spc.stem_strategy));
					queryString.set_stemmer(Xapian::Stem(field_spc.stem_language));
					std::string str_string;
					str_string.reserve(field_name.length() + field_value.length() + 1);
					str_string.assign(field_name).append(":").append(field_value);
					return queryString.parse_query(str_string, q_flags);

				}
			}
			case FieldType::TEXT:
			{
				type_s = TEXT_STR;
				auto field_value = o.as_string();
				Xapian::QueryParser queryTexts;
				field_spc.bool_term ? queryTexts.add_boolean_prefix(field_name, field_spc.prefix) : queryTexts.add_prefix(field_name, field_spc.prefix);
				queryTexts.set_stemming_strategy(getQueryParserStrategy(field_spc.stem_strategy));
				queryTexts.set_stemmer(Xapian::Stem(field_spc.stem_language));
				std::string str_texts;
				str_texts.reserve(field_value.length() + field_value.length() + 1);
				str_texts.assign(field_value).append(":").append(field_value);
				return queryTexts.parse_query(str_texts, q_flags);
			}
			case FieldType::DATE:
				type_s = DATE_STR;
				return Xapian::Query(prefixed(Serialise::date(o.as_string()), field_spc.prefix));
			case FieldType::GEO:
			{
				type_s = GEO_STR;
				std::string field_value(Serialise::ewkt(o.as_string(), field_spc.partials, field_spc.error));
				// If the region for search is empty, not process this query.
				if (field_value.empty()) {
					return Xapian::Query::MatchNothing;
				}
				return Xapian::Query(prefixed(field_value, field_spc.prefix), wqf);
			}
			case FieldType::UUID:
				type_s = UUID_STR;
				return Xapian::Query(prefixed(Serialise::uuid(o.as_string()), field_spc.prefix), wqf);
			case FieldType::BOOLEAN:
				type_s = BOOLEAN_STR;
				if (o.getType() == MsgPack::Type::STR) {
					return Xapian::Query(prefixed(Serialise::boolean(o.as_string()), field_spc.prefix), wqf);
				} else {
					return Xapian::Query(prefixed(Serialise::boolean(o.as_bool()), field_spc.prefix), wqf);
				}
			default:
				throw MSG_QueryDslError("Type error unexpected %s i", type.c_str());
		}
	} catch (const msgpack::type_error&) {
		throw MSG_QueryDslError("Type error expected %s in %s", type_s.c_str(), field_name.c_str());
	}
	return Xapian::Query();
}

Xapian::Query
QueryDSL::join_queries(const MsgPack& sub_obj, Xapian::Query::op op)
{
	Xapian::Query final_query;
	if (op == Xapian::Query::OP_AND_NOT) {
		final_query = Xapian::Query::MatchAll;
	}
	if (sub_obj.is_array()) {
		for (const auto& elem : sub_obj) {
			if (elem.is_map() && elem.size() == 1) {
				for (const auto& field : elem) {
					auto str_ob = field.as_string();
					switch (const_hash(lower_string(str_ob).c_str())) {
						case or_op:
						{
							const auto& o = elem.at(str_ob);
							final_query.empty() ? final_query = join_queries(o, Xapian::Query::OP_OR) : final_query = Xapian::Query(op, final_query, join_queries(o, Xapian::Query::OP_OR));
						}
						break;

						case and_op:
						{
							const auto& o = elem.at(str_ob);
							final_query.empty() ? final_query = join_queries(o, Xapian::Query::OP_AND) : final_query = Xapian::Query(op, final_query, join_queries(o, Xapian::Query::OP_AND));
						}
						break;

						case xor_op:
						{
							const auto& o = elem.at(str_ob);
							final_query.empty() ? final_query = join_queries(o, Xapian::Query::OP_XOR) : final_query = Xapian::Query(op, final_query, join_queries(o, Xapian::Query::OP_XOR));
						}
						break;

						case not_op:
						{
							const auto& o = elem.at(str_ob);
							final_query.empty() ? final_query = join_queries(o, Xapian::Query::OP_AND_NOT) :  final_query = Xapian::Query(op, final_query, join_queries(o, Xapian::Query::OP_AND_NOT));
						}
						break;

						case reserved_value:
							//Empty field name
							break;

						default:
							if (!startswith(str_ob, "_")) {
								const auto& o = elem.at(str_ob);
								switch (o.getType()) {
									case MsgPack::Type::ARRAY:
										throw MSG_QueryDslError("Unexpected type array in %s", str_ob.c_str());

									case MsgPack::Type::MAP:
										final_query.empty() ? final_query = process_query(o, str_ob) : final_query = Xapian::Query(op, final_query, process_query(o, str_ob));
									break;

									default:
										final_query.empty() ? final_query = build_query(o, str_ob) : final_query = Xapian::Query(op, final_query, build_query(o, str_ob));
								}
							} else {
								throw MSG_QueryDslError("Unexpected reserved word %s", str_ob.c_str());
							}
					}
				}

			} else {
				throw MSG_QueryDslError("Expected array of objects with one element");
			}
		}

	} else {
		throw MSG_QueryDslError("Type error expected map in boolean operator");
	}
	return final_query;
}

Xapian::Query
QueryDSL::process_query(const MsgPack& obj, const std::string& field_name) {

	uint64_t boost = 1;	/* Default value in xapian */
	bool term = false;

	if (obj.is_map() && obj.find(RESERVED_RANGE) != obj.end()) {
		const MsgPack* to;
		const MsgPack* from;
		const MsgPack& o = obj.at(RESERVED_RANGE);
		try {
			to = &o.at(RESERVED_TO);
		} catch (const std::out_of_range&) { }

		try {
			from = &o.at(RESERVED_FROM);
		} catch (const std::out_of_range&) { }

		if (to || from) {
			return MultipleValueRange::getQuery(schema->get_data_field(field_name), field_name, from, to);
		} else {
			throw MSG_QueryDslError("Expected %s and/or %s in %s", RESERVED_FROM, RESERVED_TO, RESERVED_RANGE);
		}
	} else {
		try {
			/* Get _boost if exist */
			auto const& o_boost = obj.at(RESERVED_BOOST);
			if (o_boost.is_number() && o_boost.getType() != MsgPack::Type::NEGATIVE_INTEGER) {
				boost = o_boost.as_u64();
			} else {
				throw MSG_QueryDslError("Type error expected unsigned int in %s", RESERVED_BOOST);
			}
		} catch (const std::out_of_range&) { }

		try {
			auto const& val = obj.at(RESERVED_VALUE);
			return build_query(val, field_name, term, boost);
		} catch (const std::out_of_range&) {
			try {
				std::string type;
				auto const& val = obj.at(RESERVED_TERM);
				term = true;
				try {
					/* Get _type if exist */
					auto const& o_type = obj.at(RESERVED_TYPE);
					if (o_type.getType() == MsgPack::Type::STR) {
						type = o_type.as_string();
					} else {
						throw MSG_QueryDslError("Type error expected string in %s", RESERVED_TYPE);
					}
				} catch (const std::out_of_range&) { }
				return build_query(val, field_name, term, boost, type);
			} catch (const std::out_of_range&) {
				throw MSG_QueryDslError("Expected %s or %s in object", RESERVED_VALUE, RESERVED_TERM);
			}
		}
	}
	return Xapian::Query();
}
<commit_msg>Format<commit_after>/*
* Copyright (C) 2015 deipi.com LLC and contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/

#include "query_dsl.h"

#include "database_utils.h"
#include "exception.h"
#include "multivalue/range.h"

#define RESERVED_TERM "_term"
#define RESERVED_BOOST "_boost"
#define RESERVED_RANGE "_range"
#define RESERVED_FROM "_from"
#define RESERVED_TO "_to"
#define RESERVED_EWKT "_ewkt"

static constexpr auto or_op = const_hash("_or");
static constexpr auto and_op = const_hash("_and");
static constexpr auto xor_op = const_hash("_xor");
static constexpr auto not_op = const_hash("_not");
static constexpr auto reserved_value = const_hash("_value");

static const std::unordered_map<std::string, FieldType> map_type({
	{ FLOAT_STR,       FieldType::FLOAT        }, { INTEGER_STR,     FieldType::INTEGER     },
	{ POSITIVE_STR,    FieldType::POSITIVE     }, { STRING_STR,      FieldType::STRING      },
	{ TEXT_STR,        FieldType::TEXT         }, { DATE_STR,        FieldType::DATE        },
	{ GEO_STR,         FieldType::GEO          }, { BOOLEAN_STR,     FieldType::BOOLEAN     },
	{ UUID_STR,        FieldType::UUID         }
});

/* A domain-specific language (DSL) for query */

QueryDSL::QueryDSL(std::shared_ptr<Schema> schema_) : schema(schema_)
{
	q_flags = Xapian::QueryParser::FLAG_DEFAULT | Xapian::QueryParser::FLAG_WILDCARD;
}

Xapian::Query
QueryDSL::get_query(const MsgPack& obj)
{
	if (obj.is_map() && obj.is_map() == 1) {
		for (auto const& elem : obj) {
			auto str_key = elem.as_string();
			switch (const_hash(lower_string(str_key).c_str())) {
				case or_op:
					return join_queries(obj.at(str_key), Xapian::Query::OP_OR);

				case and_op:
					return join_queries(obj.at(str_key), Xapian::Query::OP_AND);

				case xor_op:
					return join_queries(obj.at(str_key), Xapian::Query::OP_XOR);

				case not_op:
					return join_queries(obj.at(str_key), Xapian::Query::OP_AND_NOT);
				default: {
					auto const& o = obj.at(str_key);
					switch (o.getType()) {
						case MsgPack::Type::ARRAY:
							throw MSG_QueryDslError("Unexpected type %s in %s", MsgPackTypes[static_cast<int>(MsgPack::Type::ARRAY)], str_key.c_str());
						case MsgPack::Type::MAP:
							return process_query(o, str_key);
							break;
						default: {
							return build_query(o, str_key);
						}
					}

				}
			}
		}
	} else {
		throw MSG_QueryDslError("Type error expected map of size one at root level in query dsl");
	}
	return Xapian::Query();
}

Xapian::Query
QueryDSL::build_query(const MsgPack& o, const std::string& field_name,  bool as_term, Xapian::termcount wqf, const std::string& type) {

	auto field_spc = schema->get_data_field(field_name);
	std::string type_s;
	try {
		auto _type = type.empty() ? field_spc.get_type() : map_type.at(type);
		switch (_type) {
			case FieldType::FLOAT:
				type_s = FLOAT_STR;
				if (o.getType() == MsgPack::Type::STR) {
					return Xapian::Query(prefixed(Serialise::_float(o.as_string()), field_spc.prefix), wqf);
				} else {
					return Xapian::Query(prefixed(Serialise::_float(o.as_f64()), field_spc.prefix), wqf);
				}
			case FieldType::INTEGER:
				type_s = INTEGER_STR;
				if (o.getType() == MsgPack::Type::STR) {
					return Xapian::Query(prefixed(Serialise::integer(o.as_string()), field_spc.prefix), wqf);
				} else {
					return Xapian::Query(prefixed(Serialise::integer(o.as_i64()), field_spc.prefix));
				}
			case FieldType::POSITIVE:
				type_s = POSITIVE_STR;
				if (o.getType() == MsgPack::Type::STR) {
					return Xapian::Query(prefixed(Serialise::integer(o.as_string()), field_spc.prefix), wqf);
				} else {
					return Xapian::Query(prefixed(Serialise::integer(o.as_u64()), field_spc.prefix), wqf);
				}
			case FieldType::STRING:
			{
				type_s = STRING_STR;
				auto field_value = o.as_string();
				if (as_term) {
					return Xapian::Query(prefixed(field_spc.bool_term ? field_value : lower_string(field_value), field_spc.prefix), wqf);
				} else {
					Xapian::QueryParser queryString;
					field_spc.bool_term ? queryString.add_boolean_prefix(field_name, field_spc.prefix) : queryString.add_prefix(field_name, field_spc.prefix);
					queryString.set_stemming_strategy(getQueryParserStrategy(field_spc.stem_strategy));
					queryString.set_stemmer(Xapian::Stem(field_spc.stem_language));
					std::string str_string;
					str_string.reserve(field_name.length() + field_value.length() + 1);
					str_string.assign(field_name).append(":").append(field_value);
					return queryString.parse_query(str_string, q_flags);

				}
			}
			case FieldType::TEXT:
			{
				type_s = TEXT_STR;
				auto field_value = o.as_string();
				Xapian::QueryParser queryTexts;
				field_spc.bool_term ? queryTexts.add_boolean_prefix(field_name, field_spc.prefix) : queryTexts.add_prefix(field_name, field_spc.prefix);
				queryTexts.set_stemming_strategy(getQueryParserStrategy(field_spc.stem_strategy));
				queryTexts.set_stemmer(Xapian::Stem(field_spc.stem_language));
				std::string str_texts;
				str_texts.reserve(field_value.length() + field_value.length() + 1);
				str_texts.assign(field_value).append(":").append(field_value);
				return queryTexts.parse_query(str_texts, q_flags);
			}
			case FieldType::DATE:
				type_s = DATE_STR;
				return Xapian::Query(prefixed(Serialise::date(o.as_string()), field_spc.prefix));
			case FieldType::GEO:
			{
				type_s = GEO_STR;
				std::string field_value(Serialise::ewkt(o.as_string(), field_spc.partials, field_spc.error));
				// If the region for search is empty, not process this query.
				if (field_value.empty()) {
					return Xapian::Query::MatchNothing;
				}
				return Xapian::Query(prefixed(field_value, field_spc.prefix), wqf);
			}
			case FieldType::UUID:
				type_s = UUID_STR;
				return Xapian::Query(prefixed(Serialise::uuid(o.as_string()), field_spc.prefix), wqf);
			case FieldType::BOOLEAN:
				type_s = BOOLEAN_STR;
				if (o.getType() == MsgPack::Type::STR) {
					return Xapian::Query(prefixed(Serialise::boolean(o.as_string()), field_spc.prefix), wqf);
				} else {
					return Xapian::Query(prefixed(Serialise::boolean(o.as_bool()), field_spc.prefix), wqf);
				}
			default:
				throw MSG_QueryDslError("Type error unexpected %s i", type.c_str());
		}
	} catch (const msgpack::type_error&) {
		throw MSG_QueryDslError("Type error expected %s in %s", type_s.c_str(), field_name.c_str());
	}
	return Xapian::Query();
}

Xapian::Query
QueryDSL::join_queries(const MsgPack& sub_obj, Xapian::Query::op op)
{
	Xapian::Query final_query;
	if (op == Xapian::Query::OP_AND_NOT) {
		final_query = Xapian::Query::MatchAll;
	}
	if (sub_obj.is_array()) {
		for (const auto& elem : sub_obj) {
			if (elem.is_map() && elem.size() == 1) {
				for (const auto& field : elem) {
					auto str_ob = field.as_string();
					switch (const_hash(lower_string(str_ob).c_str())) {
						case or_op:
						{
							const auto& o = elem.at(str_ob);
							final_query.empty() ? final_query = join_queries(o, Xapian::Query::OP_OR) : final_query = Xapian::Query(op, final_query, join_queries(o, Xapian::Query::OP_OR));
						}
						break;

						case and_op:
						{
							const auto& o = elem.at(str_ob);
							final_query.empty() ? final_query = join_queries(o, Xapian::Query::OP_AND) : final_query = Xapian::Query(op, final_query, join_queries(o, Xapian::Query::OP_AND));
						}
						break;

						case xor_op:
						{
							const auto& o = elem.at(str_ob);
							final_query.empty() ? final_query = join_queries(o, Xapian::Query::OP_XOR) : final_query = Xapian::Query(op, final_query, join_queries(o, Xapian::Query::OP_XOR));
						}
						break;

						case not_op:
						{
							const auto& o = elem.at(str_ob);
							final_query.empty() ? final_query = join_queries(o, Xapian::Query::OP_AND_NOT) :  final_query = Xapian::Query(op, final_query, join_queries(o, Xapian::Query::OP_AND_NOT));
						}
						break;

						case reserved_value:
							//Empty field name
							break;

						default:
							if (!startswith(str_ob, "_")) {
								const auto& o = elem.at(str_ob);
								switch (o.getType()) {
									case MsgPack::Type::ARRAY:
										throw MSG_QueryDslError("Unexpected type array in %s", str_ob.c_str());

									case MsgPack::Type::MAP:
										final_query.empty() ? final_query = process_query(o, str_ob) : final_query = Xapian::Query(op, final_query, process_query(o, str_ob));
									break;

									default:
										final_query.empty() ? final_query = build_query(o, str_ob) : final_query = Xapian::Query(op, final_query, build_query(o, str_ob));
								}
							} else {
								throw MSG_QueryDslError("Unexpected reserved word %s", str_ob.c_str());
							}
					}
				}

			} else {
				throw MSG_QueryDslError("Expected array of objects with one element");
			}
		}

	} else {
		throw MSG_QueryDslError("Type error expected map in boolean operator");
	}
	return final_query;
}

Xapian::Query
QueryDSL::process_query(const MsgPack& obj, const std::string& field_name) {

	uint64_t boost = 1;	/* Default value in xapian */
	bool term = false;

	if (obj.is_map() && obj.find(RESERVED_RANGE) != obj.end()) {
		const MsgPack* to;
		const MsgPack* from;
		const MsgPack& o = obj.at(RESERVED_RANGE);
		try {
			to = &o.at(RESERVED_TO);
		} catch (const std::out_of_range&) { }

		try {
			from = &o.at(RESERVED_FROM);
		} catch (const std::out_of_range&) { }

		if (to || from) {
			return MultipleValueRange::getQuery(schema->get_data_field(field_name), field_name, from, to);
		} else {
			throw MSG_QueryDslError("Expected %s and/or %s in %s", RESERVED_FROM, RESERVED_TO, RESERVED_RANGE);
		}
	} else {
		try {
			/* Get _boost if exist */
			auto const& o_boost = obj.at(RESERVED_BOOST);
			if (o_boost.is_number() && o_boost.getType() != MsgPack::Type::NEGATIVE_INTEGER) {
				boost = o_boost.as_u64();
			} else {
				throw MSG_QueryDslError("Type error expected unsigned int in %s", RESERVED_BOOST);
			}
		} catch (const std::out_of_range&) { }

		try {
			auto const& val = obj.at(RESERVED_VALUE);
			return build_query(val, field_name, term, boost);
		} catch (const std::out_of_range&) {
			try {
				std::string type;
				auto const& val = obj.at(RESERVED_TERM);
				term = true;
				try {
					/* Get _type if exist */
					auto const& o_type = obj.at(RESERVED_TYPE);
					if (o_type.getType() == MsgPack::Type::STR) {
						type = o_type.as_string();
					} else {
						throw MSG_QueryDslError("Type error expected string in %s", RESERVED_TYPE);
					}
				} catch (const std::out_of_range&) { }
				return build_query(val, field_name, term, boost, type);
			} catch (const std::out_of_range&) {
				throw MSG_QueryDslError("Expected %s or %s in object", RESERVED_VALUE, RESERVED_TERM);
			}
		}
	}
	return Xapian::Query();
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <string>
#include <vector>
#include <limits>
#include <Halide.h>

using namespace Halide;

std::vector<std::string> messages;

extern "C" void halide_print(void *user_context, const char *message) {
    //printf("%s", message);
    messages.push_back(message);
}

#ifdef _MSC_VER
#define snprintf _snprintf
#endif

int main(int argc, char **argv) {
    Var x;

    {
        Func f;

        f(x) = print(x * x, "the answer is", 42.0f, "unsigned", cast<uint32_t>(145));
        f.set_custom_print(halide_print);
        Image<int32_t> result = f.realize(10);

        for (int32_t i = 0; i < 10; i++) {
            if (result(i) != i * i) {
                return -1;
            }
        }

        assert(messages.size() == 10);
        for (size_t i = 0; i < messages.size(); i++) {
            long long square;
            float forty_two;
            unsigned long long one_forty_five;

            int scan_count = sscanf(messages[i].c_str(), "%lld the answer is %f unsigned %llu",
                                    &square, &forty_two, &one_forty_five);
            assert(scan_count == 3);
            assert(square == i * i);
            assert(forty_two == 42.0f);
            assert(one_forty_five == 145);
        }
    }

    messages.clear();

    {
        Func f;

        Param<void *> random_handle;
        random_handle.set((void *)127);

        // Test a string containing a printf format specifier (It should print it as-is).
        f(x) = print_when(x == 3, x * x, "g", 42.0f, "%s", random_handle);
        f.set_custom_print(halide_print);
        Image<int32_t> result = f.realize(10);

        for (int32_t i = 0; i < 10; i++) {
            if (result(i) != i * i) {
                return -1;
            }
        }

        assert(messages.size() == 1);
        long long nine;
        float forty_two;
        void *ptr;

        int scan_count = sscanf(messages[0].c_str(), "%lld g %f %%s %p",
                                &nine, &forty_two, &ptr);
        assert(scan_count == 3);
        assert(nine == 9);
        assert(forty_two == 42.0f);
        assert(ptr == (void *)127);

    }

    messages.clear();

    {
        Func f;

        // Test a single message longer than 8K.
        std::vector<Expr> args;
        for (int i = 0; i < 500; i++) {
            Expr e = cast<uint64_t>(i);
            e *= e;
            e *= e;
            e *= e;
            e *= e;
            args.push_back(e + 100);
            e = cast<double>(e);
            e *= e;
            e *= e;
            args.push_back(e);
        }
        f(x) = print(args);
        f.set_custom_print(halide_print);
        Image<uint64_t> result = f.realize(1);

        if (result(0) != 100) {
            return -1;
        }

        assert(messages.back().size() == 8191);
    }

    messages.clear();

    // Check that Halide's stringification of floats and doubles
    // matches %f and %e respectively.

    {
        Func f, g;

        const int N = 1000000;

        Expr e = reinterpret(Float(32), random_int());
        // Make sure we cover some special values.
        e = select(x == 0, 0.0f,
                   x == 1, -0.0f,
                   x == 2, std::numeric_limits<float>::infinity(),
                   x == 3, -std::numeric_limits<float>::infinity(),
                   x == 4, std::numeric_limits<float>::quiet_NaN(),
                   x == 5, -std::numeric_limits<float>::quiet_NaN(),
                   x == 6, std::numeric_limits<float>::max(),
                   x == 7, std::numeric_limits<float>::min(),
                   x == 8, -std::numeric_limits<float>::max(),
                   x == 9, -std::numeric_limits<float>::min(),
                   e);

        f(x) = print(e);

        f.set_custom_print(halide_print);
        Image<float> imf = f.realize(N);

        assert(messages.size() == N);

        char correct[1024];
        for (int i = 0; i < N; i++) {
            snprintf(correct, sizeof(correct), "%f\n", imf(i));
            if (messages[i] != correct) {
                printf("float %d: %s vs %s for %10.20e\n", i, messages[i].c_str(), correct, imf(i));
                //return -1;
            }
        }

        messages.clear();

        g(x) = print(reinterpret(Float(64), (cast<uint64_t>(random_int()) << 32) | random_int()));
        g.set_custom_print(halide_print);
        Image<double> img = g.realize(N);

        assert(messages.size() == N);

        for (int i = 0; i < N; i++) {
            snprintf(correct, sizeof(correct), "%e\n", img(i));
            if (messages[i] != correct) {
                printf("double %d: %s vs %s for %10.20e\n", i, messages[i].c_str(), correct, img(i));
                //return -1;
            }
        }

    }

    printf("Success!\n");
    return 0;
}
<commit_msg>Include denorms in testing float printing<commit_after>#include <stdio.h>
#include <string>
#include <vector>
#include <limits>
#include <Halide.h>

using namespace Halide;

std::vector<std::string> messages;

extern "C" void halide_print(void *user_context, const char *message) {
    //printf("%s", message);
    messages.push_back(message);
}

#ifdef _MSC_VER
#define snprintf _snprintf
#endif

int main(int argc, char **argv) {
    Var x;

    {
        Func f;

        f(x) = print(x * x, "the answer is", 42.0f, "unsigned", cast<uint32_t>(145));
        f.set_custom_print(halide_print);
        Image<int32_t> result = f.realize(10);

        for (int32_t i = 0; i < 10; i++) {
            if (result(i) != i * i) {
                return -1;
            }
        }

        assert(messages.size() == 10);
        for (size_t i = 0; i < messages.size(); i++) {
            long long square;
            float forty_two;
            unsigned long long one_forty_five;

            int scan_count = sscanf(messages[i].c_str(), "%lld the answer is %f unsigned %llu",
                                    &square, &forty_two, &one_forty_five);
            assert(scan_count == 3);
            assert(square == i * i);
            assert(forty_two == 42.0f);
            assert(one_forty_five == 145);
        }
    }

    messages.clear();

    {
        Func f;

        Param<void *> random_handle;
        random_handle.set((void *)127);

        // Test a string containing a printf format specifier (It should print it as-is).
        f(x) = print_when(x == 3, x * x, "g", 42.0f, "%s", random_handle);
        f.set_custom_print(halide_print);
        Image<int32_t> result = f.realize(10);

        for (int32_t i = 0; i < 10; i++) {
            if (result(i) != i * i) {
                return -1;
            }
        }

        assert(messages.size() == 1);
        long long nine;
        float forty_two;
        void *ptr;

        int scan_count = sscanf(messages[0].c_str(), "%lld g %f %%s %p",
                                &nine, &forty_two, &ptr);
        assert(scan_count == 3);
        assert(nine == 9);
        assert(forty_two == 42.0f);
        assert(ptr == (void *)127);

    }

    messages.clear();

    {
        Func f;

        // Test a single message longer than 8K.
        std::vector<Expr> args;
        for (int i = 0; i < 500; i++) {
            Expr e = cast<uint64_t>(i);
            e *= e;
            e *= e;
            e *= e;
            e *= e;
            args.push_back(e + 100);
            e = cast<double>(e);
            e *= e;
            e *= e;
            args.push_back(e);
        }
        f(x) = print(args);
        f.set_custom_print(halide_print);
        Image<uint64_t> result = f.realize(1);

        if (result(0) != 100) {
            return -1;
        }

        assert(messages.back().size() == 8191);
    }

    messages.clear();

    // Check that Halide's stringification of floats and doubles
    // matches %f and %e respectively.

    {
        Func f, g;

        const int N = 1000000;

        Expr e = reinterpret(Float(32), random_int());
        // Make sure we cover some special values.
        e = select(x == 0, 0.0f,
                   x == 1, -0.0f,
                   x == 2, std::numeric_limits<float>::infinity(),
                   x == 3, -std::numeric_limits<float>::infinity(),
                   x == 4, std::numeric_limits<float>::quiet_NaN(),
                   x == 5, -std::numeric_limits<float>::quiet_NaN(),
                   e);
        e = select(x == 6, std::numeric_limits<float>::denorm_min(),
                   x == 7, -std::numeric_limits<float>::denorm_min(),
                   x == 8, std::numeric_limits<float>::min(),
                   x == 9, -std::numeric_limits<float>::min(),
                   x == 10, std::numeric_limits<float>::max(),
                   x == 11, -std::numeric_limits<float>::max(),
                   e);

        f(x) = print(e);

        f.set_custom_print(halide_print);
        Image<float> imf = f.realize(N);

        assert(messages.size() == N);

        char correct[1024];
        for (int i = 0; i < N; i++) {
            snprintf(correct, sizeof(correct), "%f\n", imf(i));
            if (messages[i] != correct) {
                printf("float %d: %s vs %s for %10.20e\n", i, messages[i].c_str(), correct, imf(i));
                //return -1;
            }
        }

        messages.clear();

        g(x) = print(reinterpret(Float(64), (cast<uint64_t>(random_int()) << 32) | random_int()));
        g.set_custom_print(halide_print);
        Image<double> img = g.realize(N);

        assert(messages.size() == N);

        for (int i = 0; i < N; i++) {
            snprintf(correct, sizeof(correct), "%e\n", img(i));
            if (messages[i] != correct) {
                printf("double %d: %s vs %s for %10.20e\n", i, messages[i].c_str(), correct, img(i));
                //return -1;
            }
        }

    }

    printf("Success!\n");
    return 0;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_soltools.hxx"

/*
 * adjustvisibilty -- a tool to adjust the visibility of the so called
 *                    'fix and continue' globalized symbols generated by
 *                    the Sun Studio 8 compiler from 'DEFAULT' to 'HIDDEN'
 *
 * References: "Linker and Libraries Guide", Solaris 9 documentation
 *             "Stabs Interface", SunStudio 8 documentation
 */

#include <string>
#include <iostream>
#include <exception>
#include <stdexcept>
#include <cerrno>
#include <fcntl.h>
#include <unistd.h>
#include <libelf.h>
#include <gelf.h>
#include <utime.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits>
#include <stdio.h>

// Note: There is no GELF_ST_VISIBILITY macro in gelf.h, we roll our own.
#define GELF_ST_VISIBILITY(o)   ((o)&0x3) // See "Linker and Libraries Guide".

// See "Linker and Libraries Guide", ELF object format description.
static const char* SymbolType[STT_NUM] = {
    "NOTYPE",
    "OBJECT",
    "FUNC  ",
    "SECT  ",
    "FILE  ",
    "COMM  ",
    "TLS   "
};

static const char* SymbolBinding[STB_NUM] = {
    "LOCAL ",
    "GLOBAL",
    "WEAK  "
};

static const char* SymbolVisibility[4] = {   // Note: There is no STV_NUM macro
    "DEFAULT  ",
    "INTERNAL ",
    "HIDDEN   ",
    "PROTECTED"
};

class ElfError : public std::exception
{
    public:
        ElfError(const std::string& rFile, const std::string& rMessage);
        ~ElfError() throw() {};
        virtual const char* what() const throw() { return m_sMessage.c_str(); }

    private:
        std::string m_sMessage;
};

ElfError::ElfError(const std::string& rFile, const std::string& rMessage)
{
    if ( rFile != "" ) {
        m_sMessage = rFile;
        m_sMessage += ": ";
    }
    m_sMessage += rMessage;
    const char *pElfMsg = elf_errmsg(0);
    if ( pElfMsg ) {
        m_sMessage += ": ";
        m_sMessage += pElfMsg;
    }
}

void initElfLib()
{
    if ( elf_version(EV_CURRENT) == EV_NONE) {
        throw ElfError("", "elf_version() failed");
    }
    return;
}

bool isFixAndContinueSymbol(const std::string& rSymbol)
{
    // The globalized 'fix and continue' symbols have the following
    // form, see "Stabs interface", page 164:
    // {.$}X{ABC}uniquepattern[.function_name][EQUIVn][.variable_name]
    char c0 = rSymbol[0];
    char c1 = rSymbol[1];
    char c2 = rSymbol[2];
    if ( c0 == '.' || c0 == '$' ) {
        if ( c1 == 'X' ) {
            if ( c2 == 'A' || c2 == 'B' || c2 == 'C' || c2 == 'D' ) {
                return true;
            }
        }
    }
    return false;
}

void adjustVisibility( const std::string& rFile, int fd, bool bVerbose)
{
    if ( bVerbose ) {
        std::cout << "File: " << rFile << ": adjusting 'fix and continue' symbol visibility\n";
    }

    try {
        Elf* pElf;
        if ((pElf = elf_begin(fd, ELF_C_RDWR, 0)) == NULL) {
            throw ElfError(rFile, "elf_begin() failed");
        }
        // Check if file is ELF file.
        if ( elf_kind(pElf) != ELF_K_ELF ) {
            throw ElfError(rFile, "elf_kind() failed, file is not an ELF object file");
        }

        // Iterate over sections.
        Elf_Scn* pScn = 0;
        while ( (pScn = elf_nextscn(pElf, pScn)) != 0 ) {
            GElf_Shdr aShdr;
            if ( gelf_getshdr(pScn, &aShdr) == 0 ) {
                throw ElfError(rFile, "gelf_getshdr() failed");
            }
            if ( aShdr.sh_type != SHT_SYMTAB ) {
                continue;
            }
            // Section is a symbol section. Get the assiociated data.
            Elf_Data* pSymbolData;
            if ( (pSymbolData = elf_getdata(pScn, 0)) == NULL ) {
                throw ElfError(rFile, "elf_getdata() failed");
            }
            // Iterate over symbol table.
            GElf_Xword nSymbols = aShdr.sh_size / aShdr.sh_entsize;
            if ( nSymbols > std::numeric_limits< int >::max() )
            {
                throw ElfError(rFile, "too many symbols");
            }
            for ( int nIndex = 0; nIndex < nSymbols; ++nIndex) {
                // Get symbol.
                GElf_Sym aSymbol;
                if ( gelf_getsym(pSymbolData, nIndex, &aSymbol) == NULL )
                {
                    throw ElfError(rFile, "gelf_getsym() failed");
                }
                std::string  sSymbolName(elf_strptr(pElf, aShdr.sh_link, aSymbol.st_name));
                if ( isFixAndContinueSymbol(sSymbolName) ) {
                    // Get the symbol visibility.
                    unsigned int nSymbolVisibility = GELF_ST_VISIBILITY(aSymbol.st_other);
                    if ( bVerbose ) {
                        // Get the symbol type and binding.
                        unsigned int nSymbolType       = GELF_ST_TYPE(aSymbol.st_info);
                        unsigned int nSymbolBind       = GELF_ST_BIND(aSymbol.st_info);
                        std::cout << "Symbol: " << sSymbolName << ", "
                            << "Type: ";
                            if ( SymbolType[nSymbolType] ) {
                                std::cout << SymbolType[nSymbolType];
                            } else {
                                std::cout << nSymbolType;
                            }
                            std::cout << ", Binding: ";
                            if ( SymbolBinding[nSymbolBind] ) {
                                std::cout << SymbolBinding[nSymbolBind];
                            } else {
                                std::cout << nSymbolBind;
                            }
                            std::cout << ", Visibility: ";
                            if ( SymbolVisibility[nSymbolVisibility] ) {
                                std::cout << SymbolVisibility[nSymbolVisibility];
                            } else {
                                std::cout << nSymbolVisibility;
                            }
                            std::cout << "-> " << SymbolVisibility[STV_HIDDEN] << "\n";
                    }
                    // Toggle visibility to "hidden".
                    aSymbol.st_other = GELF_ST_VISIBILITY(STV_HIDDEN);
                    // Write back symbol data to underlying structure.
                    if ( gelf_update_sym(pSymbolData, nIndex, &aSymbol) == NULL )
                    {
                        throw ElfError(rFile, "gelf_update_sym() failed");
                    }
                }
            }
        }
        // Write changed object file to disk.
        if ( elf_update(pElf, ELF_C_WRITE) == -1 ) {
            throw ElfError(rFile, "elf_update() failed");
        }
        elf_end(pElf);

    } catch (ElfError& e) {
        close(fd);
        throw;
    }
    return;
}

void processObject(const std::string& rFile, bool bPreserve, bool bVerbose)
{
    int fd;
    struct stat aStatBuf;

    if ((fd = open(rFile.c_str(), O_RDWR)) == -1) {
         std::string sMessage("adjustVisibilty() failed: can't open file ");
         sMessage += rFile;
         sMessage += ": ";
         sMessage += std::strerror(errno);
         throw std::runtime_error(sMessage);
    }

    if ( bPreserve ) {
        if ( fstat(fd, &aStatBuf) == -1) {
            close(fd);
             std::string sMessage("adjustVisibilty() failed: can't stat file ");
             sMessage += rFile;
             sMessage += ": ";
             sMessage += std::strerror(errno);
             throw std::runtime_error(sMessage);
        }
    }

    adjustVisibility(rFile, fd, bVerbose);

    close(fd);

    if ( bPreserve ) {
        struct utimbuf aUtimBuf = {aStatBuf.st_atime, aStatBuf.st_mtime};
        if ( utime(rFile.c_str(), &aUtimBuf) == -1 ) {
             std::string sMessage("adjustVisibilty() failed: can't reset timestamp ");
             sMessage += rFile;
             sMessage += ": ";
             sMessage += std::strerror(errno);
             throw std::runtime_error(sMessage);
        }
    }
    return;
}

int main(int argc, char* argv[])
{
    int  c;
    bool bPreserve = false;
    bool bVerbose  = false;

    while ( (c = getopt(argc, argv, "pv")) != -1 ) {
        switch(c) {
            case 'p':
                bPreserve = true;
                break;
            case 'v':
                bVerbose = true;
                break;
            case '?':
                std::cerr << "Unrecognized option: -" << optopt << "\n";
                break;
            default:
                break;
        }
    }

    if ( optind == argc ) {
        std::cout << "usage: " << argv[0] << " [-pv] <elf-object> ...\n";
        std::cout << "       -p     preserve time stamps\n";
        std::cout << "       -v     verbose\n";
        return 1;
    }

    try {
        initElfLib();

        for ( ; optind < argc; optind++ )  {
            processObject(std::string(argv[optind]), bPreserve, bVerbose);
        }

    } catch (std::exception& e) {
        std::cerr << argv[0] << ": " << e.what() << "\n";
        return 1;
    }

    return 0;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>adjust indent<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_soltools.hxx"

/*
 * adjustvisibilty -- a tool to adjust the visibility of the so called
 *                    'fix and continue' globalized symbols generated by
 *                    the Sun Studio 8 compiler from 'DEFAULT' to 'HIDDEN'
 *
 * References: "Linker and Libraries Guide", Solaris 9 documentation
 *             "Stabs Interface", SunStudio 8 documentation
 */

#include <string>
#include <iostream>
#include <exception>
#include <stdexcept>
#include <cerrno>
#include <fcntl.h>
#include <unistd.h>
#include <libelf.h>
#include <gelf.h>
#include <utime.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits>
#include <stdio.h>

// Note: There is no GELF_ST_VISIBILITY macro in gelf.h, we roll our own.
#define GELF_ST_VISIBILITY(o)   ((o)&0x3) // See "Linker and Libraries Guide".

// See "Linker and Libraries Guide", ELF object format description.
static const char* SymbolType[STT_NUM] = {
    "NOTYPE",
    "OBJECT",
    "FUNC  ",
    "SECT  ",
    "FILE  ",
    "COMM  ",
    "TLS   "
};

static const char* SymbolBinding[STB_NUM] = {
    "LOCAL ",
    "GLOBAL",
    "WEAK  "
};

static const char* SymbolVisibility[4] = {   // Note: There is no STV_NUM macro
    "DEFAULT  ",
    "INTERNAL ",
    "HIDDEN   ",
    "PROTECTED"
};

class ElfError : public std::exception
{
    public:
        ElfError(const std::string& rFile, const std::string& rMessage);
        ~ElfError() throw() {};
        virtual const char* what() const throw() { return m_sMessage.c_str(); }

    private:
        std::string m_sMessage;
};

ElfError::ElfError(const std::string& rFile, const std::string& rMessage)
{
    if ( rFile != "" ) {
        m_sMessage = rFile;
        m_sMessage += ": ";
    }
    m_sMessage += rMessage;
    const char *pElfMsg = elf_errmsg(0);
    if ( pElfMsg ) {
        m_sMessage += ": ";
        m_sMessage += pElfMsg;
    }
}

void initElfLib()
{
    if ( elf_version(EV_CURRENT) == EV_NONE) {
        throw ElfError("", "elf_version() failed");
    }
    return;
}

bool isFixAndContinueSymbol(const std::string& rSymbol)
{
    // The globalized 'fix and continue' symbols have the following
    // form, see "Stabs interface", page 164:
    // {.$}X{ABC}uniquepattern[.function_name][EQUIVn][.variable_name]
    char c0 = rSymbol[0];
    char c1 = rSymbol[1];
    char c2 = rSymbol[2];
    if ( c0 == '.' || c0 == '$' ) {
        if ( c1 == 'X' ) {
            if ( c2 == 'A' || c2 == 'B' || c2 == 'C' || c2 == 'D' ) {
                return true;
            }
        }
    }
    return false;
}

void adjustVisibility( const std::string& rFile, int fd, bool bVerbose)
{
    if ( bVerbose ) {
        std::cout << "File: " << rFile << ": adjusting 'fix and continue' symbol visibility\n";
    }

    try {
        Elf* pElf;
        if ((pElf = elf_begin(fd, ELF_C_RDWR, 0)) == NULL) {
            throw ElfError(rFile, "elf_begin() failed");
        }
        // Check if file is ELF file.
        if ( elf_kind(pElf) != ELF_K_ELF ) {
            throw ElfError(rFile, "elf_kind() failed, file is not an ELF object file");
        }

        // Iterate over sections.
        Elf_Scn* pScn = 0;
        while ( (pScn = elf_nextscn(pElf, pScn)) != 0 ) {
            GElf_Shdr aShdr;
            if ( gelf_getshdr(pScn, &aShdr) == 0 ) {
                throw ElfError(rFile, "gelf_getshdr() failed");
            }
            if ( aShdr.sh_type != SHT_SYMTAB ) {
                continue;
            }
            // Section is a symbol section. Get the assiociated data.
            Elf_Data* pSymbolData;
            if ( (pSymbolData = elf_getdata(pScn, 0)) == NULL ) {
                throw ElfError(rFile, "elf_getdata() failed");
            }
            // Iterate over symbol table.
            GElf_Xword nSymbols = aShdr.sh_size / aShdr.sh_entsize;
            if ( nSymbols > std::numeric_limits< int >::max() )
            {
                throw ElfError(rFile, "too many symbols");
            }
            for ( int nIndex = 0; nIndex < nSymbols; ++nIndex) {
                // Get symbol.
                GElf_Sym aSymbol;
                if ( gelf_getsym(pSymbolData, nIndex, &aSymbol) == NULL )
                {
                    throw ElfError(rFile, "gelf_getsym() failed");
                }
                std::string  sSymbolName(elf_strptr(pElf, aShdr.sh_link, aSymbol.st_name));
                if ( isFixAndContinueSymbol(sSymbolName) ) {
                    // Get the symbol visibility.
                    unsigned int nSymbolVisibility = GELF_ST_VISIBILITY(aSymbol.st_other);
                    if ( bVerbose ) {
                        // Get the symbol type and binding.
                        unsigned int nSymbolType       = GELF_ST_TYPE(aSymbol.st_info);
                        unsigned int nSymbolBind       = GELF_ST_BIND(aSymbol.st_info);
                        std::cout << "Symbol: " << sSymbolName << ", "
                            << "Type: ";
                            if ( SymbolType[nSymbolType] ) {
                                std::cout << SymbolType[nSymbolType];
                            } else {
                                std::cout << nSymbolType;
                            }
                            std::cout << ", Binding: ";
                            if ( SymbolBinding[nSymbolBind] ) {
                                std::cout << SymbolBinding[nSymbolBind];
                            } else {
                                std::cout << nSymbolBind;
                            }
                            std::cout << ", Visibility: ";
                            if ( SymbolVisibility[nSymbolVisibility] ) {
                                std::cout << SymbolVisibility[nSymbolVisibility];
                            } else {
                                std::cout << nSymbolVisibility;
                            }
                            std::cout << "-> " << SymbolVisibility[STV_HIDDEN] << "\n";
                    }
                    // Toggle visibility to "hidden".
                    aSymbol.st_other = GELF_ST_VISIBILITY(STV_HIDDEN);
                    // Write back symbol data to underlying structure.
                    if ( gelf_update_sym(pSymbolData, nIndex, &aSymbol) == NULL )
                    {
                        throw ElfError(rFile, "gelf_update_sym() failed");
                    }
                }
            }
        }
        // Write changed object file to disk.
        if ( elf_update(pElf, ELF_C_WRITE) == -1 ) {
            throw ElfError(rFile, "elf_update() failed");
        }
        elf_end(pElf);

    } catch (ElfError& e) {
        close(fd);
        throw;
    }
    return;
}

void processObject(const std::string& rFile, bool bPreserve, bool bVerbose)
{
    int fd;
    struct stat aStatBuf;

    if ((fd = open(rFile.c_str(), O_RDWR)) == -1) {
         std::string sMessage("adjustVisibilty() failed: can't open file ");
         sMessage += rFile;
         sMessage += ": ";
         sMessage += std::strerror(errno);
         throw std::runtime_error(sMessage);
    }

    if ( bPreserve ) {
        if ( fstat(fd, &aStatBuf) == -1) {
            close(fd);
            std::string sMessage("adjustVisibilty() failed: can't stat file ");
            sMessage += rFile;
            sMessage += ": ";
            sMessage += std::strerror(errno);
            throw std::runtime_error(sMessage);
        }
    }

    adjustVisibility(rFile, fd, bVerbose);

    close(fd);

    if ( bPreserve ) {
        struct utimbuf aUtimBuf = {aStatBuf.st_atime, aStatBuf.st_mtime};
        if ( utime(rFile.c_str(), &aUtimBuf) == -1 ) {
             std::string sMessage("adjustVisibilty() failed: can't reset timestamp ");
             sMessage += rFile;
             sMessage += ": ";
             sMessage += std::strerror(errno);
             throw std::runtime_error(sMessage);
        }
    }
    return;
}

int main(int argc, char* argv[])
{
    int  c;
    bool bPreserve = false;
    bool bVerbose  = false;

    while ( (c = getopt(argc, argv, "pv")) != -1 ) {
        switch(c) {
            case 'p':
                bPreserve = true;
                break;
            case 'v':
                bVerbose = true;
                break;
            case '?':
                std::cerr << "Unrecognized option: -" << optopt << "\n";
                break;
            default:
                break;
        }
    }

    if ( optind == argc ) {
        std::cout << "usage: " << argv[0] << " [-pv] <elf-object> ...\n";
        std::cout << "       -p     preserve time stamps\n";
        std::cout << "       -v     verbose\n";
        return 1;
    }

    try {
        initElfLib();

        for ( ; optind < argc; optind++ )  {
            processObject(std::string(argv[optind]), bPreserve, bVerbose);
        }

    } catch (std::exception& e) {
        std::cerr << argv[0] << ": " << e.what() << "\n";
        return 1;
    }

    return 0;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>