<commit_before>/***********************************************************************
	filename: 	CEGUIPropertySet.cpp
	created:	21/2/2004
	author:		Paul D Turner

	purpose:	Implements PropertySet class
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   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 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 "CEGUIPropertySet.h"
#include "CEGUIProperty.h"
#include "CEGUIExceptions.h"

// Start of CEGUI namespace section
namespace CEGUI
{

/*************************************************************************
	Add a new property to the set
*************************************************************************/
void PropertySet::addProperty(Property* property)
{
	if (!property)
	{
		CEGUI_THROW(NullObjectException("The given Property object pointer is invalid."));
	}

	if (d_properties.find(property->getName()) != d_properties.end())
	{
		CEGUI_THROW(AlreadyExistsException("A Property named '" + property->getName() + "' already exists in the PropertySet."));
	}

	d_properties[property->getName()] = property;
}

/*************************************************************************
	Remove a property from the set
*************************************************************************/
void PropertySet::removeProperty(const String& name)
{
	PropertyRegistry::iterator pos = d_properties.find(name);

	if (pos != d_properties.end())
	{
		d_properties.erase(pos);
	}
}

/*************************************************************************
	Remove all properties from the set
*************************************************************************/
void PropertySet::clearProperties(void)
{
	d_properties.clear();
}

/*************************************************************************
	Return true if a property with the given name is in the set
*************************************************************************/
bool PropertySet::isPropertyPresent(const String& name) const
{
	return (d_properties.find(name) != d_properties.end());
}

/*************************************************************************
	Return the help string for a property
*************************************************************************/
const String& PropertySet::getPropertyHelp(const String& name) const
{
	PropertyRegistry::const_iterator pos = d_properties.find(name);

	if (pos == d_properties.end())
	{
		CEGUI_THROW(UnknownObjectException("There is no Property named '" + name + "' available in the set."));
	}

	return pos->second->getHelp();
}

/*************************************************************************
	Return the current value of a property
*************************************************************************/
String PropertySet::getProperty(const String& name) const
{
	PropertyRegistry::const_iterator pos = d_properties.find(name);

	if (pos == d_properties.end())
	{
		CEGUI_THROW(UnknownObjectException("There is no Property named '" + name + "' available in the set."));
	}

	return pos->second->get(this);
}

/*************************************************************************
	Set the current value of a property
*************************************************************************/
void PropertySet::setProperty(const String& name,const String& value)
{
	PropertyRegistry::iterator pos = d_properties.find(name);

	if (pos == d_properties.end())
	{
		CEGUI_THROW(UnknownObjectException("There is no Property named '" + name + "' available in the set."));
	}

	pos->second->set(this, value);
}

/*************************************************************************
	Return a PropertySet::PropertyIterator object to iterate over the
	available Properties.
*************************************************************************/
PropertySet::Iterator PropertySet::getIterator(void) const
{
	return Iterator(d_properties.begin(), d_properties.end());
}

/*************************************************************************
	Returns whether a Property is at it's default value.
*************************************************************************/
bool PropertySet::isPropertyDefault(const String& name) const
{
	PropertyRegistry::const_iterator pos = d_properties.find(name);

	if (pos == d_properties.end())
	{
		CEGUI_THROW(UnknownObjectException("There is no Property named '" + name + "' available in the set."));
	}

	return pos->second->isDefault(this);
}

/*************************************************************************
	Returns the default value of a Property as a String.
*************************************************************************/
String PropertySet::getPropertyDefault(const String& name) const
{
	PropertyRegistry::const_iterator pos = d_properties.find(name);

	if (pos == d_properties.end())
	{
		CEGUI_THROW(UnknownObjectException("There is no Property named '" + name + "' available in the set."));
	}

	return pos->second->getDefault(this);
}

} // End of  CEGUI namespace section
<commit_msg>MOD: PropertySet now only checks once for Property existence in addProperty. This speeds up creation of Windows. Credit goes to zanir, http://www.cegui.org.uk/phpBB2/viewtopic.php?f=10&t=2663<commit_after>/***********************************************************************
	filename: 	CEGUIPropertySet.cpp
	created:	21/2/2004
	author:		Paul D Turner

	purpose:	Implements PropertySet class
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   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 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 "CEGUIPropertySet.h"
#include "CEGUIProperty.h"
#include "CEGUIExceptions.h"

// Start of CEGUI namespace section
namespace CEGUI
{

/*************************************************************************
	Add a new property to the set
*************************************************************************/
void PropertySet::addProperty(Property* property)
{
	if (!property)
	{
		CEGUI_THROW(NullObjectException("The given Property object pointer is invalid."));
	}

	if (!d_properties.insert(std::make_pair(property->getName(), property)).second)
	{
		CEGUI_THROW(AlreadyExistsException("A Property named '" + property->getName() + "' already exists in the PropertySet."));
	}
}

/*************************************************************************
	Remove a property from the set
*************************************************************************/
void PropertySet::removeProperty(const String& name)
{
	PropertyRegistry::iterator pos = d_properties.find(name);

	if (pos != d_properties.end())
	{
		d_properties.erase(pos);
	}
}

/*************************************************************************
	Remove all properties from the set
*************************************************************************/
void PropertySet::clearProperties(void)
{
	d_properties.clear();
}

/*************************************************************************
	Return true if a property with the given name is in the set
*************************************************************************/
bool PropertySet::isPropertyPresent(const String& name) const
{
	return (d_properties.find(name) != d_properties.end());
}

/*************************************************************************
	Return the help string for a property
*************************************************************************/
const String& PropertySet::getPropertyHelp(const String& name) const
{
	PropertyRegistry::const_iterator pos = d_properties.find(name);

	if (pos == d_properties.end())
	{
		CEGUI_THROW(UnknownObjectException("There is no Property named '" + name + "' available in the set."));
	}

	return pos->second->getHelp();
}

/*************************************************************************
	Return the current value of a property
*************************************************************************/
String PropertySet::getProperty(const String& name) const
{
	PropertyRegistry::const_iterator pos = d_properties.find(name);

	if (pos == d_properties.end())
	{
		CEGUI_THROW(UnknownObjectException("There is no Property named '" + name + "' available in the set."));
	}

	return pos->second->get(this);
}

/*************************************************************************
	Set the current value of a property
*************************************************************************/
void PropertySet::setProperty(const String& name,const String& value)
{
	PropertyRegistry::iterator pos = d_properties.find(name);

	if (pos == d_properties.end())
	{
		CEGUI_THROW(UnknownObjectException("There is no Property named '" + name + "' available in the set."));
	}

	pos->second->set(this, value);
}

/*************************************************************************
	Return a PropertySet::PropertyIterator object to iterate over the
	available Properties.
*************************************************************************/
PropertySet::Iterator PropertySet::getIterator(void) const
{
	return Iterator(d_properties.begin(), d_properties.end());
}

/*************************************************************************
	Returns whether a Property is at it's default value.
*************************************************************************/
bool PropertySet::isPropertyDefault(const String& name) const
{
	PropertyRegistry::const_iterator pos = d_properties.find(name);

	if (pos == d_properties.end())
	{
		CEGUI_THROW(UnknownObjectException("There is no Property named '" + name + "' available in the set."));
	}

	return pos->second->isDefault(this);
}

/*************************************************************************
	Returns the default value of a Property as a String.
*************************************************************************/
String PropertySet::getPropertyDefault(const String& name) const
{
	PropertyRegistry::const_iterator pos = d_properties.find(name);

	if (pos == d_properties.end())
	{
		CEGUI_THROW(UnknownObjectException("There is no Property named '" + name + "' available in the set."));
	}

	return pos->second->getDefault(this);
}

} // End of  CEGUI namespace section
<|endoftext|>


<commit_before>//
//  TilePetitions.hpp
//  G3MiOSSDK
//
//  Created by José Miguel S N on 17/07/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#ifndef G3MiOSSDK_TilePetitions_hpp
#define G3MiOSSDK_TilePetitions_hpp

#include "IDownloadListener.hpp"
#include "MutableVector2D.hpp"
#include "TileRenderer.hpp"

#include <string>
#include <vector>

#include "Tile.hpp"
#include "IFactory.hpp"

class TileImagesTileTexturizer;

class Petition {
  const std::string _url;
  const Sector *_sector;
  ByteBuffer* _bb;

public:

  Petition(Sector s, std::string url): _url(url),
  _sector(new Sector(s)),
  _bb(NULL)
  {}

  ~Petition(){
    delete _sector;
    if (_bb != NULL) delete _bb;
  }

  std::string getURL() const { return _url;}
  Sector getSector() const { return *_sector;}

  bool isArrived() const{ return _bb != NULL; }
  void setByteBuffer(ByteBuffer* bb) { _bb = bb; }
  const ByteBuffer* getByteBuffer() const { return _bb; }
};

class TilePetitions: public IDownloadListener {

  const int    _level;
  const int    _row;
  const int    _column;
  const Sector _tileSector;

  TileImagesTileTexturizer* _texturizer;
  std::vector<Petition*> _petitions;

  int _downloadsCounter;
  int _errorsCounter;

  TilePetitions(const TilePetitions& that);

  void tryToDeleteMyself()
  {
    if (_downloadsCounter + _errorsCounter == _petitions.size()){
      delete this;
    }
  }

public:

  TilePetitions(const int level,
                const int row,
                const int column,
                const Sector sector,
                const std::vector<Petition*>& petitions,
                TileImagesTileTexturizer* const texturizer):
  _level(level),
  _row(row),
  _column(column),
  _texturizer(texturizer),
  _tileSector(sector),
  _downloadsCounter(0),
  _errorsCounter(0),
  _petitions(petitions)
  {
  }

  ~TilePetitions()
  {
    for (int i = 0; i < _petitions.size(); i++) {
      delete _petitions[i];
    }
  }

  void notify(TileImagesTileTexturizer* texturizer)
  {
    _texturizer = texturizer;
  }

  int getLevel() const {
    return _level;
  }

  int getRow() const {
    return _row;
  }

  int getColumn() const {
    return _column;
  }

  Sector getSector() const{
    return _tileSector;
  }

  std::string getPetitionsID() const;

  Petition* getPetition(int i) { return _petitions[i];}
  int getNumPetitions() { return _petitions.size();}

  bool allFinished() const;

  void onDownload(const Response &response);
  void onError(const Response& e);

  void onCancel(const std::string& url);

};

