<commit_before>/*************************************************************************
 *
 *  $RCSfile: ZipPackageStream.hxx,v $
 *
 *  $Revision: 1.18 $
 *
 *  last change: $Author: kz $ $Date: 2005-07-12 12:32:00 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _ZIP_PACKAGE_STREAM_HXX
#define _ZIP_PACKAGE_STREAM_HXX

#ifndef _COM_SUN_STAR_IO_XACTIVEDATASINK_HPP_
#include <com/sun/star/io/XActiveDataSink.hpp>
#endif
#ifndef _COM_SUN_STAR_PACKAGES_XDATASINKENCRSUPPORT_HPP_
#include <com/sun/star/packages/XDataSinkEncrSupport.hpp>
#endif

#ifndef _ZIP_PACKAGE_ENTRY_HXX
#include <ZipPackageEntry.hxx>
#endif
#ifndef _VOS_REF_H_
#include <vos/ref.hxx>
#endif
#ifndef _ENCRYPTION_DATA_HXX_
#include <EncryptionData.hxx>
#endif
#ifndef _CPPUHELPER_IMPLBASE2_HXX
#include <cppuhelper/implbase2.hxx>
#endif

#ifndef __MUTEXHOLDER_HXX_
#include <mutexholder.hxx>
#endif

#define PACKAGE_STREAM_NOTSET           0
#define PACKAGE_STREAM_PACKAGEMEMBER    1
#define PACKAGE_STREAM_DETECT           2
#define PACKAGE_STREAM_DATA             3
#define PACKAGE_STREAM_RAW              4

class ZipPackage;
struct ZipEntry;
class ZipPackageStream : public cppu::ImplInheritanceHelper2
<
    ZipPackageEntry,
    ::com::sun::star::io::XActiveDataSink,
    ::com::sun::star::packages::XDataSinkEncrSupport
>
{
    static com::sun::star::uno::Sequence < sal_Int8 > aImplementationId;
protected:
    com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xStream;
    const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > m_xFactory;
    ZipPackage          &rZipPackage;
    sal_Bool            bToBeCompressed, bToBeEncrypted, bHaveOwnKey, bIsEncrypted;
    vos::ORef < EncryptionData > xEncryptionData;

    sal_uInt8   m_nStreamMode;
    sal_uInt32  m_nMagicalHackPos;
    sal_uInt32  m_nMagicalHackSize;

    SotMutexHolderRef m_aSharedMutexRef;

public:
    sal_Bool HasOwnKey ()        { return bHaveOwnKey;}
    sal_Bool IsToBeCompressed () { return bToBeCompressed;}
    sal_Bool IsToBeEncrypted ()  { return bToBeEncrypted;}
    sal_Bool IsEncrypted ()      { return bIsEncrypted;}
    sal_Bool IsPackageMember ()  { return m_nStreamMode == PACKAGE_STREAM_PACKAGEMEMBER;}
    vos::ORef < EncryptionData > & getEncryptionData ()
    { return xEncryptionData;}
    const com::sun::star::uno::Sequence < sal_Int8 >& getKey ()
    { return xEncryptionData->aKey;}
    const com::sun::star::uno::Sequence < sal_uInt8 >& getInitialisationVector ()
    { return xEncryptionData->aInitVector;}
    const com::sun::star::uno::Sequence < sal_uInt8 >& getDigest ()
    { return xEncryptionData->aDigest;}
    const com::sun::star::uno::Sequence < sal_uInt8 >& getSalt ()
    { return xEncryptionData->aSalt;}
    const sal_Int32 getIterationCount ()
    { return xEncryptionData->nIterationCount;}
    const sal_Int32 getSize ()
    { return aEntry.nSize;}

    sal_uInt8 GetStreamMode() { return m_nStreamMode; }
    sal_uInt32 GetMagicalHackPos() { return m_nMagicalHackPos; }
    sal_uInt32 GetMagicalHackSize() { return m_nMagicalHackSize; }

    void SetToBeCompressed (sal_Bool bNewValue) { bToBeCompressed = bNewValue;}
    void SetIsEncrypted (sal_Bool bNewValue) { bIsEncrypted = bNewValue;}
    void SetToBeEncrypted (sal_Bool bNewValue)
    {
        bToBeEncrypted  = bNewValue;
        if ( bToBeEncrypted && xEncryptionData.isEmpty())
            xEncryptionData = new EncryptionData;
        else if ( !bToBeEncrypted && !xEncryptionData.isEmpty() )
            xEncryptionData.unbind();
    }
    void SetPackageMember (sal_Bool bNewValue);
    void setKey (const com::sun::star::uno::Sequence < sal_Int8 >& rNewKey )
    { xEncryptionData->aKey = rNewKey;}
    void setInitialisationVector (const com::sun::star::uno::Sequence < sal_uInt8 >& rNewVector )
    { xEncryptionData->aInitVector = rNewVector;}
    void setSalt (const com::sun::star::uno::Sequence < sal_uInt8 >& rNewSalt )
    { xEncryptionData->aSalt = rNewSalt;}
    void setDigest (const com::sun::star::uno::Sequence < sal_uInt8 >& rNewDigest )
    { xEncryptionData->aDigest = rNewDigest;}
    void setIterationCount (const sal_Int32 nNewCount)
    { xEncryptionData->nIterationCount = nNewCount;}
    void setSize (const sal_Int32 nNewSize);

    ZipPackageStream ( ZipPackage & rNewPackage,
                        const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory >& xFactory,
                        sal_Bool bAllowRemoveOnInsert );
    virtual ~ZipPackageStream( void );

    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetRawEncrStreamNoHeaderCopy();
    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > TryToGetRawFromDataStream(
                                                                                sal_Bool bAddHeaderForEncr );

    sal_Bool ParsePackageRawStream();

    void setZipEntry( const ZipEntry &rInEntry);
    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getRawData()
        throw(::com::sun::star::uno::RuntimeException);

    static ::com::sun::star::uno::Sequence < sal_Int8 >& static_getImplementationId()
    {
        return aImplementationId;
    }

    // XActiveDataSink
    virtual void SAL_CALL setInputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream )
        throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream(  )
        throw(::com::sun::star::uno::RuntimeException);

    // XDataSinkEncrSupport
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getDataStream()
        throw ( ::com::sun::star::packages::WrongPasswordException,
                ::com::sun::star::io::IOException,
                ::com::sun::star::uno::RuntimeException );
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getRawStream()
        throw ( ::com::sun::star::packages::NoEncryptionException,
                ::com::sun::star::io::IOException,
                ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL setDataStream(
                    const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream )
        throw ( ::com::sun::star::io::IOException,
                ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL setRawStream(
                    const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream )
        throw ( ::com::sun::star::packages::EncryptionNotAllowedException,
                ::com::sun::star::packages::NoRawFormatException,
                ::com::sun::star::io::IOException,
                ::com::sun::star::uno::RuntimeException );
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getPlainRawStream()
        throw ( ::com::sun::star::io::IOException,
                ::com::sun::star::uno::RuntimeException );

    // XUnoTunnel
    virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
        throw(::com::sun::star::uno::RuntimeException);

    // XPropertySet
    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);

    // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName(  )
        throw (::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
        throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  )
        throw (::com::sun::star::uno::RuntimeException);
};
#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.18.14); FILE MERGED 2005/09/05 18:49:16 rt 1.18.14.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ZipPackageStream.hxx,v $
 *
 *  $Revision: 1.19 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 16:20:13 $
 *
 *  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 _ZIP_PACKAGE_STREAM_HXX
#define _ZIP_PACKAGE_STREAM_HXX

#ifndef _COM_SUN_STAR_IO_XACTIVEDATASINK_HPP_
#include <com/sun/star/io/XActiveDataSink.hpp>
#endif
#ifndef _COM_SUN_STAR_PACKAGES_XDATASINKENCRSUPPORT_HPP_
#include <com/sun/star/packages/XDataSinkEncrSupport.hpp>
#endif

#ifndef _ZIP_PACKAGE_ENTRY_HXX
#include <ZipPackageEntry.hxx>
#endif
#ifndef _VOS_REF_H_
#include <vos/ref.hxx>
#endif
#ifndef _ENCRYPTION_DATA_HXX_
#include <EncryptionData.hxx>
#endif
#ifndef _CPPUHELPER_IMPLBASE2_HXX
#include <cppuhelper/implbase2.hxx>
#endif

#ifndef __MUTEXHOLDER_HXX_
#include <mutexholder.hxx>
#endif

#define PACKAGE_STREAM_NOTSET           0
#define PACKAGE_STREAM_PACKAGEMEMBER    1
#define PACKAGE_STREAM_DETECT           2
#define PACKAGE_STREAM_DATA             3
#define PACKAGE_STREAM_RAW              4

class ZipPackage;
struct ZipEntry;
class ZipPackageStream : public cppu::ImplInheritanceHelper2
<
    ZipPackageEntry,
    ::com::sun::star::io::XActiveDataSink,
    ::com::sun::star::packages::XDataSinkEncrSupport
>
{
    static com::sun::star::uno::Sequence < sal_Int8 > aImplementationId;
protected:
    com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xStream;
    const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > m_xFactory;
    ZipPackage          &rZipPackage;
    sal_Bool            bToBeCompressed, bToBeEncrypted, bHaveOwnKey, bIsEncrypted;
    vos::ORef < EncryptionData > xEncryptionData;

    sal_uInt8   m_nStreamMode;
    sal_uInt32  m_nMagicalHackPos;
    sal_uInt32  m_nMagicalHackSize;

    SotMutexHolderRef m_aSharedMutexRef;

public:
    sal_Bool HasOwnKey ()        { return bHaveOwnKey;}
    sal_Bool IsToBeCompressed () { return bToBeCompressed;}
    sal_Bool IsToBeEncrypted ()  { return bToBeEncrypted;}
    sal_Bool IsEncrypted ()      { return bIsEncrypted;}
    sal_Bool IsPackageMember ()  { return m_nStreamMode == PACKAGE_STREAM_PACKAGEMEMBER;}
    vos::ORef < EncryptionData > & getEncryptionData ()
    { return xEncryptionData;}
    const com::sun::star::uno::Sequence < sal_Int8 >& getKey ()
    { return xEncryptionData->aKey;}
    const com::sun::star::uno::Sequence < sal_uInt8 >& getInitialisationVector ()
    { return xEncryptionData->aInitVector;}
    const com::sun::star::uno::Sequence < sal_uInt8 >& getDigest ()
    { return xEncryptionData->aDigest;}
    const com::sun::star::uno::Sequence < sal_uInt8 >& getSalt ()
    { return xEncryptionData->aSalt;}
    const sal_Int32 getIterationCount ()
    { return xEncryptionData->nIterationCount;}
    const sal_Int32 getSize ()
    { return aEntry.nSize;}

    sal_uInt8 GetStreamMode() { return m_nStreamMode; }
    sal_uInt32 GetMagicalHackPos() { return m_nMagicalHackPos; }
    sal_uInt32 GetMagicalHackSize() { return m_nMagicalHackSize; }

    void SetToBeCompressed (sal_Bool bNewValue) { bToBeCompressed = bNewValue;}
    void SetIsEncrypted (sal_Bool bNewValue) { bIsEncrypted = bNewValue;}
    void SetToBeEncrypted (sal_Bool bNewValue)
    {
        bToBeEncrypted  = bNewValue;
        if ( bToBeEncrypted && xEncryptionData.isEmpty())
            xEncryptionData = new EncryptionData;
        else if ( !bToBeEncrypted && !xEncryptionData.isEmpty() )
            xEncryptionData.unbind();
    }
    void SetPackageMember (sal_Bool bNewValue);
    void setKey (const com::sun::star::uno::Sequence < sal_Int8 >& rNewKey )
    { xEncryptionData->aKey = rNewKey;}
    void setInitialisationVector (const com::sun::star::uno::Sequence < sal_uInt8 >& rNewVector )
    { xEncryptionData->aInitVector = rNewVector;}
    void setSalt (const com::sun::star::uno::Sequence < sal_uInt8 >& rNewSalt )
    { xEncryptionData->aSalt = rNewSalt;}
    void setDigest (const com::sun::star::uno::Sequence < sal_uInt8 >& rNewDigest )
    { xEncryptionData->aDigest = rNewDigest;}
    void setIterationCount (const sal_Int32 nNewCount)
    { xEncryptionData->nIterationCount = nNewCount;}
    void setSize (const sal_Int32 nNewSize);

    ZipPackageStream ( ZipPackage & rNewPackage,
                        const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory >& xFactory,
                        sal_Bool bAllowRemoveOnInsert );
    virtual ~ZipPackageStream( void );

    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetRawEncrStreamNoHeaderCopy();
    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > TryToGetRawFromDataStream(
                                                                                sal_Bool bAddHeaderForEncr );

    sal_Bool ParsePackageRawStream();

    void setZipEntry( const ZipEntry &rInEntry);
    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getRawData()
        throw(::com::sun::star::uno::RuntimeException);

    static ::com::sun::star::uno::Sequence < sal_Int8 >& static_getImplementationId()
    {
        return aImplementationId;
    }

    // XActiveDataSink
    virtual void SAL_CALL setInputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream )
        throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream(  )
        throw(::com::sun::star::uno::RuntimeException);

    // XDataSinkEncrSupport
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getDataStream()
        throw ( ::com::sun::star::packages::WrongPasswordException,
                ::com::sun::star::io::IOException,
                ::com::sun::star::uno::RuntimeException );
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getRawStream()
        throw ( ::com::sun::star::packages::NoEncryptionException,
                ::com::sun::star::io::IOException,
                ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL setDataStream(
                    const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream )
        throw ( ::com::sun::star::io::IOException,
                ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL setRawStream(
                    const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& aStream )
        throw ( ::com::sun::star::packages::EncryptionNotAllowedException,
                ::com::sun::star::packages::NoRawFormatException,
                ::com::sun::star::io::IOException,
                ::com::sun::star::uno::RuntimeException );
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getPlainRawStream()
        throw ( ::com::sun::star::io::IOException,
                ::com::sun::star::uno::RuntimeException );

    // XUnoTunnel
    virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
        throw(::com::sun::star::uno::RuntimeException);

    // XPropertySet
    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);

    // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName(  )
        throw (::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
        throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  )
        throw (::com::sun::star::uno::RuntimeException);
};
#endif
<|endoftext|>


<commit_before>/*----------------------------------------------------------------------------*/
/* Copyright (c) Creighton 2017. All Rights Reserved.                         */
/* Open Source Software - May be modified and shared but must                 */
/* be accompanied by the license file in the root source directory            */
/*----------------------------------------------------------------------------*/

