<commit_before>/*************************************************************************
 *
 *  $RCSfile: statusbarcontrollerfactory.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: obo $ $Date: 2004-11-17 14:57:26 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#ifndef __FRAMEWORK_UIFACTORY_STATUSBARCONTROLLERFACTORY_HXX_
#define __FRAMEWORK_UIFACTORY_STATUSBARCONTROLLERFACTORY_HXX_

/** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble
               with solaris headers ...
*/
#include <vector>
#include <list>
#include <hash_map>

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_
#include <threadhelp/threadhelpbase.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_GENERIC_HXX_
#include <macros/generic.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XINTERFACE_HXX_
#include <macros/xinterface.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XTYPEPROVIDER_HXX_
#include <macros/xtypeprovider.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XSERVICEINFO_HXX_
#include <macros/xserviceinfo.hxx>
#endif

#ifndef __FRAMEWORK_STDTYPES_H_
#include <stdtypes.h>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XTYPEPROVIDER_HPP_
#include <com/sun/star/lang/XTypeProvider.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XMULTICOMPONENTFACTORY_HPP_
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#endif

#ifndef _DRAFTS_COM_SUN_STAR_FRAME_XUICONTROLLERREGISTRATION_HPP_
#include <drafts/com/sun/star/frame/XUIControllerRegistration.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

namespace framework
{

class ConfigurationAccess_StatusbarControllerFactory;
class StatusbarControllerFactory :  public com::sun::star::lang::XTypeProvider                      ,
                                    public com::sun::star::lang::XServiceInfo                       ,
                                    public com::sun::star::lang::XMultiComponentFactory             ,
                                    public drafts::com::sun::star::frame::XUIControllerRegistration ,
                                    private ThreadHelpBase                                          ,   // Struct for right initalization of mutex member! Must be first of baseclasses.
                                    public ::cppu::OWeakObject
{
    public:
        StatusbarControllerFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager );
        virtual ~StatusbarControllerFactory();

        //  XInterface, XTypeProvider, XServiceInfo
        DECLARE_XINTERFACE
        DECLARE_XTYPEPROVIDER
        DECLARE_XSERVICEINFO