#endif
<commit_msg>minor formating changes<commit_after>//
//  TilePetitions.hpp
//  G3MiOSSDK
//
//  Created by José Miguel S N on 17/07/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#ifndef G3MiOSSDK_TilePetitions_hpp
#define G3MiOSSDK_TilePetitions_hpp

#include "IDownloadListener.hpp"
#include "MutableVector2D.hpp"
#include "TileRenderer.hpp"

#include <string>
#include <vector>

#include "Tile.hpp"
#include "IFactory.hpp"

class TileImagesTileTexturizer;

class Petition {
  const std::string _url;
  const Sector      _sector;
  ByteBuffer*       _bb;

  Petition& operator=(const Petition& that);
  Petition(const Petition& that);

public:

  Petition(const Sector& sector,
           std::string url):
  _sector(sector),
  _url(url),
  _bb(NULL)
  {
  }

  ~Petition(){
    if (_bb != NULL) delete _bb;
  }

  std::string getURL() const {
    return _url;
  }

  Sector getSector() const {
    return _sector;
  }

  bool isArrived() const {
    return _bb != NULL;
  }

  void setByteBuffer(ByteBuffer* bb) {
    if (_bb != NULL) delete _bb;
    _bb = bb;
  }

  const ByteBuffer* getByteBuffer() const {
    return _bb;
  }
};

class TilePetitions: public IDownloadListener {

  const int    _level;
  const int    _row;
  const int    _column;
  const Sector _tileSector;

  TileImagesTileTexturizer* _texturizer;
  std::vector<Petition*> _petitions;

  int _downloadsCounter;
  int _errorsCounter;

  TilePetitions(const TilePetitions& that);

  void tryToDeleteMyself()
  {
    if (_downloadsCounter + _errorsCounter == _petitions.size()){
      delete this;
    }
  }

public:

  TilePetitions(const int level,
                const int row,
                const int column,
                const Sector sector,
                const std::vector<Petition*>& petitions,
                TileImagesTileTexturizer* const texturizer):
  _level(level),
  _row(row),
  _column(column),
  _texturizer(texturizer),
  _tileSector(sector),
  _downloadsCounter(0),
  _errorsCounter(0),
  _petitions(petitions)
  {
  }

  ~TilePetitions()
  {
    for (int i = 0; i < _petitions.size(); i++) {
      delete _petitions[i];
    }
  }

  void notify(TileImagesTileTexturizer* texturizer)
  {
    _texturizer = texturizer;
  }

  int getLevel() const {
    return _level;
  }

  int getRow() const {
    return _row;
  }

  int getColumn() const {
    return _column;
  }

  Sector getSector() const{
    return _tileSector;
  }

  std::string getPetitionsID() const;

  Petition* getPetition(int i) { return _petitions[i];}
  int getNumPetitions() { return _petitions.size();}

  bool allFinished() const;

  void onDownload(const Response &response);
  void onError(const Response& e);

  void onCancel(const std::string& url);

};

#endif
<|endoftext|>


<commit_before>#ifndef CLOTHO_BIT_BLOCK_FITNESS2_HPP_
#define CLOTHO_BIT_BLOCK_FITNESS2_HPP_

#include <iostream>
#include "clotho/fitness/bit_block_genotyper.hpp"
#include "clotho/utility/bit_block_iterator.hpp"

#include "clotho/fitness/no_fit.hpp"

namespace clotho {
namespace fitness {

template < class HetFit, class AltHomFit, class RefHomFit, class Result = double >
class bit_block_fitness2 {
public:
    typedef Result result_type;

    bit_block_fitness2() {}

    bit_block_fitness2( const HetFit & hets, const AltHomFit & ahoms, const RefHomFit & rhoms ) :
        m_hets( hets )
        , m_ahoms(ahoms)
        , m_rhoms(rhoms) {
    }

    template < class Block, class ElementIterator >
    result_type operator()( result_type f, Block b0, Block b1, Block keep_mask, ElementIterator first ) {
        result_type res = f;

        typedef bit_block_genotyper< Block >                    genotyper;

//        computeFitness( res, b0, b1, keep_mask, first, &genotyper::get_all_heterozygous, &m_hets);
//        computeFitness( res, b0, b1, keep_mask, first, &genotyper::get_alt_homozygous, &m_ahoms);
//        computeFitness( res, b0, b1, keep_mask, first, &genotyper::get_ref_homozygous, &m_rhoms);
//

        Block het_bits = genotyper::get_all_heterozygous(b0, b1) & keep_mask;
        Block hom_bits = genotyper::get_alt_homozygous(b0, b1) & keep_mask;
        Block ref_bits = genotyper::get_ref_homozygous(b0, b1) & keep_mask;

//        Block _bits = (het_bits | (hom_bits | ref_bits) );
        Block _bits = 0;

        combineBits( _bits, het_bits, &m_hets );
        combineBits( _bits, hom_bits, &m_ahoms );
        combineBits( _bits, ref_bits, &m_rhoms );

        typedef clotho::utility::bit_block_iterator< Block, clotho::utility::walk_iterator_tag >    iterator;
        static iterator it;

        it.reset( _bits );

        while( !it.done() ) {
            unsigned int idx = (*it);
            ++it;
            Block _m = ((Block)1 << idx);

            if( het_bits & _m ) {
                //m_hets( res, *(first + idx) );
                computeFitness( res, *(first + idx), &m_hets );
            } else if( hom_bits & _m ) {
                //m_ahoms( res, *(first + idx) );
                computeFitness( res, *(first + idx), &m_ahoms );
            } else {
                computeFitness( res, *(first + idx), &m_rhoms );
            }
        }

        return res;
    }

    virtual ~bit_block_fitness2() {}
protected:

    template < class Element, class FitOp >
    inline void computeFitness( result_type & res, const Element & elem, FitOp * op ) {
        (*op)(res, elem);
    }

    template < class Element >
    inline void computeFitness( result_type & res, const Element & elem, no_fit * op ) { }

    template < class Block, class FitOp >
    inline void combineBits( Block & res, Block & set, FitOp * op ) {
        res |= set;
    }

    template < class Block >
    inline void combineBits( Block & res, Block & set, no_fit * op ) {}

    /*
        template < class Block, class ElementIterator, class FitOp >
        void computeFitness(result_type & res, Block b, ElementIterator first, FitOp * op ) {
            typedef clotho::utility::bit_block_iterator< Block, clotho::utility::walk_iterator_tag >    iterator;

            iterator it( b ), end;
            while( it != end ) {
                (*op)( res, *(first + *it++));
            }
        }

        template < class Block, class ElementIterator, class SetOp, class FitOp >
        inline void computeFitness( result_type & res, Block b0, Block b1, Block keep, ElementIterator first, SetOp * sop, FitOp * op ) {
            Block bits = ( (*sop)(b0, b1) & keep );
            computeFitness( res, bits, first, op );
        }

        template < class Block, class ElementIterator, class SetOp >
        inline void computeFitness( result_type & res, Block b0, Block b1, Block keep, ElementIterator first, SetOp * sop, no_fit * op ) { }
    */
    HetFit      m_hets;
    AltHomFit   m_ahoms;
    RefHomFit   m_rhoms;
};

template < class HetFit, class HomFit, class Result >
class bit_block_fitness2< HetFit, HomFit, HomFit, Result > {
public:
    typedef Result result_type;

    bit_block_fitness2( ) {}

    bit_block_fitness2( const HetFit & hets, const HomFit & homs ) :
        m_hets( hets )
        , m_homs(homs) {
    }

    template < class Block, class ElementIterator >
    result_type operator()( result_type f, Block b0, Block b1, Block keep_mask, ElementIterator first ) {
        result_type res = f;

        typedef bit_block_genotyper< Block >                    genotyper;

        std::cerr << "Bad call" << std::endl;

        computeFitness( res, b0, b1, keep_mask, first, &genotyper::get_all_heterozygous, &m_hets);
        computeFitness( res, b0, b1, keep_mask, first, &genotyper::get_alt_homozygous, &m_homs);

        return res;
    }

    virtual ~bit_block_fitness2() {}
protected:
    template < class Block, class ElementIterator, class FitOp >
    inline void computeFitness(result_type & res, Block b, ElementIterator first, FitOp * op ) {
        typedef clotho::utility::bit_block_iterator< Block, clotho::utility::walk_iterator_tag >    iterator;

        iterator it( b );
        while( !it.done() ) {
            (*op)( res, *(first + *it));
            ++it;
        }
    }

    template < class Block, class ElementIterator, class SetOp, class FitOp >
    inline void computeFitness( result_type & res, Block b0, Block b1, Block keep, ElementIterator first, SetOp * sop, FitOp * op ) {
        Block bits = ( (*sop)(b0, b1) & keep );
        computeFitness( res, bits, first, op );
    }

    template < class Block, class ElementIterator, class SetOp >
    inline void computeFitness( result_type & res, Block b0, Block b1, Block keep, ElementIterator first, SetOp * sop, no_fit * op ) { }

    HetFit   m_hets;
    HomFit   m_homs;
};

template < class Result >
class bit_block_fitness2< no_fit, no_fit, no_fit, Result > {
public:
    typedef Result result_type;

    bit_block_fitness2( ) {}

    template < class Block, class ElementIterator >
    result_type operator()( result_type f, Block b0, Block b1, Block keep_mask, ElementIterator first ) {
        return f;
    }

    virtual ~bit_block_fitness2() {}
};

}   // namespace fitness2 {
}   // namespace clotho {

#endif  // CLOTHO_BIT_BLOCK_FITNESS2_HPP_
<commit_msg>Iterator should not be static as multiple fitness instances could potentially exist<commit_after>#ifndef CLOTHO_BIT_BLOCK_FITNESS2_HPP_
#define CLOTHO_BIT_BLOCK_FITNESS2_HPP_

#include <iostream>
#include "clotho/fitness/bit_block_genotyper.hpp"
#include "clotho/utility/bit_block_iterator.hpp"

#include "clotho/fitness/no_fit.hpp"

namespace clotho {
namespace fitness {

template < class HetFit, class AltHomFit, class RefHomFit, class Result = double >
class bit_block_fitness2 {
public:
    typedef Result result_type;

    bit_block_fitness2() {}

    bit_block_fitness2( const HetFit & hets, const AltHomFit & ahoms, const RefHomFit & rhoms ) :
        m_hets( hets )
        , m_ahoms(ahoms)
        , m_rhoms(rhoms) {
    }