#include "ghLib/Util.h"
#include <map>

namespace ghLib {

// From http://stackoverflow.com/a/8098080
std::string Format(const std::string fmt_str, ...) {
	int final_n, n = ((int)fmt_str.size()) * 2; /* Reserve two times as much as the length of the fmt_str */
	std::string str;
	std::unique_ptr<char[]> formatted;
	va_list ap;
	while(1) {
		formatted.reset(new char[n]); /* Wrap the plain char array into the unique_ptr */
		strcpy(&formatted[0], fmt_str.c_str());
		va_start(ap, fmt_str);
		final_n = vsnprintf(&formatted[0], n, fmt_str.c_str(), ap);
		va_end(ap);
		if (final_n < 0 || final_n >= n)
			n += abs(final_n - n + 1);
		else
			break;
	}
	return std::string(formatted.get());
}

std::string FilterASCII(const std::string in) {
	std::string out;
	for (const char& c : in) {
		//out += Format("%d,", (unsigned char)c);
		if (c < ' ' || c >= 127) {
			out += ".";
			//out += Format("\\x%02x", (unsigned char)c);
		} else {
			out += c;
		}
	}
	return out;
}

std::string EscapeString(const std::string in) {
	std::string out;
	std::map<char, std::string> escapeMap = {
		{'"', "\\\""},
		{'\\', "\\\\"},
		{'\b', "\\b"},
		{'\f', "\\f"},
		{'\n', "\\n"},
		{'\r', "\\r"},
		{'\t', "\\t"}
	};

	for (const char& c : in) {
		auto esc = escapeMap.find(c);
		if (esc == escapeMap.end()) {
			if (c < ' ') {
				out += Format("\\u00%02x,", (unsigned char)c);
			} else {
				out += c;
			}
		} else {
			out += esc->second;
		}
	}
	return out;
}
std::vector<std::string>& Tokenize(const std::string &input, char delimeter, std::vector<std::string>& tokens, char escape /* = '\0' */) {
	std::string buf = "";
	bool escaping = false;
	for (int i = 0; i < (int)input.size(); i++) {
		char c = input[i];
		if (!escaping && c == escape) {
			escaping = true;
		} else if (!escaping && c == delimeter) {
			tokens.push_back(buf);
			buf = "";
		} else {
			if (escaping && (c != escape && c != delimeter)) { // We escaped nothing, so put the escape character back
				buf += escape;
			}
			buf += c;
			escaping = false;
		}
	}
	if (buf.size()) {
		tokens.push_back(buf);
	}
	return tokens;
}

std::vector<std::string> Tokenize(const std::string &input, char delimeter, char escape /* = '\0' */) {
	std::vector<std::string> tokens;
	Tokenize(input, delimeter, tokens, escape);
	return tokens;
}

}
<commit_msg>Have Format() just call narflib's<commit_after>/*----------------------------------------------------------------------------*/
/* Copyright (c) Creighton 2017. All Rights Reserved.                         */
/* Open Source Software - May be modified and shared but must                 */
/* be accompanied by the license file in the root source directory            */
/*----------------------------------------------------------------------------*/

#include "ghLib/Util.h"
#include "narf/format.h"
#include <map>

namespace ghLib {

std::string Format(const std::string fmt_str, ...) {
	va_list argp;
	va_start(argp, fmt_str);
	auto ret = narf::util::format(fmt_str, argp);
	va_end(argp);
	return ret;
}

std::string FilterASCII(const std::string in) {
	std::string out;
	for (const char& c : in) {
		if (c < ' ' || c >= 127) {
			out += ".";
		} else {
			out += c;
		}
	}
	return out;
}

std::string EscapeString(const std::string in) {
	std::string out;
	std::map<char, std::string> escapeMap = {
		{'"', "\\\""},
		{'\\', "\\\\"},
		{'\b', "\\b"},
		{'\f', "\\f"},
		{'\n', "\\n"},
		{'\r', "\\r"},
		{'\t', "\\t"}
	};

	for (const char& c : in) {
		auto esc = escapeMap.find(c);
		if (esc == escapeMap.end()) {
			if (c < ' ') {
				out += Format("\\u00%02x,", (unsigned char)c);
			} else {
				out += c;
			}
		} else {
			out += esc->second;
		}
	}
	return out;
}

std::vector<std::string>& Tokenize(const std::string &input, char delimeter, std::vector<std::string>& tokens, char escape /* = '\0' */) {
	std::string buf = "";
	bool escaping = false;
	for (int i = 0; i < (int)input.size(); i++) {
		char c = input[i];
		if (!escaping && c == escape) {
			escaping = true;
		} else if (!escaping && c == delimeter) {
			tokens.push_back(buf);
			buf = "";
		} else {
			if (escaping && (c != escape && c != delimeter)) { // We escaped nothing, so put the escape character back
				buf += escape;
			}
			buf += c;
			escaping = false;
		}
	}
	if (buf.size()) {
		tokens.push_back(buf);
	}
	return tokens;
}

std::vector<std::string> Tokenize(const std::string &input, char delimeter, char escape /* = '\0' */) {
	std::vector<std::string> tokens;
	Tokenize(input, delimeter, tokens, escape);
	return tokens;
}

}
<|endoftext|>


<commit_before>#include "Util.h"
#include <boost/filesystem.hpp>
#include "resources/ResourceManager.h"

std::string strToUpper(const char* from)
{
	std::string str(from);
	for(unsigned int i = 0; i < str.size(); i++)
		str[i] = toupper(from[i]);
	return str;
}

std::string& strToUpper(std::string& str)
{
	for(unsigned int i = 0; i < str.size(); i++)
		str[i] = toupper(str[i]);

	return str;
}

std::string strToUpper(const std::string& str)
{
	return strToUpper(str.c_str());
}

#if _MSC_VER < 1800
float round(float num)
{
	return (float)((int)(num + 0.5f));
}
#endif

Eigen::Affine3f& roundMatrix(Eigen::Affine3f& mat)
{
	mat.translation()[0] = round(mat.translation()[0]);
	mat.translation()[1] = round(mat.translation()[1]);
	return mat;
}

Eigen::Affine3f roundMatrix(const Eigen::Affine3f& mat)
{
	Eigen::Affine3f ret = mat;
	roundMatrix(ret);
	return ret;
}

Eigen::Vector3f roundVector(const Eigen::Vector3f& vec)
{
	Eigen::Vector3f ret = vec;
	ret[0] = round(ret[0]);
	ret[1] = round(ret[1]);
	ret[2] = round(ret[2]);
	return ret;
}

Eigen::Vector2f roundVector(const Eigen::Vector2f& vec)
{
	Eigen::Vector2f ret = vec;
	ret[0] = round(ret[0]);
	ret[1] = round(ret[1]);
	return ret;
}