        // XMultiComponentFactory
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstanceWithContext( const ::rtl::OUString& aServiceSpecifier, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& Context ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstanceWithArgumentsAndContext( const ::rtl::OUString& ServiceSpecifier, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Arguments, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& Context ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getAvailableServiceNames() throw (::com::sun::star::uno::RuntimeException);

        // XUIControllerRegistration
        virtual sal_Bool SAL_CALL hasController( const ::rtl::OUString& aCommandURL, const rtl::OUString& aModuleName ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL registerController( const ::rtl::OUString& aCommandURL, const rtl::OUString& aModuleName, const ::rtl::OUString& aControllerImplementationName ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL deregisterController( const ::rtl::OUString& aCommandURL, const rtl::OUString& aModuleName ) throw (::com::sun::star::uno::RuntimeException);

    private:
        sal_Bool                                                                         m_bConfigRead;
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager;
        ConfigurationAccess_StatusbarControllerFactory*                                  m_pConfigAccess;
};

} // namespace framework

#endif // __FRAMEWORK_SERVICES_STATUSBARCONTROLLERFACTORY_HXX_
<commit_msg>INTEGRATION: CWS removedrafts (1.2.62); FILE MERGED 2005/02/17 12:45:57 cd 1.2.62.1: #i42557# move UNOIDL types from drafts to com<commit_after>/*************************************************************************
 *
 *  $RCSfile: statusbarcontrollerfactory.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2005-03-01 19:32:42 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#ifndef __FRAMEWORK_UIFACTORY_STATUSBARCONTROLLERFACTORY_HXX_
#define __FRAMEWORK_UIFACTORY_STATUSBARCONTROLLERFACTORY_HXX_

/** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble
               with solaris headers ...
*/
#include <vector>
#include <list>
#include <hash_map>

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_
#include <threadhelp/threadhelpbase.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_GENERIC_HXX_
#include <macros/generic.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XINTERFACE_HXX_
#include <macros/xinterface.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XTYPEPROVIDER_HXX_
#include <macros/xtypeprovider.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XSERVICEINFO_HXX_
#include <macros/xserviceinfo.hxx>
#endif

#ifndef __FRAMEWORK_STDTYPES_H_
#include <stdtypes.h>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XTYPEPROVIDER_HPP_
#include <com/sun/star/lang/XTypeProvider.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XMULTICOMPONENTFACTORY_HPP_
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XUICONTROLLERREGISTRATION_HPP_
#include <com/sun/star/frame/XUIControllerRegistration.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

namespace framework
{

class ConfigurationAccess_StatusbarControllerFactory;
class StatusbarControllerFactory :  public com::sun::star::lang::XTypeProvider                      ,
                                    public com::sun::star::lang::XServiceInfo                       ,
                                    public com::sun::star::lang::XMultiComponentFactory             ,
                                    public ::com::sun::star::frame::XUIControllerRegistration ,
                                    private ThreadHelpBase                                          ,   // Struct for right initalization of mutex member! Must be first of baseclasses.
                                    public ::cppu::OWeakObject
{
    public:
        StatusbarControllerFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager );
        virtual ~StatusbarControllerFactory();

        //  XInterface, XTypeProvider, XServiceInfo
        DECLARE_XINTERFACE
        DECLARE_XTYPEPROVIDER
        DECLARE_XSERVICEINFO

        // XMultiComponentFactory
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstanceWithContext( const ::rtl::OUString& aServiceSpecifier, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& Context ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstanceWithArgumentsAndContext( const ::rtl::OUString& ServiceSpecifier, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Arguments, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& Context ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getAvailableServiceNames() throw (::com::sun::star::uno::RuntimeException);

        // XUIControllerRegistration
        virtual sal_Bool SAL_CALL hasController( const ::rtl::OUString& aCommandURL, const rtl::OUString& aModuleName ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL registerController( const ::rtl::OUString& aCommandURL, const rtl::OUString& aModuleName, const ::rtl::OUString& aControllerImplementationName ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL deregisterController( const ::rtl::OUString& aCommandURL, const rtl::OUString& aModuleName ) throw (::com::sun::star::uno::RuntimeException);

    private:
        sal_Bool                                                                         m_bConfigRead;
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager;
        ConfigurationAccess_StatusbarControllerFactory*                                  m_pConfigAccess;
};

} // namespace framework

#endif // __FRAMEWORK_SERVICES_STATUSBARCONTROLLERFACTORY_HXX_
<|endoftext|>


<commit_before>/** @file
    @brief Implementation

    @date 2016

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

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

// Internal Includes
#include "ChaperoneData.h"

// Library/third-party includes
#include <json/reader.h>
#include <json/value.h>

#include <osvr/Util/Finally.h>

// Standard includes
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <sstream>

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define NO_MINMAX
#include <windows.h>

static inline std::string formatLastErrorAsString() {
    char *lpMsgBuf = nullptr;
    FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                   nullptr, GetLastError(),
                   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                   // Default language
                   reinterpret_cast<LPSTR>(&lpMsgBuf), 0, nullptr);
    /// Free that buffer when we're out of scope.
    auto cleanupBuf = osvr::util::finally([&] { LocalFree(lpMsgBuf); });
    auto errorMessage = std::string(lpMsgBuf);
    return errorMessage;
}
static inline std::string
getFile(std::string const &fn,
        std::function<void(std::string const &)> const &errorReport) {
    /// Had trouble with "permission denied" errors using standard C++ iostreams
    /// on the chaperone data, so had to go back down to Win32 API.
    HANDLE f = CreateFileA(fn.c_str(), GENERIC_READ,
                           FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
                           OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
    if (INVALID_HANDLE_VALUE == f) {
        errorReport("Could not open file: " + formatLastErrorAsString());
        return std::string{};
    }
    auto closer = osvr::util::finally([&f] { CloseHandle(f); });

    std::ostringstream os;
    static const auto BUFSIZE = 1024;
    std::array<char, BUFSIZE + 1> buf;
    /// Null terminate for ease of use.
    buf.back() = '\0';
    bool keepReading = true;
    while (1) {
        DWORD bytesRead;
        auto ret = ReadFile(f, buf.data(), buf.size() - 1, &bytesRead, nullptr);
        if (ret) {
            if (bytesRead == 0) {
                // end of file
                break;
            } else {
                // Null terminate this block and slide it in.
                // std::cout << "read " << bytesRead << " bytes this time "
                //          << std::endl;
                buf[bytesRead] = '\0';
                os << buf.data();
            }
        } else {

            errorReport("Error after reading " +
                        std::to_string(os.str().size()) + " bytes: " +
                        formatLastErrorAsString());
            return std::string{};
        }
    }
    return os.str();
}
#else

std::string
getFile(std::string const &fn,
        std::function<void(std::string const &)> const &errorReport) {
    std::ifstream s(fn, std::ios::in | std::ios::binary);
    if (!s) {
        std::ostringstream os;
        os << "Could not open file ";

        /// Sadly errno is far more useful in its error messages than
        /// failbit-triggered exceptions, etc.
        auto theErrno = errno;
        os << " (Error code: " << theErrno << " - " << strerror(theErrno)
           << ")";
        errorReport(os.str());
        return std::string{};
    }
    std::ostringstream os;
    std::string temp;
    while (std::getline(os, temp)) {
        os << temp;
    }
    return os.str();
}
#endif

namespace osvr {
namespace vive {
    static const auto PREFIX = "[ChaperoneData] ";
    static const auto CHAPERONE_DATA_FILENAME = "chaperone_info.vrchap";
#ifdef _WIN32
    static const auto PATH_SEPARATOR = "\\";
#else
    static const auto PATH_SEPARATOR = "/";
#endif

    using UniverseDataMap =
        std::map<std::uint64_t, ChaperoneData::UniverseData>;

    using UniverseBaseSerials = std::vector<
        std::pair<std::uint64_t, ChaperoneData::BaseStationSerials>>;
    struct ChaperoneData::Impl {
        Json::Value chaperoneInfo;
        UniverseDataMap universes;
        UniverseBaseSerials baseSerials;
    };

    void loadJsonIntoUniverseData(Json::Value const &obj,
                                  ChaperoneData::UniverseData &data) {
        data.yaw = obj["yaw"].asDouble();
        auto &xlate = obj["translation"];
        for (Json::Value::ArrayIndex i = 0; i < 3; ++i) {
            data.translation[i] = xlate[i].asDouble();
        }
    }
    ChaperoneData::ChaperoneData(std::string const &steamConfigDir)
        : impl_(new Impl), configDir_(steamConfigDir) {
        {
            Json::Reader reader;
            auto chapInfoFn =
                configDir_ + PATH_SEPARATOR + CHAPERONE_DATA_FILENAME;
#if 0
            std::ifstream chapInfoFile(configDir_,
                                       std::ios::in | std::ios::binary);
            if (!chapInfoFile) {
                std::ostringstream os;
                os << "Could not open chaperone info file, expected at "
                   << chapInfoFn;

                /// Sadly errno is far more useful in its error messages than
                /// failbit-triggered exceptions, etc.
                auto theErrno = errno;
                os << " (Error code: " << theErrno << " - "
                   << strerror(theErrno) << ")";
                errorOut_(os.str());
                return;
            }

            if (!chapInfoFile.good()) {
                errorOut_("Could not open chaperone info file, expected at " +
                          chapInfoFn);
                return;
            }
#endif
            std::string fileData =
                getFile(chapInfoFn, [&](std::string const &message) {
                    std::ostringstream os;
                    os << "Could not open chaperone info file, expected at "
                       << chapInfoFn;
                    os << " - details [" << message << "]";
                    errorOut_(os.str());

                });
            if (!valid()) {
                /// this means our fail handler got called.
                return;
            }
            if (!reader.parse(fileData, impl_->chaperoneInfo)) {
                errorOut_("Could not parse JSON in chaperone info file at " +
                          chapInfoFn + ": " +
                          reader.getFormattedErrorMessages());
                return;
            }

            /// Basic sanity checks
            if (impl_->chaperoneInfo["jsonid"] != "chaperone_info") {
                errorOut_("Chaperone info file at " + chapInfoFn +
                          " did not match expected format (no element "
                          "\"jsonid\": \"chaperone_info\" in top level "
                          "object)");
                return;
            }

            if (impl_->chaperoneInfo["universes"].size() == 0) {
                errorOut_("Chaperone info file at " + chapInfoFn +
                          " did not contain any known chaperone universes - "
                          "user must run Room Setup at least once");
                return;
            }
        }

        for (auto const &univ : impl_->chaperoneInfo["universes"]) {
            auto univIdString = univ["universeID"].asString();
            UniverseData data;
            auto &standing = univ["standing"];
            if (standing.isNull()) {
                warn_("No standing calibration data for universe " +
                      univIdString + ", so had to look for seated data.");
                auto &seated = univ["seated"];
                if (seated.isNull()) {
                    warn_(
                        "No seated or standing calibration data for universe " +
                        univIdString + ", so had to skip it.");
                    continue;
                } else {
                    data.type = CalibrationType::Seated;
                    loadJsonIntoUniverseData(seated, data);
                }
            } else {
                data.type = CalibrationType::Standing;
                loadJsonIntoUniverseData(standing, data);
            }
            /// Convert universe ID (64-bit int) from string, in JSON, to an int
            /// again.
            UniverseId id;
            std::istringstream is(univIdString);
            is >> id;
            /// Add the universe data in.
            impl_->universes.insert(std::make_pair(id, data));

            BaseStationSerials serials;
            for (auto const &tracker : univ["trackers"]) {
                auto &serial = tracker["serial"];
                if (serial.isString()) {
                    serials.push_back(serial.asString());
                }
            }

            /// Add the serial data in.
            impl_->baseSerials.emplace_back(id, std::move(serials));
        }
    }

    ChaperoneData::~ChaperoneData() {}

    bool ChaperoneData::valid() const { return static_cast<bool>(impl_); }

    bool ChaperoneData::knowUniverseId(UniverseId universe) const {
        if (0 == universe) {
            return false;
        }
        return (impl_->universes.find(universe) != end(impl_->universes));
    }

    ChaperoneData::UniverseData
    ChaperoneData::getDataForUniverse(UniverseId universe) const {
        auto it = impl_->universes.find(universe);
        if (it == end(impl_->universes)) {
            return UniverseData();
        }
        return it->second;
    }

    std::size_t ChaperoneData::getNumberOfKnownUniverses() const {
        return impl_->universes.size();
    }

    ChaperoneData::UniverseId ChaperoneData::guessUniverseIdFromBaseStations(
        BaseStationSerials const &bases) {
        auto providedSize = bases.size();
        UniverseId ret = 0;
        using UniverseRank = std::pair<float, UniverseId>;
        /// Compare function for heap.
        auto compare = [](UniverseRank const &a, UniverseRank const &b) {
            return a.first < b.first;
        };

        /// Will contain heap of potential universes and their value (a fraction
        /// of their base stations and provided base stations that were included
        /// in the base station list provided to the function)
        std::vector<UniverseRank> potentialUniverses;
        auto push = [&](float value, UniverseId id) {
            potentialUniverses.emplace_back(value, id);
            std::push_heap(begin(potentialUniverses), end(potentialUniverses),
                           compare);
        };

        for (auto &univBaseSerial : impl_->baseSerials) {
            auto const &baseSerials = univBaseSerial.second;
            std::size_t hits = 0;
            auto b = begin(baseSerials);
            auto e = end(baseSerials);
            /// Count the number of entries that we were given that are also in
            /// this universe's list.
            auto found = std::count_if(begin(bases), end(bases),
                                       [&](std::string const &needle) {
                                           return std::find(b, e, needle) != e;
                                       });
            if (found > 0) {
                /// This is meant to combine the influence of "found" in both
                /// providedSize and universe size, and the +1 in the
                /// denominator is to avoid division by zero.
                auto weight = 2.f * static_cast<float>(found) /
                              (baseSerials.size() + providedSize + 1);
#if 0
                std::cout << "Guessing produced weight of " << weight << " for "
                          << univBaseSerial.first << std::endl;
#endif
                push(weight, univBaseSerial.first);
            }
        }
        if (!potentialUniverses.empty()) {
            /// it's a heap, so the best one is always on top.
            return potentialUniverses.front().second;
        }
        return ret;
    }

    void ChaperoneData::errorOut_(std::string const &message) {
        /// This reset may be redundant in some cases, but better to not miss
        /// it, since it's also our error flag.
        impl_.reset();

        warn_("ERROR: " + message);
    }

    void ChaperoneData::warn_(std::string const &message) {

        if (err_.empty()) {
            /// First error
            err_ = message;
            return;
        }

        static const auto BEGIN_LIST = "[";
        static const auto BEGIN_LIST_CH = BEGIN_LIST[0];
        static const auto END_LIST = "]";
        static const auto MIDDLE_LIST = "][";
        if (BEGIN_LIST_CH == err_.front()) {
            /// We've already started a list of errors, just tack one more on.
            err_ += BEGIN_LIST + message + END_LIST;
            return;
        }

        /// OK, so this is our exactly second error, wrap the first and second.
        err_ = BEGIN_LIST + err_ + MIDDLE_LIST + message + END_LIST;
    }

} // namespace vive
} // namespace osvr
<commit_msg>Add missing includes and fix mistype in std::getline call<commit_after>/** @file
    @brief Implementation

    @date 2016

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

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

// Internal Includes
#include "ChaperoneData.h"

// Library/third-party includes
#include <json/reader.h>
#include <json/value.h>

#include <osvr/Util/Finally.h>

// Standard includes
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <sstream>
#include <algorithm>

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define NO_MINMAX
#include <windows.h>

static inline std::string formatLastErrorAsString() {
    char *lpMsgBuf = nullptr;
    FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                   nullptr, GetLastError(),
                   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                   // Default language
                   reinterpret_cast<LPSTR>(&lpMsgBuf), 0, nullptr);
    /// Free that buffer when we're out of scope.
    auto cleanupBuf = osvr::util::finally([&] { LocalFree(lpMsgBuf); });
    auto errorMessage = std::string(lpMsgBuf);
    return errorMessage;
}
static inline std::string
getFile(std::string const &fn,
        std::function<void(std::string const &)> const &errorReport) {
    /// Had trouble with "permission denied" errors using standard C++ iostreams
    /// on the chaperone data, so had to go back down to Win32 API.
    HANDLE f = CreateFileA(fn.c_str(), GENERIC_READ,
                           FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
                           OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
    if (INVALID_HANDLE_VALUE == f) {
        errorReport("Could not open file: " + formatLastErrorAsString());
        return std::string{};
    }
    auto closer = osvr::util::finally([&f] { CloseHandle(f); });

    std::ostringstream os;
    static const auto BUFSIZE = 1024;
    std::array<char, BUFSIZE + 1> buf;
    /// Null terminate for ease of use.
    buf.back() = '\0';
    bool keepReading = true;
    while (1) {
        DWORD bytesRead;
        auto ret = ReadFile(f, buf.data(), buf.size() - 1, &bytesRead, nullptr);
        if (ret) {
            if (bytesRead == 0) {
                // end of file
                break;
            } else {
                // Null terminate this block and slide it in.
                // std::cout << "read " << bytesRead << " bytes this time "
                //          << std::endl;
                buf[bytesRead] = '\0';
                os << buf.data();
            }
        } else {

            errorReport("Error after reading " +
                        std::to_string(os.str().size()) + " bytes: " +
                        formatLastErrorAsString());
            return std::string{};
        }
    }
    return os.str();
}
#else
#include <cstring> // strerror

std::string
getFile(std::string const &fn,
        std::function<void(std::string const &)> const &errorReport) {
    std::ifstream s(fn, std::ios::in | std::ios::binary);
    if (!s) {
        std::ostringstream os;
        os << "Could not open file ";

        /// Sadly errno is far more useful in its error messages than
        /// failbit-triggered exceptions, etc.
        auto theErrno = errno;
        os << " (Error code: " << theErrno << " - " << strerror(theErrno)
           << ")";
        errorReport(os.str());
        return std::string{};
    }
    std::ostringstream os;
    std::string temp;
    while (std::getline(s, temp)) {
        os << temp;
    }
    return os.str();
}
#endif

namespace osvr {
namespace vive {
    static const auto PREFIX = "[ChaperoneData] ";
    static const auto CHAPERONE_DATA_FILENAME = "chaperone_info.vrchap";
#ifdef _WIN32
    static const auto PATH_SEPARATOR = "\\";
#else
    static const auto PATH_SEPARATOR = "/";
#endif

    using UniverseDataMap =
        std::map<std::uint64_t, ChaperoneData::UniverseData>;

    using UniverseBaseSerials = std::vector<
        std::pair<std::uint64_t, ChaperoneData::BaseStationSerials>>;
    struct ChaperoneData::Impl {
        Json::Value chaperoneInfo;
        UniverseDataMap universes;
        UniverseBaseSerials baseSerials;
    };

    void loadJsonIntoUniverseData(Json::Value const &obj,
                                  ChaperoneData::UniverseData &data) {
        data.yaw = obj["yaw"].asDouble();
        auto &xlate = obj["translation"];
        for (Json::Value::ArrayIndex i = 0; i < 3; ++i) {
            data.translation[i] = xlate[i].asDouble();
        }
    }
    ChaperoneData::ChaperoneData(std::string const &steamConfigDir)
        : impl_(new Impl), configDir_(steamConfigDir) {
        {
            Json::Reader reader;
            auto chapInfoFn =
                configDir_ + PATH_SEPARATOR + CHAPERONE_DATA_FILENAME;
#if 0
            std::ifstream chapInfoFile(configDir_,
                                       std::ios::in | std::ios::binary);
            if (!chapInfoFile) {
                std::ostringstream os;
                os << "Could not open chaperone info file, expected at "
                   << chapInfoFn;

                /// Sadly errno is far more useful in its error messages than
                /// failbit-triggered exceptions, etc.
                auto theErrno = errno;
                os << " (Error code: " << theErrno << " - "
                   << strerror(theErrno) << ")";
                errorOut_(os.str());
                return;
            }

            if (!chapInfoFile.good()) {
                errorOut_("Could not open chaperone info file, expected at " +
                          chapInfoFn);
                return;
            }
#endif
            std::string fileData =
                getFile(chapInfoFn, [&](std::string const &message) {
                    std::ostringstream os;
                    os << "Could not open chaperone info file, expected at "
                       << chapInfoFn;
                    os << " - details [" << message << "]";
                    errorOut_(os.str());

                });
            if (!valid()) {
                /// this means our fail handler got called.
                return;
            }
            if (!reader.parse(fileData, impl_->chaperoneInfo)) {
                errorOut_("Could not parse JSON in chaperone info file at " +
                          chapInfoFn + ": " +
                          reader.getFormattedErrorMessages());
                return;
            }

            /// Basic sanity checks
            if (impl_->chaperoneInfo["jsonid"] != "chaperone_info") {
                errorOut_("Chaperone info file at " + chapInfoFn +
                          " did not match expected format (no element "
                          "\"jsonid\": \"chaperone_info\" in top level "
                          "object)");
                return;
            }

            if (impl_->chaperoneInfo["universes"].size() == 0) {
                errorOut_("Chaperone info file at " + chapInfoFn +
                          " did not contain any known chaperone universes - "
                          "user must run Room Setup at least once");
                return;
            }
        }

        for (auto const &univ : impl_->chaperoneInfo["universes"]) {
            auto univIdString = univ["universeID"].asString();
            UniverseData data;
            auto &standing = univ["standing"];
            if (standing.isNull()) {
                warn_("No standing calibration data for universe " +
                      univIdString + ", so had to look for seated data.");
                auto &seated = univ["seated"];
                if (seated.isNull()) {
                    warn_(
                        "No seated or standing calibration data for universe " +
                        univIdString + ", so had to skip it.");
                    continue;
                } else {
                    data.type = CalibrationType::Seated;
                    loadJsonIntoUniverseData(seated, data);
                }
            } else {
                data.type = CalibrationType::Standing;
                loadJsonIntoUniverseData(standing, data);
            }
            /// Convert universe ID (64-bit int) from string, in JSON, to an int
            /// again.
            UniverseId id;
            std::istringstream is(univIdString);
            is >> id;
            /// Add the universe data in.
            impl_->universes.insert(std::make_pair(id, data));

            BaseStationSerials serials;
            for (auto const &tracker : univ["trackers"]) {
                auto &serial = tracker["serial"];
                if (serial.isString()) {
                    serials.push_back(serial.asString());
                }
            }

            /// Add the serial data in.
            impl_->baseSerials.emplace_back(id, std::move(serials));
        }
    }

    ChaperoneData::~ChaperoneData() {}

    bool ChaperoneData::valid() const { return static_cast<bool>(impl_); }

    bool ChaperoneData::knowUniverseId(UniverseId universe) const {
        if (0 == universe) {
            return false;
        }
        return (impl_->universes.find(universe) != end(impl_->universes));
    }

    ChaperoneData::UniverseData
    ChaperoneData::getDataForUniverse(UniverseId universe) const {
        auto it = impl_->universes.find(universe);
        if (it == end(impl_->universes)) {
            return UniverseData();
        }
        return it->second;
    }

    std::size_t ChaperoneData::getNumberOfKnownUniverses() const {
        return impl_->universes.size();
    }

    ChaperoneData::UniverseId ChaperoneData::guessUniverseIdFromBaseStations(
        BaseStationSerials const &bases) {
        auto providedSize = bases.size();
        UniverseId ret = 0;
        using UniverseRank = std::pair<float, UniverseId>;
        /// Compare function for heap.
        auto compare = [](UniverseRank const &a, UniverseRank const &b) {
            return a.first < b.first;
        };

        /// Will contain heap of potential universes and their value (a fraction
        /// of their base stations and provided base stations that were included
        /// in the base station list provided to the function)
        std::vector<UniverseRank> potentialUniverses;
        auto push = [&](float value, UniverseId id) {
            potentialUniverses.emplace_back(value, id);
            std::push_heap(begin(potentialUniverses), end(potentialUniverses),
                           compare);
        };

        for (auto &univBaseSerial : impl_->baseSerials) {
            auto const &baseSerials = univBaseSerial.second;
            std::size_t hits = 0;
            auto b = begin(baseSerials);
            auto e = end(baseSerials);
            /// Count the number of entries that we were given that are also in
            /// this universe's list.
            auto found = std::count_if(begin(bases), end(bases),
                                       [&](std::string const &needle) {
                                           return std::find(b, e, needle) != e;
                                       });
            if (found > 0) {
                /// This is meant to combine the influence of "found" in both
                /// providedSize and universe size, and the +1 in the
                /// denominator is to avoid division by zero.
                auto weight = 2.f * static_cast<float>(found) /
                              (baseSerials.size() + providedSize + 1);
#if 0
                std::cout << "Guessing produced weight of " << weight << " for "
                          << univBaseSerial.first << std::endl;
#endif
                push(weight, univBaseSerial.first);
            }
        }
        if (!potentialUniverses.empty()) {
            /// it's a heap, so the best one is always on top.
            return potentialUniverses.front().second;
        }
        return ret;
    }

    void ChaperoneData::errorOut_(std::string const &message) {
        /// This reset may be redundant in some cases, but better to not miss
        /// it, since it's also our error flag.
        impl_.reset();

        warn_("ERROR: " + message);
    }

    void ChaperoneData::warn_(std::string const &message) {

        if (err_.empty()) {
            /// First error
            err_ = message;
            return;
        }

        static const auto BEGIN_LIST = "[";
        static const auto BEGIN_LIST_CH = BEGIN_LIST[0];
        static const auto END_LIST = "]";
        static const auto MIDDLE_LIST = "][";
        if (BEGIN_LIST_CH == err_.front()) {
            /// We've already started a list of errors, just tack one more on.
            err_ += BEGIN_LIST + message + END_LIST;
            return;
        }

        /// OK, so this is our exactly second error, wrap the first and second.
        err_ = BEGIN_LIST + err_ + MIDDLE_LIST + message + END_LIST;
    }

} // namespace vive
} // namespace osvr
<|endoftext|>


<commit_before>#include "gtest/gtest.h"
#include "../src/tmxparser.h"

class TmxParseTest : public ::testing::Test
{
protected:
	static void SetUpTestCase()
	{
		_map = new tmxparser::TmxMap();
		tmxparser::parseFromFile("../test_xml_level.tmx", _map, "assets/textures/");
	}

	static void TearDownTestCase()
	{
		delete _map;
		_map = NULL;
	}

	virtual void SetUp()
	{

	}

	virtual void TearDown()
	{

	}

	static tmxparser::TmxMap* _map;
};

tmxparser::TmxMap* TmxParseTest::_map = NULL;

TEST_F(TmxParseTest, MapNotNull)
{
	ASSERT_TRUE(_map != NULL);
}

TEST_F(TmxParseTest, MapProperties)
{
	ASSERT_TRUE(_map != NULL);
	ASSERT_EQ("1.0", _map->version);
	ASSERT_EQ("orthogonal", _map->orientation);
	ASSERT_EQ("right-down", _map->renderOrder);
	ASSERT_EQ(16, _map->width);
	ASSERT_EQ(16, _map->height);
	ASSERT_EQ(16, _map->tileWidth);
	ASSERT_EQ(16, _map->tileHeight);
}

TEST_F(TmxParseTest, TilesetProperties)
{
	ASSERT_EQ(2, _map->tilesetCollection.size());

	tmxparser::TmxTileset tileset = _map->tilesetCollection[0];
	ASSERT_EQ(1, tileset.firstgid);
	ASSERT_EQ("super_mario_one_tileset", tileset.name);
	ASSERT_EQ(16, tileset.tileWidth);
	ASSERT_EQ(16, tileset.tileHeight);

	tileset = _map->tilesetCollection[1];
	ASSERT_EQ(925, tileset.firstgid);
	ASSERT_EQ("BowserBreath", tileset.name);
	ASSERT_EQ(32, tileset.tileWidth);
	ASSERT_EQ(32, tileset.tileHeight);
}

TEST_F(TmxParseTest, TilesetImageSourceProperties)
{
	ASSERT_EQ(2, _map->tilesetCollection.size());

	tmxparser::TmxTileset tileset = _map->tilesetCollection[0];
	tmxparser::TmxImage image = tileset.image;

	ASSERT_EQ("assets/textures/super_mario_one_tileset.png", image.source);
	ASSERT_EQ(528, image.width);
	ASSERT_EQ(448, image.height);

	tileset = _map->tilesetCollection[1];
	image = tileset.image;

	ASSERT_EQ("assets/textures/BowserBreath.png", image.source);
	ASSERT_EQ(128, image.width);
	ASSERT_EQ(32, image.height);
}

int main(int argc, char **argv)
{
	::testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();
}
<commit_msg>- added layer properties test<commit_after>#include "gtest/gtest.h"
#include "../src/tmxparser.h"

class TmxParseTest : public ::testing::Test
{
protected:
	static void SetUpTestCase()
	{
		_map = new tmxparser::TmxMap();
		tmxparser::parseFromFile("../test_xml_level.tmx", _map, "assets/textures/");
	}

	static void TearDownTestCase()
	{
		delete _map;
		_map = NULL;
	}

	virtual void SetUp()
	{

	}

	virtual void TearDown()
	{

	}

	static tmxparser::TmxMap* _map;
};

tmxparser::TmxMap* TmxParseTest::_map = NULL;

TEST_F(TmxParseTest, MapNotNull)
{
	ASSERT_TRUE(_map != NULL);
}

TEST_F(TmxParseTest, MapProperties)
{
	ASSERT_TRUE(_map != NULL);
	ASSERT_EQ("1.0", _map->version);
	ASSERT_EQ("orthogonal", _map->orientation);
	ASSERT_EQ("right-down", _map->renderOrder);
	ASSERT_EQ(16, _map->width);
	ASSERT_EQ(16, _map->height);
	ASSERT_EQ(16, _map->tileWidth);
	ASSERT_EQ(16, _map->tileHeight);
}

TEST_F(TmxParseTest, TilesetProperties)
{
	ASSERT_EQ(2, _map->tilesetCollection.size());

	tmxparser::TmxTileset tileset = _map->tilesetCollection[0];
	ASSERT_EQ(1, tileset.firstgid);
	ASSERT_EQ("super_mario_one_tileset", tileset.name);
	ASSERT_EQ(16, tileset.tileWidth);
	ASSERT_EQ(16, tileset.tileHeight);

	tileset = _map->tilesetCollection[1];
	ASSERT_EQ(925, tileset.firstgid);
	ASSERT_EQ("BowserBreath", tileset.name);
	ASSERT_EQ(32, tileset.tileWidth);
	ASSERT_EQ(32, tileset.tileHeight);
}

TEST_F(TmxParseTest, TilesetImageSourceProperties)
{
	ASSERT_EQ(2, _map->tilesetCollection.size());

	tmxparser::TmxTileset tileset = _map->tilesetCollection[0];
	tmxparser::TmxImage image = tileset.image;

	ASSERT_EQ("assets/textures/super_mario_one_tileset.png", image.source);
	ASSERT_EQ(528, image.width);
	ASSERT_EQ(448, image.height);

	tileset = _map->tilesetCollection[1];
	image = tileset.image;

	ASSERT_EQ("assets/textures/BowserBreath.png", image.source);
	ASSERT_EQ(128, image.width);
	ASSERT_EQ(32, image.height);
}

TEST_F(TmxParseTest, LayerProperties)
{
	ASSERT_EQ(1, _map->layerCollection.size());
	tmxparser::TmxLayer layer = _map->layerCollection[0];

	ASSERT_EQ("World", layer.name);
	ASSERT_EQ(16, layer.width);
	ASSERT_EQ(16, layer.height);

	ASSERT_EQ(256, layer.tiles.size());
}

int main(int argc, char **argv)
{
	::testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#include "gtest/gtest.h"
#include "../src/tmxparser.h"

class TmxParseTest : public ::testing::Test
{
protected:
	static void SetUpTestCase()
	{
		_map = new tmxparser::TmxMap();
		tmxparser::parseFromFile("../test_files/test_xml_level.tmx", _map, "assets/textures/");
	}

	static void TearDownTestCase()
	{
		delete _map;
		_map = NULL;
	}

	virtual void SetUp()
	{

	}

	virtual void TearDown()
	{

	}

	static tmxparser::TmxMap* _map;
};

tmxparser::TmxMap* TmxParseTest::_map = NULL;

TEST_F(TmxParseTest, MapNotNull)
{
	ASSERT_TRUE(_map != NULL);
}

TEST_F(TmxParseTest, MapProperties)
{
	ASSERT_TRUE(_map != NULL);
	ASSERT_EQ("1.0", _map->version);
	ASSERT_EQ("orthogonal", _map->orientation);
	ASSERT_EQ("right-down", _map->renderOrder);
	ASSERT_EQ(10, _map->width);
	ASSERT_EQ(10, _map->height);
	ASSERT_EQ(16, _map->tileWidth);
	ASSERT_EQ(16, _map->tileHeight);
}

TEST_F(TmxParseTest, TilesetProperties)
{
	ASSERT_EQ(2, _map->tilesetCollection.size());

	tmxparser::TmxTileset tileset = _map->tilesetCollection[0];
	ASSERT_EQ(1, tileset.firstgid);
	ASSERT_EQ("super_mario_one_tileset", tileset.name);
	ASSERT_EQ(16, tileset.tileWidth);
	ASSERT_EQ(16, tileset.tileHeight);

	tileset = _map->tilesetCollection[1];
	ASSERT_EQ(925, tileset.firstgid);
	ASSERT_EQ("legend_of_zelda_one_overworld_tiles", tileset.name);
	ASSERT_EQ(16, tileset.tileWidth);
	ASSERT_EQ(16, tileset.tileHeight);
}

TEST_F(TmxParseTest, TilesetImageSourceProperties)
{
	ASSERT_EQ(2, _map->tilesetCollection.size());

	tmxparser::TmxTileset tileset = _map->tilesetCollection[0];
	tmxparser::TmxImage image = tileset.image;

	ASSERT_EQ("assets/textures/super_mario_one_tileset.png", image.source);
	ASSERT_EQ(528, image.width);
	ASSERT_EQ(448, image.height);

	tileset = _map->tilesetCollection[1];
	image = tileset.image;

	ASSERT_EQ("assets/textures/legend_of_zelda_one_overworld_tiles.png", image.source);
	ASSERT_EQ(307, image.width);
	ASSERT_EQ(163, image.height);
}

TEST_F(TmxParseTest, LayerProperties)
{
	ASSERT_EQ(1, _map->layerCollection.size());
	tmxparser::TmxLayer layer = _map->layerCollection[0];

	ASSERT_EQ("World", layer.name);
	ASSERT_EQ(10, layer.width);
	ASSERT_EQ(10, layer.height);

	ASSERT_EQ(100, layer.tiles.size());
}

int main(int argc, char **argv)
{
	::testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();
}
<commit_msg>- validating tiles in test<commit_after>#include "gtest/gtest.h"
#include "../src/tmxparser.h"

class TmxParseTest : public ::testing::Test
{
protected:
	static void SetUpTestCase()
	{
		_map = new tmxparser::TmxMap();
		tmxparser::parseFromFile("../test_files/test_xml_level.tmx", _map, "assets/textures/");
	}

	static void TearDownTestCase()
	{
		delete _map;
		_map = NULL;
	}

	virtual void SetUp()
	{

	}

	virtual void TearDown()
	{

	}

	static tmxparser::TmxMap* _map;
};

tmxparser::TmxMap* TmxParseTest::_map = NULL;

TEST_F(TmxParseTest, MapNotNull)
{
	ASSERT_TRUE(_map != NULL);
}

TEST_F(TmxParseTest, MapProperties)
{
	ASSERT_TRUE(_map != NULL);
	ASSERT_EQ("1.0", _map->version);
	ASSERT_EQ("orthogonal", _map->orientation);
	ASSERT_EQ("right-down", _map->renderOrder);
	ASSERT_EQ(10, _map->width);
	ASSERT_EQ(10, _map->height);
	ASSERT_EQ(16, _map->tileWidth);
	ASSERT_EQ(16, _map->tileHeight);
}

TEST_F(TmxParseTest, TilesetProperties)
{
	ASSERT_EQ(2, _map->tilesetCollection.size());

	tmxparser::TmxTileset tileset = _map->tilesetCollection[0];
	ASSERT_EQ(1, tileset.firstgid);
	ASSERT_EQ("super_mario_one_tileset", tileset.name);
	ASSERT_EQ(16, tileset.tileWidth);
	ASSERT_EQ(16, tileset.tileHeight);

	tileset = _map->tilesetCollection[1];
	ASSERT_EQ(925, tileset.firstgid);
	ASSERT_EQ("legend_of_zelda_one_overworld_tiles", tileset.name);
	ASSERT_EQ(16, tileset.tileWidth);
	ASSERT_EQ(16, tileset.tileHeight);
}

TEST_F(TmxParseTest, TilesetImageSourceProperties)
{
	ASSERT_EQ(2, _map->tilesetCollection.size());

	tmxparser::TmxTileset tileset = _map->tilesetCollection[0];
	tmxparser::TmxImage image = tileset.image;

	ASSERT_EQ("assets/textures/super_mario_one_tileset.png", image.source);
	ASSERT_EQ(528, image.width);
	ASSERT_EQ(448, image.height);

	tileset = _map->tilesetCollection[1];
	image = tileset.image;

	ASSERT_EQ("assets/textures/legend_of_zelda_one_overworld_tiles.png", image.source);
	ASSERT_EQ(307, image.width);
	ASSERT_EQ(163, image.height);
}

TEST_F(TmxParseTest, LayerProperties)
{
	ASSERT_EQ(1, _map->layerCollection.size());
	tmxparser::TmxLayer layer = _map->layerCollection[0];

	ASSERT_EQ("World", layer.name);
	ASSERT_EQ(10, layer.width);
	ASSERT_EQ(10, layer.height);

	ASSERT_EQ(100, layer.tiles.size());
}

TEST_F(TmxParseTest, TilesValidation)
{
	ASSERT_EQ(1, _map->layerCollection.size());
	tmxparser::TmxLayer layer = _map->layerCollection[0];

	tmxparser::TmxLayerTileCollection_t tiles = layer.tiles;
	ASSERT_EQ(100, tiles.size());

	int expectedGidValues[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
							34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
							925, 926, 927, 928, 929, 930, 931, 932, 933, 934
							};
	int testTileCount = sizeof(expectedGidValues) / sizeof(int);
	for (unsigned int i = 0; i < testTileCount; i++)
	{
		ASSERT_EQ(expectedGidValues[i], tiles[i].gid);
	}
}

int main(int argc, char **argv)
{
	int retVal = 0;

	::testing::InitGoogleTest(&argc, argv);

	printf("\033[32m" "==========\nXML TESTS\n==========\n" "\033[0m");
	retVal = RUN_ALL_TESTS();

	//printf("\033[32m" "==========\nCSV TESTS\n==========\n" "\033[0m");
	//retVal = RUN_ALL_TESTS();

	//printf("\033[32m" "==========\nBASE64 TESTS\n==========\n" "\033[0m");
	//retVal = RUN_ALL_TESTS();

	return retVal;
}
<|endoftext|>


<commit_before>// Rabin-Karp - String Matching + Hashing O(n+m)
const int B = 31;
char s[N], p[N];
int n, m; // n = strlen(s), m = strlen(p)

void rabin() {
  if (n<m) return;

  int hp = 0, hs = 0, E = 1;
  for (int i = 0; i < m; ++i)
    hp = ((hp*B)%MOD + p[i])%MOD,
    hs = ((hs*B)%MOD + s[i])%MOD,
    E = (E*B)%MOD;

  if (hs == hp) { /* matching position 0 */ }
  for (int i = m; i < n; ++i) {
    hs = ((hs*B)%MOD + s[i])%MOD;
    hs = (hs + (MOD - s[i-m]*E)%MOD)%MOD;
    if (hs == hp) { /* matching position i-m+1 */ }
  }
}
<commit_msg>Fixed overflow bug<commit_after>// Rabin-Karp - String Matching + Hashing O(n+m)
const int B = 31;
char s[N], p[N];
int n, m; // n = strlen(s), m = strlen(p)

void rabin() {
  if (n<m) return;

  int hp = 0, hs = 0, E = 1;
  for (int i = 0; i < m; ++i)
    hp = ((hp*B)%MOD + p[i])%MOD,
    hs = ((hs*B)%MOD + s[i])%MOD,
    E = (E*B)%MOD;

  if (hs == hp) { /* matching position 0 */ }
  for (int i = m; i < n; ++i) {
    hs = ((hs*B)%MOD + s[i])%MOD;
    hs = (hs + (MOD - (s[i-m]*E)%MOD)%MOD)%MOD;
    if (hs == hp) { /* matching position i-m+1 */ }
  }
}
<|endoftext|>


<commit_before>

#include <stdio.h>
#include <ssnlib_sys.h>
#include <ssnlib_shell.h>
#include <ssnlib_timer.h>
#include <ssnlib_thread.h>
#include <slankdev/system.h>

using Rxq    = ssnlib::Rxq_interface<ssnlib::Ring_dpdk>;
using Txq    = ssnlib::Txq_interface<ssnlib::Ring_dpdk>;
using Port   = ssnlib::Port_interface<Rxq, Txq>;
using Cpu    = ssnlib::Cpu_interface;
using System = ssnlib::System_interface<Cpu, Port>;
#include "commands.h"

class Allocator {
public:
    const std::string name;
    Allocator(const char* n) : name(n)
    { if (name == "") throw slankdev::exception("not set thread name"); }
    virtual ~Allocator() {}
    virtual ssnlib::ssn_thread* alloc() = 0;
};

class Allocator_wk : public Allocator {

    class Thrd_wk : public ssnlib::ssn_thread {
        bool running;
        size_t id;
    public:
        Thrd_wk() : ssn_thread("wk"), running(false) {}
        bool kill() { running = false; return true; }
        void operator()()
        {
            running = true;
            while (running) {
                sleep(1);
            }
        }
    };

public:
    Allocator_wk() : Allocator("wk") {}
    ssnlib::ssn_thread* alloc() override { return new Thrd_wk; }
};

class Allocator_rx : public Allocator {

    class Thrd_rx : public ssnlib::ssn_thread {
        bool running;
        size_t id;
    public:
        Thrd_rx() : ssn_thread("rx"), running(false) {}
        bool kill() { running = false; return true; }
        void operator()()
        {
            running = true;
            while (running) {
                sleep(1);
            }
        }
    };

public:
    Allocator_rx() : Allocator("rx") {}
    ssnlib::ssn_thread* alloc() override { return new Thrd_rx; }
};

class dta2 {

    class Cmd_dta : public ssnlib::Command {
        struct pcmd_params {
            cmdline_fixed_string_t cmd;
            cmdline_fixed_string_t op;
        };
        dta2* d;
    public:
        Cmd_dta(dta2* d_) : d(d_)
        {
            append_token(TOKEN_STRING(struct pcmd_params, cmd, "dta"));
            append_token(TOKEN_STRING(struct pcmd_params, op , NULL));
            token_fin();

            init_raw();
            set_raw("dta < inc** | dec** | stop >");
        }
        void handle(void* p)
        {
            pcmd_params* param = reinterpret_cast<pcmd_params*>(p);
            const std::string op = param->op;

            if (op == "stop") d->stop();
            else if (op == "incwk") d->inc("wk");
            else if (op == "incrx") d->inc("rx");
            else if (op == "decwk") d->dec("wk");
            else if (op == "decrx") d->dec("rx");
            else printf("Bad arguments\n");
        }
    };

public:
    System sys;
    ssnlib::Shell shell;
    std::vector<Allocator*> allocators;

public:
    dta2(int argc, char** argv) : sys(argc, argv), shell("susanow> ")
    {
        shell.add_cmd(new Cmd_clear           );
        shell.add_cmd(new Cmd_findthread(&sys));
        shell.add_cmd(new Cmd_quit      (&sys));
        shell.add_cmd(new Cmd_thread    (&sys));
        shell.add_cmd(new Cmd_port      (&sys));
        shell.add_cmd(new Cmd_lscpu     (&sys));
        shell.add_cmd(new Cmd_version   (&sys));
        shell.add_cmd(new Cmd_dta       (this));
        shell.fin();

        allocators.push_back(new Allocator_wk);
        allocators.push_back(new Allocator_rx);

        sys.append_thread(&shell);
    }
    void inc(const std::string& threadname)
    {
        try {
            for (auto* p : allocators) {
                if (p->name == threadname) {
                    sys.append_thread(p->alloc());
                    start();
                    return;
                }
            }
            printf("can't append thread\n");
        } catch (std::exception& e) {
            printf("can't append thread\n");
        }
    }
    void dec(const std::string& threadname)
    {
        size_t nb_cpus = sys.cpus.size();
        for (ssize_t i=nb_cpus-1; i>=0; i--) {
            if (i == 0) continue;

            Cpu& cpu = sys.cpus.at(i);
            if (cpu.thread && cpu.thread->name == threadname) {
                ssnlib::ssn_thread* tmp = cpu.thread;
                if (cpu.get_state() != RUNNING) {
                } else {
                    tmp->kill();
                    cpu.wait();
                }
                delete tmp;
                cpu.thread = nullptr;
                return ;
            }
        }
        printf("no such thread\n");
    }
    void start()
    {
        for (Cpu& cpu : sys.cpus) {
            if (cpu.thread && have_thread(cpu.thread->name)) {
                cpu.launch();
            }
        }
    }
    void stop()
    {
        for (Cpu& cpu : sys.cpus) {
            if (cpu.thread && have_thread(cpu.thread->name)) {
                cpu.thread->kill();
                cpu.wait();
            }
        }
    }
    bool have_thread(const std::string& name)
    {
        for (auto* alctr : allocators) {
            if (alctr->name == name) return true;
        }
        return false;
    }
};

int main(int argc, char** argv)
{
    using namespace ssnlib;

    Port::nb_rx_rings    = 2;
    Port::nb_tx_rings    = 2;
    Port::rx_ring_size   = 128;
    Port::tx_ring_size   = 512;

    dta2 d(argc, argv);

    d.sys.launch_all();
    d.sys.wait_all();
}

<commit_msg>ADD: dtaa sample interface<commit_after>

#include <stdio.h>
#include <ssnlib_sys.h>
#include <ssnlib_shell.h>
#include <ssnlib_timer.h>
#include <ssnlib_thread.h>
#include <slankdev/system.h>

using Rxq    = ssnlib::Rxq_interface<ssnlib::Ring_dpdk>;
using Txq    = ssnlib::Txq_interface<ssnlib::Ring_dpdk>;
using Port   = ssnlib::Port_interface<Rxq, Txq>;
using Cpu    = ssnlib::Cpu_interface;
using System = ssnlib::System_interface<Cpu, Port>;
#include "commands.h"

class Allocator {
public:
    const std::string name;
    Allocator(const char* n) : name(n)
    { if (name == "") throw slankdev::exception("not set thread name"); }
    virtual ~Allocator() {}
    virtual ssnlib::ssn_thread* alloc() = 0;
};

class Allocator_wk : public Allocator {

    class Thrd_wk : public ssnlib::ssn_thread {
        bool running;
        size_t id;
    public:
        Thrd_wk() : ssn_thread("wk"), running(false) {}
        bool kill() { running = false; return true; }
        void operator()()
        {
            running = true;
            while (running) {
                sleep(1);
            }
        }
    };

public:
    Allocator_wk() : Allocator("wk") {}
    ssnlib::ssn_thread* alloc() override { return new Thrd_wk; }
};

class Allocator_rx : public Allocator {

    class Thrd_rx : public ssnlib::ssn_thread {
        bool running;
        size_t id;
    public:
        Thrd_rx() : ssn_thread("rx"), running(false) {}
        bool kill() { running = false; return true; }
        void operator()()
        {
            running = true;
            while (running) {
                sleep(1);
            }
        }
    };

public:
    Allocator_rx() : Allocator("rx") {}
    ssnlib::ssn_thread* alloc() override { return new Thrd_rx; }
};

class dta2system : public System {
    std::vector<Allocator*> allocators;

public:
    dta2system(int argc, char** argv) : System(argc, argv) {}
    void append_dtaa_thread(Allocator* newthread)
    { allocators.push_back(newthread); }
    void inc(const std::string& threadname)
    {
        try {
            for (auto* p : allocators) {
                if (p->name == threadname) {
                    append_thread(p->alloc());
                    start();
                    return;
                }
            }
            printf("can't append thread\n");
        } catch (std::exception& e) {
            printf("can't append thread\n");
        }
    }
    void dec(const std::string& threadname)
    {
        size_t nb_cpus = cpus.size();
        for (ssize_t i=nb_cpus-1; i>=0; i--) {
            if (i == 0) continue;

            Cpu& cpu = cpus.at(i);
            if (cpu.thread && cpu.thread->name == threadname) {
                ssnlib::ssn_thread* tmp = cpu.thread;
                if (cpu.get_state() != RUNNING) {
                } else {
                    tmp->kill();
                    cpu.wait();
                }
                delete tmp;
                cpu.thread = nullptr;
                return ;
            }
        }
        printf("no such thread\n");
    }
    void start()
    {
        for (Cpu& cpu : cpus) {
            if (cpu.thread && have_thread(cpu.thread->name)) {
                cpu.launch();
            }
        }
    }
    void stop()
    {
        for (Cpu& cpu : cpus) {
            if (cpu.thread && have_thread(cpu.thread->name)) {
                cpu.thread->kill();
                cpu.wait();
            }
        }
    }
    bool have_thread(const std::string& name)
    {
        for (auto* alctr : allocators) {
            if (alctr->name == name) return true;
        }
        return false;
    }
};

class Cmd_dta : public ssnlib::Command {
    struct pcmd_params {
        cmdline_fixed_string_t cmd;
        cmdline_fixed_string_t op;
    };
    dta2system* sys;
public:
    Cmd_dta(dta2system* s) : sys(s)
    {
        append_token(TOKEN_STRING(struct pcmd_params, cmd, "dta"));
        append_token(TOKEN_STRING(struct pcmd_params, op , NULL));
        token_fin();

        init_raw();
        set_raw("dta < inc** | dec** | stop >");
    }
    void handle(void* p)
    {
        pcmd_params* param = reinterpret_cast<pcmd_params*>(p);
        const std::string op = param->op;

        if (op == "stop")       sys->stop();
        else if (op == "incwk") sys->inc("wk");
        else if (op == "incrx") sys->inc("rx");
        else if (op == "decwk") sys->dec("wk");
        else if (op == "decrx") sys->dec("rx");
        else printf("Bad arguments\n");
    }
};

int main(int argc, char** argv)
{
    using namespace ssnlib;

    Port::nb_rx_rings    = 2;
    Port::nb_tx_rings    = 2;
    Port::rx_ring_size   = 128;
    Port::tx_ring_size   = 512;

    dta2system sys(argc, argv);

    ssnlib::Shell shell("susanow> ");
    shell.add_cmd(new Cmd_clear           );
    shell.add_cmd(new Cmd_findthread(&sys));
    shell.add_cmd(new Cmd_quit      (&sys));
    shell.add_cmd(new Cmd_thread    (&sys));
    shell.add_cmd(new Cmd_port      (&sys));
    shell.add_cmd(new Cmd_lscpu     (&sys));
    shell.add_cmd(new Cmd_version   (&sys));
    shell.add_cmd(new Cmd_dta       (&sys));
    shell.fin();

    sys.append_thread(&shell);
    sys.append_dtaa_thread(new Allocator_wk);
    sys.append_dtaa_thread(new Allocator_rx);

    sys.launch_all();
    sys.wait_all();
}

<|endoftext|>


<commit_before>/// \file
/// \ingroup tutorial_tdataframe
/// \notebook
/// This tutorial illustrates how to express the H1 analysis with a TDataFrame.
///
/// \macro_code
///
/// \date December 2016
/// \author Axel Naumann

auto Select = [](ROOT::Experimental::TDataFrame &dataFrame) {
   using Farray_t = ROOT::Experimental::TDF::TArrayBranch<float>;
   using Iarray_t = ROOT::Experimental::TDF::TArrayBranch<int>;

   auto ret =
      dataFrame.Filter("TMath::Abs(md0_d - 1.8646) < 0.04")
         .Filter("ptds_d > 2.5")
         .Filter("TMath::Abs(etads_d) < 1.5")
         .Filter([](int ik, int ipi, Iarray_t nhitrp) { return nhitrp[ik - 1] * nhitrp[ipi - 1] > 1; },
                 {"ik", "ipi", "nhitrp"})
         .Filter([](int ik, Farray_t rstart, Farray_t rend) { return rend[ik - 1] - rstart[ik - 1] > 22; },
                 {"ik", "rstart", "rend"})
         .Filter([](int ipi, Farray_t rstart, Farray_t rend) { return rend[ipi - 1] - rstart[ipi - 1] > 22; },
                 {"ipi", "rstart", "rend"})
         .Filter([](int ik, Farray_t nlhk) { return nlhk[ik - 1] > 0.1; }, {"ik", "nlhk"})
         .Filter([](int ipi, Farray_t nlhpi) { return nlhpi[ipi - 1] > 0.1; }, {"ipi", "nlhpi"})
         .Filter([](int ipis, Farray_t nlhpi) { return nlhpi[ipis - 1] > 0.1; }, {"ipis", "nlhpi"})
         .Filter("njets >= 1");

   return ret;
};

const Double_t dxbin = (0.17 - 0.13) / 40; // Bin-width

Double_t fdm5(Double_t *xx, Double_t *par)
{
   Double_t x = xx[0];
   if (x <= 0.13957)
      return 0;
   Double_t xp3 = (x - par[3]) * (x - par[3]);
   Double_t res =
      dxbin * (par[0] * pow(x - 0.13957, par[1]) + par[2] / 2.5066 / par[4] * exp(-xp3 / 2 / par[4] / par[4]));
   return res;
}

Double_t fdm2(Double_t *xx, Double_t *par)
{
   static const Double_t sigma = 0.0012;
   Double_t x = xx[0];
   if (x <= 0.13957)
      return 0;
   Double_t xp3 = (x - 0.1454) * (x - 0.1454);
   Double_t res = dxbin * (par[0] * pow(x - 0.13957, 0.25) + par[1] / 2.5066 / sigma * exp(-xp3 / 2 / sigma / sigma));
   return res;
}

void FitAndPlotHdmd(TH1 &hdmd)
{
   // create the canvas for the h1analysis fit
   gStyle->SetOptFit();
   auto c1 = new TCanvas("c1", "h1analysis analysis", 10, 10, 800, 600);
   hdmd.GetXaxis()->SetTitle("m_{K#pi#pi} - m_{K#pi}[GeV/c^{2}]");
   hdmd.GetXaxis()->SetTitleOffset(1.4);

   // fit histogram hdmd with function f5 using the loglikelihood option
   auto f5 = new TF1("f5", fdm5, 0.139, 0.17, 5);
   f5->SetParameters(1000000, .25, 2000, .1454, .001);
   hdmd.Fit("f5", "lr");

   hdmd.DrawClone();
}

void FitAndPlotH2(TH2 &h2)
{
   // create the canvas for tau d0
   auto c2 = new TCanvas("c2", "tauD0", 100, 100, 800, 600);

   c2->SetGrid();
   c2->SetBottomMargin(0.15);

   // Project slices of 2-d histogram h2 along X , then fit each slice
   // with function f2 and make a histogram for each fit parameter
   // Note that the generated histograms are added to the list of objects
   // in the current directory.
   auto f2 = new TF1("f2", fdm2, 0.139, 0.17, 2);
   f2->SetParameters(10000, 10);
   h2.FitSlicesX(f2, 0, -1, 1, "qln");

   // See TH2::FitSlicesX documentation
   auto h2_1 = (TH1D *)gDirectory->Get("h2_1");
   h2_1->GetXaxis()->SetTitle("#tau [ps]");
   h2_1->SetMarkerStyle(21);
   h2_1->DrawClone();
   c2->Update();

   auto line = new TLine(0, 0, 0, c2->GetUymax());
   line->Draw();
}

void tdf101_h1Analysis()
{
   TChain chain("h42");
   chain.Add("http://root.cern.ch/files/h1/dstarmb.root");
   chain.Add("http://root.cern.ch/files/h1/dstarp1a.root");
   chain.Add("http://root.cern.ch/files/h1/dstarp1b.root");
   chain.Add("http://root.cern.ch/files/h1/dstarp2.root");

   ROOT::EnableImplicitMT(4);

   ROOT::Experimental::TDataFrame dataFrame(chain);
   auto selected = Select(dataFrame);
   auto hdmdARP = selected.Histo1D({"hdmd", "Dm_d", 40, 0.13, 0.17}, "dm_d");
   auto selectedAddedBranch = selected.Define("h2_y", "rpd0_t / 0.029979f * 1.8646f / ptd0_d");
   auto h2ARP = selectedAddedBranch.Histo2D({"h2", "ptD0 vs Dm_d", 30, 0.135, 0.165, 30, -3, 6}, "dm_d", "h2_y");

   FitAndPlotHdmd(*hdmdARP);
   FitAndPlotH2(*h2ARP);
}
<commit_msg>Formatting<commit_after>/// \file
/// \ingroup tutorial_tdataframe
/// \notebook
/// This tutorial illustrates how to express the H1 analysis with a TDataFrame.
///
/// \macro_code
///
/// \date December 2016
/// \author Axel Naumann

auto Select = [](ROOT::Experimental::TDataFrame &dataFrame) {
   using Farray_t = ROOT::Experimental::TDF::TArrayBranch<float>;
   using Iarray_t = ROOT::Experimental::TDF::TArrayBranch<int>;

   auto ret = dataFrame.Filter("TMath::Abs(md0_d - 1.8646) < 0.04")
                 .Filter("ptds_d > 2.5")
                 .Filter("TMath::Abs(etads_d) < 1.5")
                 .Filter([](int ik, int ipi, Iarray_t nhitrp) { return nhitrp[ik - 1] * nhitrp[ipi - 1] > 1; },
                         {"ik", "ipi", "nhitrp"})
                 .Filter([](int ik, Farray_t rstart, Farray_t rend) { return rend[ik - 1] - rstart[ik - 1] > 22; },
                         {"ik", "rstart", "rend"})
                 .Filter([](int ipi, Farray_t rstart, Farray_t rend) { return rend[ipi - 1] - rstart[ipi - 1] > 22; },
                         {"ipi", "rstart", "rend"})
                 .Filter([](int ik, Farray_t nlhk) { return nlhk[ik - 1] > 0.1; }, {"ik", "nlhk"})
                 .Filter([](int ipi, Farray_t nlhpi) { return nlhpi[ipi - 1] > 0.1; }, {"ipi", "nlhpi"})
                 .Filter([](int ipis, Farray_t nlhpi) { return nlhpi[ipis - 1] > 0.1; }, {"ipis", "nlhpi"})
                 .Filter("njets >= 1");

   return ret;
};

const Double_t dxbin = (0.17 - 0.13) / 40; // Bin-width

Double_t fdm5(Double_t *xx, Double_t *par)
{
   Double_t x = xx[0];
   if (x <= 0.13957)
      return 0;
   Double_t xp3 = (x - par[3]) * (x - par[3]);
   Double_t res =
      dxbin * (par[0] * pow(x - 0.13957, par[1]) + par[2] / 2.5066 / par[4] * exp(-xp3 / 2 / par[4] / par[4]));
   return res;
}

Double_t fdm2(Double_t *xx, Double_t *par)
{
   static const Double_t sigma = 0.0012;
   Double_t x = xx[0];
   if (x <= 0.13957)
      return 0;
   Double_t xp3 = (x - 0.1454) * (x - 0.1454);
   Double_t res = dxbin * (par[0] * pow(x - 0.13957, 0.25) + par[1] / 2.5066 / sigma * exp(-xp3 / 2 / sigma / sigma));
   return res;
}

void FitAndPlotHdmd(TH1 &hdmd)
{
   // create the canvas for the h1analysis fit
   gStyle->SetOptFit();
   auto c1 = new TCanvas("c1", "h1analysis analysis", 10, 10, 800, 600);
   hdmd.GetXaxis()->SetTitle("m_{K#pi#pi} - m_{K#pi}[GeV/c^{2}]");
   hdmd.GetXaxis()->SetTitleOffset(1.4);

   // fit histogram hdmd with function f5 using the loglikelihood option
   auto f5 = new TF1("f5", fdm5, 0.139, 0.17, 5);
   f5->SetParameters(1000000, .25, 2000, .1454, .001);
   hdmd.Fit("f5", "lr");

   hdmd.DrawClone();
}

void FitAndPlotH2(TH2 &h2)
{
   // create the canvas for tau d0
   auto c2 = new TCanvas("c2", "tauD0", 100, 100, 800, 600);

   c2->SetGrid();
   c2->SetBottomMargin(0.15);

   // Project slices of 2-d histogram h2 along X , then fit each slice
   // with function f2 and make a histogram for each fit parameter
   // Note that the generated histograms are added to the list of objects
   // in the current directory.
   auto f2 = new TF1("f2", fdm2, 0.139, 0.17, 2);
   f2->SetParameters(10000, 10);
   h2.FitSlicesX(f2, 0, -1, 1, "qln");

   // See TH2::FitSlicesX documentation
   auto h2_1 = (TH1D *)gDirectory->Get("h2_1");
   h2_1->GetXaxis()->SetTitle("#tau [ps]");
   h2_1->SetMarkerStyle(21);
   h2_1->DrawClone();
   c2->Update();

   auto line = new TLine(0, 0, 0, c2->GetUymax());
   line->Draw();
}

void tdf101_h1Analysis()
{
   TChain chain("h42");
   chain.Add("http://root.cern.ch/files/h1/dstarmb.root");
   chain.Add("http://root.cern.ch/files/h1/dstarp1a.root");
   chain.Add("http://root.cern.ch/files/h1/dstarp1b.root");
   chain.Add("http://root.cern.ch/files/h1/dstarp2.root");

   ROOT::EnableImplicitMT(4);

   ROOT::Experimental::TDataFrame dataFrame(chain);
   auto selected = Select(dataFrame);
   auto hdmdARP = selected.Histo1D({"hdmd", "Dm_d", 40, 0.13, 0.17}, "dm_d");
   auto selectedAddedBranch = selected.Define("h2_y", "rpd0_t / 0.029979f * 1.8646f / ptd0_d");
   auto h2ARP = selectedAddedBranch.Histo2D({"h2", "ptD0 vs Dm_d", 30, 0.135, 0.165, 30, -3, 6}, "dm_d", "h2_y");

   FitAndPlotHdmd(*hdmdARP);
   FitAndPlotH2(*h2ARP);
}
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum 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.

	cpp-ethereum 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 cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * @author Marek Kotewicz <marek@ethdev.com>
 * @date 2014
 * Unit tests for the solidity compiler JSON Interface output.
 */

#include <boost/test/unit_test.hpp>
#include <libsolidity/CompilerStack.h>
#include <jsoncpp/json/json.h>
#include <libdevcore/Exceptions.h>

namespace dev
{
namespace solidity
{
namespace test
{

class InterfaceChecker
{
public:
	InterfaceChecker(): m_compilerStack(false) {}

	void checkInterface(std::string const& _code, std::string const& _expectedInterfaceString)
	{
		try
		{
			m_compilerStack.parse(_code);
		}
		catch(boost::exception const& _e)
		{
			auto msg = std::string("Parsing contract failed with: ") + boost::diagnostic_information(_e);
			BOOST_FAIL(msg);
		}
		std::string generatedInterfaceString = m_compilerStack.getMetadata("", DocumentationType::ABI_INTERFACE);
		Json::Value generatedInterface;
		m_reader.parse(generatedInterfaceString, generatedInterface);
		Json::Value expectedInterface;
		m_reader.parse(_expectedInterfaceString, expectedInterface);
		BOOST_CHECK_MESSAGE(expectedInterface == generatedInterface,
							"Expected " << _expectedInterfaceString <<
							"\n but got:\n" << generatedInterfaceString);
	}

private:
	CompilerStack m_compilerStack;
	Json::Reader m_reader;
};

BOOST_FIXTURE_TEST_SUITE(SolidityABIJSON, InterfaceChecker)

BOOST_AUTO_TEST_CASE(basic_test)
{
	char const* sourceCode = "contract test {\n"
	"  function f(uint a) returns(uint d) { return a * 7; }\n"
	"}\n";

	char const* interface = R"([
	{
		"name": "f",
		"constant": false,
		"type": "function",
		"inputs": [
		{
			"name": "a",
			"type": "uint256"
		}
		],
		"outputs": [
		{
			"name": "d",
			"type": "uint256"
		}
		]
	}
	])";

	checkInterface(sourceCode, interface);
}

BOOST_AUTO_TEST_CASE(empty_contract)
{
	char const* sourceCode = "contract test {\n"
	"}\n";

	char const* interface = "[]";

	checkInterface(sourceCode, interface);
}

BOOST_AUTO_TEST_CASE(multiple_methods)
{
	char const* sourceCode = "contract test {\n"
	"  function f(uint a) returns(uint d) { return a * 7; }\n"
	"  function g(uint b) returns(uint e) { return b * 8; }\n"
	"}\n";

	char const* interface = R"([
	{
		"name": "f",
		"constant": false,
		"type": "function",
		"inputs": [
		{
			"name": "a",
			"type": "uint256"
		}
		],
		"outputs": [
		{
			"name": "d",
			"type": "uint256"
		}
		]
	},
	{
		"name": "g",
		"constant": false,
		"type": "function",
		"inputs": [
		{
			"name": "b",
			"type": "uint256"
		}
		],
		"outputs": [
		{
			"name": "e",
			"type": "uint256"
		}
		]
	}
	])";

	checkInterface(sourceCode, interface);
}

BOOST_AUTO_TEST_CASE(multiple_params)
{
	char const* sourceCode = "contract test {\n"
	"  function f(uint a, uint b) returns(uint d) { return a + b; }\n"
	"}\n";

	char const* interface = R"([
	{
		"name": "f",
		"constant": false,
		"type": "function",
		"inputs": [
		{
			"name": "a",
			"type": "uint256"
		},
		{
			"name": "b",
			"type": "uint256"
		}
		],
		"outputs": [
		{
			"name": "d",
			"type": "uint256"
		}
		]
	}
	])";

	checkInterface(sourceCode, interface);
}

BOOST_AUTO_TEST_CASE(multiple_methods_order)
{
	// methods are expected to be in alpabetical order
	char const* sourceCode = "contract test {\n"
	"  function f(uint a) returns(uint d) { return a * 7; }\n"
	"  function c(uint b) returns(uint e) { return b * 8; }\n"
	"}\n";

	char const* interface = R"([
	{
		"name": "c",
		"constant": false,
		"type": "function",
		"inputs": [
		{
			"name": "b",
			"type": "uint256"
		}
		],
		"outputs": [
		{
			"name": "e",
			"type": "uint256"
		}
		]
	},
	{
		"name": "f",
		"constant": false,
		"type": "function",
		"inputs": [
		{
			"name": "a",
			"type": "uint256"
		}
		],
		"outputs": [
		{
			"name": "d",
			"type": "uint256"
		}
		]
	}
	])";

	checkInterface(sourceCode, interface);
}