    template < class Block, class ElementIterator >
    result_type operator()( result_type f, Block b0, Block b1, Block keep_mask, ElementIterator first ) {
        result_type res = f;

        typedef bit_block_genotyper< Block >                    genotyper;

//        computeFitness( res, b0, b1, keep_mask, first, &genotyper::get_all_heterozygous, &m_hets);
//        computeFitness( res, b0, b1, keep_mask, first, &genotyper::get_alt_homozygous, &m_ahoms);
//        computeFitness( res, b0, b1, keep_mask, first, &genotyper::get_ref_homozygous, &m_rhoms);
//

        Block het_bits = genotyper::get_all_heterozygous(b0, b1) & keep_mask;
        Block hom_bits = genotyper::get_alt_homozygous(b0, b1) & keep_mask;
        Block ref_bits = genotyper::get_ref_homozygous(b0, b1) & keep_mask;

//        Block _bits = (het_bits | (hom_bits | ref_bits) );
        Block _bits = 0;

        combineBits( _bits, het_bits, &m_hets );
        combineBits( _bits, hom_bits, &m_ahoms );
        combineBits( _bits, ref_bits, &m_rhoms );

        typedef clotho::utility::bit_block_iterator< Block, clotho::utility::walk_iterator_tag >    iterator;
        iterator it( _bits );

        while( !it.done() ) {
            unsigned int idx = (*it);
            ++it;
            Block _m = ((Block)1 << idx);

            if( het_bits & _m ) {
                //m_hets( res, *(first + idx) );
                computeFitness( res, *(first + idx), &m_hets );
            } else if( hom_bits & _m ) {
                //m_ahoms( res, *(first + idx) );
                computeFitness( res, *(first + idx), &m_ahoms );
            } else {
                computeFitness( res, *(first + idx), &m_rhoms );
            }
        }

        return res;
    }

    virtual ~bit_block_fitness2() {}
protected:

    template < class Element, class FitOp >
    inline void computeFitness( result_type & res, const Element & elem, FitOp * op ) {
        (*op)(res, elem);
    }

    template < class Element >
    inline void computeFitness( result_type & res, const Element & elem, no_fit * op ) { }

    template < class Block, class FitOp >
    inline void combineBits( Block & res, Block & set, FitOp * op ) {
        res |= set;
    }

    template < class Block >
    inline void combineBits( Block & res, Block & set, no_fit * op ) {}

    /*
        template < class Block, class ElementIterator, class FitOp >
        void computeFitness(result_type & res, Block b, ElementIterator first, FitOp * op ) {
            typedef clotho::utility::bit_block_iterator< Block, clotho::utility::walk_iterator_tag >    iterator;

            iterator it( b ), end;
            while( it != end ) {
                (*op)( res, *(first + *it++));
            }
        }

        template < class Block, class ElementIterator, class SetOp, class FitOp >
        inline void computeFitness( result_type & res, Block b0, Block b1, Block keep, ElementIterator first, SetOp * sop, FitOp * op ) {
            Block bits = ( (*sop)(b0, b1) & keep );
            computeFitness( res, bits, first, op );
        }

        template < class Block, class ElementIterator, class SetOp >
        inline void computeFitness( result_type & res, Block b0, Block b1, Block keep, ElementIterator first, SetOp * sop, no_fit * op ) { }
    */
    HetFit      m_hets;
    AltHomFit   m_ahoms;
    RefHomFit   m_rhoms;
};

template < class HetFit, class HomFit, class Result >
class bit_block_fitness2< HetFit, HomFit, HomFit, Result > {
public:
    typedef Result result_type;

    bit_block_fitness2( ) {}

    bit_block_fitness2( const HetFit & hets, const HomFit & homs ) :
        m_hets( hets )
        , m_homs(homs) {
    }

    template < class Block, class ElementIterator >
    result_type operator()( result_type f, Block b0, Block b1, Block keep_mask, ElementIterator first ) {
        result_type res = f;

        typedef bit_block_genotyper< Block >                    genotyper;

        std::cerr << "Bad call" << std::endl;

        computeFitness( res, b0, b1, keep_mask, first, &genotyper::get_all_heterozygous, &m_hets);
        computeFitness( res, b0, b1, keep_mask, first, &genotyper::get_alt_homozygous, &m_homs);

        return res;
    }

    virtual ~bit_block_fitness2() {}
protected:
    template < class Block, class ElementIterator, class FitOp >
    inline void computeFitness(result_type & res, Block b, ElementIterator first, FitOp * op ) {
        typedef clotho::utility::bit_block_iterator< Block, clotho::utility::walk_iterator_tag >    iterator;

        iterator it( b );
        while( !it.done() ) {
            (*op)( res, *(first + *it));
            ++it;
        }
    }

    template < class Block, class ElementIterator, class SetOp, class FitOp >
    inline void computeFitness( result_type & res, Block b0, Block b1, Block keep, ElementIterator first, SetOp * sop, FitOp * op ) {
        Block bits = ( (*sop)(b0, b1) & keep );
        computeFitness( res, bits, first, op );
    }

    template < class Block, class ElementIterator, class SetOp >
    inline void computeFitness( result_type & res, Block b0, Block b1, Block keep, ElementIterator first, SetOp * sop, no_fit * op ) { }

    HetFit   m_hets;
    HomFit   m_homs;
};

template < class Result >
class bit_block_fitness2< no_fit, no_fit, no_fit, Result > {
public:
    typedef Result result_type;

    bit_block_fitness2( ) {}

    template < class Block, class ElementIterator >
    result_type operator()( result_type f, Block b0, Block b1, Block keep_mask, ElementIterator first ) {
        return f;
    }

    virtual ~bit_block_fitness2() {}
};

}   // namespace fitness2 {
}   // namespace clotho {

#endif  // CLOTHO_BIT_BLOCK_FITNESS2_HPP_
<|endoftext|>


<commit_before>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file multiple_of.hpp
 * \date Febuary 2015
 * \author Jan Issac (jan.issac@gmail.com)
 */

#ifndef FL__UTIL__META__OPERATOR__MULTIPLE_OF_HPP
#define FL__UTIL__META__OPERATOR__MULTIPLE_OF_HPP

#include <type_traits>

#include <fl/util/meta/operator/not_adaptive.hpp>
#include <fl/util/meta/operator/forward_adaptive.hpp>

namespace fl
{

/**
 * \ingroup meta
 *
 * Same as CreateTypeSequence, however with a reversed parameter order. This is
 * an attempt to make the use of \c CreateTypeSequence more natural. It also
 * allows dynamic sizes if needed.
 */
template <typename T, int Count>
struct MultipleOf
    //: CreateTypeSequence<Count, typename ForwardAdaptive<T>::Type>
{
    //typedef typename ForwardAdaptive<T>::Type Type;
    typedef T Type;

    MultipleOf(const Type& instance, int instance_count = Count)
        : instance(instance),
          count(instance_count)
    { }

    Type instance;
    int count;
};

}

#endif
<commit_msg>MultipleOf Stores the model count<commit_after>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file multiple_of.hpp
 * \date Febuary 2015
 * \author Jan Issac (jan.issac@gmail.com)
 */

#ifndef FL__UTIL__META__OPERATOR__MULTIPLE_OF_HPP
#define FL__UTIL__META__OPERATOR__MULTIPLE_OF_HPP

#include <type_traits>

#include <fl/util/meta/operator/not_adaptive.hpp>
#include <fl/util/meta/operator/forward_adaptive.hpp>

namespace fl
{

/**
 * \ingroup meta
 *
 * Same as CreateTypeSequence, however with a reversed parameter order. This is
 * an attempt to make the use of \c CreateTypeSequence more natural. It also
 * allows dynamic sizes if needed.
 */
template <typename T, int Count_>
struct MultipleOf
    //: CreateTypeSequence<Count, typename ForwardAdaptive<T>::Type>
{
    //typedef typename ForwardAdaptive<T>::Type Type;

    enum : signed int { Count = Count_ };
    typedef T Type;

    MultipleOf(const Type& instance, int instance_count = Count)
        : instance(instance),
          count(instance_count)
    { }

    Type instance;
    int count;
};

}

#endif
<|endoftext|>


<commit_before>// Copyright (C) 2010-2014 Joshua Boyce.
// See the file COPYING for copying permission.

#pragma once

#include <fstream>
#include <memory>
#include <string>
#include <vector>

#include <windows.h>
#include <shlwapi.h>

#include <hadesmem/config.hpp>
#include <hadesmem/error.hpp>
#include <hadesmem/detail/self_path.hpp>
#include <hadesmem/detail/smart_handle.hpp>
#include <hadesmem/detail/str_conv.hpp>

#define HADESMEM_PATHCCH_ALLOW_LONG_PATHS 0x00000001

namespace hadesmem
{
namespace detail
{
// libstdc++ doesn't support move operations on file-streams, so we have to
// return a unique_ptr instead.
template <typename CharT>
inline std::unique_ptr<std::basic_fstream<CharT>>
  OpenFile(std::wstring const& path, std::ios_base::openmode mode)
{
#if defined(HADESMEM_MSVC) || defined(HADESMEM_INTEL)
  return std::unique_ptr<std::basic_fstream<CharT>>{
    new std::basic_fstream<CharT>{path, mode}};
#else  // #if defined(HADESMEM_MSVC) || defined(HADESMEM_INTEL)
  // libstdc++ doesn't support wide character overloads for ifstream's
  // construtor.
  return std::unique_ptr<std::basic_fstream<CharT>>{
    new std::basic_fstream<CharT>{hadesmem::detail::WideCharToMultiByte(path),
                                  mode}};
#endif // #if defined(HADESMEM_MSVC) || defined(HADESMEM_INTEL)
}

inline bool DoesFileExist(std::wstring const& path)
{
  return ::GetFileAttributesW(path.c_str()) != INVALID_FILE_ATTRIBUTES;
}

inline bool DoesDirectoryExist(std::wstring const& path)
{
  auto const attrs = ::GetFileAttributesW(path.c_str());
  return attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY);
}

inline bool IsPathRelative(std::wstring const& path)
{
  // Relative paths are always limited to a total of MAX_PATH characters
  return (path.size() >= MAX_PATH) ? false : !!::PathIsRelativeW(path.c_str());
}

inline std::wstring CombinePath(std::wstring const& base,
                                std::wstring const& append)
{
  // Use newer and better PathCchCombineEx if it's available.
  detail::SmartModuleHandle const path_mod{
    LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll")};
  if (path_mod.IsValid())
  {
    using PathCchCombineExFn = HRESULT(WINAPI*)(PWSTR pszPathOut,
                                                size_t cchPathOut,
                                                PCWSTR pszPathIn,
                                                PCWSTR pszMore,
                                                unsigned long dwFlags);
    auto const path_cch_combine_ex = reinterpret_cast<PathCchCombineExFn>(
      GetProcAddress(path_mod.GetHandle(), "PathCchCombineEx"));
    if (path_cch_combine_ex)
    {
      std::vector<wchar_t> buffer(HADESMEM_DETAIL_MAX_PATH_UNICODE);
      HRESULT const hr = path_cch_combine_ex(buffer.data(),
                                             buffer.size(),
                                             base.c_str(),
                                             append.c_str(),
                                             HADESMEM_PATHCCH_ALLOW_LONG_PATHS);
      if (!SUCCEEDED(hr))
      {
        HADESMEM_DETAIL_THROW_EXCEPTION(
          Error{} << ErrorString{"PathCchCombineEx failed."}
                  << ErrorCodeWinHr{hr});
      }

      return buffer.data();
    }
  }

  // Fall back to older API with MAX_PATH limit.
  std::vector<wchar_t> buffer(MAX_PATH);
  if (!::PathCombineW(buffer.data(), base.c_str(), append.c_str()))
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"PathCombineW failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  return buffer.data();
}

inline SmartFileHandle OpenFileForMetadata(std::wstring const& path)
{
  HANDLE const file =
    ::CreateFileW(path.c_str(),
                  GENERIC_READ,
                  FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
                  nullptr,
                  OPEN_EXISTING,
                  FILE_FLAG_BACKUP_SEMANTICS,
                  nullptr);
  if (file == INVALID_HANDLE_VALUE)
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{} << ErrorString{"CreateFile failed."}
                                            << ErrorCodeWinLast{last_error});
  }