std::string getCanonicalPath(const std::string& path)
{
	// embedded resources, e.g. ":/font.ttf", need to be properly handled too
	try
	{
		const std::string canonical = boost::filesystem::canonical(path).generic_string();
		return canonical.empty() ? path : canonical;
	}
	catch (boost::filesystem::filesystem_error& e)
	{
		return path;
	}
}
<commit_msg>Fix for empty paths breaking in getCanonicalPath().<commit_after>#include "Util.h"
#include <boost/filesystem.hpp>
#include "resources/ResourceManager.h"

std::string strToUpper(const char* from)
{
	std::string str(from);
	for(unsigned int i = 0; i < str.size(); i++)
		str[i] = toupper(from[i]);
	return str;
}

std::string& strToUpper(std::string& str)
{
	for(unsigned int i = 0; i < str.size(); i++)
		str[i] = toupper(str[i]);

	return str;
}

std::string strToUpper(const std::string& str)
{
	return strToUpper(str.c_str());
}

#if _MSC_VER < 1800
float round(float num)
{
	return (float)((int)(num + 0.5f));
}
#endif

Eigen::Affine3f& roundMatrix(Eigen::Affine3f& mat)
{
	mat.translation()[0] = round(mat.translation()[0]);
	mat.translation()[1] = round(mat.translation()[1]);
	return mat;
}

Eigen::Affine3f roundMatrix(const Eigen::Affine3f& mat)
{
	Eigen::Affine3f ret = mat;
	roundMatrix(ret);
	return ret;
}

Eigen::Vector3f roundVector(const Eigen::Vector3f& vec)
{
	Eigen::Vector3f ret = vec;
	ret[0] = round(ret[0]);
	ret[1] = round(ret[1]);
	ret[2] = round(ret[2]);
	return ret;
}

Eigen::Vector2f roundVector(const Eigen::Vector2f& vec)
{
	Eigen::Vector2f ret = vec;
	ret[0] = round(ret[0]);
	ret[1] = round(ret[1]);
	return ret;
}

// embedded resources, e.g. ":/font.ttf", need to be properly handled too
std::string getCanonicalPath(const std::string& path)
{
	if(path.empty() || !boost::filesystem::exists(path))
		return path;

	return boost::filesystem::canonical(path).generic_string();
}
<|endoftext|>


<commit_before>#ifndef MACH5_UTIL_HPP
#define MACH5_UTIL_HPP

#include <string>
#include <vector>
#include <map>
#include <iostream>

#include "BenchmarkResult.hpp"
#include "BenchmarkRunner.hpp"

namespace mach5 {
  class Util {
  public:
    std::string toJson(std::map<std::string, std::vector<BenchmarkResult>> results) {
      std::ostringstream str;
      str << "{";
      for (auto kv = results.begin(); kv != results.end(); ++kv) {
        str << "\"" << kv->first << "\": [";
        for (auto it = kv->second.begin(); it != kv->second.end(); ++it) {
          str << it->json();
          if (std::next(it) != kv->second.end())
            str << ",";
        }
        str << "]";
        if (std::next(kv) != results.end())
          str << ",";
      }
      str << "}";
      return str.str();
    }

    int inputOptions(int argc, char** argv) {
      if (argc < 2) return 0;
      auto command = std::string(argv[1]);
      if (command == "help") {
        help();
        return 1;
      } else if (command == "list") {
        return 2;
      } else if (command == "run") {
        if (argc > 2) return 3;
      }
      return 0;
    }

    void help() {
      std::cout << "Usage: ./yourbinary [command] [argments*]" << std::endl;
      std::cout << "  help             show this message" << std::endl;
      std::cout << "  list             list all benchmarks names" << std::endl;
      std::cout << "  run              runs a list of benchmarks" << std::endl;
    }
  };
}

#endif<commit_msg>Fix some typo<commit_after>#ifndef MACH5_UTIL_HPP
#define MACH5_UTIL_HPP

#include <string>
#include <vector>
#include <map>
#include <iostream>

#include "BenchmarkResult.hpp"
#include "BenchmarkRunner.hpp"

namespace mach5 {
  class Util {
  public:
    std::string toJson(std::map<std::string, std::vector<BenchmarkResult>> results) {
      std::ostringstream str;
      str << "{";
      for (auto kv = results.begin(); kv != results.end(); ++kv) {
        str << "\"" << kv->first << "\": [";
        for (auto it = kv->second.begin(); it != kv->second.end(); ++it) {
          str << it->json();
          if (std::next(it) != kv->second.end())
            str << ",";
        }
        str << "]";
        if (std::next(kv) != results.end())
          str << ",";
      }
      str << "}";
      return str.str();
    }

    int inputOptions(int argc, char** argv) {
      if (argc < 2) return 0;
      auto command = std::string(argv[1]);
      if (command == "help") {
        help();
        return 1;
      } else if (command == "list") {
        return 2;
      } else if (command == "run") {
        if (argc > 2) return 3;
      }
      return 0;
    }

    void help() {
      std::cout << "Usage: ./yourbinary [command] [argments*]" << std::endl;
      std::cout << "  help             shows this message" << std::endl;
      std::cout << "  list             lists all benchmarks names" << std::endl;
      std::cout << "  run              runs a list of benchmarks" << std::endl;
    }
  };
}

#endif<|endoftext|>


<commit_before>#include "Yaml.h"
#include "cinder/Utilities.h"

using namespace kp::yaml;

bool YamlTree::load(ci::DataSourceRef dataSource) {

	std::string yamlString = ci::loadString(dataSource);

	doc = YAML::Load(yamlString);

	// YAML::Emitter out;

	std::cout << doc["root"] << std::endl;

	return true;
}
<commit_msg>Quiet.<commit_after>#include "Yaml.h"
#include "cinder/Utilities.h"

using namespace kp::yaml;

bool YamlTree::load(ci::DataSourceRef dataSource) {

	std::string yamlString = ci::loadString(dataSource);

	doc = YAML::Load(yamlString);

	// YAML::Emitter out;

	//	std::cout << doc["root"] << std::endl;

	return true;
}
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECoreGL/IECoreGL.h"
#include "IECoreGL/GL.h"
#include "IECoreGL/GLUT.h"

#include "IECore/MessageHandler.h"

static void nullDisplayFunc()
{
}

void IECoreGL::init( bool glAlreadyInitialised )
{
	static bool init = false;
	if( !init )
	{
		if( !glAlreadyInitialised )
		{
			int argc = 2;
			// on the mac, glut changes working directory during initialisation
			// unless you pass the -useWorkingDir option
			const char *argv[] = { "IECoreGL", "-useWorkingDir" };
			glutInit( &argc, const_cast<char**>( argv ) );
			/// \todo We're making a window here to make glut initialise a gl context,
			/// so that glewInit() works. But we should figure out how to initialise
			/// GL ourselves and avoid the annoying window popping up at the beginning.
			int window = glutCreateWindow( "IECoreGL Initial Window" );
			glutDisplayFunc( nullDisplayFunc );
			glutDestroyWindow( window );
		}
		GLenum initStatus = glewInit();
		if( initStatus!=GLEW_OK )
		{
			IECore::msg( IECore::Msg::Error, "IECoreGL::init", boost::format( "GLEW initialisation failed (%s)." ) % glewGetErrorString( initStatus ) );
		}
		init = true;
	}
}

unsigned int IECoreGL::coreMajorVersion()
{
	return IE_CORE_MAJOR_VERSION;
}
<commit_msg>fixed date<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2008, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECoreGL/IECoreGL.h"
#include "IECoreGL/GL.h"
#include "IECoreGL/GLUT.h"

#include "IECore/MessageHandler.h"

static void nullDisplayFunc()
{
}

void IECoreGL::init( bool glAlreadyInitialised )
{
	static bool init = false;
	if( !init )
	{
		if( !glAlreadyInitialised )
		{
			int argc = 2;
			// on the mac, glut changes working directory during initialisation
			// unless you pass the -useWorkingDir option
			const char *argv[] = { "IECoreGL", "-useWorkingDir" };
			glutInit( &argc, const_cast<char**>( argv ) );
			/// \todo We're making a window here to make glut initialise a gl context,
			/// so that glewInit() works. But we should figure out how to initialise
			/// GL ourselves and avoid the annoying window popping up at the beginning.
			int window = glutCreateWindow( "IECoreGL Initial Window" );
			glutDisplayFunc( nullDisplayFunc );
			glutDestroyWindow( window );
		}
		GLenum initStatus = glewInit();
		if( initStatus!=GLEW_OK )
		{
			IECore::msg( IECore::Msg::Error, "IECoreGL::init", boost::format( "GLEW initialisation failed (%s)." ) % glewGetErrorString( initStatus ) );
		}
		init = true;
	}
}