BOOST_AUTO_TEST_CASE(const_function)
{
	char const* sourceCode = "contract test {\n"
	"  function foo(uint a, uint b) returns(uint d) { return a + b; }\n"
	"  function boo(uint32 a) constant returns(uint b) { return a * 4; }\n"
	"}\n";

	char const* interface = R"([
	{
		"name": "foo",
		"constant": false,
		"type": "function",
		"inputs": [
		{
			"name": "a",
			"type": "uint256"
		},
		{
			"name": "b",
			"type": "uint256"
		}
		],
		"outputs": [
		{
			"name": "d",
			"type": "uint256"
		}
		]
	},
	{
		"name": "boo",
		"constant": true,
		"type": "function",
		"inputs": [{
			"name": "a",
			"type": "uint32"
		}],
		"outputs": [
		{
			"name": "b",
			"type": "uint256"
		}
		]
	}
	])";

	checkInterface(sourceCode, interface);
}

BOOST_AUTO_TEST_CASE(exclude_fallback_function)
{
	char const* sourceCode = "contract test { function() {} }";

	char const* interface = "[]";

	checkInterface(sourceCode, interface);
}

BOOST_AUTO_TEST_SUITE_END()

}
}
}
<commit_msg>json and solidity ABI generted for events<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum 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.

	cpp-ethereum 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 cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * @author Marek Kotewicz <marek@ethdev.com>
 * @date 2014
 * Unit tests for the solidity compiler JSON Interface output.
 */