  return SmartFileHandle(file);
}

inline BY_HANDLE_FILE_INFORMATION GetFileInformationByHandle(HANDLE file)
{
  BY_HANDLE_FILE_INFORMATION file_info{};
  if (!::GetFileInformationByHandle(file, &file_info))
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(
      Error{} << ErrorString{"GetFileInformationByHandle failed."}
              << ErrorCodeWinLast{last_error});
  }

  return file_info;
}

inline bool ArePathsEquivalent(std::wstring const& left,
                               std::wstring const& right)
{
  SmartFileHandle const left_file{OpenFileForMetadata(left)};
  SmartFileHandle const right_file{OpenFileForMetadata(right)};
  BY_HANDLE_FILE_INFORMATION left_file_info =
    GetFileInformationByHandle(left_file.GetHandle());
  BY_HANDLE_FILE_INFORMATION right_file_info =
    GetFileInformationByHandle(right_file.GetHandle());
  return left_file_info.dwVolumeSerialNumber ==
           right_file_info.dwVolumeSerialNumber &&
         left_file_info.nFileIndexHigh == right_file_info.nFileIndexHigh &&
         left_file_info.nFileIndexLow == right_file_info.nFileIndexLow &&
         left_file_info.nFileSizeHigh == right_file_info.nFileSizeHigh &&
         left_file_info.nFileSizeLow == right_file_info.nFileSizeLow &&
         left_file_info.ftLastWriteTime.dwLowDateTime ==
           right_file_info.ftLastWriteTime.dwLowDateTime &&
         left_file_info.ftLastWriteTime.dwHighDateTime ==
           right_file_info.ftLastWriteTime.dwHighDateTime;
}

inline std::wstring GetRootPath(std::wstring const& path)
{
  int const drive_num = ::PathGetDriveNumberW(path.c_str());
  if (drive_num == -1)
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"PathGetDriveNumber failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  std::vector<wchar_t> drive_path(4);
  ::PathBuildRootW(drive_path.data(), drive_num);
  if (drive_path[0] == L'\0' || drive_path[1] == L'\0' ||
      drive_path[2] == L'\0')
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"PathBuildRoot failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  return drive_path.data();
}

inline DWORD GetFileAttributesWrapper(std::wstring const& path)
{
  DWORD const attributes = ::GetFileAttributesW(path.c_str());
  if (attributes == INVALID_FILE_ATTRIBUTES)
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"GetFileAttributes failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  return attributes;
}

inline void CreateDirectoryWrapper(std::wstring const& path)
{
  if (!CreateDirectoryW(path.c_str(), nullptr))
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"CreateDirectory failed."}
                                    << ErrorCodeWinLast{last_error});
  }
}

inline void CopyFileWrapper(std::wstring const& existing_path,
                            std::wstring const& new_path,
                            bool fail_if_exists)
{
  if (!CopyFileW(existing_path.c_str(), new_path.c_str(), fail_if_exists))
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{} << ErrorString{"CopyFile failed."}
                                            << ErrorCodeWinLast{last_error});
  }
}

inline bool IsDirectory(std::wstring const& path)
{
  DWORD const attributes =
    ::hadesmem::detail::GetFileAttributesWrapper(path.c_str());
  return !!(attributes & FILE_ATTRIBUTE_DIRECTORY);
}

inline bool IsSymlink(std::wstring const& path)
{
  DWORD const attributes =
    ::hadesmem::detail::GetFileAttributesWrapper(path.c_str());
  return !!(attributes & FILE_ATTRIBUTE_REPARSE_POINT);
}

inline std::wstring GetFullPathNameWrapper(std::wstring const& path)
{
  std::vector<wchar_t> full_path(HADESMEM_DETAIL_MAX_PATH_UNICODE);
  DWORD len = GetFullPathNameW(path.c_str(),
                               static_cast<DWORD>(full_path.size()),
                               full_path.data(),
                               nullptr);
  if (!len || full_path.size() < len)
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(
      Error{} << ErrorString{"GetFullPathNameW failed."}
              << ErrorCodeWinLast{last_error} << ErrorCodeWinOther{len});
  }

  return full_path.data();
}

inline std::wstring GetPathBaseName(std::wstring const& path)
{
  return std::wstring(std::find_if(path.rbegin(),
                                   path.rend(),
                                   [](wchar_t c)
                                   {
                                     return c == '\\' || c == '/';
                                   }).base(),
                      path.end());
}

inline std::wstring PathFindFileNameWrapper(std::wstring const& path)
{
  std::vector<wchar_t> file_name(MAX_PATH);
  auto const p = PathFindFileNameW(path.c_str());
  if (p == path.c_str())
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"PathFindFileNameW failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  return file_name.data();
}

inline std::wstring MakeExtendedPath(std::wstring path)
{
  // Use newer and better PathCchCanonicalizeEx if it's available, then fall
  // through to the custom implementation to ensure we always get an extended
  // path back out, rather than just when it's longer than MAX_PATH.
  detail::SmartModuleHandle const path_mod{
    LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll")};
  if (path_mod.IsValid())
  {
    using PathCchCanonicalizeExFn = HRESULT(WINAPI*)(PWSTR pszPathOut,
                                                     size_t cchPathOut,
                                                     PCWSTR pszPathIn,
                                                     unsigned long dwFlags);
    auto const path_cch_combine_ex = reinterpret_cast<PathCchCanonicalizeExFn>(
      GetProcAddress(path_mod.GetHandle(), "PathCchCanonicalizeEx"));
    if (path_cch_combine_ex)
    {
      std::vector<wchar_t> buffer(HADESMEM_DETAIL_MAX_PATH_UNICODE);
      HRESULT const hr = path_cch_combine_ex(buffer.data(),
                                             buffer.size(),
                                             path.c_str(),
                                             HADESMEM_PATHCCH_ALLOW_LONG_PATHS);
      if (!SUCCEEDED(hr))
      {
        HADESMEM_DETAIL_THROW_EXCEPTION(
          Error{} << ErrorString{"PathCchCanonicalizeEx failed."}
                  << ErrorCodeWinHr{hr});
      }

      path = buffer.data();
    }
  }

  // Modified code from http://bit.ly/1int3Iv.
  if (path.compare(0, 2, L"\\\\"))
  {
    if (hadesmem::detail::IsPathRelative(path))
    {
      // ..\foo\bar
      return MakeExtendedPath(hadesmem::detail::CombinePath(
        hadesmem::detail::GetSelfDirPath(), path));
    }
    else
    {
      if (path.compare(0, 1, L"\\"))
      {
        // c:\foo\bar
        return L"\\\\?\\" + path;
      }
      else
      {
        // \foo\bar
        return MakeExtendedPath(hadesmem::detail::GetFullPathNameWrapper(path));
      }
    }
  }
  else
  {
    if (path.compare(0, 3, L"\\\\?"))
    {
      // \\server\share\folder
      return L"\\\\?\\UNC\\" + path.substr(2);
    }
    else
    {
      // \\?\c:\foo\bar
      return path;
    }
  }
}

inline void BufferToFile(std::wstring const& path,
                         void const* buffer,
                         std::streamsize len)
{
  auto const file = OpenFile<char>(path, std::ios::out | std::ios::binary);
  if (!*file)
  {
    HADESMEM_DETAIL_THROW_EXCEPTION(
      hadesmem::Error{} << hadesmem::ErrorString{"Failed to create file."});
  }

  if (!file->write(static_cast<char const*>(buffer), len))
  {
    HADESMEM_DETAIL_THROW_EXCEPTION(
      hadesmem::Error{} << hadesmem::ErrorString{"Failed to write file."});
  }
}
}
}
<commit_msg>[Filesystem] Add FileToBuffer.<commit_after>// Copyright (C) 2010-2014 Joshua Boyce.
// See the file COPYING for copying permission.

#pragma once

#include <fstream>
#include <memory>
#include <string>
#include <vector>

#include <windows.h>
#include <shlwapi.h>

#include <hadesmem/config.hpp>
#include <hadesmem/error.hpp>
#include <hadesmem/detail/self_path.hpp>
#include <hadesmem/detail/smart_handle.hpp>
#include <hadesmem/detail/str_conv.hpp>

#define HADESMEM_PATHCCH_ALLOW_LONG_PATHS 0x00000001