unsigned int IECoreGL::coreMajorVersion()
{
	return IE_CORE_MAJOR_VERSION;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2010-2011 Dmitry Marakasov
 *
 * This file is part of glosm.
 *
 * glosm is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * glosm is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with glosm.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <glosm/GeometryOperations.hh>

#include <glosm/geomath.h>

#include <math.h>

bool IntersectSegmentWithHorizontal(const Vector3i& one, const Vector3i& two, osmint_t y, Vector3i& out) {
	if (one.y < y && two.y < y)
		return false;

	if (one.y > y && two.y > y)
		return false;

	float t = (float)(one.y - y) / (float)(one.y - two.y);

	float x = (float)(two.x - one.x) * t;
	float z = (float)(two.z - one.z) * t;

	out = Vector3i(one.x + round(x), y, one.z + round(z));
	return true;
}

bool IntersectSegmentWithVertical(const Vector3i& one, const Vector3i& two, osmint_t x, Vector3i& out) {
	if (one.x < x && two.x < x)
		return false;

	if (one.x > x && two.x > x)
		return false;

	float t = (float)(one.x - x) / (float)(one.x - two.x);

	float y = (float)(two.y - one.y) * t;
	float z = (float)(two.z - one.z) * t;

	out = Vector3i(x, one.y + round(y), one.z + round(z));
	return true;
}

bool IntersectPlaneWithVertical(const Vector3i& a, const Vector3i& b, const Vector3i& c, const Vector2i& xy, Vector3i& out) {
	/* Equation of a plane:
	 * |  x-x1  y-y1  z-z1 |
	 * | x2-x1 y2-y1 z2-y1 | = 0
	 * | x3-x1 y3-y1 z3-y1 |
	 *
	 * Determinant:
	 * | a11 a12 a13 |
	 * | a21 a22 a23 | = a11a22a33 − a11a23a32 − a12a21a33 + a12a23a31 + a13a21a32 − a13a22a31
	 * | a31 a32 a33 |
	 *
	 * In terms of array:
	 * | 0 1 2 |
	 * | 3 4 5 | = 0*4*8 - 0*5*7 - 1*3*8 + 1*5*6 + 2*3*7 - 2*4*6
	 * | 6 7 8 |
	 */
	float m[9] = {
		(float)(xy.x - a.x), (float)(xy.y - a.y), 0.0 /* to find */,
		(float)(b.x - a.x), (float)(b.y - a.y), (float)(b.z - a.z),
		(float)(c.x - a.x), (float)(c.y - a.y), (float)(c.z - a.z)
	};

	float divisor = m[3]*m[7] - m[4]*m[6];

	if (fabsf(divisor) < std::numeric_limits<float>::epsilon())
		return false;

	float divided = -m[0]*m[4]*m[8] + m[0]*m[5]*m[7] + m[1]*m[3]*m[8] - m[1]*m[5]*m[6];

	out = Vector3i(xy.x, xy.y, (osmint_t)round(divided/divisor) + a.z);
	return true;
}

bool IntersectSegmentWithBBoxSide(const Vector3i& one, const Vector3i& two, const BBoxi& bbox, BBoxi::Side side, Vector3i& out) {
	switch (side) {
	case BBoxi::LEFT:
		return IntersectSegmentWithVertical(one, two, bbox.left, out);
	case BBoxi::BOTTOM:
		return IntersectSegmentWithHorizontal(one, two, bbox.bottom, out);
	case BBoxi::RIGHT:
		return IntersectSegmentWithVertical(one, two, bbox.right, out);
	case BBoxi::TOP:
		return IntersectSegmentWithHorizontal(one, two, bbox.top, out);
	default:
		return false;
	}
}

BBoxi::Side IntersectSegmentWithBBox(const Vector3i& one, const Vector3i& two, const BBoxi& bbox, Vector3i& out) {
	if (IntersectSegmentWithVertical(one, two, bbox.left, out) && bbox.Contains(out))
		return BBoxi::LEFT;

	if (IntersectSegmentWithHorizontal(one, two, bbox.bottom, out) && bbox.Contains(out))
		return BBoxi::BOTTOM;

	if (IntersectSegmentWithVertical(one, two, bbox.right, out) && bbox.Contains(out))
		return BBoxi::RIGHT;

	if (IntersectSegmentWithHorizontal(one, two, bbox.top, out) && bbox.Contains(out))
		return BBoxi::TOP;

	return BBoxi::NONE;
}

BBoxi::Side IntersectSegmentWithBBox2(const Vector3i& one, const Vector3i& two, const BBoxi& bbox, Vector3i& out) {
	if (IntersectSegmentWithHorizontal(one, two, bbox.top, out) && bbox.Contains(out))
		return BBoxi::TOP;

	if (IntersectSegmentWithVertical(one, two, bbox.right, out) && bbox.Contains(out))
		return BBoxi::RIGHT;

	if (IntersectSegmentWithHorizontal(one, two, bbox.bottom, out) && bbox.Contains(out))
		return BBoxi::BOTTOM;

	if (IntersectSegmentWithVertical(one, two, bbox.left, out) && bbox.Contains(out))
		return BBoxi::LEFT;

	return BBoxi::NONE;
}

bool CropSegmentByBBox(const Vector3i& one, const Vector3i& two, const BBoxi& bbox, Vector3i& outone, Vector3i& outtwo) {
	if (bbox.Contains(one)) {
		/* one is in the bbox */
		outone = one;
		if (bbox.Contains(two)) {
			/* both points are in the bbox */
			outtwo = two;
		} else {
			/* other point is outside - find intersection */
			return IntersectSegmentWithBBox(one, two, bbox, outtwo);
		}
	} else if (bbox.Contains(two)) {
		/* two is inside, one is outside */
		outtwo = two;
		return IntersectSegmentWithBBox(one, two, bbox, outone);
	}

	/* both points are outside, find two points of intersection */
	return IntersectSegmentWithBBox(one, two, bbox, outone) && IntersectSegmentWithBBox2(one, two, bbox, outtwo);
}

Vector3d ToLocalMetric(Vector3i what, Vector3i ref) {
	const double coslat = cos(ref.y * GEOM_DEG_TO_RAD);

	double dx = (double)(what.x - ref.x) / GEOM_LONSPAN * WGS84_EARTH_EQ_LENGTH * coslat;
	double dy = (double)(what.y - ref.y) / GEOM_LONSPAN * WGS84_EARTH_EQ_LENGTH;
	double dz = (double)(what.z - ref.z) / GEOM_UNITSINMETER;

	return Vector3f(dx, dy, dz);
}

Vector3i FromLocalMetric(Vector3d what, Vector3i ref) {
	const double coslat = cos(ref.y * GEOM_DEG_TO_RAD);

	int x = ref.x;
	if (coslat > std::numeric_limits<double>::epsilon())
		x += round(what.x * GEOM_LONSPAN / WGS84_EARTH_EQ_LENGTH / coslat);

	int y = ref.y + round(what.y * GEOM_LONSPAN / WGS84_EARTH_EQ_LENGTH);
	int z = ref.z + round(what.z * GEOM_UNITSINMETER);

	return Vector3i(x, y, z);
}

<commit_msg>Whitespace nit<commit_after>/*
 * Copyright (C) 2010-2011 Dmitry Marakasov
 *
 * This file is part of glosm.
 *
 * glosm is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * glosm is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with glosm.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <glosm/GeometryOperations.hh>

#include <glosm/geomath.h>

#include <math.h>

bool IntersectSegmentWithHorizontal(const Vector3i& one, const Vector3i& two, osmint_t y, Vector3i& out) {
	if (one.y < y && two.y < y)
		return false;

	if (one.y > y && two.y > y)
		return false;

	float t = (float)(one.y - y) / (float)(one.y - two.y);

	float x = (float)(two.x - one.x) * t;
	float z = (float)(two.z - one.z) * t;

	out = Vector3i(one.x + round(x), y, one.z + round(z));
	return true;
}

bool IntersectSegmentWithVertical(const Vector3i& one, const Vector3i& two, osmint_t x, Vector3i& out) {
	if (one.x < x && two.x < x)
		return false;

	if (one.x > x && two.x > x)
		return false;

	float t = (float)(one.x - x) / (float)(one.x - two.x);

	float y = (float)(two.y - one.y) * t;
	float z = (float)(two.z - one.z) * t;

	out = Vector3i(x, one.y + round(y), one.z + round(z));
	return true;
}

bool IntersectPlaneWithVertical(const Vector3i& a, const Vector3i& b, const Vector3i& c, const Vector2i& xy, Vector3i& out) {
	/* Equation of a plane:
	 * |  x-x1  y-y1  z-z1 |
	 * | x2-x1 y2-y1 z2-y1 | = 0
	 * | x3-x1 y3-y1 z3-y1 |
	 *
	 * Determinant:
	 * | a11 a12 a13 |
	 * | a21 a22 a23 | = a11a22a33 − a11a23a32 − a12a21a33 + a12a23a31 + a13a21a32 − a13a22a31
	 * | a31 a32 a33 |
	 *
	 * In terms of array:
	 * | 0 1 2 |
	 * | 3 4 5 | = 0*4*8 - 0*5*7 - 1*3*8 + 1*5*6 + 2*3*7 - 2*4*6
	 * | 6 7 8 |
	 */
	float m[9] = {
		(float)(xy.x - a.x), (float)(xy.y - a.y), 0.0 /* to find */,
		(float)(b.x - a.x), (float)(b.y - a.y), (float)(b.z - a.z),
		(float)(c.x - a.x), (float)(c.y - a.y), (float)(c.z - a.z)
	};

	float divisor = m[3]*m[7] - m[4]*m[6];

	if (fabsf(divisor) < std::numeric_limits<float>::epsilon())
		return false;

	float divided = -m[0]*m[4]*m[8] + m[0]*m[5]*m[7] + m[1]*m[3]*m[8] - m[1]*m[5]*m[6];

	out = Vector3i(xy.x, xy.y, (osmint_t)round(divided/divisor) + a.z);
	return true;
}

bool IntersectSegmentWithBBoxSide(const Vector3i& one, const Vector3i& two, const BBoxi& bbox, BBoxi::Side side, Vector3i& out) {
	switch (side) {
	case BBoxi::LEFT:
		return IntersectSegmentWithVertical(one, two, bbox.left, out);
	case BBoxi::BOTTOM:
		return IntersectSegmentWithHorizontal(one, two, bbox.bottom, out);
	case BBoxi::RIGHT:
		return IntersectSegmentWithVertical(one, two, bbox.right, out);
	case BBoxi::TOP:
		return IntersectSegmentWithHorizontal(one, two, bbox.top, out);
	default:
		return false;
	}
}

BBoxi::Side IntersectSegmentWithBBox(const Vector3i& one, const Vector3i& two, const BBoxi& bbox, Vector3i& out) {
	if (IntersectSegmentWithVertical(one, two, bbox.left, out) && bbox.Contains(out))
		return BBoxi::LEFT;

	if (IntersectSegmentWithHorizontal(one, two, bbox.bottom, out) && bbox.Contains(out))
		return BBoxi::BOTTOM;

	if (IntersectSegmentWithVertical(one, two, bbox.right, out) && bbox.Contains(out))
		return BBoxi::RIGHT;

	if (IntersectSegmentWithHorizontal(one, two, bbox.top, out) && bbox.Contains(out))
		return BBoxi::TOP;

	return BBoxi::NONE;
}

BBoxi::Side IntersectSegmentWithBBox2(const Vector3i& one, const Vector3i& two, const BBoxi& bbox, Vector3i& out) {
	if (IntersectSegmentWithHorizontal(one, two, bbox.top, out) && bbox.Contains(out))
		return BBoxi::TOP;

	if (IntersectSegmentWithVertical(one, two, bbox.right, out) && bbox.Contains(out))
		return BBoxi::RIGHT;

	if (IntersectSegmentWithHorizontal(one, two, bbox.bottom, out) && bbox.Contains(out))
		return BBoxi::BOTTOM;

	if (IntersectSegmentWithVertical(one, two, bbox.left, out) && bbox.Contains(out))
		return BBoxi::LEFT;

	return BBoxi::NONE;
}

bool CropSegmentByBBox(const Vector3i& one, const Vector3i& two, const BBoxi& bbox, Vector3i& outone, Vector3i& outtwo) {
	if (bbox.Contains(one)) {
		/* one is in the bbox */
		outone = one;
		if (bbox.Contains(two)) {
			/* both points are in the bbox */
			outtwo = two;
		} else {
			/* other point is outside - find intersection */
			return IntersectSegmentWithBBox(one, two, bbox, outtwo);
		}
	} else if (bbox.Contains(two)) {
		/* two is inside, one is outside */
		outtwo = two;
		return IntersectSegmentWithBBox(one, two, bbox, outone);
	}

	/* both points are outside, find two points of intersection */
	return IntersectSegmentWithBBox(one, two, bbox, outone) && IntersectSegmentWithBBox2(one, two, bbox, outtwo);
}