#include <boost/test/unit_test.hpp>
#include <libsolidity/CompilerStack.h>
#include <jsoncpp/json/json.h>
#include <libdevcore/Exceptions.h>

namespace dev
{
namespace solidity
{
namespace test
{

class InterfaceChecker
{
public:
	InterfaceChecker(): m_compilerStack(false) {}

	void checkInterface(std::string const& _code, std::string const& _expectedInterfaceString, std::string const& expectedSolidityInterface)
	{
		try
		{
			m_compilerStack.parse(_code);
		}
		catch(boost::exception const& _e)
		{
			auto msg = std::string("Parsing contract failed with: ") + boost::diagnostic_information(_e);
			BOOST_FAIL(msg);
		}
		std::string generatedInterfaceString = m_compilerStack.getMetadata("", DocumentationType::ABI_INTERFACE);
		std::string generatedSolidityInterfaceString = m_compilerStack.getMetadata("", DocumentationType::ABI_SOLIDITY_INTERFACE);
		Json::Value generatedInterface;
		m_reader.parse(generatedInterfaceString, generatedInterface);
		Json::Value expectedInterface;
		m_reader.parse(_expectedInterfaceString, expectedInterface);
		BOOST_CHECK_MESSAGE(expectedInterface == generatedInterface,
							"Expected:\n" << expectedInterface.toStyledString() <<
							"\n but got:\n" << generatedInterface.toStyledString());
		BOOST_CHECK_MESSAGE(expectedSolidityInterface == generatedSolidityInterfaceString,
							"Expected:\n" << expectedSolidityInterface <<
							"\n but got:\n" << generatedSolidityInterfaceString);
	}

private:
	CompilerStack m_compilerStack;
	Json::Reader m_reader;
};

BOOST_FIXTURE_TEST_SUITE(SolidityABIJSON, InterfaceChecker)

BOOST_AUTO_TEST_CASE(basic_test)
{
	char const* sourceCode = "contract test {\n"
	"  function f(uint a) returns(uint d) { return a * 7; }\n"
	"}\n";

	char const* sourceInterface = "contract test{function f(uint256 a)returns(uint256 d){}}";

	char const* interface = R"([
	{
		"name": "f",
		"constant": false,
		"type": "function",
		"inputs": [
		{
			"name": "a",
			"type": "uint256"
		}
		],
		"outputs": [
		{
			"name": "d",
			"type": "uint256"
		}
		]
	}
	])";