namespace hadesmem
{
namespace detail
{
// libstdc++ doesn't support move operations on file-streams, so we have to
// return a unique_ptr instead.
template <typename CharT>
inline std::unique_ptr<std::basic_fstream<CharT>>
  OpenFile(std::wstring const& path, std::ios_base::openmode mode)
{
#if defined(HADESMEM_MSVC) || defined(HADESMEM_INTEL)
  return std::unique_ptr<std::basic_fstream<CharT>>{
    new std::basic_fstream<CharT>{path, mode}};
#else  // #if defined(HADESMEM_MSVC) || defined(HADESMEM_INTEL)
  // libstdc++ doesn't support wide character overloads for ifstream's
  // construtor.
  return std::unique_ptr<std::basic_fstream<CharT>>{
    new std::basic_fstream<CharT>{hadesmem::detail::WideCharToMultiByte(path),
                                  mode}};
#endif // #if defined(HADESMEM_MSVC) || defined(HADESMEM_INTEL)
}

inline bool DoesFileExist(std::wstring const& path)
{
  return ::GetFileAttributesW(path.c_str()) != INVALID_FILE_ATTRIBUTES;
}

inline bool DoesDirectoryExist(std::wstring const& path)
{
  auto const attrs = ::GetFileAttributesW(path.c_str());
  return attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY);
}

inline bool IsPathRelative(std::wstring const& path)
{
  // Relative paths are always limited to a total of MAX_PATH characters
  return (path.size() >= MAX_PATH) ? false : !!::PathIsRelativeW(path.c_str());
}

inline std::wstring CombinePath(std::wstring const& base,
                                std::wstring const& append)
{
  // Use newer and better PathCchCombineEx if it's available.
  detail::SmartModuleHandle const path_mod{
    LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll")};
  if (path_mod.IsValid())
  {
    using PathCchCombineExFn = HRESULT(WINAPI*)(PWSTR pszPathOut,
                                                size_t cchPathOut,
                                                PCWSTR pszPathIn,
                                                PCWSTR pszMore,
                                                unsigned long dwFlags);
    auto const path_cch_combine_ex = reinterpret_cast<PathCchCombineExFn>(
      GetProcAddress(path_mod.GetHandle(), "PathCchCombineEx"));
    if (path_cch_combine_ex)
    {
      std::vector<wchar_t> buffer(HADESMEM_DETAIL_MAX_PATH_UNICODE);
      HRESULT const hr = path_cch_combine_ex(buffer.data(),
                                             buffer.size(),
                                             base.c_str(),
                                             append.c_str(),
                                             HADESMEM_PATHCCH_ALLOW_LONG_PATHS);
      if (!SUCCEEDED(hr))
      {
        HADESMEM_DETAIL_THROW_EXCEPTION(
          Error{} << ErrorString{"PathCchCombineEx failed."}
                  << ErrorCodeWinHr{hr});
      }

      return buffer.data();
    }
  }

  // Fall back to older API with MAX_PATH limit.
  std::vector<wchar_t> buffer(MAX_PATH);
  if (!::PathCombineW(buffer.data(), base.c_str(), append.c_str()))
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"PathCombineW failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  return buffer.data();
}

inline SmartFileHandle OpenFileForMetadata(std::wstring const& path)
{
  HANDLE const file =
    ::CreateFileW(path.c_str(),
                  GENERIC_READ,
                  FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
                  nullptr,
                  OPEN_EXISTING,
                  FILE_FLAG_BACKUP_SEMANTICS,
                  nullptr);
  if (file == INVALID_HANDLE_VALUE)
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{} << ErrorString{"CreateFile failed."}
                                            << ErrorCodeWinLast{last_error});
  }

  return SmartFileHandle(file);
}

inline BY_HANDLE_FILE_INFORMATION GetFileInformationByHandle(HANDLE file)
{
  BY_HANDLE_FILE_INFORMATION file_info{};
  if (!::GetFileInformationByHandle(file, &file_info))
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(
      Error{} << ErrorString{"GetFileInformationByHandle failed."}
              << ErrorCodeWinLast{last_error});
  }

  return file_info;
}

inline bool ArePathsEquivalent(std::wstring const& left,
                               std::wstring const& right)
{
  SmartFileHandle const left_file{OpenFileForMetadata(left)};
  SmartFileHandle const right_file{OpenFileForMetadata(right)};
  BY_HANDLE_FILE_INFORMATION left_file_info =
    GetFileInformationByHandle(left_file.GetHandle());
  BY_HANDLE_FILE_INFORMATION right_file_info =
    GetFileInformationByHandle(right_file.GetHandle());
  return left_file_info.dwVolumeSerialNumber ==
           right_file_info.dwVolumeSerialNumber &&
         left_file_info.nFileIndexHigh == right_file_info.nFileIndexHigh &&
         left_file_info.nFileIndexLow == right_file_info.nFileIndexLow &&
         left_file_info.nFileSizeHigh == right_file_info.nFileSizeHigh &&
         left_file_info.nFileSizeLow == right_file_info.nFileSizeLow &&
         left_file_info.ftLastWriteTime.dwLowDateTime ==
           right_file_info.ftLastWriteTime.dwLowDateTime &&
         left_file_info.ftLastWriteTime.dwHighDateTime ==
           right_file_info.ftLastWriteTime.dwHighDateTime;
}

inline std::wstring GetRootPath(std::wstring const& path)
{
  int const drive_num = ::PathGetDriveNumberW(path.c_str());
  if (drive_num == -1)
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"PathGetDriveNumber failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  std::vector<wchar_t> drive_path(4);
  ::PathBuildRootW(drive_path.data(), drive_num);
  if (drive_path[0] == L'\0' || drive_path[1] == L'\0' ||
      drive_path[2] == L'\0')
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"PathBuildRoot failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  return drive_path.data();
}

inline DWORD GetFileAttributesWrapper(std::wstring const& path)
{
  DWORD const attributes = ::GetFileAttributesW(path.c_str());
  if (attributes == INVALID_FILE_ATTRIBUTES)
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"GetFileAttributes failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  return attributes;
}

inline void CreateDirectoryWrapper(std::wstring const& path)
{
  if (!CreateDirectoryW(path.c_str(), nullptr))
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"CreateDirectory failed."}
                                    << ErrorCodeWinLast{last_error});
  }
}

inline void CopyFileWrapper(std::wstring const& existing_path,
                            std::wstring const& new_path,
                            bool fail_if_exists)
{
  if (!CopyFileW(existing_path.c_str(), new_path.c_str(), fail_if_exists))
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{} << ErrorString{"CopyFile failed."}
                                            << ErrorCodeWinLast{last_error});
  }
}

inline bool IsDirectory(std::wstring const& path)
{
  DWORD const attributes =
    ::hadesmem::detail::GetFileAttributesWrapper(path.c_str());
  return !!(attributes & FILE_ATTRIBUTE_DIRECTORY);
}

inline bool IsSymlink(std::wstring const& path)
{
  DWORD const attributes =
    ::hadesmem::detail::GetFileAttributesWrapper(path.c_str());
  return !!(attributes & FILE_ATTRIBUTE_REPARSE_POINT);
}

inline std::wstring GetFullPathNameWrapper(std::wstring const& path)
{
  std::vector<wchar_t> full_path(HADESMEM_DETAIL_MAX_PATH_UNICODE);
  DWORD len = GetFullPathNameW(path.c_str(),
                               static_cast<DWORD>(full_path.size()),
                               full_path.data(),
                               nullptr);
  if (!len || full_path.size() < len)
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(
      Error{} << ErrorString{"GetFullPathNameW failed."}
              << ErrorCodeWinLast{last_error} << ErrorCodeWinOther{len});
  }

  return full_path.data();
}

inline std::wstring GetPathBaseName(std::wstring const& path)
{
  return std::wstring(std::find_if(path.rbegin(),
                                   path.rend(),
                                   [](wchar_t c)
                                   {
                                     return c == '\\' || c == '/';
                                   }).base(),
                      path.end());
}

inline std::wstring PathFindFileNameWrapper(std::wstring const& path)
{
  std::vector<wchar_t> file_name(MAX_PATH);
  auto const p = PathFindFileNameW(path.c_str());
  if (p == path.c_str())
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"PathFindFileNameW failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  return file_name.data();
}

inline std::wstring MakeExtendedPath(std::wstring path)
{
  // Use newer and better PathCchCanonicalizeEx if it's available, then fall
  // through to the custom implementation to ensure we always get an extended
  // path back out, rather than just when it's longer than MAX_PATH.
  detail::SmartModuleHandle const path_mod{
    LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll")};
  if (path_mod.IsValid())
  {
    using PathCchCanonicalizeExFn = HRESULT(WINAPI*)(PWSTR pszPathOut,
                                                     size_t cchPathOut,
                                                     PCWSTR pszPathIn,
                                                     unsigned long dwFlags);
    auto const path_cch_combine_ex = reinterpret_cast<PathCchCanonicalizeExFn>(
      GetProcAddress(path_mod.GetHandle(), "PathCchCanonicalizeEx"));
    if (path_cch_combine_ex)
    {
      std::vector<wchar_t> buffer(HADESMEM_DETAIL_MAX_PATH_UNICODE);
      HRESULT const hr = path_cch_combine_ex(buffer.data(),
                                             buffer.size(),
                                             path.c_str(),
                                             HADESMEM_PATHCCH_ALLOW_LONG_PATHS);
      if (!SUCCEEDED(hr))
      {
        HADESMEM_DETAIL_THROW_EXCEPTION(
          Error{} << ErrorString{"PathCchCanonicalizeEx failed."}
                  << ErrorCodeWinHr{hr});
      }

      path = buffer.data();
    }
  }

  // Modified code from http://bit.ly/1int3Iv.
  if (path.compare(0, 2, L"\\\\"))
  {
    if (hadesmem::detail::IsPathRelative(path))
    {
      // ..\foo\bar
      return MakeExtendedPath(hadesmem::detail::CombinePath(
        hadesmem::detail::GetSelfDirPath(), path));
    }
    else
    {
      if (path.compare(0, 1, L"\\"))
      {
        // c:\foo\bar
        return L"\\\\?\\" + path;
      }
      else
      {
        // \foo\bar
        return MakeExtendedPath(hadesmem::detail::GetFullPathNameWrapper(path));
      }
    }
  }
  else
  {
    if (path.compare(0, 3, L"\\\\?"))
    {
      // \\server\share\folder
      return L"\\\\?\\UNC\\" + path.substr(2);
    }
    else
    {
      // \\?\c:\foo\bar
      return path;
    }
  }
}

inline void BufferToFile(std::wstring const& path,
                         void const* buffer,
                         std::streamsize len)
{
  auto const file = OpenFile<char>(path, std::ios::out | std::ios::binary);
  if (!*file)
  {
    HADESMEM_DETAIL_THROW_EXCEPTION(
      hadesmem::Error{} << hadesmem::ErrorString{"Failed to create file."});
  }

  if (!file->write(static_cast<char const*>(buffer), len))
  {
    HADESMEM_DETAIL_THROW_EXCEPTION(
      hadesmem::Error{} << hadesmem::ErrorString{"Failed to write file."});
  }
}

inline std::vector<char> FileToBuffer(std::wstring const& path)
{
  auto const file =
    OpenFile<char>(path, std::ios::in | std::ios::binary | std::ios::ate);
  if (!*file)
  {
    HADESMEM_DETAIL_THROW_EXCEPTION(
      hadesmem::Error{} << hadesmem::ErrorString{"Failed to create file."});
  }

  std::streampos const size = file->tellg();
  if (size <= 0)
  {
    HADESMEM_DETAIL_THROW_EXCEPTION(
      hadesmem::Error() << hadesmem::ErrorString("Empty or invalid file."));
  }

  if (!file->seekg(0, std::ios::beg))
  {
    HADESMEM_DETAIL_THROW_EXCEPTION(hadesmem::Error() << hadesmem::ErrorString(
                                      "Seeking to beginning of file failed."));
  }

  std::vector<char> buffer(static_cast<std::size_t>(size));
  if (!file->read(buffer.data(), size))
  {
    HADESMEM_DETAIL_THROW_EXCEPTION(
      hadesmem::Error{} << hadesmem::ErrorString{"Failed to write file."});
  }

  return buffer;
}
}
}
<|endoftext|>


