<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: viewobjectcontact.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-26 12:02:19 $
 *
 *  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 _SDR_CONTACT_VIEWOBJECTCONTACT_HXX
#define _SDR_CONTACT_VIEWOBJECTCONTACT_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#include <vector>

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _SDR_CONTACT_VIEWOBJECTCONTACTLIST_HXX
#include <svx/sdr/contact/viewobjectcontactlist.hxx>
#endif

#ifndef _SV_GEN_HXX
#include <tools/gen.hxx>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

//////////////////////////////////////////////////////////////////////////////
// predeclarations

class Region;

namespace sdr
{
    namespace contact
    {
        class ObjectContact;
        class ViewContact;
        class ViewObjectContactRedirector;
    } // end of namespace contact
    namespace animation
    {
        class AnimationState;
        class AnimationInfo;
    } // end of namespace animation
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////

namespace sdr
{
    namespace contact
    {
        class SVX_DLLPUBLIC ViewObjectContact
        {
            // must-exist and constant contacts
            ObjectContact&                              mrObjectContact;
            ViewContact&                                mrViewContact;

            // for building up a mirror of the draw object hierarchy. One
            // parent pointer and a list of sub objects.
            ViewObjectContact*                          mpParent;
            ViewObjectContactList                       maVOCList;

            // The AnimationState if the object supports animation.
            sdr::animation::AnimationState*             mpAnimationState;

        protected:
            // This rectangle remembers the last positive paint output rectangle.
            // It is then used for invalidating. It needs to be set together with
            // the mbIsPainted flag.
            Rectangle                                   maPaintedRectangle;

            // bitfield
            // This flag describes if the object corresponding to this VOC
            // was painted and thus would need to be invalidated if changes
            // happen. Init with sal_False.
            unsigned                                    mbIsPainted : 1;

            // This flag remembers if the DrawHierarchy below this entry is
            // valid or not. Init with sal_False.
            unsigned                                    mbdrawHierarchyValid : 1;

            // method to get the AnimationState. Needs to give a result. It will
            // return a existing one or create a new one using CreateAnimationState()
            // at the AnimationInfo.
            sdr::animation::AnimationState* GetAnimationState(sdr::animation::AnimationInfo& rInfo) const;

        public:
            // basic constructor.
            ViewObjectContact(ObjectContact& rObjectContact, ViewContact& rViewContact);

            // The destructor. When PrepareDelete() was not called before (see there)
            // warnings will be generated in debug version if there are still contacts
            // existing.
            virtual ~ViewObjectContact();

            // Prepare deletion of this object. This needs to be called always
            // before really deleting this objects. This is necessary since in a c++
            // destructor no virtual function calls are allowed. To avoid this problem,
            // it is required to first call PrepareDelete().
            virtual void PrepareDelete();

            // access to ObjectContact
            ObjectContact& GetObjectContact() const { return mrObjectContact; }

            // access to ViewContact
            ViewContact& GetViewContact() const { return mrViewContact; }

            // access to parent
            void SetParent(ViewObjectContact* pNew) { mpParent = pNew; }
            ViewObjectContact* GetParent() const { return mpParent; }

            // A ViewObjectContact was deleted and shall be forgotten.
            void RemoveViewObjectContact(ViewObjectContact& rVOContact);

            // This method recursively rebuilds the draw hierarchy structure in parallel
            // to the SdrObject structure.
            void BuildDrawHierarchy(ObjectContact& rObjectContact, ViewContact& rSourceNode);

            // This method recursively checks the draw hierarchy structure in parallel
            // to the SdrObject structure and rebuilds the invalid parts.
            void CheckDrawHierarchy(ObjectContact& rObjectContact);

            // This method only recursively clears the draw hierarchy structure between the
            // DrawObjectContacts, it does not delete any to make them reusable.
            void ClearDrawHierarchy();

            // Paint this object. This is before evtl. SubObjects get painted. This method
            // needs to set the flag mbIsPainted and to set the
            // maPaintedRectangle member. This information is later used for invalidates
            // and repaints.
            virtual void PaintObject(DisplayInfo& rDisplayInfo);

            // Pre- and Post-Paint this object. Is used e.g. for page background/foreground painting.
            virtual void PrePaintObject(DisplayInfo& rDisplayInfo);
            virtual void PostPaintObject(DisplayInfo& rDisplayInfo);

            // Paint this objects DrawHierarchy
            virtual void PaintDrawHierarchy(DisplayInfo& rDisplayInfo);

            // This method recursively paints the draw hierarchy. It is also the
            // start point for the mechanism seen from the ObjectContact.
            void PaintObjectHierarchy(DisplayInfo& rDisplayInfo);

            // Get info if this is the active group of the view
            sal_Bool IsActiveGroup() const;

            // React on changes of the object of this ViewContact
            virtual void ActionChanged();

            // Get info if it's painted
            sal_Bool IsPainted() const;

            // Get info about the painted rectangle
            const Rectangle& GetPaintedRectangle() const;

            // Take some action when new objects are inserted
            virtual void ActionChildInserted(const Rectangle& rInitialRectangle);

            // Get info about validity of DrawHierarchy,
            // set to invalid
            sal_Bool IsDrawHierarchyValid() const;
            void InvalidateDrawHierarchy();

            // If DrawHierarchy is handled by a object itself, the sub-objects are set
            // to be equally painted to that object
            void CopyPaintFlagsFromParent(const ViewObjectContact& rParent);

            // take care for clean shutdown of an existing AnimationState
            void DeleteAnimationState();

            // Check for AnimationFeatures. Take necessary actions to evtl. create
            // an AnimationState and register at the ObjectContact's animator
            void CheckForAnimationFeatures(sdr::animation::AnimationInfo& rInfo);

            // Test if this VOC has an animation state and thus is animated
            sal_Bool HasAnimationState() const;

            // get the correct redirector
            ViewObjectContactRedirector* GetRedirector() const;
        };

        // typedefs for a list of ViewObjectContact
        typedef ::std::vector< ViewObjectContact* > ViewObjectContactVector;

    } // end of namespace contact
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////

#endif //_SDR_CONTACT_VIEWOBJECTCONTACT_HXX

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

#ifndef _SDR_CONTACT_VIEWOBJECTCONTACT_HXX
#define _SDR_CONTACT_VIEWOBJECTCONTACT_HXX

#include <sal/types.h>

#include <vector>
#include <tools/debug.hxx>
#include <svx/sdr/contact/viewobjectcontactlist.hxx>
#include <tools/gen.hxx>
#include "svx/svxdllapi.h"

//////////////////////////////////////////////////////////////////////////////
// predeclarations

class Region;

namespace sdr
{
    namespace contact
    {
        class ObjectContact;
        class ViewContact;
        class ViewObjectContactRedirector;
    } // end of namespace contact
    namespace animation
    {
        class AnimationState;
        class AnimationInfo;
    } // end of namespace animation
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////

namespace sdr
{
    namespace contact
    {
        class SVX_DLLPUBLIC ViewObjectContact
        {
            // must-exist and constant contacts
            ObjectContact&                              mrObjectContact;
            ViewContact&                                mrViewContact;

            // for building up a mirror of the draw object hierarchy. One
            // parent pointer and a list of sub objects.
            ViewObjectContact*                          mpParent;
            ViewObjectContactList                       maVOCList;

            // The AnimationState if the object supports animation.
            sdr::animation::AnimationState*             mpAnimationState;

        protected:
            // This rectangle remembers the last positive paint output rectangle.
            // It is then used for invalidating. It needs to be set together with
            // the mbIsPainted flag.
            Rectangle                                   maPaintedRectangle;

            // bitfield
            // This flag describes if the object corresponding to this VOC
            // was painted and thus would need to be invalidated if changes
            // happen. Init with sal_False.
            unsigned                                    mbIsPainted : 1;

            // This flag remembers if the DrawHierarchy below this entry is
            // valid or not. Init with sal_False.
            unsigned                                    mbdrawHierarchyValid : 1;

            // method to get the AnimationState. Needs to give a result. It will
            // return a existing one or create a new one using CreateAnimationState()
            // at the AnimationInfo.
            sdr::animation::AnimationState* GetAnimationState(sdr::animation::AnimationInfo& rInfo) const;

        public:
            // basic constructor.
            ViewObjectContact(ObjectContact& rObjectContact, ViewContact& rViewContact);

            // The destructor. When PrepareDelete() was not called before (see there)
            // warnings will be generated in debug version if there are still contacts
            // existing.
            virtual ~ViewObjectContact();

            // Prepare deletion of this object. This needs to be called always
            // before really deleting this objects. This is necessary since in a c++
            // destructor no virtual function calls are allowed. To avoid this problem,
            // it is required to first call PrepareDelete().
            virtual void PrepareDelete();

            // access to ObjectContact
            ObjectContact& GetObjectContact() const { return mrObjectContact; }

            // access to ViewContact
            ViewContact& GetViewContact() const { return mrViewContact; }

            // access to parent
            void SetParent(ViewObjectContact* pNew) { mpParent = pNew; }
            ViewObjectContact* GetParent() const { return mpParent; }

            // A ViewObjectContact was deleted and shall be forgotten.
            void RemoveViewObjectContact(ViewObjectContact& rVOContact);

            // This method recursively rebuilds the draw hierarchy structure in parallel
            // to the SdrObject structure.
            void BuildDrawHierarchy(ObjectContact& rObjectContact, ViewContact& rSourceNode);

            // This method recursively checks the draw hierarchy structure in parallel
            // to the SdrObject structure and rebuilds the invalid parts.
            void CheckDrawHierarchy(ObjectContact& rObjectContact);

            // This method only recursively clears the draw hierarchy structure between the
            // DrawObjectContacts, it does not delete any to make them reusable.
            void ClearDrawHierarchy();

            // Paint this object. This is before evtl. SubObjects get painted. This method
            // needs to set the flag mbIsPainted and to set the
            // maPaintedRectangle member. This information is later used for invalidates
            // and repaints.
            virtual void PaintObject(DisplayInfo& rDisplayInfo);

            // Pre- and Post-Paint this object. Is used e.g. for page background/foreground painting.
            virtual void PrePaintObject(DisplayInfo& rDisplayInfo);
            virtual void PostPaintObject(DisplayInfo& rDisplayInfo);