	checkInterface(sourceCode, interface, sourceInterface);
}

BOOST_AUTO_TEST_CASE(empty_contract)
{
	char const* sourceCode = "contract test {\n"
	"}\n";
	char const* sourceInterface = "contract test{}";

	char const* interface = "[]";

	checkInterface(sourceCode, interface, sourceInterface);
}

BOOST_AUTO_TEST_CASE(multiple_methods)
{
	char const* sourceCode = "contract test {\n"
	"  function f(uint a) returns(uint d) { return a * 7; }\n"
	"  function g(uint b) returns(uint e) { return b * 8; }\n"
	"}\n";
	char const* sourceInterface = "contract test{function f(uint256 a)returns(uint256 d){}function g(uint256 b)returns(uint256 e){}}";

	char const* interface = R"([
	{
		"name": "f",
		"constant": false,
		"type": "function",
		"inputs": [
		{
			"name": "a",
			"type": "uint256"
		}
		],
		"outputs": [
		{
			"name": "d",
			"type": "uint256"
		}
		]
	},
	{
		"name": "g",
		"constant": false,
		"type": "function",
		"inputs": [
		{
			"name": "b",
			"type": "uint256"
		}
		],
		"outputs": [
		{
			"name": "e",
			"type": "uint256"
		}
		]
	}
	])";

	checkInterface(sourceCode, interface, sourceInterface);
}