Vector3d ToLocalMetric(Vector3i what, Vector3i ref) {
	const double coslat = cos(ref.y * GEOM_DEG_TO_RAD);

	double dx = (double)(what.x - ref.x) / GEOM_LONSPAN * WGS84_EARTH_EQ_LENGTH * coslat;
	double dy = (double)(what.y - ref.y) / GEOM_LONSPAN * WGS84_EARTH_EQ_LENGTH;
	double dz = (double)(what.z - ref.z) / GEOM_UNITSINMETER;

	return Vector3f(dx, dy, dz);
}

Vector3i FromLocalMetric(Vector3d what, Vector3i ref) {
	const double coslat = cos(ref.y * GEOM_DEG_TO_RAD);

	int x = ref.x;
	if (coslat > std::numeric_limits<double>::epsilon())
		x += round(what.x * GEOM_LONSPAN / WGS84_EARTH_EQ_LENGTH / coslat);

	int y = ref.y + round(what.y * GEOM_LONSPAN / WGS84_EARTH_EQ_LENGTH);
	int z = ref.z + round(what.z * GEOM_UNITSINMETER);

	return Vector3i(x, y, z);
}
<|endoftext|>


<commit_before>/*
Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
(HOOMD-blue) Open Source Software License Copyright 2008-2011 Ames Laboratory
Iowa State University and The Regents of the University of Michigan All rights
reserved.

HOOMD-blue may contain modifications ("Contributions") provided, and to which
copyright is held, by various Contributors who have granted The Regents of the
University of Michigan the right to modify and/or distribute such Contributions.

You may redistribute, use, and create derivate works of HOOMD-blue, in source
and binary forms, provided you abide by the following conditions:

* Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer both in the code and
prominently in any materials provided with the distribution.

* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions, and the following disclaimer in the documentation and/or
other materials provided with the distribution.

* All publications and presentations based on HOOMD-blue, including any reports
or published results obtained, in whole or in part, with HOOMD-blue, will
acknowledge its use according to the terms posted at the time of submission on:
http://codeblue.umich.edu/hoomd-blue/citations.html

* Any electronic documents citing HOOMD-Blue will link to the HOOMD-Blue website:
http://codeblue.umich.edu/hoomd-blue/

* Apart from the above required attributions, neither the name of the copyright
holder nor the names of HOOMD-blue's contributors may be used to endorse or
promote products derived from this software without specific prior written
permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR ANY
WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

// Maintainer: joaander

/*! \file ComputeThermoGPU.cc
    \brief Contains code for the ComputeThermoGPU class
*/

#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4103 4244 )
#endif

#include "ComputeThermoGPU.h"
#include "ComputeThermoGPU.cuh"
#include "PPPMForceGPU.cuh"

#include <boost/python.hpp>
using namespace boost::python;
#include <boost/bind.hpp>
using namespace boost;

#include <iostream>
using namespace std;

/*! \param sysdef System for which to compute thermodynamic properties
    \param group Subset of the system over which properties are calculated
    \param suffix Suffix to append to all logged quantity names
*/

ComputeThermoGPU::ComputeThermoGPU(boost::shared_ptr<SystemDefinition> sysdef,
                                   boost::shared_ptr<ParticleGroup> group,
                                   const std::string& suffix)
    : ComputeThermo(sysdef, group, suffix)
    {
    if (!exec_conf->isCUDAEnabled())
        {
        cerr << endl << "***Error! Creating a ComputeThermoGPU with no GPU in the execution configuration" << endl << endl;
        throw std::runtime_error("Error initializing ComputeThermoGPU");
        }

    m_block_size = 512;
    m_num_blocks = m_group->getNumMembers() / m_block_size + 1;

    GPUArray< float4 > scratch(m_num_blocks, exec_conf);
    m_scratch.swap(scratch);

    GPUArray< float > scratch_pressure_tensor(m_num_blocks * 6, exec_conf);
    m_scratch_pressure_tensor.swap(scratch_pressure_tensor);
    }

/*! Computes all thermodynamic properties of the system in one fell swoop, on the GPU.
 */
void ComputeThermoGPU::computeProperties()
    {
    unsigned int group_size = m_group->getNumLocalMembers();
    // just drop out if the group is an empty group
    if (group_size == 0)
        return;

    if (m_prof) m_prof->push("Thermo");

    assert(m_pdata);
    assert(m_ndof != 0);

    // access the particle data
    ArrayHandle<Scalar4> d_vel(m_pdata->getVelocities(), access_location::device, access_mode::read);
    gpu_boxsize box = m_pdata->getGlobalBoxGPU();

    { // scope these array handles so they are released before the additional terms are added
    // access the net force, pe, and virial
    const GPUArray< Scalar4 >& net_force = m_pdata->getNetForce();
    const GPUArray< Scalar >& net_virial = m_pdata->getNetVirial();
    ArrayHandle<Scalar4> d_net_force(net_force, access_location::device, access_mode::read);
    ArrayHandle<Scalar> d_net_virial(net_virial, access_location::device, access_mode::read);
    ArrayHandle<float4> d_scratch(m_scratch, access_location::device, access_mode::overwrite);
    ArrayHandle<float> d_scratch_pressure_tensor(m_scratch_pressure_tensor, access_location::device, access_mode::overwrite);
    ArrayHandle<float> d_properties(m_properties, access_location::device, access_mode::overwrite);

    // access the group
    ArrayHandle< unsigned int > d_index_array(m_group->getIndexArray(), access_location::device, access_mode::read);

    // build up args list
    compute_thermo_args args;
    args.d_net_force = d_net_force.data;
    args.d_net_virial = d_net_virial.data;
    args.virial_pitch = net_virial.getPitch();
    args.ndof = m_ndof;
    args.D = m_sysdef->getNDimensions();
    args.d_scratch = d_scratch.data;
    args.d_scratch_pressure_tensor = d_scratch_pressure_tensor.data;
    args.block_size = m_block_size;
    args.n_blocks = m_num_blocks;

    PDataFlags flags = m_pdata->getFlags();

    // perform the computation on the GPU
    gpu_compute_thermo( d_properties.data,
                        d_vel.data,
                        d_index_array.data,
                        group_size,
                        box,
                        args,
                        flags[pdata_flag::pressure_tensor]);

    if (exec_conf->isCUDAErrorCheckingEnabled())
        CHECK_CUDA_ERROR();

    }

    if(PPPMData::compute_pppm_flag) {
        Scalar2 pppm_thermo = ComputeThermoGPU::PPPM_thermo_compute();
        ArrayHandle<float> h_properties(m_properties, access_location::host, access_mode::readwrite);
        h_properties.data[thermo_index::pressure] += pppm_thermo.x;
        h_properties.data[thermo_index::potential_energy] += pppm_thermo.y;
        PPPMData::pppm_energy = pppm_thermo.y;
        }

#ifdef ENABLE_MPI
    // for MPI, we have to copy data back to the host to perform collective operations

    boost::shared_ptr<const boost::mpi::communicator> mpi_comm = m_pdata->getMPICommunicator();

    if (mpi_comm)
        {
        ArrayHandle<Scalar> h_properties(m_properties, access_location::host, access_mode::readwrite);

        Scalar & T = h_properties.data[thermo_index::temperature];
        Scalar & P = h_properties.data[thermo_index::pressure];
        Scalar & ke =  h_properties.data[thermo_index::kinetic_energy];
        Scalar & pe =  h_properties.data[thermo_index::potential_energy];
        Scalar & Pxx =  h_properties.data[thermo_index::pressure_xx];
        Scalar & Pxy =  h_properties.data[thermo_index::pressure_xy];
        Scalar & Pxz =  h_properties.data[thermo_index::pressure_xz];
        Scalar & Pyy =  h_properties.data[thermo_index::pressure_yy];
        Scalar & Pyz =  h_properties.data[thermo_index::pressure_yz];
        Scalar & Pzz =  h_properties.data[thermo_index::pressure_zz];
        T = all_reduce(*mpi_comm, T, std::plus<Scalar>());
        P = all_reduce(*mpi_comm, P, std::plus<Scalar>());
        ke = all_reduce(*mpi_comm, ke, std::plus<Scalar>());
        pe = all_reduce(*mpi_comm, pe, std::plus<Scalar>());
        Pxx = all_reduce(*mpi_comm, Pxx, std::plus<Scalar>());
        Pxy = all_reduce(*mpi_comm, Pxy, std::plus<Scalar>());
        Pxz = all_reduce(*mpi_comm, Pxz, std::plus<Scalar>());
        Pyy = all_reduce(*mpi_comm, Pyy, std::plus<Scalar>());
        Pyz = all_reduce(*mpi_comm, Pyz, std::plus<Scalar>());
        Pzz = all_reduce(*mpi_comm, Pzz, std::plus<Scalar>());
        }
#endif

    if (m_prof) m_prof->pop();
    }

Scalar2 ComputeThermoGPU::PPPM_thermo_compute()
    {

    gpu_boxsize box = m_pdata->getBoxGPU();

    ArrayHandle<cufftComplex> d_rho_real_space(PPPMData::m_rho_real_space, access_location::device, access_mode::readwrite);
    ArrayHandle<Scalar> d_green_hat(PPPMData::m_green_hat, access_location::device, access_mode::readwrite);
    ArrayHandle<Scalar3> d_vg(PPPMData::m_vg, access_location::device, access_mode::readwrite);
    ArrayHandle<Scalar2> d_i_data(PPPMData::i_data, access_location::device, access_mode::readwrite);
    ArrayHandle<Scalar2> d_o_data(PPPMData::o_data, access_location::device, access_mode::readwrite);

    Scalar2 pppm_virial_energy =  gpu_compute_pppm_thermo(PPPMData::Nx,
                                                          PPPMData::Ny,
                                                          PPPMData::Nz,
                                                          d_rho_real_space.data,
                                                          d_vg.data,
                                                          d_green_hat.data,
                                                          d_o_data.data,
                                                          d_i_data.data,
                                                          256);

    pppm_virial_energy.x *= PPPMData::energy_virial_factor/ (3.0f * box.Lx * box.Ly * box.Lz);
    pppm_virial_energy.y *= PPPMData::energy_virial_factor;
    pppm_virial_energy.y -= PPPMData::q2 * PPPMData::kappa / 1.772453850905516027298168f;
    pppm_virial_energy.y -= 0.5*M_PI*PPPMData::q*PPPMData::q / (PPPMData::kappa*PPPMData::kappa* box.Lx * box.Ly * box.Lz);

    return pppm_virial_energy;

    }