            // Paint this objects DrawHierarchy
            virtual void PaintDrawHierarchy(DisplayInfo& rDisplayInfo);

            // This method recursively paints the draw hierarchy. It is also the
            // start point for the mechanism seen from the ObjectContact.
            void PaintObjectHierarchy(DisplayInfo& rDisplayInfo);

            // Get info if this is the active group of the view
            sal_Bool IsActiveGroup() const;

            // React on changes of the object of this ViewContact
            virtual void ActionChanged();

            // Get info if it's painted
            sal_Bool IsPainted() const;

            // Get info about the painted rectangle
            const Rectangle& GetPaintedRectangle() const;

            // Take some action when new objects are inserted
            virtual void ActionChildInserted(const Rectangle& rInitialRectangle);

            // Get info about validity of DrawHierarchy,
            // set to invalid
            sal_Bool IsDrawHierarchyValid() const;
            void InvalidateDrawHierarchy();

            // If DrawHierarchy is handled by a object itself, the sub-objects are set
            // to be equally painted to that object
            void CopyPaintFlagsFromParent(const ViewObjectContact& rParent);

            // take care for clean shutdown of an existing AnimationState
            void DeleteAnimationState();

            // Check for AnimationFeatures. Take necessary actions to evtl. create
            // an AnimationState and register at the ObjectContact's animator
            void CheckForAnimationFeatures(sdr::animation::AnimationInfo& rInfo);

            // Test if this VOC has an animation state and thus is animated
            sal_Bool HasAnimationState() const;

            // get the correct redirector
            ViewObjectContactRedirector* GetRedirector() const;
        };

        // typedefs for a list of ViewObjectContact
        typedef ::std::vector< ViewObjectContact* > ViewObjectContactVector;

    } // end of namespace contact
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////

#endif //_SDR_CONTACT_VIEWOBJECTCONTACT_HXX

// eof
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: viewcontactofgroup.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 05:35:43 $
 *
 *  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
 *
 ************************************************************************/

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

#ifndef _SDR_CONTACT_VIEWCONTACTOFGROUP_HXX
#include <svx/sdr/contact/viewcontactofgroup.hxx>
#endif

#ifndef _SVDOGRP_HXX
#include <svdogrp.hxx>
#endif

#ifndef _SVDPAGE_HXX
#include <svdpage.hxx>
#endif

//////////////////////////////////////////////////////////////////////////////

namespace sdr
{
    namespace contact
    {
        // method to recalculate the PaintRectangle if the validity flag shows that
        // it is invalid. The flag is set from GetPaintRectangle, thus the implementation
        // only needs to refresh maPaintRectangle itself.
        void ViewContactOfGroup::CalcPaintRectangle()
        {
            maPaintRectangle = GetSdrObjGroup().GetCurrentBoundRect();
        }

        ViewContactOfGroup::ViewContactOfGroup(SdrObjGroup& rGroup)
        :   ViewContactOfSdrObj(rGroup)
        {
        }

        ViewContactOfGroup::~ViewContactOfGroup()
        {
        }

        // When ShouldPaintObject() returns sal_True, the object itself is painted and
        // PaintObject() is called.
        sal_Bool ViewContactOfGroup::ShouldPaintObject(DisplayInfo& /*rDisplayInfo*/, const ViewObjectContact& /*rAssociatedVOC*/)
        {
            // Do not paint groups themthelves only when they are empty
            if(!GetSdrObjGroup().GetSubList() || !GetSdrObjGroup().GetSubList()->GetObjCount())
            {
                // Paint empty group to get a replacement visualisation
                return sal_True;
            }

            return sal_False;
        }

        // Paint this object. This is before evtl. SubObjects get painted. It needs to return
        // sal_True when something was pained and the paint output rectangle in rPaintRectangle.
        sal_Bool ViewContactOfGroup::PaintObject(DisplayInfo& rDisplayInfo, Rectangle& rPaintRectangle, const ViewObjectContact& /*rAssociatedVOC*/)
        {
            // Paint the object. If this is called, the group is empty.
            // Paint a replacement object.
            return PaintReplacementObject(rDisplayInfo, rPaintRectangle);
        }
    } // end of namespace contact
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////
// eof
<commit_msg>INTEGRATION: CWS vgbugs07 (1.5.350); FILE MERGED 2007/06/04 13:27:15 vg 1.5.350.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: viewcontactofgroup.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 18:45:09 $
 *
 *  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
 *
 ************************************************************************/

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

#ifndef _SDR_CONTACT_VIEWCONTACTOFGROUP_HXX
#include <svx/sdr/contact/viewcontactofgroup.hxx>
#endif

#ifndef _SVDOGRP_HXX
#include <svx/svdogrp.hxx>
#endif

#ifndef _SVDPAGE_HXX
#include <svx/svdpage.hxx>
#endif

//////////////////////////////////////////////////////////////////////////////

namespace sdr
{
    namespace contact
    {
        // method to recalculate the PaintRectangle if the validity flag shows that
        // it is invalid. The flag is set from GetPaintRectangle, thus the implementation
        // only needs to refresh maPaintRectangle itself.
        void ViewContactOfGroup::CalcPaintRectangle()
        {
            maPaintRectangle = GetSdrObjGroup().GetCurrentBoundRect();
        }

        ViewContactOfGroup::ViewContactOfGroup(SdrObjGroup& rGroup)
        :   ViewContactOfSdrObj(rGroup)
        {
        }

        ViewContactOfGroup::~ViewContactOfGroup()
        {
        }

        // When ShouldPaintObject() returns sal_True, the object itself is painted and
        // PaintObject() is called.
        sal_Bool ViewContactOfGroup::ShouldPaintObject(DisplayInfo& /*rDisplayInfo*/, const ViewObjectContact& /*rAssociatedVOC*/)
        {
            // Do not paint groups themthelves only when they are empty
            if(!GetSdrObjGroup().GetSubList() || !GetSdrObjGroup().GetSubList()->GetObjCount())
            {
                // Paint empty group to get a replacement visualisation
                return sal_True;
            }

            return sal_False;
        }