<commit_before>// Copyright (C) 2010-2014 Joshua Boyce.
// See the file COPYING for copying permission.

#pragma once

#include <fstream>
#include <memory>
#include <string>
#include <vector>

#include <windows.h>
#include <shlwapi.h>

#include <hadesmem/config.hpp>
#include <hadesmem/error.hpp>
#include <hadesmem/detail/self_path.hpp>
#include <hadesmem/detail/smart_handle.hpp>
#include <hadesmem/detail/str_conv.hpp>

#define HADESMEM_PATHCCH_ALLOW_LONG_PATHS 0x00000001

namespace hadesmem
{
namespace detail
{
// libstdc++ doesn't support move operations on file-streams, so we have to
// return a unique_ptr instead.
template <typename CharT>
inline std::unique_ptr<std::basic_fstream<CharT>>
  OpenFile(std::wstring const& path, std::ios_base::openmode mode)
{
#if defined(HADESMEM_MSVC) || defined(HADESMEM_INTEL)
  return std::unique_ptr<std::basic_fstream<CharT>>{
    new std::basic_fstream<CharT>{path, mode}};
#else  // #if defined(HADESMEM_MSVC) || defined(HADESMEM_INTEL)
  // libstdc++ doesn't support wide character overloads for ifstream's
  // construtor.
  return std::unique_ptr<std::basic_fstream<CharT>>{
    new std::basic_fstream<CharT>{hadesmem::detail::WideCharToMultiByte(path),
                                  mode}};
#endif // #if defined(HADESMEM_MSVC) || defined(HADESMEM_INTEL)
}

inline bool DoesFileExist(std::wstring const& path)
{
  return ::GetFileAttributesW(path.c_str()) != INVALID_FILE_ATTRIBUTES;
}

inline bool IsPathRelative(std::wstring const& path)
{
  // Relative paths are always limited to a total of MAX_PATH characters
  return (path.size() >= MAX_PATH) ? false : !!::PathIsRelativeW(path.c_str());
}

inline std::wstring CombinePath(std::wstring const& base,
                                std::wstring const& append)
{
  // Use newer and better PathCchCombineEx if it's available.
  detail::SmartModuleHandle const path_mod{
    LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll")};
  if (path_mod.IsValid())
  {
    using PathCchCombineExFn = HRESULT(WINAPI*)(PWSTR pszPathOut,
                                                size_t cchPathOut,
                                                PCWSTR pszPathIn,
                                                PCWSTR pszMore,
                                                unsigned long dwFlags);
    auto const path_cch_combine_ex = reinterpret_cast<PathCchCombineExFn>(
      GetProcAddress(path_mod.GetHandle(), "PathCchCombineEx"));
    if (path_cch_combine_ex)
    {
      std::vector<wchar_t> buffer(HADESMEM_DETAIL_MAX_PATH_UNICODE);
      HRESULT const hr = path_cch_combine_ex(buffer.data(),
                                             buffer.size(),
                                             base.c_str(),
                                             append.c_str(),
                                             HADESMEM_PATHCCH_ALLOW_LONG_PATHS);
      if (!SUCCEEDED(hr))
      {
        HADESMEM_DETAIL_THROW_EXCEPTION(
          Error{} << ErrorString{"PathCchCombineEx failed."}
                  << ErrorCodeWinHr{hr});
      }

      return buffer.data();
    }
  }

  // Fall back to older API with MAX_PATH limit.
  std::vector<wchar_t> buffer(MAX_PATH);
  if (!::PathCombineW(buffer.data(), base.c_str(), append.c_str()))
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"PathCombineW failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  return buffer.data();
}

inline SmartFileHandle OpenFileForMetadata(std::wstring const& path)
{
  HANDLE const file =
    ::CreateFileW(path.c_str(),
                  GENERIC_READ,
                  FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
                  nullptr,
                  OPEN_EXISTING,
                  FILE_FLAG_BACKUP_SEMANTICS,
                  nullptr);
  if (file == INVALID_HANDLE_VALUE)
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{} << ErrorString{"CreateFile failed."}
                                            << ErrorCodeWinLast{last_error});
  }

  return SmartFileHandle(file);
}

inline BY_HANDLE_FILE_INFORMATION GetFileInformationByHandle(HANDLE file)
{
  BY_HANDLE_FILE_INFORMATION file_info{};
  if (!::GetFileInformationByHandle(file, &file_info))
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(
      Error{} << ErrorString{"GetFileInformationByHandle failed."}
              << ErrorCodeWinLast{last_error});
  }

  return file_info;
}

inline bool ArePathsEquivalent(std::wstring const& left,
                               std::wstring const& right)
{
  SmartFileHandle const left_file{OpenFileForMetadata(left)};
  SmartFileHandle const right_file{OpenFileForMetadata(right)};
  BY_HANDLE_FILE_INFORMATION left_file_info =
    GetFileInformationByHandle(left_file.GetHandle());
  BY_HANDLE_FILE_INFORMATION right_file_info =
    GetFileInformationByHandle(right_file.GetHandle());
  return left_file_info.dwVolumeSerialNumber ==
           right_file_info.dwVolumeSerialNumber &&
         left_file_info.nFileIndexHigh == right_file_info.nFileIndexHigh &&
         left_file_info.nFileIndexLow == right_file_info.nFileIndexLow &&
         left_file_info.nFileSizeHigh == right_file_info.nFileSizeHigh &&
         left_file_info.nFileSizeLow == right_file_info.nFileSizeLow &&
         left_file_info.ftLastWriteTime.dwLowDateTime ==
           right_file_info.ftLastWriteTime.dwLowDateTime &&
         left_file_info.ftLastWriteTime.dwHighDateTime ==
           right_file_info.ftLastWriteTime.dwHighDateTime;
}

inline std::wstring GetRootPath(std::wstring const& path)
{
  int const drive_num = ::PathGetDriveNumberW(path.c_str());
  if (drive_num == -1)
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"PathGetDriveNumber failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  std::vector<wchar_t> drive_path(4);
  ::PathBuildRootW(drive_path.data(), drive_num);
  if (drive_path[0] == L'\0' || drive_path[1] == L'\0' ||
      drive_path[2] == L'\0')
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"PathBuildRoot failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  return drive_path.data();
}

inline DWORD GetFileAttributesWrapper(std::wstring const& path)
{
  DWORD const attributes = ::GetFileAttributesW(path.c_str());
  if (attributes == INVALID_FILE_ATTRIBUTES)
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"GetFileAttributes failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  return attributes;
}

inline bool IsDirectory(std::wstring const& path)
{
  DWORD const attributes =
    ::hadesmem::detail::GetFileAttributesWrapper(path.c_str());
  return !!(attributes & FILE_ATTRIBUTE_DIRECTORY);
}

inline bool IsSymlink(std::wstring const& path)
{
  DWORD const attributes =
    ::hadesmem::detail::GetFileAttributesWrapper(path.c_str());
  return !!(attributes & FILE_ATTRIBUTE_REPARSE_POINT);
}

inline std::wstring GetFullPathNameWrapper(std::wstring const& path)
{
  std::vector<wchar_t> full_path(HADESMEM_DETAIL_MAX_PATH_UNICODE);
  DWORD len = GetFullPathNameW(path.c_str(),
                               static_cast<DWORD>(full_path.size()),
                               full_path.data(),
                               nullptr);
  if (!len || full_path.size() < len)
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(
      Error{} << ErrorString{"GetFullPathNameW failed."}
              << ErrorCodeWinLast{last_error} << ErrorCodeWinOther{len});
  }

  return full_path.data();
}

inline std::wstring MakeExtendedPath(std::wstring path)
{
  // Use newer and better PathCchCanonicalizeEx if it's available, then fall
  // through to the custom implementation to ensure we always get an extended
  // path back out, rather than just when it's longer than MAX_PATH.
  detail::SmartModuleHandle const path_mod{
    LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll")};
  if (path_mod.IsValid())
  {
    using PathCchCanonicalizeExFn = HRESULT(WINAPI*)(PWSTR pszPathOut,
                                                     size_t cchPathOut,
                                                     PCWSTR pszPathIn,
                                                     unsigned long dwFlags);
    auto const path_cch_combine_ex = reinterpret_cast<PathCchCanonicalizeExFn>(
      GetProcAddress(path_mod.GetHandle(), "PathCchCanonicalizeEx"));
    if (path_cch_combine_ex)
    {
      std::vector<wchar_t> buffer(HADESMEM_DETAIL_MAX_PATH_UNICODE);
      HRESULT const hr = path_cch_combine_ex(buffer.data(),
                                             buffer.size(),
                                             path.c_str(),
                                             HADESMEM_PATHCCH_ALLOW_LONG_PATHS);
      if (!SUCCEEDED(hr))
      {
        HADESMEM_DETAIL_THROW_EXCEPTION(
          Error{} << ErrorString{"PathCchCanonicalizeEx failed."}
                  << ErrorCodeWinHr{hr});
      }

      path = buffer.data();
    }
  }

  // Modified code from http://bit.ly/1int3Iv.
  if (path.compare(0, 2, L"\\\\"))
  {
    if (hadesmem::detail::IsPathRelative(path))
    {
      // ..\foo\bar
      return MakeExtendedPath(hadesmem::detail::CombinePath(
        hadesmem::detail::GetSelfDirPath(), path));
    }
    else
    {
      if (path.compare(0, 1, L"\\"))
      {
        // c:\foo\bar
        return L"\\\\?\\" + path;
      }
      else
      {
        // \foo\bar
        return MakeExtendedPath(hadesmem::detail::GetFullPathNameWrapper(path));
      }
    }
  }
  else
  {
    if (path.compare(0, 3, L"\\\\?"))
    {
      // \\server\share\folder
      return L"\\\\?\\UNC\\" + path.substr(2);
    }
    else
    {
      // \\?\c:\foo\bar
      return path;
    }
  }
}
}
}
<commit_msg>* [Filesystem] Add some more helpers.<commit_after>// Copyright (C) 2010-2014 Joshua Boyce.
// See the file COPYING for copying permission.