void export_ComputeThermoGPU()
    {
    class_<ComputeThermoGPU, boost::shared_ptr<ComputeThermoGPU>, bases<ComputeThermo>, boost::noncopyable >
        ("ComputeThermoGPU", init< boost::shared_ptr<SystemDefinition>,
         boost::shared_ptr<ParticleGroup>,
         const std::string& >())
        ;
    }

#ifdef WIN32
#pragma warning( pop )
#endif

<commit_msg>Only communicate thermodynamic properties if needed (but there still seems to be a performance with ComputeThermo)<commit_after>/*
Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
(HOOMD-blue) Open Source Software License Copyright 2008-2011 Ames Laboratory
Iowa State University and The Regents of the University of Michigan All rights
reserved.

HOOMD-blue may contain modifications ("Contributions") provided, and to which
copyright is held, by various Contributors who have granted The Regents of the
University of Michigan the right to modify and/or distribute such Contributions.

You may redistribute, use, and create derivate works of HOOMD-blue, in source
and binary forms, provided you abide by the following conditions:

* Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer both in the code and
prominently in any materials provided with the distribution.

* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions, and the following disclaimer in the documentation and/or
other materials provided with the distribution.

* All publications and presentations based on HOOMD-blue, including any reports
or published results obtained, in whole or in part, with HOOMD-blue, will
acknowledge its use according to the terms posted at the time of submission on:
http://codeblue.umich.edu/hoomd-blue/citations.html

* Any electronic documents citing HOOMD-Blue will link to the HOOMD-Blue website:
http://codeblue.umich.edu/hoomd-blue/

* Apart from the above required attributions, neither the name of the copyright
holder nor the names of HOOMD-blue's contributors may be used to endorse or
promote products derived from this software without specific prior written
permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR ANY
WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

// Maintainer: joaander

/*! \file ComputeThermoGPU.cc
    \brief Contains code for the ComputeThermoGPU class
*/

#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4103 4244 )
#endif

#include "ComputeThermoGPU.h"
#include "ComputeThermoGPU.cuh"
#include "PPPMForceGPU.cuh"

#include <boost/python.hpp>
using namespace boost::python;
#include <boost/bind.hpp>
using namespace boost;

#include <iostream>
using namespace std;

/*! \param sysdef System for which to compute thermodynamic properties
    \param group Subset of the system over which properties are calculated
    \param suffix Suffix to append to all logged quantity names
*/

ComputeThermoGPU::ComputeThermoGPU(boost::shared_ptr<SystemDefinition> sysdef,
                                   boost::shared_ptr<ParticleGroup> group,
                                   const std::string& suffix)
    : ComputeThermo(sysdef, group, suffix)
    {
    if (!exec_conf->isCUDAEnabled())
        {
        cerr << endl << "***Error! Creating a ComputeThermoGPU with no GPU in the execution configuration" << endl << endl;
        throw std::runtime_error("Error initializing ComputeThermoGPU");
        }

    m_block_size = 512;
    m_num_blocks = m_group->getNumMembers() / m_block_size + 1;

    GPUArray< float4 > scratch(m_num_blocks, exec_conf);
    m_scratch.swap(scratch);

    GPUArray< float > scratch_pressure_tensor(m_num_blocks * 6, exec_conf);
    m_scratch_pressure_tensor.swap(scratch_pressure_tensor);
    }

/*! Computes all thermodynamic properties of the system in one fell swoop, on the GPU.
 */
void ComputeThermoGPU::computeProperties()
    {
    unsigned int group_size = m_group->getNumLocalMembers();
    // just drop out if the group is an empty group
    if (group_size == 0)
        return;

    if (m_prof) m_prof->push("Thermo");

    assert(m_pdata);
    assert(m_ndof != 0);

    // access the particle data
    ArrayHandle<Scalar4> d_vel(m_pdata->getVelocities(), access_location::device, access_mode::read);
    gpu_boxsize box = m_pdata->getGlobalBoxGPU();

    PDataFlags flags = m_pdata->getFlags();

    { // scope these array handles so they are released before the additional terms are added
    // access the net force, pe, and virial
    const GPUArray< Scalar4 >& net_force = m_pdata->getNetForce();
    const GPUArray< Scalar >& net_virial = m_pdata->getNetVirial();
    ArrayHandle<Scalar4> d_net_force(net_force, access_location::device, access_mode::read);
    ArrayHandle<Scalar> d_net_virial(net_virial, access_location::device, access_mode::read);
    ArrayHandle<float4> d_scratch(m_scratch, access_location::device, access_mode::overwrite);
    ArrayHandle<float> d_scratch_pressure_tensor(m_scratch_pressure_tensor, access_location::device, access_mode::overwrite);
    ArrayHandle<float> d_properties(m_properties, access_location::device, access_mode::overwrite);

    // access the group
    ArrayHandle< unsigned int > d_index_array(m_group->getIndexArray(), access_location::device, access_mode::read);

    // build up args list
    compute_thermo_args args;
    args.d_net_force = d_net_force.data;
    args.d_net_virial = d_net_virial.data;
    args.virial_pitch = net_virial.getPitch();
    args.ndof = m_ndof;
    args.D = m_sysdef->getNDimensions();
    args.d_scratch = d_scratch.data;
    args.d_scratch_pressure_tensor = d_scratch_pressure_tensor.data;
    args.block_size = m_block_size;
    args.n_blocks = m_num_blocks;

    // perform the computation on the GPU
    gpu_compute_thermo( d_properties.data,
                        d_vel.data,
                        d_index_array.data,
                        group_size,
                        box,
                        args,
                        flags[pdata_flag::pressure_tensor]);

    if (exec_conf->isCUDAErrorCheckingEnabled())
        CHECK_CUDA_ERROR();

    }

    if(PPPMData::compute_pppm_flag) {
        Scalar2 pppm_thermo = ComputeThermoGPU::PPPM_thermo_compute();
        ArrayHandle<float> h_properties(m_properties, access_location::host, access_mode::readwrite);
        h_properties.data[thermo_index::pressure] += pppm_thermo.x;
        h_properties.data[thermo_index::potential_energy] += pppm_thermo.y;
        PPPMData::pppm_energy = pppm_thermo.y;
        }

#ifdef ENABLE_MPI
    // for MPI, we have to copy data back to the host to perform collective operations

    boost::shared_ptr<const boost::mpi::communicator> mpi_comm = m_pdata->getMPICommunicator();

    if (mpi_comm)
        {
        ArrayHandle<Scalar> h_properties(m_properties, access_location::host, access_mode::readwrite);

        Scalar & T = h_properties.data[thermo_index::temperature];
        Scalar & P = h_properties.data[thermo_index::pressure];
        Scalar & ke =  h_properties.data[thermo_index::kinetic_energy];
        Scalar & pe =  h_properties.data[thermo_index::potential_energy];
        Scalar & Pxx =  h_properties.data[thermo_index::pressure_xx];
        Scalar & Pxy =  h_properties.data[thermo_index::pressure_xy];
        Scalar & Pxz =  h_properties.data[thermo_index::pressure_xz];
        Scalar & Pyy =  h_properties.data[thermo_index::pressure_yy];
        Scalar & Pyz =  h_properties.data[thermo_index::pressure_yz];
        Scalar & Pzz =  h_properties.data[thermo_index::pressure_zz];
        T = all_reduce(*mpi_comm, T, std::plus<Scalar>());

        if (flags[pdata_flag::isotropic_virial])
            P = all_reduce(*mpi_comm, P, std::plus<Scalar>());

        ke = all_reduce(*mpi_comm, ke, std::plus<Scalar>());

        if (flags[pdata_flag::potential_energy])
            pe = all_reduce(*mpi_comm, pe, std::plus<Scalar>());

        if (flags[pdata_flag::pressure_tensor])
            {
            Pxx = all_reduce(*mpi_comm, Pxx, std::plus<Scalar>());
            Pxy = all_reduce(*mpi_comm, Pxy, std::plus<Scalar>());
            Pxz = all_reduce(*mpi_comm, Pxz, std::plus<Scalar>());
            Pyy = all_reduce(*mpi_comm, Pyy, std::plus<Scalar>());
            Pyz = all_reduce(*mpi_comm, Pyz, std::plus<Scalar>());
            Pzz = all_reduce(*mpi_comm, Pzz, std::plus<Scalar>());
            }
        }
#endif

    if (m_prof) m_prof->pop();
    }

Scalar2 ComputeThermoGPU::PPPM_thermo_compute()
    {

    gpu_boxsize box = m_pdata->getBoxGPU();

    ArrayHandle<cufftComplex> d_rho_real_space(PPPMData::m_rho_real_space, access_location::device, access_mode::readwrite);
    ArrayHandle<Scalar> d_green_hat(PPPMData::m_green_hat, access_location::device, access_mode::readwrite);
    ArrayHandle<Scalar3> d_vg(PPPMData::m_vg, access_location::device, access_mode::readwrite);
    ArrayHandle<Scalar2> d_i_data(PPPMData::i_data, access_location::device, access_mode::readwrite);
    ArrayHandle<Scalar2> d_o_data(PPPMData::o_data, access_location::device, access_mode::readwrite);

    Scalar2 pppm_virial_energy =  gpu_compute_pppm_thermo(PPPMData::Nx,
                                                          PPPMData::Ny,
                                                          PPPMData::Nz,
                                                          d_rho_real_space.data,
                                                          d_vg.data,
                                                          d_green_hat.data,
                                                          d_o_data.data,
                                                          d_i_data.data,
                                                          256);

    pppm_virial_energy.x *= PPPMData::energy_virial_factor/ (3.0f * box.Lx * box.Ly * box.Lz);
    pppm_virial_energy.y *= PPPMData::energy_virial_factor;
    pppm_virial_energy.y -= PPPMData::q2 * PPPMData::kappa / 1.772453850905516027298168f;
    pppm_virial_energy.y -= 0.5*M_PI*PPPMData::q*PPPMData::q / (PPPMData::kappa*PPPMData::kappa* box.Lx * box.Ly * box.Lz);

    return pppm_virial_energy;

    }

void export_ComputeThermoGPU()
    {
    class_<ComputeThermoGPU, boost::shared_ptr<ComputeThermoGPU>, bases<ComputeThermo>, boost::noncopyable >
        ("ComputeThermoGPU", init< boost::shared_ptr<SystemDefinition>,
         boost::shared_ptr<ParticleGroup>,
         const std::string& >())
        ;
    }

#ifdef WIN32
#pragma warning( pop )
#endif

<|endoftext|>


<commit_before>/****************************************************************************
 *
 *   Copyright (c) 2019 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name PX4 nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/**
 * @file PreFlightChecker.hpp
 * Class handling the EKF2 innovation pre flight checks
 *
 * First call the update(...) function and then get the results
 * using the hasXxxFailed() getters
 */

#pragma once

#include <uORB/topics/vehicle_status.h>
#include <uORB/topics/estimator_innovations.h>