        // Paint this object. This is before evtl. SubObjects get painted. It needs to return
        // sal_True when something was pained and the paint output rectangle in rPaintRectangle.
        sal_Bool ViewContactOfGroup::PaintObject(DisplayInfo& rDisplayInfo, Rectangle& rPaintRectangle, const ViewObjectContact& /*rAssociatedVOC*/)
        {
            // Paint the object. If this is called, the group is empty.
            // Paint a replacement object.
            return PaintReplacementObject(rDisplayInfo, rPaintRectangle);
        }
    } // end of namespace contact
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////
// eof
<|endoftext|>


<commit_before>#include "directinput/Manager.h"
#include "directinput/Keyboard.h"
#include "directinput/Joystick.h"
#include <stdexcept>

using namespace Framework::DirectInput;

CManager::CManager()
: m_updateThreadHandle(NULL)
, m_updateThreadOver(false)
, m_nextInputEventHandlerId(1)
{
	if(FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, reinterpret_cast<void**>(&m_directInput), NULL)))
	{
		throw std::runtime_error("Couldn't create DirectInput8");
	}
	m_directInput->EnumDevices(DI8DEVCLASS_GAMECTRL, &CManager::EnumDevicesCallback, this, DIEDFL_ATTACHEDONLY);
	{
		DWORD threadId = 0;
		InitializeCriticalSection(&m_updateMutex);
		m_updateThreadHandle = CreateThread(NULL, NULL, &CManager::UpdateThreadProcStub, this, NULL, &threadId);
	}
}

CManager::~CManager()
{
	m_updateThreadOver = true;
	WaitForSingleObject(m_updateThreadHandle, INFINITE);
	DeleteCriticalSection(&m_updateMutex);
}

uint32 CManager::RegisterInputEventHandler(const InputEventHandler& inputEventHandler)
{
	uint32 eventHandlerId = m_nextInputEventHandlerId++;
	EnterCriticalSection(&m_updateMutex);
	{
		m_inputEventHandlers[eventHandlerId] = inputEventHandler;
	}
	LeaveCriticalSection(&m_updateMutex);
	return eventHandlerId;
}

void CManager::UnregisterInputEventHandler(uint32 eventHandlerId)
{
	EnterCriticalSection(&m_updateMutex);
	{
		auto inputEventHandlerIterator = m_inputEventHandlers.find(eventHandlerId);
		assert(inputEventHandlerIterator != std::end(m_inputEventHandlers));
		m_inputEventHandlers.erase(inputEventHandlerIterator);
	}
	LeaveCriticalSection(&m_updateMutex);
}

void CManager::CreateKeyboard(HWND window)
{
	CDevice::DirectInputDevicePtr device;
	if(FAILED(m_directInput->CreateDevice(GUID_SysKeyboard, &device, NULL)))
	{
		throw std::runtime_error("Couldn't create device.");
	}
	EnterCriticalSection(&m_updateMutex);
	{
		m_devices[GUID_SysKeyboard] = std::make_shared<CKeyboard>(device, window);
	}
	LeaveCriticalSection(&m_updateMutex);
}

void CManager::CreateJoysticks(HWND window)
{
	for(auto joystickIterator(std::begin(m_joystickInstances));
		std::end(m_joystickInstances) != joystickIterator; joystickIterator++)
	{
		CDevice::DirectInputDevicePtr device;
		const auto& deviceGuid(*joystickIterator);
		if(FAILED(m_directInput->CreateDevice(deviceGuid, &device, NULL)))
		{
			continue;
		}
		EnterCriticalSection(&m_updateMutex);
		{
			m_devices[deviceGuid] = std::make_shared<CJoystick>(device, window);
		}
		LeaveCriticalSection(&m_updateMutex);
	}
}

bool CManager::GetDeviceInfo(const GUID& deviceId, DIDEVICEINSTANCE* deviceInfo)
{
	if(!deviceInfo) return false;
	auto deviceIterator(m_devices.find(deviceId));
	if(deviceIterator == std::end(m_devices)) return false;
	auto& device = deviceIterator->second;
	return device->GetInfo(deviceInfo);
}

bool CManager::GetDeviceObjectInfo(const GUID& deviceId, uint32 id, DIDEVICEOBJECTINSTANCE* objectInfo)
{
	if(!objectInfo) return false;
	auto deviceIterator(m_devices.find(deviceId));
	if(deviceIterator == std::end(m_devices)) return false;
	auto& device = deviceIterator->second;
	return device->GetObjectInfo(id, objectInfo);
}

BOOL CALLBACK CManager::EnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
{
	return static_cast<CManager*>(pvRef)->EnumDevicesCallbackImpl(lpddi);
}

BOOL CManager::EnumDevicesCallbackImpl(LPCDIDEVICEINSTANCE lpddi)
{
	m_joystickInstances.push_back(lpddi->guidInstance);
	return DIENUM_CONTINUE;
}

void CManager::CallInputEventHandlers(const GUID& device, uint32 id, uint32 value)
{
	for(auto inputEventHandlerIterator(std::begin(m_inputEventHandlers));
		inputEventHandlerIterator != std::end(m_inputEventHandlers); inputEventHandlerIterator++)
	{
		inputEventHandlerIterator->second(device, id, value);
	}
}

DWORD CManager::UpdateThreadProc()
{
	auto inputEventHandler = std::bind(&CManager::CallInputEventHandlers, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
	while(!m_updateThreadOver)
	{
		EnterCriticalSection(&m_updateMutex);
		{
			for(auto deviceIterator(std::begin(m_devices));
				deviceIterator != std::end(m_devices); deviceIterator++)
			{
				auto& device = deviceIterator->second;
				device->ProcessEvents(inputEventHandler);
			}
		}
		LeaveCriticalSection(&m_updateMutex);
		Sleep(16);
	}
	return 0;
}

DWORD WINAPI CManager::UpdateThreadProcStub(void* param)
{
	return reinterpret_cast<CManager*>(param)->UpdateThreadProc();
}
<commit_msg>More cleanup.<commit_after>#include "directinput/Manager.h"
#include "directinput/Keyboard.h"
#include "directinput/Joystick.h"
#include <stdexcept>

using namespace Framework::DirectInput;

CManager::CManager()
: m_updateThreadHandle(NULL)
, m_updateThreadOver(false)
, m_nextInputEventHandlerId(1)
{
	if(FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, reinterpret_cast<void**>(&m_directInput), NULL)))
	{
		throw std::runtime_error("Couldn't create DirectInput8");
	}
	m_directInput->EnumDevices(DI8DEVCLASS_GAMECTRL, &CManager::EnumDevicesCallback, this, DIEDFL_ATTACHEDONLY);
	{
		DWORD threadId = 0;
		InitializeCriticalSection(&m_updateMutex);
		m_updateThreadHandle = CreateThread(NULL, NULL, &CManager::UpdateThreadProcStub, this, NULL, &threadId);
	}
}

CManager::~CManager()
{
	m_updateThreadOver = true;
	WaitForSingleObject(m_updateThreadHandle, INFINITE);
	DeleteCriticalSection(&m_updateMutex);
}

uint32 CManager::RegisterInputEventHandler(const InputEventHandler& inputEventHandler)
{
	uint32 eventHandlerId = m_nextInputEventHandlerId++;
	EnterCriticalSection(&m_updateMutex);
	{
		m_inputEventHandlers[eventHandlerId] = inputEventHandler;
	}
	LeaveCriticalSection(&m_updateMutex);
	return eventHandlerId;
}

void CManager::UnregisterInputEventHandler(uint32 eventHandlerId)
{
	EnterCriticalSection(&m_updateMutex);
	{
		auto inputEventHandlerIterator = m_inputEventHandlers.find(eventHandlerId);
		assert(inputEventHandlerIterator != std::end(m_inputEventHandlers));
		m_inputEventHandlers.erase(inputEventHandlerIterator);
	}
	LeaveCriticalSection(&m_updateMutex);
}

void CManager::CreateKeyboard(HWND window)
{
	CDevice::DirectInputDevicePtr device;
	if(FAILED(m_directInput->CreateDevice(GUID_SysKeyboard, &device, NULL)))
	{
		throw std::runtime_error("Couldn't create device.");
	}
	EnterCriticalSection(&m_updateMutex);
	{
		m_devices[GUID_SysKeyboard] = std::make_shared<CKeyboard>(device, window);
	}
	LeaveCriticalSection(&m_updateMutex);
}

void CManager::CreateJoysticks(HWND window)
{
	for(const auto& joystickInstance : m_joystickInstances)
	{
		CDevice::DirectInputDevicePtr device;
		if(FAILED(m_directInput->CreateDevice(joystickInstance, &device, NULL)))
		{
			continue;
		}
		EnterCriticalSection(&m_updateMutex);
		{
			m_devices[joystickInstance] = std::make_shared<CJoystick>(device, window);
		}
		LeaveCriticalSection(&m_updateMutex);
	}
}

bool CManager::GetDeviceInfo(const GUID& deviceId, DIDEVICEINSTANCE* deviceInfo)
{
	if(!deviceInfo) return false;
	auto deviceIterator(m_devices.find(deviceId));
	if(deviceIterator == std::end(m_devices)) return false;
	auto& device = deviceIterator->second;
	return device->GetInfo(deviceInfo);
}

bool CManager::GetDeviceObjectInfo(const GUID& deviceId, uint32 id, DIDEVICEOBJECTINSTANCE* objectInfo)
{
	if(!objectInfo) return false;
	auto deviceIterator(m_devices.find(deviceId));
	if(deviceIterator == std::end(m_devices)) return false;
	auto& device = deviceIterator->second;
	return device->GetObjectInfo(id, objectInfo);
}

BOOL CALLBACK CManager::EnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
{
	return static_cast<CManager*>(pvRef)->EnumDevicesCallbackImpl(lpddi);
}

BOOL CManager::EnumDevicesCallbackImpl(LPCDIDEVICEINSTANCE lpddi)
{
	m_joystickInstances.push_back(lpddi->guidInstance);
	return DIENUM_CONTINUE;
}

void CManager::CallInputEventHandlers(const GUID& device, uint32 id, uint32 value)
{
	for(const auto& inputEventHandler : m_inputEventHandlers)
	{
		inputEventHandler.second(device, id, value);
	}
}

DWORD CManager::UpdateThreadProc()
{
	auto inputEventHandler = std::bind(&CManager::CallInputEventHandlers, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
	while(!m_updateThreadOver)
	{
		EnterCriticalSection(&m_updateMutex);
		{
			for(auto deviceIterator(std::begin(m_devices));
				deviceIterator != std::end(m_devices); deviceIterator++)
			{
				auto& device = deviceIterator->second;
				device->ProcessEvents(inputEventHandler);
			}
		}
		LeaveCriticalSection(&m_updateMutex);
		Sleep(16);
	}
	return 0;
}

DWORD WINAPI CManager::UpdateThreadProcStub(void* param)
{
	return reinterpret_cast<CManager*>(param)->UpdateThreadProc();
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "iosprobe.h"

#include <utils/logging.h>

#include <QFileInfo>
#include <QProcess>
#include <QDir>
#include <QFileInfoList>

namespace {
Q_LOGGING_CATEGORY(probeLog, "qtc.ios.probe")
}
namespace Ios {

static QString qsystem(const QString &exe, const QStringList &args = QStringList())
{
    QProcess p;
    p.setProcessChannelMode(QProcess::MergedChannels);
    p.start(exe, args);
    p.waitForFinished();
    return QString::fromLocal8Bit(p.readAll());
}

QMap<QString, Platform> IosProbe::detectPlatforms(const QString &devPath)
{
    IosProbe probe;
    probe.addDeveloperPath(devPath);
    probe.detectFirst();
    return probe.detectedPlatforms();
}

static int compareVersions(const QString &v1, const QString &v2)
{
    QStringList v1L = v1.split(QLatin1Char('.'));
    QStringList v2L = v2.split(QLatin1Char('.'));
    int i = 0;
    while (v1.length() > i && v1.length() > i) {
        bool n1Ok, n2Ok;
        int n1 = v1L.value(i).toInt(&n1Ok);
        int n2 = v2L.value(i).toInt(&n2Ok);
        if (!(n1Ok && n2Ok)) {
            qCWarning(probeLog) << QString::fromLatin1("Failed to compare version %1 and %2").arg(v1, v2);
            return 0;
        }
        if (n1 > n2)
            return -1;
        else if (n1 < n2)
            return 1;
        ++i;
    }
    if (v1.length() > v2.length())
        return -1;
    if (v1.length() < v2.length())
        return 1;
    return 0;
}

void IosProbe::addDeveloperPath(const QString &path)
{
    if (path.isEmpty())
        return;
    QFileInfo pInfo(path);
    if (!pInfo.exists() || !pInfo.isDir())
        return;
    if (m_developerPaths.contains(path))
        return;
    m_developerPaths.append(path);
    qCDebug(probeLog) << QString::fromLatin1("Added developer path %1").arg(path);
}

void IosProbe::detectDeveloperPaths()
{
    QProcess selectedXcode;
    QString program = QLatin1String("/usr/bin/xcode-select");
    QStringList arguments(QLatin1String("--print-path"));
    selectedXcode.start(program, arguments, QProcess::ReadOnly);
    if (!selectedXcode.waitForFinished() || selectedXcode.exitCode()) {
        qCWarning(probeLog) << QString::fromLatin1("Could not detect selected xcode with /usr/bin/xcode-select");
    } else {
        QString path = QString::fromLocal8Bit(selectedXcode.readAllStandardOutput());
        path.chop(1);
        addDeveloperPath(path);
    }
    addDeveloperPath(QLatin1String("/Applications/Xcode.app/Contents/Developer"));
}

void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xcodeName)
{
    qCDebug(probeLog) << QString::fromLatin1("Setting up platform \"%1\".").arg(xcodeName);
    QString indent = QLatin1String("  ");

    // detect clang (default toolchain)
    QFileInfo clangFileInfo(devPath
                            + QLatin1String("/Toolchains/XcodeDefault.xctoolchain/usr/bin")
                            + QLatin1String("/clang++"));
    bool hasClang = clangFileInfo.exists();
    if (!hasClang)
        qCWarning(probeLog) << indent << QString::fromLatin1("Default toolchain %1 not found.")
                                .arg(clangFileInfo.canonicalFilePath());
    // Platforms
    QDir platformsDir(devPath + QLatin1String("/Platforms"));
    QFileInfoList platforms = platformsDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
    foreach (const QFileInfo &fInfo, platforms) {
        if (fInfo.isDir() && fInfo.suffix() == QLatin1String("platform")) {
            qCDebug(probeLog) << indent << QString::fromLatin1("Setting up %1").arg(fInfo.fileName());
            QSettingsPtr infoSettings(new QSettings(
                                   fInfo.absoluteFilePath() + QLatin1String("/Info.plist"),
                                   QSettings::NativeFormat));
            if (!infoSettings->contains(QLatin1String("Name"))) {
                qCWarning(probeLog) << indent << QString::fromLatin1("Missing platform name in Info.plist of %1")
                             .arg(fInfo.absoluteFilePath());
                continue;
            }
            QString name = infoSettings->value(QLatin1String("Name")).toString();
            if (name != QLatin1String("macosx") && name != QLatin1String("iphoneos")
                    && name != QLatin1String("iphonesimulator"))
            {
                qCWarning(probeLog) << indent << QString::fromLatin1("Skipping unknown platform %1").arg(name);
                continue;
            }

            // prepare default platform properties
            QVariantMap defaultProp = infoSettings->value(QLatin1String("DefaultProperties"))
                    .toMap();
            QVariantMap overrideProp = infoSettings->value(QLatin1String("OverrideProperties"))
                    .toMap();
            QMapIterator<QString, QVariant> i(overrideProp);
            while (i.hasNext()) {
                i.next();
                // use unite? might lead to double insertions...
                defaultProp[i.key()] = i.value();
            }

            QString clangFullName = name + QLatin1String("-clang") + xcodeName;
            QString clang11FullName = name + QLatin1String("-clang11") + xcodeName;
            // detect gcc
            QFileInfo gccFileInfo(fInfo.absoluteFilePath() + QLatin1String("/Developer/usr/bin/g++"));
            QString gccFullName = name + QLatin1String("-gcc") + xcodeName;
            if (!gccFileInfo.exists())
                gccFileInfo = QFileInfo(devPath + QLatin1String("/usr/bin/g++"));
            bool hasGcc = gccFileInfo.exists();

            QStringList extraFlags;
            if (defaultProp.contains(QLatin1String("NATIVE_ARCH"))) {
                QString arch = defaultProp.value(QLatin1String("NATIVE_ARCH")).toString();
                if (!arch.startsWith(QLatin1String("arm")))
                    qCWarning(probeLog) << indent << QString::fromLatin1("Expected arm architecture, not %1").arg(arch);
                extraFlags << QLatin1String("-arch") << arch;
            } else if (name == QLatin1String("iphonesimulator")) {
                // don't generate a toolchain for 64 bit (to fix when we support that)
                extraFlags << QLatin1String("-arch") << QLatin1String("i386");
            }
            if (hasClang) {
                Platform clangProfile;
                clangProfile.developerPath = Utils::FileName::fromString(devPath);
                clangProfile.platformKind = 0;
                clangProfile.name = clangFullName;
                clangProfile.platformPath = Utils::FileName(fInfo);
                clangProfile.platformInfo = infoSettings;
                clangProfile.compilerPath = Utils::FileName(clangFileInfo);
                QStringList flags = extraFlags;
                flags << QLatin1String("-dumpmachine");
                QString compilerTriplet = qsystem(clangFileInfo.canonicalFilePath(), flags)
                        .simplified();
                QStringList compilerTripletl = compilerTriplet.split(QLatin1Char('-'));
                clangProfile.architecture = compilerTripletl.value(0);
                clangProfile.backendFlags = extraFlags;
                qCDebug(probeLog) << indent << QString::fromLatin1("* adding profile %1").arg(clangProfile.name);
                m_platforms[clangProfile.name] = clangProfile;
                clangProfile.platformKind |= Platform::Cxx11Support;
                clangProfile.backendFlags.append(QLatin1String("-std=c++11"));
                clangProfile.backendFlags.append(QLatin1String("-stdlib=libc++"));
                clangProfile.name = clang11FullName;
                m_platforms[clangProfile.name] = clangProfile;
            }
            if (hasGcc) {
                Platform gccProfile;
                gccProfile.developerPath = Utils::FileName::fromString(devPath);
                gccProfile.name = gccFullName;
                gccProfile.platformKind = 0;
                // use the arm-apple-darwin10-llvm-* variant and avoid the extraFlags if available???
                gccProfile.platformPath = Utils::FileName(fInfo);
                gccProfile.platformInfo = infoSettings;
                gccProfile.compilerPath = Utils::FileName(gccFileInfo);
                QStringList flags = extraFlags;
                flags << QLatin1String("-dumpmachine");
                QString compilerTriplet = qsystem(gccFileInfo.canonicalFilePath(), flags)
                        .simplified();
                QStringList compilerTripletl = compilerTriplet.split(QLatin1Char('-'));
                gccProfile.architecture = compilerTripletl.value(0);
                gccProfile.backendFlags = extraFlags;
                qCDebug(probeLog) << indent << QString::fromLatin1("* adding profile %1").arg(gccProfile.name);
                m_platforms[gccProfile.name] = gccProfile;
            }

            // set SDKs/sysroot
            QString sysRoot;
            QSettingsPtr sdkSettings;
            {
                QString sdkName;
                if (defaultProp.contains(QLatin1String("SDKROOT")))
                    sdkName = defaultProp.value(QLatin1String("SDKROOT")).toString();
                QString sdkPath;
                QDir sdks(fInfo.absoluteFilePath() + QLatin1String("/Developer/SDKs"));
                QString maxVersion;
                foreach (const QFileInfo &sdkDirInfo, sdks.entryInfoList(QDir::Dirs
                                                                         | QDir::NoDotAndDotDot)) {
                    indent = QLatin1String("    ");
                    QSettingsPtr sdkInfo(new QSettings(sdkDirInfo.absoluteFilePath()
                                                       + QLatin1String("/SDKSettings.plist"),
                                                       QSettings::NativeFormat));
                    QString versionStr = sdkInfo->value(QLatin1String("Version")).toString();
                    QVariant currentSdkName = sdkInfo->value(QLatin1String("CanonicalName"));
                    bool isBaseSdk = sdkInfo->value((QLatin1String("isBaseSDK"))).toString()
                            .toLower() != QLatin1String("no");
                    if (!isBaseSdk) {
                        qCDebug(probeLog) << indent << QString::fromLatin1("Skipping non base Sdk %1")
                                                .arg(currentSdkName.toString());
                        continue;
                    }
                    if (sdkName.isEmpty()) {
                        if (compareVersions(maxVersion, versionStr) > 0) {
                            maxVersion = versionStr;
                            sdkPath = sdkDirInfo.canonicalFilePath();
                            sdkSettings = sdkInfo;
                        }
                    } else if (currentSdkName == sdkName) {
                        sdkPath = sdkDirInfo.canonicalFilePath();
                        sdkSettings = sdkInfo;
                    }
                }
                if (!sdkPath.isEmpty())
                    sysRoot = sdkPath;
                else if (!sdkName.isEmpty())
                    qCDebug(probeLog) << indent << QString::fromLatin1("Failed to find sysroot %1").arg(sdkName);
            }
            if (hasClang && !sysRoot.isEmpty()) {
                m_platforms[clangFullName].platformKind |= Platform::BasePlatform;
                m_platforms[clangFullName].sdkPath = Utils::FileName::fromString(sysRoot);
                m_platforms[clangFullName].sdkSettings = sdkSettings;
                m_platforms[clang11FullName].platformKind |= Platform::BasePlatform;
                m_platforms[clang11FullName].sdkPath = Utils::FileName::fromString(sysRoot);
                m_platforms[clang11FullName].sdkSettings = sdkSettings;
            }
            if (hasGcc && !sysRoot.isEmpty()) {
                m_platforms[gccFullName].platformKind |= Platform::BasePlatform;
                m_platforms[gccFullName].sdkPath = Utils::FileName::fromString(sysRoot);
                m_platforms[gccFullName].sdkSettings = sdkSettings;
            }
        }
        indent = QLatin1String("  ");
    }
}

void IosProbe::detectFirst()
{
    detectDeveloperPaths();
    if (!m_developerPaths.isEmpty())
        setupDefaultToolchains(m_developerPaths.value(0),QLatin1String(""));
}

QMap<QString, Platform> IosProbe::detectedPlatforms()
{
    return m_platforms;
}

}
<commit_msg>Ios: Fix version comparison<commit_after>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "iosprobe.h"

#include <utils/logging.h>

#include <QFileInfo>
#include <QProcess>
#include <QDir>
#include <QFileInfoList>

namespace {
Q_LOGGING_CATEGORY(probeLog, "qtc.ios.probe")
}
namespace Ios {

static QString qsystem(const QString &exe, const QStringList &args = QStringList())
{
    QProcess p;
    p.setProcessChannelMode(QProcess::MergedChannels);
    p.start(exe, args);
    p.waitForFinished();
    return QString::fromLocal8Bit(p.readAll());
}

QMap<QString, Platform> IosProbe::detectPlatforms(const QString &devPath)
{
    IosProbe probe;
    probe.addDeveloperPath(devPath);
    probe.detectFirst();
    return probe.detectedPlatforms();
}

static int compareVersions(const QString &v1, const QString &v2)
{
    QStringList v1L = v1.split(QLatin1Char('.'));
    QStringList v2L = v2.split(QLatin1Char('.'));
    int i = 0;
    while (v1L.length() > i && v2L.length() > i) {
        bool n1Ok, n2Ok;
        int n1 = v1L.value(i).toInt(&n1Ok);
        int n2 = v2L.value(i).toInt(&n2Ok);
        if (!(n1Ok && n2Ok)) {
            qCWarning(probeLog) << QString::fromLatin1("Failed to compare version %1 and %2").arg(v1, v2);
            return 0;
        }
        if (n1 > n2)
            return -1;
        else if (n1 < n2)
            return 1;
        ++i;
    }
    if (v1L.length() > v2L.length())
        return -1;
    if (v1L.length() < v2L.length())
        return 1;
    return 0;
}

void IosProbe::addDeveloperPath(const QString &path)
{
    if (path.isEmpty())
        return;
    QFileInfo pInfo(path);
    if (!pInfo.exists() || !pInfo.isDir())
        return;
    if (m_developerPaths.contains(path))
        return;
    m_developerPaths.append(path);
    qCDebug(probeLog) << QString::fromLatin1("Added developer path %1").arg(path);
}

void IosProbe::detectDeveloperPaths()
{
    QProcess selectedXcode;
    QString program = QLatin1String("/usr/bin/xcode-select");
    QStringList arguments(QLatin1String("--print-path"));
    selectedXcode.start(program, arguments, QProcess::ReadOnly);
    if (!selectedXcode.waitForFinished() || selectedXcode.exitCode()) {
        qCWarning(probeLog) << QString::fromLatin1("Could not detect selected xcode with /usr/bin/xcode-select");
    } else {
        QString path = QString::fromLocal8Bit(selectedXcode.readAllStandardOutput());
        path.chop(1);
        addDeveloperPath(path);
    }
    addDeveloperPath(QLatin1String("/Applications/Xcode.app/Contents/Developer"));
}

void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xcodeName)
{
    qCDebug(probeLog) << QString::fromLatin1("Setting up platform \"%1\".").arg(xcodeName);
    QString indent = QLatin1String("  ");

    // detect clang (default toolchain)
    QFileInfo clangFileInfo(devPath
                            + QLatin1String("/Toolchains/XcodeDefault.xctoolchain/usr/bin")
                            + QLatin1String("/clang++"));
    bool hasClang = clangFileInfo.exists();
    if (!hasClang)
        qCWarning(probeLog) << indent << QString::fromLatin1("Default toolchain %1 not found.")
                                .arg(clangFileInfo.canonicalFilePath());
    // Platforms
    QDir platformsDir(devPath + QLatin1String("/Platforms"));
    QFileInfoList platforms = platformsDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
    foreach (const QFileInfo &fInfo, platforms) {
        if (fInfo.isDir() && fInfo.suffix() == QLatin1String("platform")) {
            qCDebug(probeLog) << indent << QString::fromLatin1("Setting up %1").arg(fInfo.fileName());
            QSettingsPtr infoSettings(new QSettings(
                                   fInfo.absoluteFilePath() + QLatin1String("/Info.plist"),
                                   QSettings::NativeFormat));
            if (!infoSettings->contains(QLatin1String("Name"))) {
                qCWarning(probeLog) << indent << QString::fromLatin1("Missing platform name in Info.plist of %1")
                             .arg(fInfo.absoluteFilePath());
                continue;
            }
            QString name = infoSettings->value(QLatin1String("Name")).toString();
            if (name != QLatin1String("macosx") && name != QLatin1String("iphoneos")
                    && name != QLatin1String("iphonesimulator"))
            {
                qCWarning(probeLog) << indent << QString::fromLatin1("Skipping unknown platform %1").arg(name);
                continue;
            }

            // prepare default platform properties
            QVariantMap defaultProp = infoSettings->value(QLatin1String("DefaultProperties"))
                    .toMap();
            QVariantMap overrideProp = infoSettings->value(QLatin1String("OverrideProperties"))
                    .toMap();
            QMapIterator<QString, QVariant> i(overrideProp);
            while (i.hasNext()) {
                i.next();
                // use unite? might lead to double insertions...
                defaultProp[i.key()] = i.value();
            }

            QString clangFullName = name + QLatin1String("-clang") + xcodeName;
            QString clang11FullName = name + QLatin1String("-clang11") + xcodeName;
            // detect gcc
            QFileInfo gccFileInfo(fInfo.absoluteFilePath() + QLatin1String("/Developer/usr/bin/g++"));
            QString gccFullName = name + QLatin1String("-gcc") + xcodeName;
            if (!gccFileInfo.exists())
                gccFileInfo = QFileInfo(devPath + QLatin1String("/usr/bin/g++"));
            bool hasGcc = gccFileInfo.exists();

            QStringList extraFlags;
            if (defaultProp.contains(QLatin1String("NATIVE_ARCH"))) {
                QString arch = defaultProp.value(QLatin1String("NATIVE_ARCH")).toString();
                if (!arch.startsWith(QLatin1String("arm")))
                    qCWarning(probeLog) << indent << QString::fromLatin1("Expected arm architecture, not %1").arg(arch);
                extraFlags << QLatin1String("-arch") << arch;
            } else if (name == QLatin1String("iphonesimulator")) {
                // don't generate a toolchain for 64 bit (to fix when we support that)
                extraFlags << QLatin1String("-arch") << QLatin1String("i386");
            }
            if (hasClang) {
                Platform clangProfile;
                clangProfile.developerPath = Utils::FileName::fromString(devPath);
                clangProfile.platformKind = 0;
                clangProfile.name = clangFullName;
                clangProfile.platformPath = Utils::FileName(fInfo);
                clangProfile.platformInfo = infoSettings;
                clangProfile.compilerPath = Utils::FileName(clangFileInfo);
                QStringList flags = extraFlags;
                flags << QLatin1String("-dumpmachine");
                QString compilerTriplet = qsystem(clangFileInfo.canonicalFilePath(), flags)
                        .simplified();
                QStringList compilerTripletl = compilerTriplet.split(QLatin1Char('-'));
                clangProfile.architecture = compilerTripletl.value(0);
                clangProfile.backendFlags = extraFlags;
                qCDebug(probeLog) << indent << QString::fromLatin1("* adding profile %1").arg(clangProfile.name);
                m_platforms[clangProfile.name] = clangProfile;
                clangProfile.platformKind |= Platform::Cxx11Support;
                clangProfile.backendFlags.append(QLatin1String("-std=c++11"));
                clangProfile.backendFlags.append(QLatin1String("-stdlib=libc++"));
                clangProfile.name = clang11FullName;
                m_platforms[clangProfile.name] = clangProfile;
            }
            if (hasGcc) {
                Platform gccProfile;
                gccProfile.developerPath = Utils::FileName::fromString(devPath);
                gccProfile.name = gccFullName;
                gccProfile.platformKind = 0;
                // use the arm-apple-darwin10-llvm-* variant and avoid the extraFlags if available???
                gccProfile.platformPath = Utils::FileName(fInfo);
                gccProfile.platformInfo = infoSettings;
                gccProfile.compilerPath = Utils::FileName(gccFileInfo);
                QStringList flags = extraFlags;
                flags << QLatin1String("-dumpmachine");
                QString compilerTriplet = qsystem(gccFileInfo.canonicalFilePath(), flags)
                        .simplified();
                QStringList compilerTripletl = compilerTriplet.split(QLatin1Char('-'));
                gccProfile.architecture = compilerTripletl.value(0);
                gccProfile.backendFlags = extraFlags;
                qCDebug(probeLog) << indent << QString::fromLatin1("* adding profile %1").arg(gccProfile.name);
                m_platforms[gccProfile.name] = gccProfile;
            }

            // set SDKs/sysroot
            QString sysRoot;
            QSettingsPtr sdkSettings;
            {
                QString sdkName;
                if (defaultProp.contains(QLatin1String("SDKROOT")))
                    sdkName = defaultProp.value(QLatin1String("SDKROOT")).toString();
                QString sdkPath;
                QDir sdks(fInfo.absoluteFilePath() + QLatin1String("/Developer/SDKs"));
                QString maxVersion;
                foreach (const QFileInfo &sdkDirInfo, sdks.entryInfoList(QDir::Dirs
                                                                         | QDir::NoDotAndDotDot)) {
                    indent = QLatin1String("    ");
                    QSettingsPtr sdkInfo(new QSettings(sdkDirInfo.absoluteFilePath()
                                                       + QLatin1String("/SDKSettings.plist"),
                                                       QSettings::NativeFormat));
                    QString versionStr = sdkInfo->value(QLatin1String("Version")).toString();
                    QVariant currentSdkName = sdkInfo->value(QLatin1String("CanonicalName"));
                    bool isBaseSdk = sdkInfo->value((QLatin1String("isBaseSDK"))).toString()
                            .toLower() != QLatin1String("no");
                    if (!isBaseSdk) {
                        qCDebug(probeLog) << indent << QString::fromLatin1("Skipping non base Sdk %1")
                                                .arg(currentSdkName.toString());
                        continue;
                    }
                    if (sdkName.isEmpty()) {
                        if (compareVersions(maxVersion, versionStr) > 0) {
                            maxVersion = versionStr;
                            sdkPath = sdkDirInfo.canonicalFilePath();
                            sdkSettings = sdkInfo;
                        }
                    } else if (currentSdkName == sdkName) {
                        sdkPath = sdkDirInfo.canonicalFilePath();
                        sdkSettings = sdkInfo;
                    }
                }
                if (!sdkPath.isEmpty())
                    sysRoot = sdkPath;
                else if (!sdkName.isEmpty())
                    qCDebug(probeLog) << indent << QString::fromLatin1("Failed to find sysroot %1").arg(sdkName);
            }
            if (hasClang && !sysRoot.isEmpty()) {
                m_platforms[clangFullName].platformKind |= Platform::BasePlatform;
                m_platforms[clangFullName].sdkPath = Utils::FileName::fromString(sysRoot);
                m_platforms[clangFullName].sdkSettings = sdkSettings;
                m_platforms[clang11FullName].platformKind |= Platform::BasePlatform;
                m_platforms[clang11FullName].sdkPath = Utils::FileName::fromString(sysRoot);
                m_platforms[clang11FullName].sdkSettings = sdkSettings;
            }
            if (hasGcc && !sysRoot.isEmpty()) {
                m_platforms[gccFullName].platformKind |= Platform::BasePlatform;
                m_platforms[gccFullName].sdkPath = Utils::FileName::fromString(sysRoot);
                m_platforms[gccFullName].sdkSettings = sdkSettings;
            }
        }
        indent = QLatin1String("  ");
    }
}

void IosProbe::detectFirst()
{
    detectDeveloperPaths();
    if (!m_developerPaths.isEmpty())
        setupDefaultToolchains(m_developerPaths.value(0),QLatin1String(""));
}

QMap<QString, Platform> IosProbe::detectedPlatforms()
{
    return m_platforms;
}

}
<|endoftext|>


<commit_before>/**
 * @file
 *
 * @brief Read key sets using yaml-cpp
 *
 * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
 */

#include "read.hpp"
#include "yaml-cpp/yaml.h"

#include <kdb.hpp>
#include <kdbease.h>
#include <kdblogger.h>
#include <kdbplugin.h>

#include <sstream>

using namespace std;
using namespace kdb;

namespace
{
/**
 * @brief This function creates a new key from the given parameters.
 *
 * @param name This string specifies the postfix of the name of the key produced by this function.
 * @param parent This key specifies the prefix of the name of the key produced by this function.
 *
 * @returns The function returns a new key that combines the name of the parent key and `name`.
 */
Key newKey (string const & name, Key const & parent)
{
	Key key{ parent.getFullName (), KEY_END };
	key.addBaseName (name);

	return key;
}

/**
 * @brief This function creates a new array key from the given parameters.
 *
 * @param mappings This argument specifies the key set of the new key this function creates.
 * @param arrayKey This argument specifies the key that represents the root of the array.
 *
 * @returns The function returns a new key that is part of the array represented by `arrayKey`.
 */
Key newArrayKey (KeySet const & mappings, Key & arrayKey)
{
	KeySet arrayEntries{ elektraArrayGet (arrayKey.getKey (), mappings.getKeySet ()) };

	if (arrayEntries.size () <= 0)
	{
		Key first = arrayKey.dup ();
		first.addBaseName ("#");
		arrayEntries.append (first);
	}

	Key newKey{ elektraArrayGetNextKey (arrayEntries.getKeySet ()) };
	arrayKey.setMeta ("array", newKey.getBaseName ());

	return newKey;
}

/**
 * @brief Add metadata saved in a YAML map to the specified key
 *
 * @param key This parameter saves the key to which this function should add the metadata stored in `node`.
 * @param node This YAML node stores a map containing metadata.
 */
void addMetadata (Key & key, YAML::Node const & node)
{
	for (auto & element : node)
	{
		auto metakey = element.first.as<string> ();
		auto metavalue = element.second.IsNull () ? "" : element.second.as<string> ();
		ELEKTRA_LOG_DEBUG ("Add metakey “%s: %s”", metakey.c_str (), metavalue.c_str ());
		key.setMeta (metakey, metavalue);
	}
}

/**
 * @brief Convert a YAML node to a key set
 *
 * @param node This YAML node stores the data that should be added to the keyset `mappings`
 * @param mappings The key set where the YAML data will be stored
 * @param parent This key stores the prefix for the key name
 */
void convertNodeToKeySet (YAML::Node const & node, KeySet & mappings, Key & parent)
{
	if (node.Tag () == "!elektra/meta")
	{
		Key key (parent.getFullName (), KEY_VALUE, node[0].as<string> ().c_str (), KEY_END);
		ELEKTRA_LOG_DEBUG ("Add key “%s: %s”", key.getName ().c_str (), key.get<string> ().c_str ());
		mappings.append (key);
		addMetadata (key, node[1]);
	}
	else if (node.IsScalar () || node.IsNull ())
	{
		Key key (parent.getFullName (), KEY_END);
		if (node.IsNull ())
		{
			key.setMeta ("binary", "");
		}
		else
		{
			key.setString (node.as<string> ());
		}
		ELEKTRA_LOG_DEBUG ("Add key “%s: %s”", key.getName ().c_str (),
				   key.getBinarySize () == 0 ? "NULL" : key.get<string> ().c_str ());
		if (node.Tag () == "tag:yaml.org,2002:binary")
		{
			ELEKTRA_LOG_DEBUG ("Set metadata type of key to binary");
			key.setMeta ("type", "binary");
		}
		mappings.append (key);
	}
	else if (node.IsMap () || node.IsSequence ())
	{
		for (auto element : node)
		{
			Key key = node.IsMap () ? newKey (element.first.as<string> (), parent) : newArrayKey (mappings, parent);
			ELEKTRA_LOG_DEBUG ("Add intermediate key “%s”", key.getName ().c_str ());
			mappings.append (key);
			convertNodeToKeySet (node.IsMap () ? element.second : element, mappings, key);
		}
	}
}
} // end namespace

/**
 * @brief Read a YAML file and add the resulting data to a given key set
 *
 * @param mappings The key set where the YAML data will be stored
 * @param parent This key stores the path to the YAML data file that should be read
 */
void yamlcpp::yamlRead (KeySet & mappings, Key & parent)
{
	YAML::Node config = YAML::LoadFile (parent.getString ());

#ifdef HAVE_LOGGER
	ostringstream data;
	data << config;
	ELEKTRA_LOG_DEBUG ("Read data “%s”", data.str ().c_str ());
#endif

	convertNodeToKeySet (config, mappings, parent);
	ELEKTRA_LOG_DEBUG ("Added %zd key%s", mappings.size (), mappings.size () == 1 ? "" : "s");
}
<commit_msg>YAML CPP: Add separate function to create Key<commit_after>/**
 * @file
 *
 * @brief Read key sets using yaml-cpp
 *
 * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
 */

#include "read.hpp"
#include "yaml-cpp/yaml.h"

#include <kdb.hpp>
#include <kdbease.h>
#include <kdblogger.h>
#include <kdbplugin.h>

#include <sstream>

using namespace std;
using namespace kdb;

namespace
{
/**
 * @brief This function creates a new key from the given parameters.
 *
 * @param name This string specifies the postfix of the name of the key produced by this function.
 * @param parent This key specifies the prefix of the name of the key produced by this function.
 *
 * @returns The function returns a new key that combines the name of the parent key and `name`.
 */
Key newKey (string const & name, Key const & parent)
{
	Key key{ parent.getFullName (), KEY_END };
	key.addBaseName (name);

	return key;
}

/**
 * @brief This function creates a new array key from the given parameters.
 *
 * @param mappings This argument specifies the key set of the new key this function creates.
 * @param arrayKey This argument specifies the key that represents the root of the array.
 *
 * @returns The function returns a new key that is part of the array represented by `arrayKey`.
 */
Key newArrayKey (KeySet const & mappings, Key & arrayKey)
{
	KeySet arrayEntries{ elektraArrayGet (arrayKey.getKey (), mappings.getKeySet ()) };

	if (arrayEntries.size () <= 0)
	{
		Key first = arrayKey.dup ();
		first.addBaseName ("#");
		arrayEntries.append (first);
	}

	Key newKey{ elektraArrayGetNextKey (arrayEntries.getKeySet ()) };
	arrayKey.setMeta ("array", newKey.getBaseName ());

	return newKey;
}

/**
 * @brief Add metadata saved in a YAML map to the specified key
 *
 * @param key This parameter saves the key to which this function should add the metadata stored in `node`.
 * @param node This YAML node stores a map containing metadata.
 */
void addMetadata (Key & key, YAML::Node const & node)
{
	for (auto & element : node)
	{
		auto metakey = element.first.as<string> ();
		auto metavalue = element.second.IsNull () ? "" : element.second.as<string> ();
		ELEKTRA_LOG_DEBUG ("Add metakey “%s: %s”", metakey.c_str (), metavalue.c_str ());
		key.setMeta (metakey, metavalue);
	}
}

/**
 * @brief Create a key containing a (possibly empty) value.
 *
 * @param node This YAML node stores the data that should be converted to a new `Key`.
 * @param name This text specifies the name of the key this function creates.
 *
 * @return A new key containing the data specified in `node`
 */
Key createLeafKey (YAML::Node const & node, string const & name)
{
	Key key (name, KEY_END);
	if (node.IsNull ())
	{
		key.setMeta ("binary", "");
	}
	else
	{
		key.setString (node.as<string> ());
	}
	ELEKTRA_LOG_DEBUG ("Add key “%s: %s”", key.getName ().c_str (), key.getBinarySize () == 0 ? "NULL" : key.get<string> ().c_str ());
	if (node.Tag () == "tag:yaml.org,2002:binary")
	{
		ELEKTRA_LOG_DEBUG ("Set metadata type of key to binary");
		key.setMeta ("type", "binary");
	}
	return key;
}

/**
 * @brief Convert a YAML node to a key set
 *
 * @param node This YAML node stores the data that should be added to the keyset `mappings`
 * @param mappings The key set where the YAML data will be stored
 * @param parent This key stores the prefix for the key name
 */
void convertNodeToKeySet (YAML::Node const & node, KeySet & mappings, Key & parent)
{
	if (node.Tag () == "!elektra/meta")
	{
		Key key (parent.getFullName (), KEY_VALUE, node[0].as<string> ().c_str (), KEY_END);
		ELEKTRA_LOG_DEBUG ("Add key “%s: %s”", key.getName ().c_str (), key.get<string> ().c_str ());
		mappings.append (key);
		addMetadata (key, node[1]);
	}
	else if (node.IsScalar () || node.IsNull ())
	{
		auto key = createLeafKey (node, parent.getFullName ());
		mappings.append (key);
	}
	else if (node.IsMap () || node.IsSequence ())
	{
		for (auto element : node)
		{
			Key key = node.IsMap () ? newKey (element.first.as<string> (), parent) : newArrayKey (mappings, parent);
			ELEKTRA_LOG_DEBUG ("Add intermediate key “%s”", key.getName ().c_str ());
			mappings.append (key);
			convertNodeToKeySet (node.IsMap () ? element.second : element, mappings, key);
		}
	}
}
} // end namespace

/**
 * @brief Read a YAML file and add the resulting data to a given key set
 *
 * @param mappings The key set where the YAML data will be stored
 * @param parent This key stores the path to the YAML data file that should be read
 */
void yamlcpp::yamlRead (KeySet & mappings, Key & parent)
{
	YAML::Node config = YAML::LoadFile (parent.getString ());

#ifdef HAVE_LOGGER
	ostringstream data;
	data << config;
	ELEKTRA_LOG_DEBUG ("Read data “%s”", data.str ().c_str ());
#endif

	convertNodeToKeySet (config, mappings, parent);
	ELEKTRA_LOG_DEBUG ("Added %zd key%s", mappings.size (), mappings.size () == 1 ? "" : "s");
}
<|endoftext|>


<commit_before>//=============================================================================================================
/**
* @file     test_fiff_anonymize.cpp
* @author   Lorenz Esch <lorenzesch@hotmail.com>;
* @version  1.0
* @date     September, 2019
*
* @section  LICENSE
*
* Copyright (C) 2019, Lorenz Esch. 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 MNE-CPP authors 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.
*
*
* @brief    Test for anonymizing a fiff raw file
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include <fiff/fiff.h>

#include <iostream>

//*************************************************************************************************************
//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QtTest>
#include <QProcess>
#include <QScopedPointer>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace FIFFLIB;

//=============================================================================================================
/**
* DECLARE CLASS TestFiffAnonymize
*
* @brief The TestFiffAnonymize class provides fiff anonymizing verification tests
*
*/
class TestFiffAnonymize: public QObject
{
    Q_OBJECT

public:
    TestFiffAnonymize();

private slots:
    void initTestCase();
    void compareData();
    void cleanupTestCase();

private:
    double epsilon;
};

//*************************************************************************************************************

TestFiffAnonymize::TestFiffAnonymize()
: epsilon(0.000001)
{
}

//*************************************************************************************************************

void TestFiffAnonymize::initTestCase()
{
    qInfo() << "TestFiffAnonymize::initTestCase - Epsilon" << epsilon;

    // Init testing arguments
    QString sFileIn("./mne-cpp-test-data/MEG/sample/sample_audvis_raw_short.fif");
    QString sFileOut("./mne-cpp-test-data/MEG/sample/sample_audvis_raw_short_anonymized.fif");

    qInfo() << "TestFiffAnonymize::initTestCase - sFileIn" << sFileIn;
    qInfo() << "TestFiffAnonymize::initTestCase - sFileOut" << sFileOut;

    QString program = "./mne_anonymize";
    QStringList arguments;
    arguments << "--in" << sFileIn;
    arguments << "--out" << sFileOut;

    // Pass arguments to application and anaonyimze the fiff file
    QScopedPointer<QProcess> myProcess (new QProcess);
    myProcess->start(program, arguments);
    myProcess->waitForFinished();
}

//*************************************************************************************************************

void TestFiffAnonymize::compareData()
{
    // Open ./mne-cpp-test-data/MEG/sample/sample_audvis_raw_anonymized.fif

    // ToDo: Implement function which reads sensitive tags and checks if they were anaonymized. Use Q_VERIFY().
}

//*************************************************************************************************************

void TestFiffAnonymize::cleanupTestCase()
{
}

//*************************************************************************************************************
//=============================================================================================================
// MAIN
//=============================================================================================================

QTEST_APPLESS_MAIN(TestFiffAnonymize)
#include "test_fiff_anonymize.moc"
<commit_msg>[ci skip] add file crc code for comparison<commit_after>//=============================================================================================================
/**
* @file     test_fiff_anonymize.cpp
* @author   Lorenz Esch <lorenzesch@hotmail.com>;
* @version  1.0
* @date     September, 2019
*
* @section  LICENSE
*
* Copyright (C) 2019, Lorenz Esch. 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 MNE-CPP authors 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.
*
*
* @brief    Test for anonymizing a fiff raw file
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include <fiff/fiff.h>

#include <iostream>

//*************************************************************************************************************
//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QtTest>
#include <QProcess>
#include <QScopedPointer>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace FIFFLIB;

//=============================================================================================================
/**
* DECLARE CLASS TestFiffAnonymize
*
* @brief The TestFiffAnonymize class provides fiff anonymizing verification tests
*
*/
class TestFiffAnonymize: public QObject
{
    Q_OBJECT

public:
    TestFiffAnonymize();

private slots:
    void initTestCase();
    void compareData();
    void cleanupTestCase();

private:
    double epsilon;
};

//*************************************************************************************************************

TestFiffAnonymize::TestFiffAnonymize()
: epsilon(0.000001)
{
}

//*************************************************************************************************************

void TestFiffAnonymize::initTestCase()
{
    qInfo() << "TestFiffAnonymize::initTestCase - Epsilon" << epsilon;

    // Init testing arguments
    QString sFileIn("./mne-cpp-test-data/MEG/sample/sample_audvis_raw_short.fif");
    QString sFileOut("./mne-cpp-test-data/MEG/sample/sample_audvis_raw_short_anonymized.fif");

    qInfo() << "TestFiffAnonymize::initTestCase - sFileIn" << sFileIn;
    qInfo() << "TestFiffAnonymize::initTestCase - sFileOut" << sFileOut;

    QString program = "./mne_anonymize";
    QStringList arguments;
    arguments << "--in" << sFileIn;
    arguments << "--out" << sFileOut;

    // Pass arguments to application and anaonyimze the fiff file
    QScopedPointer<QProcess> myProcess (new QProcess);
    myProcess->start(program, arguments);
    myProcess->waitForFinished();
}

//*************************************************************************************************************

void TestFiffAnonymize::compareData()
{
    // Open ./mne-cpp-test-data/MEG/sample/sample_audvis_raw_anonymized.fif
    QString inFileName("./mne-cpp-test-data/MEG/sample/sample_audvis_raw_anonymized.fif");
    QFile inFile(inFileName);
    QByteArray inData(inFile.readAll());
    quint16 crc = qChecksum(inData.data(),static_cast<uint>(inData.size()));
    qDebug() << crc;

    // ToDo: Implement function which reads sensitive tags and checks if they were anaonymized. Use Q_VERIFY().
}

//*************************************************************************************************************

void TestFiffAnonymize::cleanupTestCase()
{
}

//*************************************************************************************************************
//=============================================================================================================
// MAIN
//=============================================================================================================

QTEST_APPLESS_MAIN(TestFiffAnonymize)
#include "test_fiff_anonymize.moc"
<|endoftext|>


<commit_before>#ifndef ITER_COMBINATIONS_HPP_
#define ITER_COMBINATIONS_HPP_

#include "internal/iterbase.hpp"
#include "internal/iteratoriterator.hpp"

#include <vector>
#include <type_traits>
#include <iterator>
#include <initializer_list>

namespace iter {
  namespace impl {
    template <typename Container>
    class Combinator;
  }