#pragma once

#include <fstream>
#include <memory>
#include <string>
#include <vector>

#include <windows.h>
#include <shlwapi.h>

#include <hadesmem/config.hpp>
#include <hadesmem/error.hpp>
#include <hadesmem/detail/self_path.hpp>
#include <hadesmem/detail/smart_handle.hpp>
#include <hadesmem/detail/str_conv.hpp>

#define HADESMEM_PATHCCH_ALLOW_LONG_PATHS 0x00000001

namespace hadesmem
{
namespace detail
{
// libstdc++ doesn't support move operations on file-streams, so we have to
// return a unique_ptr instead.
template <typename CharT>
inline std::unique_ptr<std::basic_fstream<CharT>>
  OpenFile(std::wstring const& path, std::ios_base::openmode mode)
{
#if defined(HADESMEM_MSVC) || defined(HADESMEM_INTEL)
  return std::unique_ptr<std::basic_fstream<CharT>>{
    new std::basic_fstream<CharT>{path, mode}};
#else  // #if defined(HADESMEM_MSVC) || defined(HADESMEM_INTEL)
  // libstdc++ doesn't support wide character overloads for ifstream's
  // construtor.
  return std::unique_ptr<std::basic_fstream<CharT>>{
    new std::basic_fstream<CharT>{hadesmem::detail::WideCharToMultiByte(path),
                                  mode}};
#endif // #if defined(HADESMEM_MSVC) || defined(HADESMEM_INTEL)
}

inline bool DoesFileExist(std::wstring const& path)
{
  return ::GetFileAttributesW(path.c_str()) != INVALID_FILE_ATTRIBUTES;
}

inline bool DoesDirectoryExist(std::wstring const& path)
{
  auto const attrs = ::GetFileAttributesW(path.c_str());
  return attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY);
}

inline bool IsPathRelative(std::wstring const& path)
{
  // Relative paths are always limited to a total of MAX_PATH characters
  return (path.size() >= MAX_PATH) ? false : !!::PathIsRelativeW(path.c_str());
}

inline std::wstring CombinePath(std::wstring const& base,
                                std::wstring const& append)
{
  // Use newer and better PathCchCombineEx if it's available.
  detail::SmartModuleHandle const path_mod{
    LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll")};
  if (path_mod.IsValid())
  {
    using PathCchCombineExFn = HRESULT(WINAPI*)(PWSTR pszPathOut,
                                                size_t cchPathOut,
                                                PCWSTR pszPathIn,
                                                PCWSTR pszMore,
                                                unsigned long dwFlags);
    auto const path_cch_combine_ex = reinterpret_cast<PathCchCombineExFn>(
      GetProcAddress(path_mod.GetHandle(), "PathCchCombineEx"));
    if (path_cch_combine_ex)
    {
      std::vector<wchar_t> buffer(HADESMEM_DETAIL_MAX_PATH_UNICODE);
      HRESULT const hr = path_cch_combine_ex(buffer.data(),
                                             buffer.size(),
                                             base.c_str(),
                                             append.c_str(),
                                             HADESMEM_PATHCCH_ALLOW_LONG_PATHS);
      if (!SUCCEEDED(hr))
      {
        HADESMEM_DETAIL_THROW_EXCEPTION(
          Error{} << ErrorString{"PathCchCombineEx failed."}
                  << ErrorCodeWinHr{hr});
      }

      return buffer.data();
    }
  }

  // Fall back to older API with MAX_PATH limit.
  std::vector<wchar_t> buffer(MAX_PATH);
  if (!::PathCombineW(buffer.data(), base.c_str(), append.c_str()))
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"PathCombineW failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  return buffer.data();
}

inline SmartFileHandle OpenFileForMetadata(std::wstring const& path)
{
  HANDLE const file =
    ::CreateFileW(path.c_str(),
                  GENERIC_READ,
                  FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
                  nullptr,
                  OPEN_EXISTING,
                  FILE_FLAG_BACKUP_SEMANTICS,
                  nullptr);
  if (file == INVALID_HANDLE_VALUE)
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{} << ErrorString{"CreateFile failed."}
                                            << ErrorCodeWinLast{last_error});
  }

  return SmartFileHandle(file);
}

inline BY_HANDLE_FILE_INFORMATION GetFileInformationByHandle(HANDLE file)
{
  BY_HANDLE_FILE_INFORMATION file_info{};
  if (!::GetFileInformationByHandle(file, &file_info))
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(
      Error{} << ErrorString{"GetFileInformationByHandle failed."}
              << ErrorCodeWinLast{last_error});
  }

  return file_info;
}

inline bool ArePathsEquivalent(std::wstring const& left,
                               std::wstring const& right)
{
  SmartFileHandle const left_file{OpenFileForMetadata(left)};
  SmartFileHandle const right_file{OpenFileForMetadata(right)};
  BY_HANDLE_FILE_INFORMATION left_file_info =
    GetFileInformationByHandle(left_file.GetHandle());
  BY_HANDLE_FILE_INFORMATION right_file_info =
    GetFileInformationByHandle(right_file.GetHandle());
  return left_file_info.dwVolumeSerialNumber ==
           right_file_info.dwVolumeSerialNumber &&
         left_file_info.nFileIndexHigh == right_file_info.nFileIndexHigh &&
         left_file_info.nFileIndexLow == right_file_info.nFileIndexLow &&
         left_file_info.nFileSizeHigh == right_file_info.nFileSizeHigh &&
         left_file_info.nFileSizeLow == right_file_info.nFileSizeLow &&
         left_file_info.ftLastWriteTime.dwLowDateTime ==
           right_file_info.ftLastWriteTime.dwLowDateTime &&
         left_file_info.ftLastWriteTime.dwHighDateTime ==
           right_file_info.ftLastWriteTime.dwHighDateTime;
}

inline std::wstring GetRootPath(std::wstring const& path)
{
  int const drive_num = ::PathGetDriveNumberW(path.c_str());
  if (drive_num == -1)
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"PathGetDriveNumber failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  std::vector<wchar_t> drive_path(4);
  ::PathBuildRootW(drive_path.data(), drive_num);
  if (drive_path[0] == L'\0' || drive_path[1] == L'\0' ||
      drive_path[2] == L'\0')
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"PathBuildRoot failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  return drive_path.data();
}

inline DWORD GetFileAttributesWrapper(std::wstring const& path)
{
  DWORD const attributes = ::GetFileAttributesW(path.c_str());
  if (attributes == INVALID_FILE_ATTRIBUTES)
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"GetFileAttributes failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  return attributes;
}

inline void CreateDirectoryWrapper(std::wstring const& path)
{
  if (!CreateDirectoryW(path.c_str(), nullptr))
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"CreateDirectory failed."}
                                    << ErrorCodeWinLast{last_error});
  }
}

inline void CopyFileWrapper(std::wstring const& existing_path,
                            std::wstring const& new_path,
                            bool fail_if_exists)
{
  if (!CopyFileW(existing_path.c_str(), new_path.c_str(), fail_if_exists))
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{} << ErrorString{"CopyFile failed."}
                                            << ErrorCodeWinLast{last_error});
  }
}

inline bool IsDirectory(std::wstring const& path)
{
  DWORD const attributes =
    ::hadesmem::detail::GetFileAttributesWrapper(path.c_str());
  return !!(attributes & FILE_ATTRIBUTE_DIRECTORY);
}

inline bool IsSymlink(std::wstring const& path)
{
  DWORD const attributes =
    ::hadesmem::detail::GetFileAttributesWrapper(path.c_str());
  return !!(attributes & FILE_ATTRIBUTE_REPARSE_POINT);
}

inline std::wstring GetFullPathNameWrapper(std::wstring const& path)
{
  std::vector<wchar_t> full_path(HADESMEM_DETAIL_MAX_PATH_UNICODE);
  DWORD len = GetFullPathNameW(path.c_str(),
                               static_cast<DWORD>(full_path.size()),
                               full_path.data(),
                               nullptr);
  if (!len || full_path.size() < len)
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(
      Error{} << ErrorString{"GetFullPathNameW failed."}
              << ErrorCodeWinLast{last_error} << ErrorCodeWinOther{len});
  }

  return full_path.data();
}

inline std::wstring GetPathBaseName(std::wstring const& path)
{
  return std::wstring(std::find_if(path.rbegin(),
                                   path.rend(),
                                   [](wchar_t c)
                                   {
                                     return c == '\\' || c == '/';
                                   }).base(),
                      path.end());
}

inline std::wstring PathFindFileNameWrapper(std::wstring const& path)
{
  std::vector<wchar_t> file_name(MAX_PATH);
  auto const p = PathFindFileNameW(path.c_str());
  if (p == path.c_str())
  {
    DWORD const last_error = ::GetLastError();
    HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                    << ErrorString{"PathFindFileNameW failed."}
                                    << ErrorCodeWinLast{last_error});
  }

  return file_name.data();
}