#include <matrix/matrix/math.hpp>

#include "InnovationLpf.hpp"

using matrix::Vector2f;

class PreFlightChecker
{
public:
	PreFlightChecker() = default;
	~PreFlightChecker() = default;

	/*
	 * Reset all the internal states of the class to their default value
	 */
	void reset();

	/*
	 * Update the internal states
	 * @param dt the sampling time
	 * @param innov the ekf2_innovation_s struct containing the current innovations
	 */
	void update(float dt, const estimator_innovations_s &innov);

	/*
	 * If set to true, the checker will use a less conservative heading innovation check
	 */
	void setVehicleCanObserveHeadingInFlight(bool val) { _can_observe_heading_in_flight = val; }

	void setUsingGpsAiding(bool val) { _is_using_gps_aiding = val; }
	void setUsingFlowAiding(bool val) { _is_using_flow_aiding = val; }
	void setUsingEvPosAiding(bool val) { _is_using_ev_pos_aiding = val; }
	void setUsingEvVelAiding(bool val) { _is_using_ev_vel_aiding = val; }

	bool hasHeadingFailed() const { return _has_heading_failed; }
	bool hasHorizVelFailed() const { return _has_horiz_vel_failed; }
	bool hasVertVelFailed() const { return _has_vert_vel_failed; }
	bool hasHeightFailed() const { return _has_height_failed; }

	/*
	 * Overall state of the pre fligh checks
	 * @return true if any of the check failed
	 */
	bool hasFailed() const { return hasHorizFailed() || hasVertFailed(); }

	/*
	 * Horizontal checks overall result
	 * @return true if one of the horizontal checks failed
	 */
	bool hasHorizFailed() const { return _has_heading_failed || _has_horiz_vel_failed; }

	/*
	 * Vertical checks overall result
	 * @return true if one of the vertical checks failed
	 */
	bool hasVertFailed() const { return _has_vert_vel_failed || _has_height_failed; }

	/*
	 * Check if the innovation fails the test
	 * To pass the test, the following conditions should be true:
	 * innov_lpf <= test_limit
	 * innov <= spike_limit
	 * @param innov_lpf the low-pass filtered innovation
	 * @param innov the current unfiltered innovation
	 * @param test_limit the magnitude test limit for innov_lpf
	 * @param spike_limit the magnitude test limit for innov
	 * @return true if the check failed the test, false otherwise
	 */
	static bool checkInnovFailed(float innov_lpf, float innov, float test_limit, float spike_limit);

	/*
	 * Check if the a innovation of a 2D vector fails the test
	 * To pass the test, the following conditions should be true:
	 * innov_lpf <= test_limit
	 * innov <= spike_limit
	 * @param innov_lpf the low-pass filtered innovation
	 * @param innov the current unfiltered innovation
	 * @param test_limit the magnitude test limit for innov_lpf
	 * @param spike_limit the magnitude test limit for innov
	 * @return true if the check failed the test, false otherwise
	 */
	static bool checkInnov2DFailed(const Vector2f &innov_lpf, const Vector2f &innov, float test_limit, float spike_limit);

	static constexpr float sq(float var) { return var * var; }

private:
	bool preFlightCheckHeadingFailed(const estimator_innovations_s &innov, float alpha);
	float selectHeadingTestLimit();

	bool preFlightCheckHorizVelFailed(const estimator_innovations_s &innov, float alpha);
	bool preFlightCheckVertVelFailed(const estimator_innovations_s &innov, float alpha);
	bool preFlightCheckHeightFailed(const estimator_innovations_s &innov, float alpha);

	void resetPreFlightChecks();

	bool _has_heading_failed{};
	bool _has_horiz_vel_failed{};
	bool _has_vert_vel_failed{};
	bool _has_height_failed{};

	bool _can_observe_heading_in_flight{};
	bool _is_using_gps_aiding{};
	bool _is_using_flow_aiding{};
	bool _is_using_ev_pos_aiding{};
	bool _is_using_ev_vel_aiding{};

	// Low-pass filters for innovation pre-flight checks
	InnovationLpf _filter_vel_n_innov;	///< Preflight low pass filter N axis velocity innovations (m/sec)
	InnovationLpf _filter_vel_e_innov;	///< Preflight low pass filter E axis velocity innovations (m/sec)
	InnovationLpf _filter_vel_d_innov;	///< Preflight low pass filter D axis velocity innovations (m/sec)
	InnovationLpf _filter_hgt_innov;	///< Preflight low pass filter height innovation (m)
	InnovationLpf _filter_heading_innov;	///< Preflight low pass filter heading innovation magntitude (rad)
	InnovationLpf _filter_flow_x_innov;	///< Preflight low pass filter optical flow innovation (rad)
	InnovationLpf _filter_flow_y_innov;	///< Preflight low pass filter optical flow innovation (rad)

	// Preflight low pass filter time constant inverse (1/sec)
	static constexpr float _innov_lpf_tau_inv = 0.2f;
	// Maximum permissible velocity innovation to pass pre-flight checks (m/sec)
	static constexpr float _vel_innov_test_lim = 0.5f;
	// Maximum permissible height innovation to pass pre-flight checks (m)
	static constexpr float _hgt_innov_test_lim = 1.5f;
	// Maximum permissible yaw innovation to pass pre-flight checks when aiding inertial nav using NE frame observations (rad)
	static constexpr float _nav_heading_innov_test_lim = 0.25f;
	// Maximum permissible yaw innovation to pass pre-flight checks when not aiding inertial nav using NE frame observations (rad)
	static constexpr float _heading_innov_test_lim = 0.52f;
	// Maximum permissible flow innovation to pass pre-flight checks
	static constexpr float _flow_innov_test_lim = 0.25f;
	// Preflight velocity innovation spike limit (m/sec)
	static constexpr float _vel_innov_spike_lim = 2.0f * _vel_innov_test_lim;
	// Preflight position innovation spike limit (m)
	static constexpr float _hgt_innov_spike_lim = 2.0f * _hgt_innov_test_lim;
	// Preflight flow innovation spike limit (rad)
	static constexpr float _flow_innov_spike_lim = 2.0f * _flow_innov_test_lim;
};
<commit_msg>ekf2: remove unused function declatation<commit_after>/****************************************************************************
 *
 *   Copyright (c) 2019 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name PX4 nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/**
 * @file PreFlightChecker.hpp
 * Class handling the EKF2 innovation pre flight checks
 *
 * First call the update(...) function and then get the results
 * using the hasXxxFailed() getters
 */

#pragma once

#include <uORB/topics/vehicle_status.h>
#include <uORB/topics/estimator_innovations.h>

#include <matrix/matrix/math.hpp>

#include "InnovationLpf.hpp"

using matrix::Vector2f;

class PreFlightChecker
{
public:
	PreFlightChecker() = default;
	~PreFlightChecker() = default;

	/*
	 * Reset all the internal states of the class to their default value
	 */
	void reset();

	/*
	 * Update the internal states
	 * @param dt the sampling time
	 * @param innov the ekf2_innovation_s struct containing the current innovations
	 */
	void update(float dt, const estimator_innovations_s &innov);

	/*
	 * If set to true, the checker will use a less conservative heading innovation check
	 */
	void setVehicleCanObserveHeadingInFlight(bool val) { _can_observe_heading_in_flight = val; }

	void setUsingGpsAiding(bool val) { _is_using_gps_aiding = val; }
	void setUsingFlowAiding(bool val) { _is_using_flow_aiding = val; }
	void setUsingEvPosAiding(bool val) { _is_using_ev_pos_aiding = val; }
	void setUsingEvVelAiding(bool val) { _is_using_ev_vel_aiding = val; }

	bool hasHeadingFailed() const { return _has_heading_failed; }
	bool hasHorizVelFailed() const { return _has_horiz_vel_failed; }
	bool hasVertVelFailed() const { return _has_vert_vel_failed; }
	bool hasHeightFailed() const { return _has_height_failed; }

	/*
	 * Overall state of the pre fligh checks
	 * @return true if any of the check failed
	 */
	bool hasFailed() const { return hasHorizFailed() || hasVertFailed(); }

	/*
	 * Horizontal checks overall result
	 * @return true if one of the horizontal checks failed
	 */
	bool hasHorizFailed() const { return _has_heading_failed || _has_horiz_vel_failed; }

	/*
	 * Vertical checks overall result
	 * @return true if one of the vertical checks failed
	 */
	bool hasVertFailed() const { return _has_vert_vel_failed || _has_height_failed; }

	/*
	 * Check if the innovation fails the test
	 * To pass the test, the following conditions should be true:
	 * innov_lpf <= test_limit
	 * innov <= spike_limit
	 * @param innov_lpf the low-pass filtered innovation
	 * @param innov the current unfiltered innovation
	 * @param test_limit the magnitude test limit for innov_lpf
	 * @param spike_limit the magnitude test limit for innov
	 * @return true if the check failed the test, false otherwise
	 */
	static bool checkInnovFailed(float innov_lpf, float innov, float test_limit, float spike_limit);

	/*
	 * Check if the a innovation of a 2D vector fails the test
	 * To pass the test, the following conditions should be true:
	 * innov_lpf <= test_limit
	 * innov <= spike_limit
	 * @param innov_lpf the low-pass filtered innovation
	 * @param innov the current unfiltered innovation
	 * @param test_limit the magnitude test limit for innov_lpf
	 * @param spike_limit the magnitude test limit for innov
	 * @return true if the check failed the test, false otherwise
	 */
	static bool checkInnov2DFailed(const Vector2f &innov_lpf, const Vector2f &innov, float test_limit, float spike_limit);

	static constexpr float sq(float var) { return var * var; }

private:
	bool preFlightCheckHeadingFailed(const estimator_innovations_s &innov, float alpha);
	float selectHeadingTestLimit();

	bool preFlightCheckHorizVelFailed(const estimator_innovations_s &innov, float alpha);
	bool preFlightCheckVertVelFailed(const estimator_innovations_s &innov, float alpha);
	bool preFlightCheckHeightFailed(const estimator_innovations_s &innov, float alpha);

	bool _has_heading_failed{};
	bool _has_horiz_vel_failed{};
	bool _has_vert_vel_failed{};
	bool _has_height_failed{};

	bool _can_observe_heading_in_flight{};
	bool _is_using_gps_aiding{};
	bool _is_using_flow_aiding{};
	bool _is_using_ev_pos_aiding{};
	bool _is_using_ev_vel_aiding{};