  template <typename Container>
  impl::Combinator<Container> combinations(Container&&, std::size_t);

  template <typename T>
  impl::Combinator<std::initializer_list<T>> combinations(
      std::initializer_list<T>, std::size_t);
}

template <typename Container>
class iter::impl::Combinator {
 private:
  Container container;
  std::size_t length;

  friend Combinator iter::combinations<Container>(Container&&, std::size_t);
  template <typename T>
  friend Combinator<std::initializer_list<T>> iter::combinations(
      std::initializer_list<T>, std::size_t);

  Combinator(Container&& in_container, std::size_t in_length)
      : container(std::forward<Container>(in_container)), length{in_length} {}

  using IndexVector = std::vector<iterator_type<Container>>;
  using CombIteratorDeref = IterIterWrapper<IndexVector>;

 public:
  class Iterator
      : public std::iterator<std::input_iterator_tag, CombIteratorDeref> {
   private:
    constexpr static const int COMPLETE = -1;
    typename std::remove_reference<Container>::type* container_p;
    CombIteratorDeref indices;
    int steps{};

   public:
    Iterator(Container& in_container, std::size_t n)
        : container_p{&in_container}, indices{n} {
      if (n == 0) {
        this->steps = COMPLETE;
        return;
      }
      size_t inc = 0;
      for (auto& iter : this->indices.get()) {
        auto it = std::begin(*this->container_p);
        dumb_advance(it, std::end(*this->container_p), inc);
        if (it != std::end(*this->container_p)) {
          iter = it;
          ++inc;
        } else {
          this->steps = COMPLETE;
          break;
        }
      }
    }

    CombIteratorDeref& operator*() {
      return this->indices;
    }

    CombIteratorDeref* operator->() {
      return &this->indices;
    }

    Iterator& operator++() {
      for (auto iter = indices.get().rbegin(); iter != indices.get().rend();
           ++iter) {
        ++(*iter);

        // what we have to check here is if the distance between
        // the index and the end of indices is >= the distance
        // between the item and end of item
        auto dist = std::distance(this->indices.get().rbegin(), iter);

        if (!(dumb_next(*iter, dist) != std::end(*this->container_p))) {
          if ((iter + 1) != indices.get().rend()) {
            size_t inc = 1;
            for (auto down = iter; down != indices.get().rbegin() - 1; --down) {
              (*down) = dumb_next(*(iter + 1), 1 + inc);
              ++inc;
            }
          } else {
            this->steps = COMPLETE;
            break;
          }
        } else {
          break;
        }
        // we break because none of the rest of the items need
        // to be incremented
      }
      if (this->steps != COMPLETE) {
        ++this->steps;
      }
      return *this;
    }

    Iterator operator++(int) {
      auto ret = *this;
      ++*this;
      return ret;
    }

    bool operator!=(const Iterator& other) const {
      return !(*this == other);
    }

    bool operator==(const Iterator& other) const {
      return this->steps == other.steps;
    }
  };