inline std::wstring MakeExtendedPath(std::wstring path)
{
  // Use newer and better PathCchCanonicalizeEx if it's available, then fall
  // through to the custom implementation to ensure we always get an extended
  // path back out, rather than just when it's longer than MAX_PATH.
  detail::SmartModuleHandle const path_mod{
    LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll")};
  if (path_mod.IsValid())
  {
    using PathCchCanonicalizeExFn = HRESULT(WINAPI*)(PWSTR pszPathOut,
                                                     size_t cchPathOut,
                                                     PCWSTR pszPathIn,
                                                     unsigned long dwFlags);
    auto const path_cch_combine_ex = reinterpret_cast<PathCchCanonicalizeExFn>(
      GetProcAddress(path_mod.GetHandle(), "PathCchCanonicalizeEx"));
    if (path_cch_combine_ex)
    {
      std::vector<wchar_t> buffer(HADESMEM_DETAIL_MAX_PATH_UNICODE);
      HRESULT const hr = path_cch_combine_ex(buffer.data(),
                                             buffer.size(),
                                             path.c_str(),
                                             HADESMEM_PATHCCH_ALLOW_LONG_PATHS);
      if (!SUCCEEDED(hr))
      {
        HADESMEM_DETAIL_THROW_EXCEPTION(
          Error{} << ErrorString{"PathCchCanonicalizeEx failed."}
                  << ErrorCodeWinHr{hr});
      }

      path = buffer.data();
    }
  }

  // Modified code from http://bit.ly/1int3Iv.
  if (path.compare(0, 2, L"\\\\"))
  {
    if (hadesmem::detail::IsPathRelative(path))
    {
      // ..\foo\bar
      return MakeExtendedPath(hadesmem::detail::CombinePath(
        hadesmem::detail::GetSelfDirPath(), path));
    }
    else
    {
      if (path.compare(0, 1, L"\\"))
      {
        // c:\foo\bar
        return L"\\\\?\\" + path;
      }
      else
      {
        // \foo\bar
        return MakeExtendedPath(hadesmem::detail::GetFullPathNameWrapper(path));
      }
    }
  }
  else
  {
    if (path.compare(0, 3, L"\\\\?"))
    {
      // \\server\share\folder
      return L"\\\\?\\UNC\\" + path.substr(2);
    }
    else
    {
      // \\?\c:\foo\bar
      return path;
    }
  }
}

inline void BufferToFile(std::wstring const& path,
                         void const* buffer,
                         std::streamsize len)
{
  std::ofstream file(path, std::ios::binary);
  if (!file)
  {
    HADESMEM_DETAIL_THROW_EXCEPTION(
      hadesmem::Error{} << hadesmem::ErrorString{"Failed to create file."});
  }

  if (!file.write(static_cast<char const*>(buffer), len))
  {
    HADESMEM_DETAIL_THROW_EXCEPTION(
      hadesmem::Error{} << hadesmem::ErrorString{"Failed to write file."});
  }
}
}
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "SubStringRenderer.h"

//--- standard modules used ----------------------------------------------------
#include "Dbg.h"

//--- c-modules used -----------------------------------------------------------

//---- SubStringRenderer ---------------------------------------------------------------
RegisterRenderer(SubStringRenderer);

SubStringRenderer::SubStringRenderer(const char *name) : Renderer(name) { }

SubStringRenderer::~SubStringRenderer() { }

void SubStringRenderer::RenderAll(ostream &reply, Context &ctx, const ROAnything &config)
{
	StartTrace(SubStringRenderer.RenderAll);

	long start = config["Start"].AsLong(0L);
	long len   = config["Length"].AsLong(-1L);
	String str;

	Renderer::RenderOnString(str, ctx, config["String"]);
	if (str.Length()) {
		String ret(str.SubString(start, len));
		Trace("SubString(" << start << "," << len << ")-->" << ret);
		reply << ret;
	}
}
<commit_msg>Start and Length slot can be Rendererspecs now<commit_after>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "SubStringRenderer.h"

//--- standard modules used ----------------------------------------------------
#include "Dbg.h"

//--- c-modules used -----------------------------------------------------------

//---- SubStringRenderer ---------------------------------------------------------------
RegisterRenderer(SubStringRenderer);

SubStringRenderer::SubStringRenderer(const char *name)
	: Renderer(name)
{
}

SubStringRenderer::~SubStringRenderer()
{
}

void SubStringRenderer::RenderAll(ostream &reply, Context &ctx, const ROAnything &config)
{
	StartTrace(SubStringRenderer.RenderAll);

	long start = RenderToString(ctx, config["Start"]).AsLong(0L);
	long len   = RenderToString(ctx, config["Length"]).AsLong(-1L);
	String str;

	Renderer::RenderOnString(str, ctx, config["String"]);
	if (str.Length()) {
		String ret(str.SubString(start, len));
		Trace("SubString(" << start << "," << len << ")-->" << ret);
		reply << ret;
	}
}
<|endoftext|>


<commit_before>#include "MyModel.h"
#include "DNest4/code/DNest4.h"
#include "Data.h"
#include <cmath>

using namespace std;
using namespace DNest4;

const Cauchy MyModel::cauchy(0.0, 5.0);

MyModel::MyModel()
:objects(3, 100, false, MyConditionalPrior(), PriorType::log_uniform)
,mu(Data::get_instance().get_t().size())
{

}

void MyModel::from_prior(RNG& rng)
{
	objects.from_prior(rng);
	log_sigma = cauchy.generate(rng);
    sigma = exp(log_sigma);
	calculate_mu();
}

void MyModel::calculate_mu(bool update)
{
	// Get the times from the data
	const vector<double>& t = Data::get_instance().get_t();

	// Get the components
	const vector< vector<double> >& components = (update)?(objects.get_added()):
				                                          (objects.get_components());

	// Zero the signal
	if(!update)
		mu.assign(mu.size(), 0.0);

	double T, A, phi;
	for(size_t j=0; j<components.size(); j++)
	{
		T = exp(components[j][0]);
		A = exp(components[j][1]);
		phi = components[j][2];
		for(size_t i=0; i<t.size(); i++)
			mu[i] += A*sin(2.*M_PI*t[i]/T + phi);
	}
}

double MyModel::perturb(RNG& rng)
{
	double logH = 0.;

	if(rng.rand() <= 0.75)
	{
		logH += objects.perturb(rng);
		calculate_mu(objects.get_removed().size() == 0);
	}
	else
	{
		logH += cauchy.perturb(log_sigma, rng);
        sigma = exp(log_sigma);
	}

	return logH;
}

double MyModel::log_likelihood() const
{
	// Get the data
	const vector<double>& y = Data::get_instance().get_y();
    const vector<double>& sig = Data::get_instance().get_sig();

	double logL = 0.;
	double var;
	for(size_t i=0; i<y.size(); i++)
    {
        var = sig[i]*sig[i] + sigma*sigma;
		logL += -0.5*log(2.*M_PI*var) - 0.5*pow(y[i] - mu[i], 2)/var;
    }

	return logL;
}

void MyModel::print(std::ostream& out) const
{
	for(size_t i=0; i<mu.size(); i++)
		out<<mu[i]<<' ';
	out<<sigma<<' ';
	objects.print(out); out<<' ';
}

void MyModel::read(std::istream& in)
{
    double junk;
	for(size_t i=0; i<mu.size(); i++)
		in>>junk;
	in>>sigma;
    log_sigma = log(sigma);

	objects.read(in);
    calculate_mu();
}

string MyModel::description() const
{
	return string("objects, sigma");
}

<commit_msg>Description function<commit_after>#include "MyModel.h"
#include "DNest4/code/DNest4.h"
#include "Data.h"
#include <cmath>
#include <sstream>

using namespace std;
using namespace DNest4;

const Cauchy MyModel::cauchy(0.0, 5.0);

MyModel::MyModel()
:objects(3, 100, false, MyConditionalPrior(), PriorType::log_uniform)
,mu(Data::get_instance().get_t().size())
{

}

void MyModel::from_prior(RNG& rng)
{
	objects.from_prior(rng);
	log_sigma = cauchy.generate(rng);
    sigma = exp(log_sigma);
	calculate_mu();
}

void MyModel::calculate_mu(bool update)
{
	// Get the times from the data
	const vector<double>& t = Data::get_instance().get_t();

	// Get the components
	const vector< vector<double> >& components = (update)?(objects.get_added()):
				                                          (objects.get_components());

	// Zero the signal
	if(!update)
		mu.assign(mu.size(), 0.0);

	double T, A, phi;
	for(size_t j=0; j<components.size(); j++)
	{
		T = exp(components[j][0]);
		A = exp(components[j][1]);
		phi = components[j][2];
		for(size_t i=0; i<t.size(); i++)
			mu[i] += A*sin(2.*M_PI*t[i]/T + phi);
	}
}

double MyModel::perturb(RNG& rng)
{
	double logH = 0.;

	if(rng.rand() <= 0.75)
	{
		logH += objects.perturb(rng);
		calculate_mu(objects.get_removed().size() == 0);
	}
	else
	{
		logH += cauchy.perturb(log_sigma, rng);
        sigma = exp(log_sigma);
	}

	return logH;
}

double MyModel::log_likelihood() const
{
	// Get the data
	const vector<double>& y = Data::get_instance().get_y();
    const vector<double>& sig = Data::get_instance().get_sig();

	double logL = 0.;
	double var;
	for(size_t i=0; i<y.size(); i++)
    {
        var = sig[i]*sig[i] + sigma*sigma;
		logL += -0.5*log(2.*M_PI*var) - 0.5*pow(y[i] - mu[i], 2)/var;
    }

	return logL;
}

void MyModel::print(std::ostream& out) const
{
	for(size_t i=0; i<mu.size(); i++)
		out<<mu[i]<<' ';
	out<<sigma<<' ';
	objects.print(out); out<<' ';
}

void MyModel::read(std::istream& in)
{
    double junk;
	for(size_t i=0; i<mu.size(); i++)
		in>>junk;
	in>>sigma;
    log_sigma = log(sigma);

	objects.read(in);
    calculate_mu();
}

string MyModel::description() const
{
    stringstream s;

    // Anything printed by MyModel::print (except the last line)
    for(size_t i=0; i<mu.size(); i++)
        s<<"mu ["<<i<<"], ";
    s<<"sigma, ";

    // The rest is all what happens when you call .print on an RJObject
    s<<"dim_components, max_num_components, ";

    // Then the hyperparameters (i.e. whatever MyConditionalPrior::print prints)
    s<<"location_log_period, scale_log_period, ";
    s<<"location_log_amplitude, scale_log_amplitude, ";

    // Then the actual number of components
    s<<"num_components, ";

    // Then it's all the components, padded with zeros
    // max_num_components is 100 in this model, so that's how far the
    // zero padding goes.
    for(int i=0; i<100; ++i)
        s<<"log_period["<<i<<"], ";
    for(int i=0; i<100; ++i)
        s<<"log_amplitude["<<i<<"], ";
    for(int i=0; i<100; ++i)
        s<<"phase["<<i<<"], ";
	return s.str();
}

<|endoftext|>