BOOST_AUTO_TEST_CASE(multiple_params)
{
	char const* sourceCode = "contract test {\n"
	"  function f(uint a, uint b) returns(uint d) { return a + b; }\n"
	"}\n";
	char const* sourceInterface = "contract test{function f(uint256 a,uint256 b)returns(uint256 d){}}";

	char const* interface = R"([
	{
		"name": "f",
		"constant": false,
		"type": "function",
		"inputs": [
		{
			"name": "a",
			"type": "uint256"
		},
		{
			"name": "b",
			"type": "uint256"
		}
		],
		"outputs": [
		{
			"name": "d",
			"type": "uint256"
		}
		]
	}
	])";

	checkInterface(sourceCode, interface, sourceInterface);
}

BOOST_AUTO_TEST_CASE(multiple_methods_order)
{
	// methods are expected to be in alpabetical order
	char const* sourceCode = "contract test {\n"
	"  function f(uint a) returns(uint d) { return a * 7; }\n"
	"  function c(uint b) returns(uint e) { return b * 8; }\n"
	"}\n";
	char const* sourceInterface = "contract test{function c(uint256 b)returns(uint256 e){}function f(uint256 a)returns(uint256 d){}}";

	char const* interface = R"([
	{
		"name": "c",
		"constant": false,
		"type": "function",
		"inputs": [
		{
			"name": "b",
			"type": "uint256"
		}
		],
		"outputs": [
		{
			"name": "e",
			"type": "uint256"
		}
		]
	},
	{
		"name": "f",
		"constant": false,
		"type": "function",
		"inputs": [
		{
			"name": "a",
			"type": "uint256"
		}
		],
		"outputs": [
		{
			"name": "d",
			"type": "uint256"
		}
		]
	}
	])";

	checkInterface(sourceCode, interface, sourceInterface);
}