  Iterator begin() {
    return {this->container, this->length};
  }

  Iterator end() {
    return {this->container, 0};
  }
};

template <typename Container>
iter::impl::Combinator<Container> iter::combinations(
    Container&& container, std::size_t length) {
  return {std::forward<Container>(container), length};
}

template <typename T>
iter::impl::Combinator<std::initializer_list<T>> iter::combinations(
    std::initializer_list<T> il, std::size_t length) {
  return {std::move(il), length};
}

#endif
<commit_msg>makes combinations impl class move-only<commit_after>#ifndef ITER_COMBINATIONS_HPP_
#define ITER_COMBINATIONS_HPP_

#include "internal/iterbase.hpp"
#include "internal/iteratoriterator.hpp"

#include <vector>
#include <type_traits>
#include <iterator>
#include <initializer_list>

namespace iter {
  namespace impl {
    template <typename Container>
    class Combinator;
  }

  template <typename Container>
  impl::Combinator<Container> combinations(Container&&, std::size_t);

  template <typename T>
  impl::Combinator<std::initializer_list<T>> combinations(
      std::initializer_list<T>, std::size_t);
}

template <typename Container>
class iter::impl::Combinator {
 private:
  Container container;
  std::size_t length;

  friend Combinator iter::combinations<Container>(Container&&, std::size_t);
  template <typename T>
  friend Combinator<std::initializer_list<T>> iter::combinations(
      std::initializer_list<T>, std::size_t);