	// Low-pass filters for innovation pre-flight checks
	InnovationLpf _filter_vel_n_innov;	///< Preflight low pass filter N axis velocity innovations (m/sec)
	InnovationLpf _filter_vel_e_innov;	///< Preflight low pass filter E axis velocity innovations (m/sec)
	InnovationLpf _filter_vel_d_innov;	///< Preflight low pass filter D axis velocity innovations (m/sec)
	InnovationLpf _filter_hgt_innov;	///< Preflight low pass filter height innovation (m)
	InnovationLpf _filter_heading_innov;	///< Preflight low pass filter heading innovation magntitude (rad)
	InnovationLpf _filter_flow_x_innov;	///< Preflight low pass filter optical flow innovation (rad)
	InnovationLpf _filter_flow_y_innov;	///< Preflight low pass filter optical flow innovation (rad)

	// Preflight low pass filter time constant inverse (1/sec)
	static constexpr float _innov_lpf_tau_inv = 0.2f;
	// Maximum permissible velocity innovation to pass pre-flight checks (m/sec)
	static constexpr float _vel_innov_test_lim = 0.5f;
	// Maximum permissible height innovation to pass pre-flight checks (m)
	static constexpr float _hgt_innov_test_lim = 1.5f;
	// Maximum permissible yaw innovation to pass pre-flight checks when aiding inertial nav using NE frame observations (rad)
	static constexpr float _nav_heading_innov_test_lim = 0.25f;
	// Maximum permissible yaw innovation to pass pre-flight checks when not aiding inertial nav using NE frame observations (rad)
	static constexpr float _heading_innov_test_lim = 0.52f;
	// Maximum permissible flow innovation to pass pre-flight checks
	static constexpr float _flow_innov_test_lim = 0.25f;
	// Preflight velocity innovation spike limit (m/sec)
	static constexpr float _vel_innov_spike_lim = 2.0f * _vel_innov_test_lim;
	// Preflight position innovation spike limit (m)
	static constexpr float _hgt_innov_spike_lim = 2.0f * _hgt_innov_test_lim;
	// Preflight flow innovation spike limit (rad)
	static constexpr float _flow_innov_spike_lim = 2.0f * _flow_innov_test_lim;
};
<|endoftext|>


<commit_before>#include "cmainwindow.h"
#include "settings/csettings.h"

DISABLE_COMPILER_WARNINGS
#include <QApplication>
RESTORE_COMPILER_WARNINGS

int main(int argc, char *argv[])
{
	QApplication app(argc, argv);
	app.setQuitOnLastWindowClosed(false);

	app.setOrganizationName("GitHubSoft");
	app.setApplicationName("Simple Camera Viewer");

	CSettings::setApplicationName(app.applicationName());
	CSettings::setOrganizationName(app.organizationName());

	CMainWindow w;

	return app.exec();
}
<commit_msg>AdvancedAssert configured to print failed assertions to qDebug<commit_after>#include "cmainwindow.h"
#include "settings/csettings.h"
#include "assert/advanced_assert.h"

DISABLE_COMPILER_WARNINGS
#include <QApplication>
#include <QDebug>
RESTORE_COMPILER_WARNINGS

int main(int argc, char *argv[])
{
	AdvancedAssert::setLoggingFunc([](const char* message){
		qDebug() << message;
	});

	QApplication app(argc, argv);
	app.setQuitOnLastWindowClosed(false);

	app.setOrganizationName("GitHubSoft");
	app.setApplicationName("Simple Camera Viewer");

	CSettings::setApplicationName(app.applicationName());
	CSettings::setOrganizationName(app.organizationName());

	CMainWindow w;

	return app.exec();
}
<|endoftext|>


<commit_before><commit_msg>tests/tdd: add ecdh tests<commit_after><|endoftext|>


<commit_before><commit_msg>Used stack-allocated variables instead of heap-allocated.<commit_after><|endoftext|>


<commit_before>#include "bvsd.h"

/** Main function, creates interactive loop. */
int main(const int argc, const char** argv)
{
	signal(SIGINT, mainSignal);
	signal(SIGSEGV, mainSignal);
	signal(SIGALRM, mainSignal);

	LOG(2, "starting!");
	bvs = new BVS::BVS(argc, argv, &shutdownFunction);

	LOG(2, "loading modules!");
	bvs->loadModules();

	LOG(2, "connecting modules!");
	bvs->connectAllModules();

	LOG(2, "starting!");
	bvs->start();

	bvs->run();

	std::string input;
	while (true)
	{
		std::getline(std::cin, input);
		if (std::cin.eof()) input = "q";

		if (input == "r" || input == "run" || input == "c" || input == "continue")
		{
			LOG(2, "RUN!!!");
			bvs->run();
		}
		else if (input.empty() || input == "s" || input == "step")
		{
			LOG(2, "STEP!!!");
			bvs->step();
		}
		else if (input == "p" || input == "pause")
		{
			LOG(2, "PAUSING!!!");
			bvs->pause();
		}
		else if (input.substr(0,2) == "hs" || input.substr(0, 7) == "hotswap")
		{
			size_t delimiter = input.find_first_of(" ");
			input.erase(0, delimiter+1);
			if (input.empty() || delimiter==std::string::npos) std::cout << "ERROR: no module ID given!" << std::endl;
			else bvs->hotSwap(input);
		}
		else if (input == "q" || input == "quit")
		{
			LOG(2, "quitting...");
			bvs->quit();
			LOG(2, "finished!");
			break;
		}
		else if (input == "h" || input == "help")
		{
			std::cout << "usage:" << std::endl;
			std::cout << "   r|run            run system until paused" << std::endl;
			std::cout << "   c|continue       same as run" << std::endl;
			std::cout << "   s|step           advance system by one step" << std::endl;
			std::cout << "   p|pause          pause(stop) system" << std::endl;
			std::cout << "   hs|hotswap <arg> HotSwap(TM) <moduleID>" << std::endl;
			std::cout << "   q|quit           shutdown system and quit" << std::endl;
			std::cout << "   h|help           show help" << std::endl;
		}
		else
		{
			std::cout << ">>> unknown command: " << input << std::endl << ">>> for help press 'h<enter>'!" << std::endl;
		}
	}

	delete bvs;

	return 0;
}

void mainSignal(int sig)
{
	switch (sig)
	{
		case SIGINT:
			LOG(2, "Caught 'Ctrl-C', quitting!");
			break;
		case SIGSEGV:
			LOG(2, "Caught segmentation fault...!");
			void *msgs[100];
			size_t size;
			size = backtrace(msgs, 100);
			fprintf(stderr, "\n\n\nCaught signal %d (%s)!\n\n", sig, strsignal(sig));
			char** messages;
			messages = backtrace_symbols(msgs, size);
			for (size_t i=2; i < size && messages != NULL; ++i)
				fprintf(stderr, "[bt]: (%lu) %s\n", i-2, messages[i]);
			free(messages);
			break;
		case SIGALRM:
			LOG(2, "Shutdown requested, quitting!");
			break;
	}

	if (sig==SIGSEGV)
	{
		signal(SIGSEGV, SIG_DFL);
		raise(SIGSEGV);
	}
	else
	{
		bvs->quit();
		delete bvs;
		exit(EXIT_FAILURE);
	}
}

void shutdownFunction()
{
	LOG(1,"daemon exit caused by bvs shutdown request!");
	bvs->quit();
	alarm(1); // SIGALRM after 1 second so all framework/module threads have a chance to quit
}

<commit_msg>daemon: remove LOG message before bvs startup<commit_after>#include "bvsd.h"

/** Main function, creates interactive loop. */
int main(const int argc, const char** argv)
{
	signal(SIGINT, mainSignal);
	signal(SIGSEGV, mainSignal);
	signal(SIGALRM, mainSignal);

	bvs = new BVS::BVS(argc, argv, &shutdownFunction);

	LOG(2, "loading modules!");
	bvs->loadModules();

	LOG(2, "connecting modules!");
	bvs->connectAllModules();

	LOG(2, "starting!");
	bvs->start();

	bvs->run();

	std::string input;
	while (true)
	{
		std::getline(std::cin, input);
		if (std::cin.eof()) input = "q";

		if (input == "r" || input == "run" || input == "c" || input == "continue")
		{
			LOG(2, "RUN!!!");
			bvs->run();
		}
		else if (input.empty() || input == "s" || input == "step")
		{
			LOG(2, "STEP!!!");
			bvs->step();
		}
		else if (input == "p" || input == "pause")
		{
			LOG(2, "PAUSING!!!");
			bvs->pause();
		}
		else if (input.substr(0,2) == "hs" || input.substr(0, 7) == "hotswap")
		{
			size_t delimiter = input.find_first_of(" ");
			input.erase(0, delimiter+1);
			if (input.empty() || delimiter==std::string::npos) std::cout << "ERROR: no module ID given!" << std::endl;
			else bvs->hotSwap(input);
		}
		else if (input == "q" || input == "quit")
		{
			LOG(2, "quitting...");
			bvs->quit();
			LOG(2, "finished!");
			break;
		}
		else if (input == "h" || input == "help")
		{
			std::cout << "usage:" << std::endl;
			std::cout << "   r|run            run system until paused" << std::endl;
			std::cout << "   c|continue       same as run" << std::endl;
			std::cout << "   s|step           advance system by one step" << std::endl;
			std::cout << "   p|pause          pause(stop) system" << std::endl;
			std::cout << "   hs|hotswap <arg> HotSwap(TM) <moduleID>" << std::endl;
			std::cout << "   q|quit           shutdown system and quit" << std::endl;
			std::cout << "   h|help           show help" << std::endl;
		}
		else
		{
			std::cout << ">>> unknown command: " << input << std::endl << ">>> for help press 'h<enter>'!" << std::endl;
		}
	}

	delete bvs;

	return 0;
}

void mainSignal(int sig)
{
	switch (sig)
	{
		case SIGINT:
			LOG(2, "Caught 'Ctrl-C', quitting!");
			break;
		case SIGSEGV:
			LOG(2, "Caught segmentation fault...!");
			void *msgs[100];
			size_t size;
			size = backtrace(msgs, 100);
			fprintf(stderr, "\n\n\nCaught signal %d (%s)!\n\n", sig, strsignal(sig));
			char** messages;
			messages = backtrace_symbols(msgs, size);
			for (size_t i=2; i < size && messages != NULL; ++i)
				fprintf(stderr, "[bt]: (%lu) %s\n", i-2, messages[i]);
			free(messages);
			break;
		case SIGALRM:
			LOG(2, "Shutdown requested, quitting!");
			break;
	}

	if (sig==SIGSEGV)
	{
		signal(SIGSEGV, SIG_DFL);
		raise(SIGSEGV);
	}
	else
	{
		bvs->quit();
		delete bvs;
		exit(EXIT_FAILURE);
	}
}

void shutdownFunction()
{
	LOG(1,"daemon exit caused by bvs shutdown request!");
	bvs->quit();
	alarm(1); // SIGALRM after 1 second so all framework/module threads have a chance to quit
}

<|endoftext|>