BOOST_AUTO_TEST_CASE(const_function)
{
	char const* sourceCode = "contract test {\n"
	"  function foo(uint a, uint b) returns(uint d) { return a + b; }\n"
	"  function boo(uint32 a) constant returns(uint b) { return a * 4; }\n"
	"}\n";
	char const* sourceInterface = "contract test{function foo(uint256 a,uint256 b)returns(uint256 d){}function boo(uint32 a)constant returns(uint256 b){}}";

	char const* interface = R"([
	{
		"name": "foo",
		"constant": false,
		"type": "function",
		"inputs": [
		{
			"name": "a",
			"type": "uint256"
		},
		{
			"name": "b",
			"type": "uint256"
		}
		],
		"outputs": [
		{
			"name": "d",
			"type": "uint256"
		}
		]
	},
	{
		"name": "boo",
		"constant": true,
		"type": "function",
		"inputs": [{
			"name": "a",
			"type": "uint32"
		}],
		"outputs": [
		{
			"name": "b",
			"type": "uint256"
		}
		]
	}
	])";

	checkInterface(sourceCode, interface, sourceInterface);
}

BOOST_AUTO_TEST_CASE(exclude_fallback_function)
{
	char const* sourceCode = "contract test { function() {} }";
	char const* sourceInterface = "contract test{}";

	char const* interface = "[]";

	checkInterface(sourceCode, interface, sourceInterface);
}