  Combinator(Container&& in_container, std::size_t in_length)
      : container(std::forward<Container>(in_container)), length{in_length} {}

  using IndexVector = std::vector<iterator_type<Container>>;
  using CombIteratorDeref = IterIterWrapper<IndexVector>;

 public:
  Combinator(Combinator&&) = default;
  class Iterator
      : public std::iterator<std::input_iterator_tag, CombIteratorDeref> {
   private:
    constexpr static const int COMPLETE = -1;
    typename std::remove_reference<Container>::type* container_p;
    CombIteratorDeref indices;
    int steps{};

   public:
    Iterator(Container& in_container, std::size_t n)
        : container_p{&in_container}, indices{n} {
      if (n == 0) {
        this->steps = COMPLETE;
        return;
      }
      size_t inc = 0;
      for (auto& iter : this->indices.get()) {
        auto it = std::begin(*this->container_p);
        dumb_advance(it, std::end(*this->container_p), inc);
        if (it != std::end(*this->container_p)) {
          iter = it;
          ++inc;
        } else {
          this->steps = COMPLETE;
          break;
        }
      }
    }

    CombIteratorDeref& operator*() {
      return this->indices;
    }

    CombIteratorDeref* operator->() {
      return &this->indices;
    }

    Iterator& operator++() {
      for (auto iter = indices.get().rbegin(); iter != indices.get().rend();
           ++iter) {
        ++(*iter);

        // what we have to check here is if the distance between
        // the index and the end of indices is >= the distance
        // between the item and end of item
        auto dist = std::distance(this->indices.get().rbegin(), iter);

        if (!(dumb_next(*iter, dist) != std::end(*this->container_p))) {
          if ((iter + 1) != indices.get().rend()) {
            size_t inc = 1;
            for (auto down = iter; down != indices.get().rbegin() - 1; --down) {
              (*down) = dumb_next(*(iter + 1), 1 + inc);
              ++inc;
            }
          } else {
            this->steps = COMPLETE;
            break;
          }
        } else {
          break;
        }
        // we break because none of the rest of the items need
        // to be incremented
      }
      if (this->steps != COMPLETE) {
        ++this->steps;
      }
      return *this;
    }

    Iterator operator++(int) {
      auto ret = *this;
      ++*this;
      return ret;
    }

    bool operator!=(const Iterator& other) const {
      return !(*this == other);
    }

    bool operator==(const Iterator& other) const {
      return this->steps == other.steps;
    }
  };