BOOST_AUTO_TEST_CASE(events)
{
	char const* sourceCode = "contract test {\n"
	"  function f(uint a) returns(uint d) { return a * 7; }\n"
	"  event e1(uint b, address indexed c); \n"
	"  event e2(); \n"
	"}\n";
	char const* sourceInterface = "contract test{function f(uint256 a)returns(uint256 d){}event e1(uint256 b,address indexed c);event e2;}";

	char const* interface = R"([
	{
		"name": "f",
		"constant": false,
		"type": "function",
		"inputs": [
		{
			"name": "a",
			"type": "uint256"
		}
		],
		"outputs": [
		{
			"name": "d",
			"type": "uint256"
		}
		]
	},
	{
		"name": "e1",
		"type": "event",
		"inputs": [
		{
			"indexed": false,
			"name": "b",
			"type": "uint256"
		},
		{
			"indexed": true,
			"name": "c",
			"type": "address"
		}
		]
	},
	{
		"name": "e2",
		"type": "event",
		"inputs": []
	}

	])";

	checkInterface(sourceCode, interface, sourceInterface);
}

BOOST_AUTO_TEST_CASE(inherited)
{
	char const* sourceCode =
	"	contract Base { \n"
	"		function baseFunction(uint p) returns (uint i) { return p; } \n"
	"		event baseEvent(string32 indexed evtArgBase); \n"
	"	} \n"
	"	contract Derived is Base { \n"
	"		function derivedFunction(string32 p) returns (string32 i) { return p; } \n"
	"		event derivedEvent(uint indexed evtArgDerived); \n"
	"	}";
	char const* sourceInterface = "contract Derived{function baseFunction(uint256 p)returns(uint256 i){}function derivedFunction(string32 p)returns(string32 i){}event derivedEvent(uint256 indexed evtArgDerived);event baseEvent(string32 indexed evtArgBase);}";

	char const* interface = R"([
	{
		"name": "baseFunction",
		"constant": false,
		"type": "function",
		"inputs":
		[{
			"name": "p",
			"type": "uint256"
		}],
		"outputs":
		[{
			"name": "i",
			"type": "uint256"
		}]
	},
	{
		"name": "derivedFunction",
		"constant": false,
		"type": "function",
		"inputs":
		[{
			"name": "p",
			"type": "string32"
		}],
		"outputs":
		[{
			"name": "i",
			"type": "string32"
		}]
	},
	{
		"name": "derivedEvent",
		"type": "event",
		"inputs":
		[{
			"indexed": true,
			"name": "evtArgDerived",
			"type": "uint256"
		}]
	},
	{
		"name": "baseEvent",
		"type": "event",
		"inputs":
		[{
			"indexed": true,
			"name": "evtArgBase",
			"type": "string32"
		}]
	}])";

	checkInterface(sourceCode, interface, sourceInterface);
}

BOOST_AUTO_TEST_SUITE_END()

}
}
}
<|endoftext|>