  Iterator begin() {
    return {this->container, this->length};
  }

  Iterator end() {
    return {this->container, 0};
  }
};

template <typename Container>
iter::impl::Combinator<Container> iter::combinations(
    Container&& container, std::size_t length) {
  return {std::forward<Container>(container), length};
}

template <typename T>
iter::impl::Combinator<std::initializer_list<T>> iter::combinations(
    std::initializer_list<T> il, std::size_t length) {
  return {std::move(il), length};
}

#endif
<|endoftext|>


<commit_before>/*
 * Main.cpp
 *
 *  Created on: 06.04.2017
 *      Author: aca619
 */
#include <iostream>
#include <chrono>
#include <sys/neutrino.h>
#include "ITimer.h"
#include "TimerService.h"

#define PM_CODE 4
#define PM_VALUE 123456

int main(void){
	std::cout << "Geht los hier" << std::endl;

	int chid = ChannelCreate_r(0);
	if(chid < 0){
		std::cout << "Channel Create failed" << std::endl;
	}

	std::chrono::time_point<std::chrono::system_clock> start, end;

	struct _pulse pulse;

	ITimer* timer  = new TimerService(chid, PM_CODE, PM_VALUE);

	start = std::chrono::system_clock::now();

	timer->setAlarm(500);

	int err = MsgReceive_r(chid, &pulse, sizeof(_pulse),NULL);
		if(err) {
				// TODO error handling
				std::cout << "client MsgReceive_r failed" << std::endl;
		}
	end = std::chrono::system_clock::now();

	int elapsed_seconds = std::chrono::duration_cast<std::chrono::milliseconds> (end-start).count();

	std::cout << "Message received: " << pulse.value.sival_int << " after: " << elapsed_seconds << std::endl;

	std::cout << "Zuende hier" << std::endl;
}

<commit_msg>Enhanced the timer example<commit_after>/*
 * Main.cpp
 *
 *  Created on: 06.04.2017
 *      Author: aca619
 */
#include <iostream>
#include <chrono>
#include <sys/neutrino.h>
#include "ITimer.h"
#include "TimerService.h"

#define PM_CODE 4
#define PM_VALUE 123456

int main(void){
	std::cout << "Geht los hier" << std::endl;

	int chid = ChannelCreate_r(0);
	if(chid < 0){
		std::cout << "Channel Create failed" << std::endl;
	}

	std::chrono::time_point<std::chrono::system_clock> start, end;

	struct _pulse pulse;

	ITimer* timer  = new TimerService(chid, PM_CODE);

	start = std::chrono::system_clock::now();

	timer->setAlarm(500, PM_VALUE);

	std::this_thread::sleep_for(std::chrono::milliseconds(200));

	timer->stopAlarm();

	std::this_thread::sleep_for(std::chrono::seconds(1));

	timer->resumeAlarm();

	int err = MsgReceive_r(chid, &pulse, sizeof(_pulse),NULL);
		if(err) {
				// TODO error handling
				std::cout << "client MsgReceive_r failed" << std::endl;
		}
	end = std::chrono::system_clock::now();

	int elapsed_seconds = std::chrono::duration_cast<std::chrono::milliseconds> (end-start).count();

	std::cout << "Message received: " << pulse.value.sival_int << " after: " << elapsed_seconds << std::endl;

	std::cout << "Zuende hier" << std::endl;

	start = std::chrono::system_clock::now();

	timer->setAlarm(500, PM_VALUE);

	err = MsgReceive_r(chid, &pulse, sizeof(_pulse),NULL);
		if(err) {
				// TODO error handling
				std::cout << "client MsgReceive_r failed" << std::endl;
		}
	end = std::chrono::system_clock::now();

	elapsed_seconds = std::chrono::duration_cast<std::chrono::milliseconds> (end-start).count();

	std::cout << "Message received: " << pulse.value.sival_int << " after: " << elapsed_seconds << std::endl;

	std::cout << "Zuende hier" << std::endl;
}

<|endoftext|>


<commit_before>/* Rapicorn Tests
 * Copyright (C) 2008 Tim Janik
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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.
 *
 * A copy of the GNU Lesser General Public License should ship along
 * with this library; if not, see http://www.gnu.org/copyleft/.
 */
#include <rapicorn.hh>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>

namespace {
using namespace Rapicorn;

static void
fill_store (Store1       &s1,
            const String &dirname)
{
  DIR *d = opendir (dirname.c_str());
  s1.clear();
  if (!d)
    {
      critical ("failed to access directory: %s: %s", dirname.c_str(), strerror (errno));
      return;
    }
  struct dirent *e = readdir (d);
  while (e)
    {
      Array row;
      uint n = 0;
      row[n++] = e->d_ino;
      row[n++] = " | ";
      row[n++] = e->d_type;
      row[n++] = " | ";
      row[n++] = e->d_name;
      s1.insert (-1, row);
      e = readdir (d);
    }
  closedir (d);
}

static Store1*
create_store ()
{
  Store1 *s1 = Store1::create_memory_store ("models/files",
                                            Type::lookup ("string"), SELECTION_BROWSE);
  fill_store (*s1, ".");
  return s1;
}

extern "C" int
main (int   argc,
      char *argv[])
{
  /* initialize Rapicorn for X11 */
  Application_SmartHandle smApp = init_app ("FileView", &argc, argv); // acquires Rapicorn mutex
  ApplicationImpl &app = ApplicationImpl::the(); // FIXME: use Application_SmartHandle once C++ bindings are ready

  /* load GUI definition file, relative to argv[0] */
  app.auto_load ("RapicornTest", "fileview.xml", argv[0]);

  /* create root item */
  Store1 *s1 = create_store();
  Wind0wIface &wind0w = *app.create_wind0w ("main-dialog",
                                            Args (""),
                                            Args ("ListModel=" + s1->model().plor_name()));
  wind0w.show();

  app.execute_loops();

  return 0;
}

} // anon
<commit_msg>TESTS: fixed fileview to use IDL API, model/store support still missing<commit_after>// Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
#include <rapicorn.hh>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>

namespace {
using namespace Rapicorn;

static void
fill_store (Store1       &s1,
            const String &dirname)
{
  DIR *d = opendir (dirname.c_str());
  s1.clear();
  if (!d)
    {
      critical ("failed to access directory: %s: %s", dirname.c_str(), strerror (errno));
      return;
    }
  struct dirent *e = readdir (d);
  while (e)
    {
      Array row;
      uint n = 0;
      row[n++] = e->d_ino;
      row[n++] = " | ";
      row[n++] = e->d_type;
      row[n++] = " | ";
      row[n++] = e->d_name;
      s1.insert (-1, row);
      e = readdir (d);
    }
  closedir (d);
}

static Store1*
create_store ()
{
  Store1 *s1 = Store1::create_memory_store ("models/files",
                                            Type::lookup ("string"), SELECTION_BROWSE);
  fill_store (*s1, ".");
  return s1;
}

extern "C" int
main (int   argc,
      char *argv[])
{
  // initialize Rapicorn
  Application app = init_app ("RapicornFileView", &argc, argv);

  // find and load GUI definitions relative to argv[0]
  app.auto_load ("RapicornFileView", "fileview.xml", argv[0]);

  // create main wind0w
  // FIXME: Store1 *s1 = create_store();
  Wind0w wind0w = app.create_wind0w ("main-dialog"); // FIXME: Args (""), Args ("ListModel=" + s1->model().plor_name()));
  wind0w.show();

  // run event loops while wind0ws are on screen
  return app.run_and_exit();
}

} // anon
<|endoftext|>