<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: pe_attri.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 18:46:53 $
 *
 *  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
 *
 ************************************************************************/

#include <precomp.h>
#include <s2_luidl/pe_attri.hxx>

// NOT FULLY DEFINED SERVICES
#include <ary/idl/i_gate.hxx>
#include <ary/idl/i_attribute.hxx>
#include <ary/idl/i_service.hxx>
#include <ary/idl/ip_ce.hxx>
#include <ary_i/codeinf2.hxx>
#include <s2_luidl/pe_type2.hxx>
#include <s2_luidl/pe_vari2.hxx>
#include <s2_luidl/tk_keyw.hxx>
#include <s2_luidl/tk_ident.hxx>
#include <s2_luidl/tk_punct.hxx>

namespace csi
{
namespace uidl
{

PE_Attribute::PE_Attribute( const Ce_id & i_rCurOwner )
    :   eState(e_none),
        pCurOwner(&i_rCurOwner),
        pPE_Variable(0),
        pPE_Exception(0),
        pCurAttribute(0),
        nCurParsedType(0),
        sCurParsedName(),
        bReadOnly(false),
        bBound(false)
{
    pPE_Variable    = new PE_Variable(nCurParsedType, sCurParsedName);
    pPE_Exception   = new PE_Type(nCurParsedType);
}

void
PE_Attribute::EstablishContacts( UnoIDL_PE *                io_pParentPE,
                                 ary::n22::Repository &     io_rRepository,
                                 TokenProcessing_Result &   o_rResult )
{
    UnoIDL_PE::EstablishContacts(io_pParentPE,io_rRepository,o_rResult);
    pPE_Variable->EstablishContacts(this,io_rRepository,o_rResult);
    pPE_Exception->EstablishContacts(this,io_rRepository,o_rResult);
}

PE_Attribute::~PE_Attribute()
{
}

void
PE_Attribute::ProcessToken( const Token & i_rToken )
{
    i_rToken.Trigger(*this);
}

void
PE_Attribute::Process_Identifier( const TokIdentifier & i_rToken )
{
    switch (eState)
    {
        case e_start:
            SetResult(not_done, push_sure, pPE_Variable.Ptr());
            eState = in_variable;
            break;
        case in_raise_std:
            if (strcmp(i_rToken.Text(),"get") == 0)
            {
                SetResult(done, stay);
                eState = in_get;
            }
            else if (strcmp(i_rToken.Text(),"set") == 0)
            {
                SetResult(done, stay);
                eState = in_set;
            }
            else
            {
                SetResult(not_done, pop_failure);
                eState = e_none;
            }
            break;
        case in_get:
        case in_set:
            SetResult(not_done, push_sure, pPE_Exception.Ptr());
            break;
        default:
            SetResult(not_done, pop_failure);
    }   // end switch
}

void
PE_Attribute::Process_Stereotype( const TokStereotype & i_rToken )
{
    if (eState != e_start)
    {
        SetResult(not_done, pop_failure);
        eState = e_none;
        return;
    }

    switch (i_rToken.Id())
    {
        case TokStereotype::ste_readonly:
            bReadOnly = true;
            break;
        case TokStereotype::ste_bound:
            bBound = true;
            break;
        default:
            SetResult(not_done, pop_failure);
            eState = e_none;
            return;
    }   // end switch

    SetResult(done, stay);
}

void
PE_Attribute::Process_MetaType( const TokMetaType & i_rToken )
{
    if (eState != e_start OR i_rToken.Id() != TokMetaType::mt_attribute)
    {
        SetResult(not_done, pop_failure);
        eState = e_none;
        return;
    }

    SetResult(done, stay);
}

void
PE_Attribute::Process_Punctuation( const TokPunctuation & i_rToken )
{
    switch (eState)
    {
        case e_start:
            SetResult(done, stay);
            break;
        case expect_end:
            switch(i_rToken.Id())
            {
                case TokPunctuation::Semicolon:
                    SetResult(done, pop_success);
                    eState = e_none;
                    break;
                case TokPunctuation::Comma:
                    SetResult(not_done, pop_failure);
                    Cerr() << "Autodoc does not support comma separated attributes, because those are discouraged by IDL policies." << Endl();
                    break;
                case TokPunctuation::CurledBracketOpen:
                    SetResult(done, stay);
                    eState = in_raise_std;
                    break;
                default:
                    SetResult(not_done, pop_failure);
            }   // end switch
            break;
        case in_raise_std:
            SetResult(done, stay);
            if (i_rToken.Id() == TokPunctuation::CurledBracketClose)
            {
                eState = expect_end;
            }
            break;
        case in_get:
        case in_set:
            SetResult(done, stay);
            if (i_rToken.Id() == TokPunctuation::Semicolon)
            {
                eState = in_raise_std;
            }
            break;
        default:
            csv_assert(false);
    }
}

void
PE_Attribute::Process_Raises()
{
    if (eState == in_get OR eState == in_set)
    {
        SetResult(done, stay);
    }
    else
        SetResult(not_done, pop_failure);
}

void
PE_Attribute::Process_Default()
{
    if (eState == e_start)
    {
        SetResult(not_done, push_sure, pPE_Variable.Ptr());
        eState = in_variable;
    }
    else if (eState == in_get OR eState == in_set)
        SetResult(not_done, push_sure, pPE_Exception.Ptr());
    else
        SetResult(not_done, pop_failure);
}

void
PE_Attribute::InitData()
{
    eState = e_start;

    pCurAttribute = 0;
    nCurParsedType = 0;
    sCurParsedName = "";
    bReadOnly = false;
    bBound = false;
}

void
PE_Attribute::TransferData()
{
    eState = e_none;
}

void
PE_Attribute::ReceiveData()
{
    switch (eState)
    {
        case in_variable:
            csv_assert(pCurOwner->IsValid());
            pCurAttribute = &Gate().Ces().Store_Attribute(
                                                    *pCurOwner,
                                                    sCurParsedName,
                                                    nCurParsedType,
                                                    bReadOnly,
                                                    bBound );
            PassDocuAt(*pCurAttribute);
            nCurParsedType = 0;
            eState = expect_end;
            break;
        case in_get:
            csv_assert(pCurAttribute != 0);
            pCurAttribute->Add_GetException(nCurParsedType);
            nCurParsedType = 0;
            break;
        case in_set:
            csv_assert(pCurAttribute != 0);
            pCurAttribute->Add_SetException(nCurParsedType);
            nCurParsedType = 0;
            break;
        default:
            csv_assert(false);
    }   // end switch
}

UnoIDL_PE &
PE_Attribute::MyPE()
{
    return *this;
}

}   // namespace uidl
}   // namespace csi
<commit_msg>INTEGRATION: CWS pchfix02 (1.4.30); FILE MERGED 2006/09/01 17:15:47 kaib 1.4.30.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: pe_attri.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 17:08:28 $
 *
 *  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_autodoc.hxx"

#include <precomp.h>
#include <s2_luidl/pe_attri.hxx>

// NOT FULLY DEFINED SERVICES
#include <ary/idl/i_gate.hxx>
#include <ary/idl/i_attribute.hxx>
#include <ary/idl/i_service.hxx>
#include <ary/idl/ip_ce.hxx>
#include <ary_i/codeinf2.hxx>
#include <s2_luidl/pe_type2.hxx>
#include <s2_luidl/pe_vari2.hxx>
#include <s2_luidl/tk_keyw.hxx>
#include <s2_luidl/tk_ident.hxx>
#include <s2_luidl/tk_punct.hxx>

namespace csi
{
namespace uidl
{

PE_Attribute::PE_Attribute( const Ce_id & i_rCurOwner )
    :   eState(e_none),
        pCurOwner(&i_rCurOwner),
        pPE_Variable(0),
        pPE_Exception(0),
        pCurAttribute(0),
        nCurParsedType(0),
        sCurParsedName(),
        bReadOnly(false),
        bBound(false)
{
    pPE_Variable    = new PE_Variable(nCurParsedType, sCurParsedName);
    pPE_Exception   = new PE_Type(nCurParsedType);
}

void
PE_Attribute::EstablishContacts( UnoIDL_PE *                io_pParentPE,
                                 ary::n22::Repository &     io_rRepository,
                                 TokenProcessing_Result &   o_rResult )
{
    UnoIDL_PE::EstablishContacts(io_pParentPE,io_rRepository,o_rResult);
    pPE_Variable->EstablishContacts(this,io_rRepository,o_rResult);
    pPE_Exception->EstablishContacts(this,io_rRepository,o_rResult);
}

PE_Attribute::~PE_Attribute()
{
}

void
PE_Attribute::ProcessToken( const Token & i_rToken )
{
    i_rToken.Trigger(*this);
}

void
PE_Attribute::Process_Identifier( const TokIdentifier & i_rToken )
{
    switch (eState)
    {
        case e_start:
            SetResult(not_done, push_sure, pPE_Variable.Ptr());
            eState = in_variable;
            break;
        case in_raise_std:
            if (strcmp(i_rToken.Text(),"get") == 0)
            {
                SetResult(done, stay);
                eState = in_get;
            }
            else if (strcmp(i_rToken.Text(),"set") == 0)
            {
                SetResult(done, stay);
                eState = in_set;
            }
            else
            {
                SetResult(not_done, pop_failure);
                eState = e_none;
            }
            break;
        case in_get:
        case in_set:
            SetResult(not_done, push_sure, pPE_Exception.Ptr());
            break;
        default:
            SetResult(not_done, pop_failure);
    }   // end switch
}

void
PE_Attribute::Process_Stereotype( const TokStereotype & i_rToken )
{
    if (eState != e_start)
    {
        SetResult(not_done, pop_failure);
        eState = e_none;
        return;
    }

    switch (i_rToken.Id())
    {
        case TokStereotype::ste_readonly:
            bReadOnly = true;
            break;
        case TokStereotype::ste_bound:
            bBound = true;
            break;
        default:
            SetResult(not_done, pop_failure);
            eState = e_none;
            return;
    }   // end switch

    SetResult(done, stay);
}

void
PE_Attribute::Process_MetaType( const TokMetaType & i_rToken )
{
    if (eState != e_start OR i_rToken.Id() != TokMetaType::mt_attribute)
    {
        SetResult(not_done, pop_failure);
        eState = e_none;
        return;
    }

    SetResult(done, stay);
}

void
PE_Attribute::Process_Punctuation( const TokPunctuation & i_rToken )
{
    switch (eState)
    {
        case e_start:
            SetResult(done, stay);
            break;
        case expect_end:
            switch(i_rToken.Id())
            {
                case TokPunctuation::Semicolon:
                    SetResult(done, pop_success);
                    eState = e_none;
                    break;
                case TokPunctuation::Comma:
                    SetResult(not_done, pop_failure);
                    Cerr() << "Autodoc does not support comma separated attributes, because those are discouraged by IDL policies." << Endl();
                    break;
                case TokPunctuation::CurledBracketOpen:
                    SetResult(done, stay);
                    eState = in_raise_std;
                    break;
                default:
                    SetResult(not_done, pop_failure);
            }   // end switch
            break;
        case in_raise_std:
            SetResult(done, stay);
            if (i_rToken.Id() == TokPunctuation::CurledBracketClose)
            {
                eState = expect_end;
            }
            break;
        case in_get:
        case in_set:
            SetResult(done, stay);
            if (i_rToken.Id() == TokPunctuation::Semicolon)
            {
                eState = in_raise_std;
            }
            break;
        default:
            csv_assert(false);
    }
}

void
PE_Attribute::Process_Raises()
{
    if (eState == in_get OR eState == in_set)
    {
        SetResult(done, stay);
    }
    else
        SetResult(not_done, pop_failure);
}

void
PE_Attribute::Process_Default()
{
    if (eState == e_start)
    {
        SetResult(not_done, push_sure, pPE_Variable.Ptr());
        eState = in_variable;
    }
    else if (eState == in_get OR eState == in_set)
        SetResult(not_done, push_sure, pPE_Exception.Ptr());
    else
        SetResult(not_done, pop_failure);
}

void
PE_Attribute::InitData()
{
    eState = e_start;

    pCurAttribute = 0;
    nCurParsedType = 0;
    sCurParsedName = "";
    bReadOnly = false;
    bBound = false;
}

void
PE_Attribute::TransferData()
{
    eState = e_none;
}

void
PE_Attribute::ReceiveData()
{
    switch (eState)
    {
        case in_variable:
            csv_assert(pCurOwner->IsValid());
            pCurAttribute = &Gate().Ces().Store_Attribute(
                                                    *pCurOwner,
                                                    sCurParsedName,
                                                    nCurParsedType,
                                                    bReadOnly,
                                                    bBound );
            PassDocuAt(*pCurAttribute);
            nCurParsedType = 0;
            eState = expect_end;
            break;
        case in_get:
            csv_assert(pCurAttribute != 0);
            pCurAttribute->Add_GetException(nCurParsedType);
            nCurParsedType = 0;
            break;
        case in_set:
            csv_assert(pCurAttribute != 0);
            pCurAttribute->Add_SetException(nCurParsedType);
            nCurParsedType = 0;
            break;
        default:
            csv_assert(false);
    }   // end switch
}

UnoIDL_PE &
PE_Attribute::MyPE()
{
    return *this;
}

}   // namespace uidl
}   // namespace csi
<|endoftext|>


<commit_before>// $Id: rtti.C,v 1.7 2001/06/28 14:13:34 oliver Exp $

#include <BALL/COMMON/rtti.h>
#include <typeinfo>
#include <ctype.h>

#ifdef __GNUC__
	extern "C" char* cplus_demangle(const char* s, int options);
#endif

namespace BALL
{

	string streamClassName(const std::type_info& t)
	{
#ifdef __GNUC__
    #if (__GNUC__ < 3)
			string s(t.name());
      s = GNUDemangling::demangle(s);
    #else
      string s("_Z");
      s += t.name();
      char* name = cplus_demangle(s.c_str(), 1 << 8);
      if (name != 0)
      {
        s = name;
			}
    #endif
#else
		string s(t.name());
#endif

		for (unsigned int i = 0; i < s.size(); i++)
		{
			if (s[i] == ' ')
			{
				s[i] = '_';
			}
		}

		if (string(s, 0, 6) == "const_")
		{
			s.erase(0, 6);
		}

		return s;
	}

#ifdef __GNUC__

	namespace GNUDemangling
	{

		string decode_mangling(string& s)
		{
			string tmp;
			int i,len;

			if (s.size() == 0)
				return "";

			if (!isdigit(s[0]))
			{ // decode GNU shortcuts for built-in types
				char c = s[0];
				s.erase(0, 1);
				switch (c)
				{
					case 'Q': // start of class name
						len = atoi(string(s,1,1).c_str());
						s.erase(0, 1);
						for (i = 0; i < len; i++)
						{
							tmp.append(decode_mangling(s));
							tmp.append("::");
						}
						tmp.erase(tmp.end() - 2, tmp.end());
						break;
					case 'Z': // template parameter
						return decode_mangling(s);
						break;

					case 'i':
						return "int";
						break;

					case 'l':
						return "long";
						break;

					case 's':
						return "short";
						break;

					case 'c':
						return "char";
						break;

					case 'x':
						return "long long";
						break;

					case 'f':
						return "float";
						break;

					case 'd':
						return "double";
						break;

					case 'b':
						return "bool";
						break;

					case 'w':
						return "wchar_t";
						break;

					case 'U': // unsigned variants
						tmp = "unsigned ";
						tmp.append(decode_mangling(s));
						break;

					case 'C': // const
						tmp = "const ";
						tmp.append(decode_mangling(s));
						break;

					case 'P': // pointer
						tmp = decode_mangling(s);
						tmp.append("*");
						break;

					case 'R': // reference
						tmp = decode_mangling(s);
						tmp.append("&");
						break;

					case 't':
						tmp = decode_mangling(s);
						tmp.append("<");

						len = atoi(string(1, s[0]).c_str());
						s.erase(0,1);
						for (i = 0; i < len; i++)
						{
							tmp.append(decode_mangling(s));
							tmp.append(",");
						}

						// remove last ','
						tmp.erase(tmp.end() - 1, tmp.end());
						tmp.append(">");
						break;

					default:
						tmp = "?";
				}
				return tmp;
			}
			else
			{
				i = s.find_first_not_of("0123456789");
				len = atol(string(s, 0, i).c_str());
				if (len == 0)
				{
					s.erase(0,1);

					if (s.size() > 0)
					{
						return decode_mangling(s);
					}
					else
					{
						return "";
					}
				}
				else
				{
					string h(s, i, len);
					s.erase(0, i + len);

					return h;
				}
			}
		}

		string demangle(string s)
		{
			string tmp = decode_mangling(s);

			while (tmp[tmp.size() - 1] == ':')
			{
				tmp.erase(tmp.end() - 1, tmp.end());
			}

			while (tmp[0] == ':')
			{
				tmp.erase(0, 1);
			}

			return tmp;
		}

	} // namespace GNUDemangling

#endif // __GNUC__

} // namespace BALL

<commit_msg>added: comment<commit_after>// $Id: rtti.C,v 1.8 2002/01/03 01:53:39 oliver Exp $

#include <BALL/COMMON/rtti.h>
#include <typeinfo>
#include <ctype.h>

// nasty hack to support the stupid name mangling scheme in g++
// Stating V3.0 we use libiberty to demangle the names...
#ifdef __GNUC__
	extern "C" char* cplus_demangle(const char* s, int options);
#endif

namespace BALL
{

	string streamClassName(const std::type_info& t)
	{
#ifdef __GNUC__
    #if (__GNUC__ < 3)
			string s(t.name());
      s = GNUDemangling::demangle(s);
    #else
      string s("_Z");
      s += t.name();
      char* name = cplus_demangle(s.c_str(), 1 << 8);
      if (name != 0)
      {
        s = name;
			}
    #endif
#else
		string s(t.name());
#endif

		for (unsigned int i = 0; i < s.size(); i++)
		{
			if (s[i] == ' ')
			{
				s[i] = '_';
			}
		}

		if (string(s, 0, 6) == "const_")
		{
			s.erase(0, 6);
		}

		return s;
	}

#ifdef __GNUC__

	namespace GNUDemangling
	{

		string decode_mangling(string& s)
		{
			string tmp;
			int i,len;

			if (s.size() == 0)
				return "";

			if (!isdigit(s[0]))
			{ // decode GNU shortcuts for built-in types
				char c = s[0];
				s.erase(0, 1);
				switch (c)
				{
					case 'Q': // start of class name
						len = atoi(string(s,1,1).c_str());
						s.erase(0, 1);
						for (i = 0; i < len; i++)
						{
							tmp.append(decode_mangling(s));
							tmp.append("::");
						}
						tmp.erase(tmp.end() - 2, tmp.end());
						break;
					case 'Z': // template parameter
						return decode_mangling(s);
						break;

					case 'i':
						return "int";
						break;

					case 'l':
						return "long";
						break;

					case 's':
						return "short";
						break;

					case 'c':
						return "char";
						break;

					case 'x':
						return "long long";
						break;

					case 'f':
						return "float";
						break;

					case 'd':
						return "double";
						break;

					case 'b':
						return "bool";
						break;

					case 'w':
						return "wchar_t";
						break;

					case 'U': // unsigned variants
						tmp = "unsigned ";
						tmp.append(decode_mangling(s));
						break;

					case 'C': // const
						tmp = "const ";
						tmp.append(decode_mangling(s));
						break;

					case 'P': // pointer
						tmp = decode_mangling(s);
						tmp.append("*");
						break;

					case 'R': // reference
						tmp = decode_mangling(s);
						tmp.append("&");
						break;

					case 't':
						tmp = decode_mangling(s);
						tmp.append("<");

						len = atoi(string(1, s[0]).c_str());
						s.erase(0,1);
						for (i = 0; i < len; i++)
						{
							tmp.append(decode_mangling(s));
							tmp.append(",");
						}

						// remove last ','
						tmp.erase(tmp.end() - 1, tmp.end());
						tmp.append(">");
						break;

					default:
						tmp = "?";
				}
				return tmp;
			}
			else
			{
				i = s.find_first_not_of("0123456789");
				len = atol(string(s, 0, i).c_str());
				if (len == 0)
				{
					s.erase(0,1);

					if (s.size() > 0)
					{
						return decode_mangling(s);
					}
					else
					{
						return "";
					}
				}
				else
				{
					string h(s, i, len);
					s.erase(0, i + len);

					return h;
				}
			}
		}

		string demangle(string s)
		{
			string tmp = decode_mangling(s);

			while (tmp[tmp.size() - 1] == ':')
			{
				tmp.erase(tmp.end() - 1, tmp.end());
			}

			while (tmp[0] == ':')
			{
				tmp.erase(0, 1);
			}

			return tmp;
		}

	} // namespace GNUDemangling

#endif // __GNUC__

} // namespace BALL

<|endoftext|>


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

#include "client/client_user_authorizer.h"

#include <QCryptographicHash>

#include "base/message_serialization.h"
#include "client/ui/authorization_dialog.h"
#include "crypto/secure_memory.h"

namespace aspia {

namespace {

const int kKeyHashingRounds = 100000;
const int kPasswordHashingRounds = 100000;

QByteArray createPasswordHash(const QString& password)
{
    QByteArray data = password.toUtf8();

    for (int i = 0; i < kPasswordHashingRounds; ++i)
    {
        data = QCryptographicHash::hash(data, QCryptographicHash::Sha512);
    }

    return data;
}

QByteArray createSessionKey(const QByteArray& password_hash, const QByteArray& nonce)
{
    QByteArray data = password_hash;

    for (int i = 0; i < kKeyHashingRounds; ++i)
    {
        QCryptographicHash hash(QCryptographicHash::Sha512);

        hash.addData(data);
        hash.addData(nonce);

        data = hash.result();
    }

    return data;
}

} // namespace

ClientUserAuthorizer::ClientUserAuthorizer(QWidget* parent)
    : QObject(parent)
{
    // Nothing
}

ClientUserAuthorizer::~ClientUserAuthorizer()
{
    secureMemZero(&username_);
    secureMemZero(&password_);

    cancel();
}

void ClientUserAuthorizer::setSessionType(proto::auth::SessionType session_type)
{
    if (state_ != State::NOT_STARTED)
    {
        qDebug("An attempt to set a session type in an already running authorizer");
        return;
    }

    session_type_ = session_type;
}

void ClientUserAuthorizer::setUserName(const QString& username)
{
    if (state_ != State::NOT_STARTED)
    {
        qDebug("An attempt to set a user name in an already running authorizer");
        return;
    }

    username_ = username;
}

void ClientUserAuthorizer::setPassword(const QString& password)
{
    if (state_ != State::NOT_STARTED)
    {
        qDebug("An attempt to set a password in an already running authorizer");
        return;
    }

    password_ = password;
}

void ClientUserAuthorizer::start()
{
    if (state_ != State::NOT_STARTED)
    {
        qDebug("Authorizer already started");
        return;
    }

    state_ = State::STARTED;
    writeLogonRequest();
    emit started();
}

void ClientUserAuthorizer::cancel()
{
    if (state_ == State::FINISHED)
        return;

    state_ = State::FINISHED;
    emit finished(proto::auth::STATUS_CANCELED);
}

void ClientUserAuthorizer::messageReceived(const QByteArray& buffer)
{
    if (state_ == State::FINISHED)
        return;

    proto::auth::HostToClient message;

    if (parseMessage(buffer, message))
    {
        if (message.has_server_challenge())
        {
            readServerChallenge(message.server_challenge());
            return;
        }
        else if (message.has_logon_result())
        {
            readLogonResult(message.logon_result());
            return;
        }
    }

    emit errorOccurred(tr("Protocol error: Unknown message from host."));
    cancel();
}

void ClientUserAuthorizer::writeLogonRequest()
{
    proto::auth::ClientToHost message;

    // We do not support other authorization methods yet.
    message.mutable_logon_request()->set_method(proto::auth::METHOD_BASIC);
    emit sendMessage(serializeMessage(message));
}

void ClientUserAuthorizer::readServerChallenge(
    const proto::auth::ServerChallenge& server_challenge)
{
    QByteArray nonce = QByteArray::fromStdString(server_challenge.nonce());
    if (nonce.isEmpty())
    {
        emit errorOccurred(tr("Authorization error: Empty nonce is not allowed."));
        cancel();
        return;
    }

    if (username_.isEmpty() || password_.isEmpty())
    {
        AuthorizationDialog dialog(dynamic_cast<QWidget*>(parent()));

        dialog.setUserName(username_);
        dialog.setPassword(password_);

        if (dialog.exec() == AuthorizationDialog::Rejected)
        {
            emit errorOccurred(tr("Authorization is canceled by the user."));
            cancel();
            return;
        }

        username_ = dialog.userName();
        password_ = dialog.password();
    }

    QByteArray password_hash = createPasswordHash(password_);
    QByteArray session_key = createSessionKey(password_hash, nonce);

    proto::auth::ClientToHost message;

    proto::auth::ClientChallenge* client_challenge = message.mutable_client_challenge();
    client_challenge->set_session_type(session_type_);
    client_challenge->set_username(username_.toStdString());
    client_challenge->set_session_key(session_key.constData(), session_key.size());

    secureMemZero(&password_hash);
    secureMemZero(&session_key);

    QByteArray serialized_message = serializeMessage(message);

    secureMemZero(client_challenge->mutable_username());
    secureMemZero(client_challenge->mutable_session_key());

    emit sendMessage(serialized_message);

    secureMemZero(&serialized_message);
    secureMemZero(&nonce);
}

void ClientUserAuthorizer::readLogonResult(const proto::auth::LogonResult& logon_result)
{
    if (logon_result.status() != proto::auth::STATUS_SUCCESS)
    {
        // Previous data for authorization is not correct. We clear the password so that the
        // authorization dialog is invoked.
        secureMemZero(&password_);
        password_.clear();

        // If the authorization fails, we send the authorization request again.
        writeLogonRequest();
    }
    else
    {
        state_ = State::FINISHED;
        emit finished(logon_result.status());
    }
}

} // namespace aspia
<commit_msg>- Using QByteArray::toStdString method.<commit_after>//
// Aspia Project
// Copyright (C) 2018 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "client/client_user_authorizer.h"

#include <QCryptographicHash>

#include "base/message_serialization.h"
#include "client/ui/authorization_dialog.h"
#include "crypto/secure_memory.h"

namespace aspia {

namespace {

const int kKeyHashingRounds = 100000;
const int kPasswordHashingRounds = 100000;

QByteArray createPasswordHash(const QString& password)
{
    QByteArray data = password.toUtf8();

    for (int i = 0; i < kPasswordHashingRounds; ++i)
    {
        data = QCryptographicHash::hash(data, QCryptographicHash::Sha512);
    }

    return data;
}

QByteArray createSessionKey(const QByteArray& password_hash, const QByteArray& nonce)
{
    QByteArray data = password_hash;

    for (int i = 0; i < kKeyHashingRounds; ++i)
    {
        QCryptographicHash hash(QCryptographicHash::Sha512);

        hash.addData(data);
        hash.addData(nonce);

        data = hash.result();
    }

    return data;
}

} // namespace

ClientUserAuthorizer::ClientUserAuthorizer(QWidget* parent)
    : QObject(parent)
{
    // Nothing
}

ClientUserAuthorizer::~ClientUserAuthorizer()
{
    secureMemZero(&username_);
    secureMemZero(&password_);

    cancel();
}

void ClientUserAuthorizer::setSessionType(proto::auth::SessionType session_type)
{
    if (state_ != State::NOT_STARTED)
    {
        qDebug("An attempt to set a session type in an already running authorizer");
        return;
    }

    session_type_ = session_type;
}

void ClientUserAuthorizer::setUserName(const QString& username)
{
    if (state_ != State::NOT_STARTED)
    {
        qDebug("An attempt to set a user name in an already running authorizer");
        return;
    }

    username_ = username;
}

void ClientUserAuthorizer::setPassword(const QString& password)
{
    if (state_ != State::NOT_STARTED)
    {
        qDebug("An attempt to set a password in an already running authorizer");
        return;
    }

    password_ = password;
}

void ClientUserAuthorizer::start()
{
    if (state_ != State::NOT_STARTED)
    {
        qDebug("Authorizer already started");
        return;
    }

    state_ = State::STARTED;
    writeLogonRequest();
    emit started();
}

void ClientUserAuthorizer::cancel()
{
    if (state_ == State::FINISHED)
        return;

    state_ = State::FINISHED;
    emit finished(proto::auth::STATUS_CANCELED);
}

void ClientUserAuthorizer::messageReceived(const QByteArray& buffer)
{
    if (state_ == State::FINISHED)
        return;

    proto::auth::HostToClient message;

    if (parseMessage(buffer, message))
    {
        if (message.has_server_challenge())
        {
            readServerChallenge(message.server_challenge());
            return;
        }
        else if (message.has_logon_result())
        {
            readLogonResult(message.logon_result());
            return;
        }
    }

    emit errorOccurred(tr("Protocol error: Unknown message from host."));
    cancel();
}

void ClientUserAuthorizer::writeLogonRequest()
{
    proto::auth::ClientToHost message;

    // We do not support other authorization methods yet.
    message.mutable_logon_request()->set_method(proto::auth::METHOD_BASIC);
    emit sendMessage(serializeMessage(message));
}

void ClientUserAuthorizer::readServerChallenge(
    const proto::auth::ServerChallenge& server_challenge)
{
    QByteArray nonce = QByteArray::fromStdString(server_challenge.nonce());
    if (nonce.isEmpty())
    {
        emit errorOccurred(tr("Authorization error: Empty nonce is not allowed."));
        cancel();
        return;
    }

    if (username_.isEmpty() || password_.isEmpty())
    {
        AuthorizationDialog dialog(dynamic_cast<QWidget*>(parent()));

        dialog.setUserName(username_);
        dialog.setPassword(password_);

        if (dialog.exec() == AuthorizationDialog::Rejected)
        {
            emit errorOccurred(tr("Authorization is canceled by the user."));
            cancel();
            return;
        }

        username_ = dialog.userName();
        password_ = dialog.password();
    }

    QByteArray password_hash = createPasswordHash(password_);
    QByteArray session_key = createSessionKey(password_hash, nonce);

    proto::auth::ClientToHost message;

    proto::auth::ClientChallenge* client_challenge = message.mutable_client_challenge();
    client_challenge->set_session_type(session_type_);
    client_challenge->set_username(username_.toStdString());
    client_challenge->set_session_key(session_key.toStdString());

    secureMemZero(&password_hash);
    secureMemZero(&session_key);

    QByteArray serialized_message = serializeMessage(message);

    secureMemZero(client_challenge->mutable_username());
    secureMemZero(client_challenge->mutable_session_key());

    emit sendMessage(serialized_message);

    secureMemZero(&serialized_message);
    secureMemZero(&nonce);
}

void ClientUserAuthorizer::readLogonResult(const proto::auth::LogonResult& logon_result)
{
    if (logon_result.status() != proto::auth::STATUS_SUCCESS)
    {
        // Previous data for authorization is not correct. We clear the password so that the
        // authorization dialog is invoked.
        secureMemZero(&password_);
        password_.clear();

        // If the authorization fails, we send the authorization request again.
        writeLogonRequest();
    }
    else
    {
        state_ = State::FINISHED;
        emit finished(logon_result.status());
    }
}

} // namespace aspia
<|endoftext|>


<commit_before>#include "shaderlab/Evaluator.h"
#include "shaderlab/Node.h"

#include <unirender/Device.h>
#include <unirender/ShaderProgram.h>
#include <unirender/Uniform.h>
#include <shadergraph/typedef.h>
#include <shadergraph/Evaluator.h>
#include <shadergraph/ValueImpl.h>
#include <shadergraph/block/FragmentShader.h>
#include <shadergraph/block/Time.h>
#include <painting0/TimeUpdater.h>

namespace shaderlab
{

std::shared_ptr<ur::ShaderProgram>
Evaluator::BuildShader(const ur::Device& dev, const std::string& vs,
                       const std::vector<bp::NodePtr>& nodes)
{
    assert(m_front_eval);

    std::string code;

    // build frag m_shader
    for (auto& node : nodes)
    {
        auto back_node = m_front_eval->QueryBackNode(*node);
        if (!back_node) {
            continue;
        }
        assert(back_node);
        auto block = std::static_pointer_cast<shadergraph::Block>(back_node);
        if (block->get_type() == rttr::type::get<shadergraph::block::FragmentShader>())
        {
            m_back_eval.Rebuild(block);
            code = m_back_eval.GenShaderCode();
            break;
        }
    }

    if (code.empty()) {
        return nullptr;
    }

    m_shader = dev.CreateShaderProgram(vs, code);
    if (!m_shader->CheckStatus()) {
        return nullptr;
    }

    for (auto& node : nodes)
    {
        auto back_node = m_front_eval->QueryBackNode(*node);
        if (!back_node) {
            continue;
        }
        assert(back_node);
        auto block = std::static_pointer_cast<shadergraph::Block>(back_node);
        if (block->get_type() == rttr::type::get<shadergraph::block::Time>())
        {
            auto up = std::make_shared<pt0::TimeUpdater>(*m_shader,
                shadergraph::block::Time::TIME_STR,
                shadergraph::block::Time::SIN_TIME_STR,
                shadergraph::block::Time::COS_TIME_STR,
                shadergraph::block::Time::DELTA_TIME_STR);
            m_shader->AddUniformUpdater(up);
        }
    }

    UpdateUniforms();

    return m_shader;
}

void Evaluator::UpdateUniforms()
{
    auto uniforms = m_back_eval.CalcUniformValues();
    for (auto& u : uniforms)
    {
        auto uniform = m_shader->QueryUniform(u.name);
        if (!uniform) {
            continue;
        }

        auto unif = std::static_pointer_cast<shadergraph::UniformVal>(u.val);
        switch (unif->var.type)
        {
        case shadergraph::VarType::Invalid:
            break;
        case shadergraph::VarType::Bool:
        {
            auto b = std::static_pointer_cast<shadergraph::BoolVal>(unif->var.val)->x;
            const int i = b ? 1 : 0;
            uniform->SetValue(&i, 1);
        }
            break;
        case shadergraph::VarType::Int:
        {
            const int i = std::static_pointer_cast<shadergraph::IntVal>(unif->var.val)->x;
            uniform->SetValue(&i, 1);
        }
            break;
        case shadergraph::VarType::Float:
        {
            const float f = std::static_pointer_cast<shadergraph::FloatVal>(unif->var.val)->x;
            uniform->SetValue(&f, 1);
        }
            break;
        default:
            assert(0);
        }
    }
}

}<commit_msg>[FIXED] update float4 uniform<commit_after>#include "shaderlab/Evaluator.h"
#include "shaderlab/Node.h"

#include <unirender/Device.h>
#include <unirender/ShaderProgram.h>
#include <unirender/Uniform.h>
#include <shadergraph/typedef.h>
#include <shadergraph/Evaluator.h>
#include <shadergraph/ValueImpl.h>
#include <shadergraph/block/FragmentShader.h>
#include <shadergraph/block/Time.h>
#include <painting0/TimeUpdater.h>

namespace shaderlab
{

std::shared_ptr<ur::ShaderProgram>
Evaluator::BuildShader(const ur::Device& dev, const std::string& vs,
                       const std::vector<bp::NodePtr>& nodes)
{
    assert(m_front_eval);

    std::string code;

    // build frag m_shader
    for (auto& node : nodes)
    {
        auto back_node = m_front_eval->QueryBackNode(*node);
        if (!back_node) {
            continue;
        }
        assert(back_node);
        auto block = std::static_pointer_cast<shadergraph::Block>(back_node);
        if (block->get_type() == rttr::type::get<shadergraph::block::FragmentShader>())
        {
            m_back_eval.Rebuild(block);
            code = m_back_eval.GenShaderCode();
            break;
        }
    }

    if (code.empty()) {
        return nullptr;
    }

    m_shader = dev.CreateShaderProgram(vs, code);
    if (!m_shader->CheckStatus()) {
        return nullptr;
    }

    for (auto& node : nodes)
    {
        auto back_node = m_front_eval->QueryBackNode(*node);
        if (!back_node) {
            continue;
        }
        assert(back_node);
        auto block = std::static_pointer_cast<shadergraph::Block>(back_node);
        if (block->get_type() == rttr::type::get<shadergraph::block::Time>())
        {
            auto up = std::make_shared<pt0::TimeUpdater>(*m_shader,
                shadergraph::block::Time::TIME_STR,
                shadergraph::block::Time::SIN_TIME_STR,
                shadergraph::block::Time::COS_TIME_STR,
                shadergraph::block::Time::DELTA_TIME_STR);
            m_shader->AddUniformUpdater(up);
        }
    }

    UpdateUniforms();

    return m_shader;
}

void Evaluator::UpdateUniforms()
{
    auto uniforms = m_back_eval.CalcUniformValues();
    for (auto& u : uniforms)
    {
        auto uniform = m_shader->QueryUniform(u.name);
        if (!uniform) {
            continue;
        }

        auto unif = std::static_pointer_cast<shadergraph::UniformVal>(u.val);
        switch (unif->var.type)
        {
        case shadergraph::VarType::Invalid:
            break;
        case shadergraph::VarType::Bool:
        {
            auto b = std::static_pointer_cast<shadergraph::BoolVal>(unif->var.val)->x;
            const int i = b ? 1 : 0;
            uniform->SetValue(&i, 1);
        }
            break;
        case shadergraph::VarType::Int:
        {
            const int i = std::static_pointer_cast<shadergraph::IntVal>(unif->var.val)->x;
            uniform->SetValue(&i, 1);
        }
            break;
        case shadergraph::VarType::Float:
        {
            const float f = std::static_pointer_cast<shadergraph::FloatVal>(unif->var.val)->x;
            uniform->SetValue(&f, 1);
        }
            break;
        case shadergraph::VarType::Float4:
        {
            const auto f4 = std::static_pointer_cast<shadergraph::Float4Val>(unif->var.val)->xyzw;
            switch (uniform->GetType())
            {
            case ur::UniformType::Float1:
                uniform->SetValue(f4, 1);
                break;
            case ur::UniformType::Float2:
                uniform->SetValue(f4, 2);
                break;
            case ur::UniformType::Float3:
                uniform->SetValue(f4, 3);
                break;
            case ur::UniformType::Float4:
                uniform->SetValue(f4, 4);
                break;
            default:
                assert(0);
            }
        }
            break;
        default:
            assert(0);
        }
    }
}

}<|endoftext|>


<commit_before>#include <string>

#include "pixelboost/maths/boundingBox.h"

#include "command/standard/modifyDepth.h"
#include "core/uidHelpers.h"
#include "project/entity.h"
#include "project/project.h"
#include "project/record.h"
#include "project/schema.h"
#include "view/entity/entity.h"
#include "view/level.h"
#include "core.h"
#include "view.h"

using namespace pixeleditor;

Command* ModifyDepthCommand::Create()
{
    return new ModifyDepthCommand();
}

std::string ModifyDepthCommand::GetStaticName()
{
    return "modifyDepth";
}

ModifyDepthCommand::ModifyDepthCommand()
{

}

ModifyDepthCommand::~ModifyDepthCommand()
{
}

std::string ModifyDepthCommand::GetName()
{
    return ModifyDepthCommand::GetStaticName();
}

bool ModifyDepthCommand::CanUndo()
{
    return false;
}

bool ModifyDepthCommand::Do(std::string& returnString)
{
    Core* core = Core::Instance();
    Level* level = View::Instance()->GetLevel();

    Selection& selection = core->GetSelection();

    pb::BoundingBox selectionBounds;

    const Selection::Entities& entities = selection.GetSelection();

    float selectionMin = +INFINITY;
    float selectionMax = -INFINITY;

    for (Selection::Entities::const_iterator it = entities.begin(); it != entities.end(); ++it)
    {
        ViewEntity* entity = level->GetEntityById(it->first);
        selectionBounds.Expand(entity->GetBoundingBox());

        selectionMin = glm::min(selectionMin, entity->GetPosition().z);
        selectionMax = glm::max(selectionMax, entity->GetPosition().z);
    }

    float offset = 0.f;
    bool modify = false;
    float otherMin = +INFINITY;
    float otherMax = -INFINITY;

    Level::EntityList boundsEntities = level->GetEntitiesInBounds(selectionBounds);

    for (Level::EntityList::iterator it = boundsEntities.begin(); it != boundsEntities.end(); ++it)
    {
        ViewEntity* entity = *it;
        if (!selection.IsSelected(GenerateSelectionUid((*it)->GetUid())))
        {
            modify = true;
            otherMin = glm::min(otherMin, entity->GetPosition().z);
            otherMax = glm::max(otherMax, entity->GetPosition().z);
        }
    }

    if (IsArgumentSet("f"))
    {
        offset = (otherMax + 1.f) - selectionMax;
    } else if (IsArgumentSet("b"))
    {
        offset = (otherMin - 1.f) - selectionMin;
    }

    if (modify && offset != 0.f)
    {
        for (Selection::Entities::const_iterator it = entities.begin(); it != entities.end(); ++it)
        {
            ViewEntity* entity = level->GetEntityById(it->first);
            entity->Transform(glm::vec3(0,0,offset));
            entity->CommitTransform();
        }
    }

    return true;
}
<commit_msg>Fix modify depth not working with multiple entities in selection<commit_after>#include <string>

#include "pixelboost/maths/boundingBox.h"

#include "command/standard/modifyDepth.h"
#include "core/uidHelpers.h"
#include "project/entity.h"
#include "project/project.h"
#include "project/record.h"
#include "project/schema.h"
#include "view/entity/entity.h"
#include "view/level.h"
#include "core.h"
#include "view.h"

using namespace pixeleditor;

Command* ModifyDepthCommand::Create()
{
    return new ModifyDepthCommand();
}

std::string ModifyDepthCommand::GetStaticName()
{
    return "modifyDepth";
}

ModifyDepthCommand::ModifyDepthCommand()
{

}

ModifyDepthCommand::~ModifyDepthCommand()
{
}

std::string ModifyDepthCommand::GetName()
{
    return ModifyDepthCommand::GetStaticName();
}

bool ModifyDepthCommand::CanUndo()
{
    return false;
}

bool ModifyDepthCommand::Do(std::string& returnString)
{
    Core* core = Core::Instance();
    Level* level = View::Instance()->GetLevel();

    Selection& selection = core->GetSelection();

    pb::BoundingBox selectionBounds;

    const Selection::Entities& entities = selection.GetSelection();

    float selectionMin = +INFINITY;
    float selectionMax = -INFINITY;

    for (Selection::Entities::const_iterator it = entities.begin(); it != entities.end(); ++it)
    {
        ViewEntity* entity = level->GetEntityById(it->first);
        selectionBounds.Expand(entity->GetBoundingBox());

        selectionMin = glm::min(selectionMin, entity->GetPosition().z);
        selectionMax = glm::max(selectionMax, entity->GetPosition().z);
    }

    float offset = 0.f;
    bool modify = false;
    float otherMin = +INFINITY;
    float otherMax = -INFINITY;

    Level::EntityList boundsEntities = level->GetEntitiesInBounds(selectionBounds);

    for (Level::EntityList::iterator it = boundsEntities.begin(); it != boundsEntities.end(); ++it)
    {
        ViewEntity* entity = *it;
        if (!selection.IsSelected(GenerateSelectionUid(entity->GetUid())))
        {
            modify = true;
            otherMin = glm::min(otherMin, entity->GetPosition().z);
            otherMax = glm::max(otherMax, entity->GetPosition().z);
        }
    }

    if (IsArgumentSet("f"))
    {
        offset = (otherMax + 1.f) - selectionMin;
    } else if (IsArgumentSet("b"))
    {
        offset = (otherMin - 1.f) - selectionMax;
    }

    if (modify && offset != 0.f)
    {
        for (Selection::Entities::const_iterator it = entities.begin(); it != entities.end(); ++it)
        {
            ViewEntity* entity = level->GetEntityById(it->first);
            entity->Transform(glm::vec3(0,0,offset));
            entity->CommitTransform();
        }
    }

    return true;
}
<|endoftext|>


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

#include "base/debug.h"

#include "build/build_config.h"

#if defined(OS_WIN)
#include <Windows.h>
#endif

namespace base {

bool isDebuggerPresent()
{
#if defined(OS_WIN)
    return !!IsDebuggerPresent();
#else
#warning Platform support not implemented
    return false;
#endif
}

void debugPrint(const char* str)
{
#if defined(OS_WIN)
    OutputDebugStringA(str);
#else
#warning Platform support not implemented
#endif
}

void debugBreak()
{
#if defined(ARCH_CPU_X86_FAMILY)

#if defined(CC_MSVC)
    __debugbreak();
#elif defined(CC_GCC)
    __asm__("int3");
#elif defined(CC_CLANG)

#if defined(OS_WIN)
    { __asm int 3 };
#else
    __asm__("int3");
#endif // OS_WIN

#else // CC_*
#define Compiller support not implemented
#endif // CC_*

#else // ARCH_CPU_*
#error CPU family support not implemented
#endif // ARCH_CPU_*
}

} // namespace base
<commit_msg>Implement debugBreak function for arm/arm64.<commit_after>//
// Aspia Project
// Copyright (C) 2020 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "base/debug.h"

#include "build/build_config.h"

#if defined(OS_WIN)
#include <Windows.h>
#endif

namespace base {

bool isDebuggerPresent()
{
#if defined(OS_WIN)
    return !!IsDebuggerPresent();
#else
#warning Platform support not implemented
    return false;
#endif
}

void debugPrint(const char* str)
{
#if defined(OS_WIN)
    OutputDebugStringA(str);
#else
#warning Platform support not implemented
#endif
}

void debugBreak()
{
#if defined(ARCH_CPU_X86_FAMILY)

#if defined(CC_MSVC)
    __debugbreak();
#elif defined(CC_GCC)
    __asm__("int3");
#elif defined(CC_CLANG)

#if defined(OS_WIN)
    { __asm int 3 };
#else
    __asm__("int3");
#endif // OS_WIN

#else // CC_*
#define Compiller support not implemented
#endif // CC_*

#elif defined(ARCH_CPU_ARM64)
    asm("brk 0");
#elif defined(ARCH_CPU_ARMEL)
    asm("break 2");
#else // ARCH_CPU_*
#error CPU family support not implemented
#endif // ARCH_CPU_*
}

} // namespace base
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** 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, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qcontactmanager.h"
#include "qcontactmanager_p.h"
#include "qcontactmanagerengine.h"
#include "qcontactmanagerenginefactory.h"

#include "qcontact_p.h"

#include "qcontactaction.h"
#include "qcontactactiondescriptor.h"
#include "qcontactactionfactory.h"

#include <QSharedData>
#include <QtPlugin>
#include <QPluginLoader>

#include <QDebug>
#include <QDir>

#include <QApplication>

#include "qcontactmemorybackend_p.h"
#include "qcontactinvalidbackend_p.h"

QTM_BEGIN_NAMESPACE

/* Shared QContactManager stuff here, default engine stuff below */
QList<QContactActionFactory*> QContactManagerData::m_actionfactories; // list of all factories
QList<QContactActionDescriptor> QContactManagerData::m_descriptors;
QHash<QString, QContactManagerEngineFactory*> QContactManagerData::m_engines;
QContactManagerData::DescriptorHash QContactManagerData::m_descriptormap;
QHash<QString, int> QContactManagerData::m_vendormap;
QHash<QString, int> QContactManagerData::m_actionmap;

bool QContactManagerData::m_discovered;
bool QContactManagerData::m_discoveredStatic;
QStringList QContactManagerData::m_pluginPaths;

static void qContactsCleanEngines()
{
    QContactManagerData::m_discovered = false;
    QList<QContactManagerEngineFactory*> factories = QContactManagerData::m_engines.values();
    QList<QContactActionFactory*> actionfactories = QContactManagerData::m_actionfactories;

    for (int i=0; i < factories.count(); i++) {
        delete factories.at(i);
    }
    for(int i=0; i < actionfactories.count(); i++) {
        delete actionfactories.at(i);
    }
    QContactManagerData::m_engines.clear();
    QContactManagerData::m_actionfactories.clear();
    QContactManagerData::m_descriptors.clear();
    QContactManagerData::m_descriptormap.clear();
    QContactManagerData::m_actionmap.clear();
    QContactManagerData::m_vendormap.clear();
}

static int parameterValue(const QMap<QString, QString>& parameters, const char* key, int defaultValue)
{
    if (parameters.contains(QString::fromAscii(key))) {
        bool ok;
        int version = parameters.value(QString::fromAscii(key)).toInt(&ok);

        if (ok)
            return version;
    }
    return defaultValue;
}

void QContactManagerData::createEngine(const QString& managerName, const QMap<QString, QString>& parameters)
{
    int apiVersion = parameterValue(parameters, QTCONTACTS_VERSION_NAME, QContactManager::version());
    m_engine = 0;

    if (apiVersion != QContactManager::version()) {
        m_error = QContactManager::VersionMismatchError;
        m_engine = new QContactInvalidEngine(); // XXX share
        return;
    }

    QString builtManagerName = managerName.isEmpty() ? QContactManager::availableManagers().value(0) : managerName;
    if (builtManagerName == QLatin1String("memory")) {
        m_engine = QContactMemoryEngine::createMemoryEngine(parameters);
    } else {
        int implementationVersion = parameterValue(parameters, QTCONTACTS_IMPLEMENTATION_VERSION_NAME, -1);

        bool found = false;
        bool loadedDynamic = false;

        /* First check static factories */
        loadStaticFactories();

        /* See if we got a fast hit */
        QList<QContactManagerEngineFactory*> factories = m_engines.values(builtManagerName);
        m_error = QContactManager::NoError;

        while(!found) {
            foreach (QContactManagerEngineFactory* f, factories) {
                QList<int> versions = f->supportedImplementationVersions();
                if (f && f->version() == apiVersion) {
                    if (implementationVersion == -1 //no given implementation version required
                        || versions.isEmpty() //the manager engine factory does not report any version
                        || versions.contains(implementationVersion)) {
                        m_engine = f->engine(parameters, m_error);
                        found = true;
                        break;
                    }
                }
            }

            // If this is the second time through, break
            if (loadedDynamic)
                break;

            // otherwise load dynamic factories and reloop
            loadFactories();
            factories = m_engines.values(builtManagerName);
            loadedDynamic = true;
        }

        // XXX remove this
        // the engine factory could lie to us, so check the real implementation version
        if (m_engine && (m_engine->version() != apiVersion || (implementationVersion != -1 && m_engine->implementationVersion() != implementationVersion))) {
            m_error = QContactManager::VersionMismatchError;
            m_engine = 0;
        }

        if (!m_engine) {
            if (m_error == QContactManager::NoError)
                m_error = QContactManager::DoesNotExistError;
            m_engine = new QContactInvalidEngine(); // XXX share
        }
    }
}

void QContactManagerData::loadStaticFactories()
{
    if (!m_discoveredStatic) {
        m_discoveredStatic = true;

        /* Clean stuff up at the end */
        qAddPostRoutine(qContactsCleanEngines);

        /* Loop over all the static plugins */
        QObjectList staticPlugins = QPluginLoader::staticInstances();
        for (int i=0; i < staticPlugins.count(); i++ ){
            QContactManagerEngineFactory *f = qobject_cast<QContactManagerEngineFactory*>(staticPlugins.at(i));
            QContactActionFactory *g = qobject_cast<QContactActionFactory*>(staticPlugins.at(i));
            if (f && f->version() == QContactManager::version()) {
                QString name = f->managerName();
                qDebug() << "Static: found an engine plugin" << f << "with name" << name;
                if (name != QLatin1String("memory") && name != QLatin1String("invalid") && !name.isEmpty()) {
                    // we also need to ensure that we haven't already loaded this factory.
                    if (m_engines.keys().contains(name)) {
                        qWarning() << "Static contacts plugin" << name << "has the same name as a currently loaded plugin; ignored";
                    } else {
                        m_engines.insertMulti(name, f);
                    }
                } else {
                    qWarning() << "Static contacts plugin with reserved name" << name << "ignored";
                }
            }

            if (g) {
                QString name = g->name();
                qDebug() << "Static: found an action factory" << g << "with name" << name;

                if (m_actionfactories.contains(g)) {
                    qWarning() << "Static contacts plugin" << name << "has the same name as currently loaded plugin; ignored";
                } else {
                    m_actionfactories.append(g);

                    QList<QContactActionDescriptor> actions = g->actionDescriptors();
                    QMap<QContactActionDescriptor, QContactActionFactory*>::iterator it;
                    for (int j = 0; j < actions.size(); j++) {
                        QContactActionDescriptor desc = actions.at(j);
                        m_descriptormap.insert(desc, g);
                        m_descriptors.append(desc);
                        m_actionmap.insertMulti(desc.actionName(), m_descriptors.count() - 1);
                        m_vendormap.insertMulti(desc.vendorName(), m_descriptors.count() - 1);
                    }
                }
            }
        }
    }
}

/* Plugin loader */
void QContactManagerData::loadFactories()
{
    // Always do this..
    loadStaticFactories();

    if (!m_discovered || QApplication::libraryPaths() != m_pluginPaths) {
        m_discovered = true;
        m_pluginPaths = QApplication::libraryPaths();

        /* Discover a bunch o plugins */
        QStringList plugins;

        QStringList paths;
        QSet<QString> processed;

        paths << QApplication::applicationDirPath() << QApplication::libraryPaths();
        qDebug() << "Plugin paths:" << paths;

        /* Enumerate our plugin paths */
        for (int i=0; i < paths.count(); i++) {
            if (processed.contains(paths.at(i)))
                continue;
            processed.insert(paths.at(i));
            QDir pluginsDir(paths.at(i));
#if defined(Q_OS_WIN)
             if (pluginsDir.dirName().toLower() == QLatin1String("debug") || pluginsDir.dirName().toLower() == QLatin1String("release"))
                 pluginsDir.cdUp();
#elif defined(Q_OS_MAC)
             if (pluginsDir.dirName() == QLatin1String("MacOS")) {
                 pluginsDir.cdUp();
                 pluginsDir.cdUp();
                 pluginsDir.cdUp();
             }
#endif
            if (pluginsDir.cd(QLatin1String("plugins/contacts")) || pluginsDir.cd(QLatin1String("contacts")) || (pluginsDir.cdUp() && pluginsDir.cd(QLatin1String("plugins/contacts")))) {
                const QStringList& files = pluginsDir.entryList(QDir::Files);
                qDebug() << "Looking for plugins in" << pluginsDir.path() << files;
                for (int j=0; j < files.count(); j++) {
                    plugins << pluginsDir.absoluteFilePath(files.at(j));
                }
            }
        }

        /* Now discover the dynamic plugins */
        for (int i=0; i < plugins.count(); i++) {
            QPluginLoader qpl(plugins.at(i));
            QContactManagerEngineFactory *f = qobject_cast<QContactManagerEngineFactory*>(qpl.instance());
            QContactActionFactory *g = qobject_cast<QContactActionFactory*>(qpl.instance());

            if (f) {
                QString name = f->managerName();
                qDebug() << "Dynamic: found an engine plugin" << f << "with name" << name;

                if (name != QLatin1String("memory") && name != QLatin1String("invalid") && !name.isEmpty()) {
                    // we also need to ensure that we haven't already loaded this factory.
                    if (m_engines.keys().contains(name)) {
                        qWarning() << "Contacts plugin" << plugins.at(i) << "has the same name as currently loaded plugin" << name << "; ignored";
                    } else {
                        m_engines.insertMulti(name, f);
                    }
                } else {
                    qWarning() << "Contacts plugin" << plugins.at(i) << "with reserved name" << name << "ignored";
                }
            }

            if (g) {
                QString name = g->name();
                qDebug() << "Dynamic: found an action factory" << g << "with name" << name;

                // we also need to ensure that we haven't already loaded this factory.
                if (m_actionfactories.contains(g)) {
                    qWarning() << "Contacts plugin" << plugins.at(i) << "has the same name as currently loaded plugin" << name << "; ignored";
                } else {
                    m_actionfactories.append(g);

                    QList<QContactActionDescriptor> actions = g->actionDescriptors();
                    QMap<QContactActionDescriptor, QContactActionFactory*>::iterator it;
                    for (int j = 0; j < actions.size(); j++) {
                        const QContactActionDescriptor& desc = actions.at(j);
                        m_descriptormap.insert(desc, g);
                        m_descriptors.append(desc);
                        m_actionmap.insertMulti(desc.actionName(), m_descriptors.count() - 1);
                        m_vendormap.insertMulti(desc.vendorName(), m_descriptors.count() - 1);
                    }
                }
            }

            /* Debugging */
            if (!f && !g) {
                qDebug() << "Unknown plugin:" << qpl.errorString();
                if (qpl.instance()) {
                    qDebug() << "[qobject:" << qpl.instance() << "]";
                }
            }
        }

        QStringList engineNames;
        foreach (QContactManagerEngineFactory* f, m_engines.values()) {
            QStringList versions;
            foreach (int v, f->supportedImplementationVersions()) {
                versions << QString::fromAscii("%1.%2").arg(f->version()).arg(v);
            }
            engineNames << QString::fromAscii("%1[%2]").arg(f->managerName()).arg(versions.join(QString::fromAscii(",")));
        }
        qDebug() << "Found engines:" << engineNames;
        qDebug() << "Found actions:" << m_actionmap.keys();
    }
}

QList<QContactActionDescriptor> QContactManagerData::actionDescriptors(const QString& actionName, const QString& vendorName, int implementationVersion)
{
    loadFactories();

    bool restrict = false;
    QSet<int> subset;
    QList<QContactActionDescriptor> descriptors;

    // Go through our list of descriptors, looking for a match
    if (!actionName.isEmpty()) {
        subset = m_actionmap.values(actionName).toSet();
        restrict = true;
    }

    if (!vendorName.isEmpty()) {
        if (restrict)
            subset &= m_vendormap.values(vendorName).toSet();
        else
            subset = m_vendormap.values(vendorName).toSet();
        restrict = true;

        /* We still have to check versions, since we don't hash that */
        if (implementationVersion != -1) {
            QMutableSetIterator<int> it(subset);
            while(it.hasNext()) {
                if (m_descriptors.at(it.next()).implementationVersion() != implementationVersion)
                    it.remove();
            }
        }
    }

    if (restrict) {
        QSetIterator<int> it(subset);
        while(it.hasNext()) {
            descriptors << m_descriptors.at(it.next());
        }
    } else {
        /* No restrictions, just iterate over all descriptors and return all actions (!) */
        descriptors = m_descriptors;
    }

    return descriptors;
}

QContactAction* QContactManagerData::action(const QContactActionDescriptor& actionDescriptor)
{
    loadFactories();
    QContactActionFactory* actionFactory = m_descriptormap.value(actionDescriptor, 0);
    if (actionFactory)
        return actionFactory->instance(actionDescriptor);
    return 0;
}

// trampoline for private classes
QContactManagerEngine* QContactManagerData::engine(const QContactManager* manager)
{
    if (manager)
        return manager->d->m_engine;
    return 0;
}

QTM_END_NAMESPACE

<commit_msg>Added comment pinpointing Symbian AllFiles-platsec warning, and some pointers for solution ideas. Platsec warning in this case does not cause functional harm, but is rather 'ugly' and confusing.<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** 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, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qcontactmanager.h"
#include "qcontactmanager_p.h"
#include "qcontactmanagerengine.h"
#include "qcontactmanagerenginefactory.h"

#include "qcontact_p.h"

#include "qcontactaction.h"
#include "qcontactactiondescriptor.h"
#include "qcontactactionfactory.h"

#include <QSharedData>
#include <QtPlugin>
#include <QPluginLoader>

#include <QDebug>
#include <QDir>

#include <QApplication>

#include "qcontactmemorybackend_p.h"
#include "qcontactinvalidbackend_p.h"

QTM_BEGIN_NAMESPACE

/* Shared QContactManager stuff here, default engine stuff below */
QList<QContactActionFactory*> QContactManagerData::m_actionfactories; // list of all factories
QList<QContactActionDescriptor> QContactManagerData::m_descriptors;
QHash<QString, QContactManagerEngineFactory*> QContactManagerData::m_engines;
QContactManagerData::DescriptorHash QContactManagerData::m_descriptormap;
QHash<QString, int> QContactManagerData::m_vendormap;
QHash<QString, int> QContactManagerData::m_actionmap;

bool QContactManagerData::m_discovered;
bool QContactManagerData::m_discoveredStatic;
QStringList QContactManagerData::m_pluginPaths;

static void qContactsCleanEngines()
{
    QContactManagerData::m_discovered = false;
    QList<QContactManagerEngineFactory*> factories = QContactManagerData::m_engines.values();
    QList<QContactActionFactory*> actionfactories = QContactManagerData::m_actionfactories;

    for (int i=0; i < factories.count(); i++) {
        delete factories.at(i);
    }
    for(int i=0; i < actionfactories.count(); i++) {
        delete actionfactories.at(i);
    }
    QContactManagerData::m_engines.clear();
    QContactManagerData::m_actionfactories.clear();
    QContactManagerData::m_descriptors.clear();
    QContactManagerData::m_descriptormap.clear();
    QContactManagerData::m_actionmap.clear();
    QContactManagerData::m_vendormap.clear();
}

static int parameterValue(const QMap<QString, QString>& parameters, const char* key, int defaultValue)
{
    if (parameters.contains(QString::fromAscii(key))) {
        bool ok;
        int version = parameters.value(QString::fromAscii(key)).toInt(&ok);

        if (ok)
            return version;
    }
    return defaultValue;
}

void QContactManagerData::createEngine(const QString& managerName, const QMap<QString, QString>& parameters)
{
    int apiVersion = parameterValue(parameters, QTCONTACTS_VERSION_NAME, QContactManager::version());
    m_engine = 0;

    if (apiVersion != QContactManager::version()) {
        m_error = QContactManager::VersionMismatchError;
        m_engine = new QContactInvalidEngine(); // XXX share
        return;
    }

    QString builtManagerName = managerName.isEmpty() ? QContactManager::availableManagers().value(0) : managerName;
    if (builtManagerName == QLatin1String("memory")) {
        m_engine = QContactMemoryEngine::createMemoryEngine(parameters);
    } else {
        int implementationVersion = parameterValue(parameters, QTCONTACTS_IMPLEMENTATION_VERSION_NAME, -1);

        bool found = false;
        bool loadedDynamic = false;

        /* First check static factories */
        loadStaticFactories();

        /* See if we got a fast hit */
        QList<QContactManagerEngineFactory*> factories = m_engines.values(builtManagerName);
        m_error = QContactManager::NoError;

        while(!found) {
            foreach (QContactManagerEngineFactory* f, factories) {
                QList<int> versions = f->supportedImplementationVersions();
                if (f && f->version() == apiVersion) {
                    if (implementationVersion == -1 //no given implementation version required
                        || versions.isEmpty() //the manager engine factory does not report any version
                        || versions.contains(implementationVersion)) {
                        m_engine = f->engine(parameters, m_error);
                        found = true;
                        break;
                    }
                }
            }

            // If this is the second time through, break
            if (loadedDynamic)
                break;

            // otherwise load dynamic factories and reloop
            loadFactories();
            factories = m_engines.values(builtManagerName);
            loadedDynamic = true;
        }

        // XXX remove this
        // the engine factory could lie to us, so check the real implementation version
        if (m_engine && (m_engine->version() != apiVersion || (implementationVersion != -1 && m_engine->implementationVersion() != implementationVersion))) {
            m_error = QContactManager::VersionMismatchError;
            m_engine = 0;
        }

        if (!m_engine) {
            if (m_error == QContactManager::NoError)
                m_error = QContactManager::DoesNotExistError;
            m_engine = new QContactInvalidEngine(); // XXX share
        }
    }
}

void QContactManagerData::loadStaticFactories()
{
    if (!m_discoveredStatic) {
        m_discoveredStatic = true;

        /* Clean stuff up at the end */
        qAddPostRoutine(qContactsCleanEngines);

        /* Loop over all the static plugins */
        QObjectList staticPlugins = QPluginLoader::staticInstances();
        for (int i=0; i < staticPlugins.count(); i++ ){
            QContactManagerEngineFactory *f = qobject_cast<QContactManagerEngineFactory*>(staticPlugins.at(i));
            QContactActionFactory *g = qobject_cast<QContactActionFactory*>(staticPlugins.at(i));
            if (f && f->version() == QContactManager::version()) {
                QString name = f->managerName();
                qDebug() << "Static: found an engine plugin" << f << "with name" << name;
                if (name != QLatin1String("memory") && name != QLatin1String("invalid") && !name.isEmpty()) {
                    // we also need to ensure that we haven't already loaded this factory.
                    if (m_engines.keys().contains(name)) {
                        qWarning() << "Static contacts plugin" << name << "has the same name as a currently loaded plugin; ignored";
                    } else {
                        m_engines.insertMulti(name, f);
                    }
                } else {
                    qWarning() << "Static contacts plugin with reserved name" << name << "ignored";
                }
            }

            if (g) {
                QString name = g->name();
                qDebug() << "Static: found an action factory" << g << "with name" << name;

                if (m_actionfactories.contains(g)) {
                    qWarning() << "Static contacts plugin" << name << "has the same name as currently loaded plugin; ignored";
                } else {
                    m_actionfactories.append(g);

                    QList<QContactActionDescriptor> actions = g->actionDescriptors();
                    QMap<QContactActionDescriptor, QContactActionFactory*>::iterator it;
                    for (int j = 0; j < actions.size(); j++) {
                        QContactActionDescriptor desc = actions.at(j);
                        m_descriptormap.insert(desc, g);
                        m_descriptors.append(desc);
                        m_actionmap.insertMulti(desc.actionName(), m_descriptors.count() - 1);
                        m_vendormap.insertMulti(desc.vendorName(), m_descriptors.count() - 1);
                    }
                }
            }
        }
    }
}

/* Plugin loader */
void QContactManagerData::loadFactories()
{
    // Always do this..
    loadStaticFactories();

    if (!m_discovered || QApplication::libraryPaths() != m_pluginPaths) {
        m_discovered = true;
        m_pluginPaths = QApplication::libraryPaths();

        /* Discover a bunch o plugins */
        QStringList plugins;

        QStringList paths;
        QSet<QString> processed;

        paths << QApplication::applicationDirPath() << QApplication::libraryPaths();
        qDebug() << "Plugin paths:" << paths;

        /* Enumerate our plugin paths */
        for (int i=0; i < paths.count(); i++) {
            if (processed.contains(paths.at(i)))
                continue;
            processed.insert(paths.at(i));
            QDir pluginsDir(paths.at(i));
#if defined(Q_OS_WIN)
             if (pluginsDir.dirName().toLower() == QLatin1String("debug") || pluginsDir.dirName().toLower() == QLatin1String("release"))
                 pluginsDir.cdUp();
#elif defined(Q_OS_MAC)
             if (pluginsDir.dirName() == QLatin1String("MacOS")) {
                 pluginsDir.cdUp();
                 pluginsDir.cdUp();
                 pluginsDir.cdUp();
             }
#endif
             // In Symbian, going cdUp() in a c:/private/<uid3>/ will result in *platsec* error at fileserver (requires AllFiles capability)
             // Also, trying to cd() to a nonexistent directory causes *platsec* error. This does not cause functional harm, but should
             // nevertheless be changed to use native Symbian methods to avoid unnecessary platsec warnings. See for example: qpluginloader.cpp::setFileName() for solution ideas.
             // Alternatively, this whole changing directory thing should be altered (see for example Qtmultimedia's plugin loading)
             if (pluginsDir.cd(QLatin1String("plugins/contacts")) || pluginsDir.cd(QLatin1String("contacts")) || (pluginsDir.cdUp() && pluginsDir.cd(QLatin1String("plugins/contacts")))) {
                const QStringList& files = pluginsDir.entryList(QDir::Files);
                qDebug() << "Looking for plugins in" << pluginsDir.path() << files;
                for (int j=0; j < files.count(); j++) {
                    plugins << pluginsDir.absoluteFilePath(files.at(j));
                }
            }
        }

        /* Now discover the dynamic plugins */
        for (int i=0; i < plugins.count(); i++) {
            QPluginLoader qpl(plugins.at(i));
            QContactManagerEngineFactory *f = qobject_cast<QContactManagerEngineFactory*>(qpl.instance());
            QContactActionFactory *g = qobject_cast<QContactActionFactory*>(qpl.instance());

            if (f) {
                QString name = f->managerName();
                qDebug() << "Dynamic: found an engine plugin" << f << "with name" << name;

                if (name != QLatin1String("memory") && name != QLatin1String("invalid") && !name.isEmpty()) {
                    // we also need to ensure that we haven't already loaded this factory.
                    if (m_engines.keys().contains(name)) {
                        qWarning() << "Contacts plugin" << plugins.at(i) << "has the same name as currently loaded plugin" << name << "; ignored";
                    } else {
                        m_engines.insertMulti(name, f);
                    }
                } else {
                    qWarning() << "Contacts plugin" << plugins.at(i) << "with reserved name" << name << "ignored";
                }
            }

            if (g) {
                QString name = g->name();
                qDebug() << "Dynamic: found an action factory" << g << "with name" << name;

                // we also need to ensure that we haven't already loaded this factory.
                if (m_actionfactories.contains(g)) {
                    qWarning() << "Contacts plugin" << plugins.at(i) << "has the same name as currently loaded plugin" << name << "; ignored";
                } else {
                    m_actionfactories.append(g);

                    QList<QContactActionDescriptor> actions = g->actionDescriptors();
                    QMap<QContactActionDescriptor, QContactActionFactory*>::iterator it;
                    for (int j = 0; j < actions.size(); j++) {
                        const QContactActionDescriptor& desc = actions.at(j);
                        m_descriptormap.insert(desc, g);
                        m_descriptors.append(desc);
                        m_actionmap.insertMulti(desc.actionName(), m_descriptors.count() - 1);
                        m_vendormap.insertMulti(desc.vendorName(), m_descriptors.count() - 1);
                    }
                }
            }

            /* Debugging */
            if (!f && !g) {
                qDebug() << "Unknown plugin:" << qpl.errorString();
                if (qpl.instance()) {
                    qDebug() << "[qobject:" << qpl.instance() << "]";
                }
            }
        }

        QStringList engineNames;
        foreach (QContactManagerEngineFactory* f, m_engines.values()) {
            QStringList versions;
            foreach (int v, f->supportedImplementationVersions()) {
                versions << QString::fromAscii("%1.%2").arg(f->version()).arg(v);
            }
            engineNames << QString::fromAscii("%1[%2]").arg(f->managerName()).arg(versions.join(QString::fromAscii(",")));
        }
        qDebug() << "Found engines:" << engineNames;
        qDebug() << "Found actions:" << m_actionmap.keys();
    }
}

QList<QContactActionDescriptor> QContactManagerData::actionDescriptors(const QString& actionName, const QString& vendorName, int implementationVersion)
{
    loadFactories();

    bool restrict = false;
    QSet<int> subset;
    QList<QContactActionDescriptor> descriptors;

    // Go through our list of descriptors, looking for a match
    if (!actionName.isEmpty()) {
        subset = m_actionmap.values(actionName).toSet();
        restrict = true;
    }

    if (!vendorName.isEmpty()) {
        if (restrict)
            subset &= m_vendormap.values(vendorName).toSet();
        else
            subset = m_vendormap.values(vendorName).toSet();
        restrict = true;

        /* We still have to check versions, since we don't hash that */
        if (implementationVersion != -1) {
            QMutableSetIterator<int> it(subset);
            while(it.hasNext()) {
                if (m_descriptors.at(it.next()).implementationVersion() != implementationVersion)
                    it.remove();
            }
        }
    }

    if (restrict) {
        QSetIterator<int> it(subset);
        while(it.hasNext()) {
            descriptors << m_descriptors.at(it.next());
        }
    } else {
        /* No restrictions, just iterate over all descriptors and return all actions (!) */
        descriptors = m_descriptors;
    }

    return descriptors;
}

QContactAction* QContactManagerData::action(const QContactActionDescriptor& actionDescriptor)
{
    loadFactories();
    QContactActionFactory* actionFactory = m_descriptormap.value(actionDescriptor, 0);
    if (actionFactory)
        return actionFactory->instance(actionDescriptor);
    return 0;
}

// trampoline for private classes
QContactManagerEngine* QContactManagerData::engine(const QContactManager* manager)
{
    if (manager)
        return manager->d->m_engine;
    return 0;
}

QTM_END_NAMESPACE

<|endoftext|>


<commit_before>// --------------------------------------------------------------------------
#include <cmath>
#include <iomanip>
#include <algorithm>
#include <iostream>
#include "UniSetTypes.h"
#include "DigitalFilter.h"
//--------------------------------------------------------------------------
using namespace UniSetTypes;
using namespace std;
//--------------------------------------------------------------------------
DigitalFilter::DigitalFilter( unsigned int bufsize, double T, double lsq,
	                          int iir_thr, double iir_coeff_prev,
	                          double iir_coeff_new ):
	Ti(T),
	val(0),
	M(0),
	S(0),
	tmr(UniSetTimer::WaitUpTime),
	maxsize(bufsize),
	mvec(bufsize),
	w(bufsize),
	lsparam(lsq),
	ls(0),
	thr(iir_thr),
	prev(0),
	coeff_prev(iir_coeff_prev),
	coeff_new(iir_coeff_new)
{
}
//--------------------------------------------------------------------------
DigitalFilter::~DigitalFilter()
{
}
//--------------------------------------------------------------------------
void DigitalFilter::setSettings( unsigned int bufsize, double T, double lsq,
	                             int iir_thr, double iir_coeff_prev,
	                             double iir_coeff_new )
{
	Ti = T;
	maxsize = bufsize;
	if( maxsize < 1 )
		maxsize = 1;

	coeff_prev = iir_coeff_prev;
	coeff_new = iir_coeff_new;
	if( iir_thr > 0 )
		thr = iir_thr;

	if( buf.size() > maxsize )
	{
		// удаляем лишние (первые) элементы
		int sub = buf.size() - maxsize;
		for( int i=0; i<sub; i++ )
			buf.erase( buf.begin() );
	}

	if( w.size() != maxsize || lsq != lsparam )
		w.assign(maxsize, 1.0/maxsize);
	lsparam = lsq;
}
//--------------------------------------------------------------------------
void DigitalFilter::init( int val )
{
	buf.clear();
	for( unsigned int i=0; i<maxsize; i++ )
		buf.push_back(val);

	w.assign(maxsize, 1.0/maxsize);

	tmr.reset();
	this->val = val;
}
//--------------------------------------------------------------------------
double DigitalFilter::firstLevel()
{
	// считаем среднее арифметическое
	M=0;
	for( FIFOBuffer::iterator i=buf.begin(); i!=buf.end(); ++i )
		M = M + (*i);

	M = M/buf.size();

	// считаем среднеквадратичное отклонение
	S=0;
	double r=0;
	for( FIFOBuffer::iterator i=buf.begin(); i!=buf.end(); ++i )
	{
		r = M-(*i);
		S = S + r*r;
	}

	S = S/buf.size();
	S = sqrt(S);

	if( S == 0 )
		return M;

	// Находим среднее арифметическое без учета элементов, отклонение которых вдвое превышает среднеквадратичное
	int n = 0;
	double val = 0; // Конечное среднее значение
	for( FIFOBuffer::iterator i=buf.begin(); i!=buf.end(); ++i )
	{
		if( fabs(M-(*i)) > S*2 )
		{
			val = val + (*i);
			n = n + 1;
		}
	}

	if( n==0 )
		return M;

	return ( val / n );
}
//--------------------------------------------------------------------------
int DigitalFilter::filterRC( int rawval )
{
	if( Ti <= 0 )
		return rawval;

	return lroundf(secondLevel(rawval));
}
//--------------------------------------------------------------------------

double DigitalFilter::secondLevel( double rawval )
{
	if( Ti <= 0 )
		return rawval;

	// Измеряем время с прошлого вызова функции
	int dt = tmr.getCurrent();
	if( dt == 0 )
		return val;

	tmr.reset();

	// Сама формула RC фильтра
	val = (rawval + Ti*val/dt) / (Ti/dt + 1);

	return val;
}
//--------------------------------------------------------------------------
int DigitalFilter::filter1( int newval )
{
	if( maxsize < 1 )
		return newval;

	add(newval);
	return lroundf(firstLevel());
}
//--------------------------------------------------------------------------
void DigitalFilter::add( int newval )
{
	// помещаем очередное значение в буфер
	// удаляя при этом старое (FIFO)
	buf.push_back(newval);
	if( buf.size() > maxsize )
		buf.erase( buf.begin() );
}
//--------------------------------------------------------------------------
int DigitalFilter::current1()
{
	return lroundf(firstLevel());
}
//--------------------------------------------------------------------------
int DigitalFilter::currentRC()
{
	return lroundf(secondLevel(current1()));
}
//--------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& os, const DigitalFilter& d )
{
	os << "(" << d.buf.size() << ")[";
	for( DigitalFilter::FIFOBuffer::const_iterator i=d.buf.begin(); i!=d.buf.end(); ++i )
	{
		os << " " << setw(5) << (*i);
	}
	os << " ]";
	return os;
}
//--------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& os, const DigitalFilter* d)
{
	return os << (*d);
}
//--------------------------------------------------------------------------
int DigitalFilter::median( int newval )
{
	if( maxsize < 1 )
		return newval;

	add(newval);

	// ???????? ? ??????
	FIFOBuffer::iterator it = buf.begin();
	for( unsigned int i=0; i<maxsize && it!=buf.end(); i++,it++ )
		mvec[i] = (*it);

	// ????????? ??????
	sort(mvec.begin(),mvec.end());

	return mvec[maxsize/2];
}
//--------------------------------------------------------------------------
int DigitalFilter::currentMedian()
{
	return mvec[maxsize/2];
}
//--------------------------------------------------------------------------
int DigitalFilter::leastsqr( int newval )
{
	ls = 0;

	add(newval);

	// Цифровая фильтрация
	FIFOBuffer::const_iterator it = buf.begin();
	for( unsigned int i=0; i<maxsize; i++,it++ )
		ls += *it * w[i];

	// Вычисляем ошибку выхода
	double er = newval - ls;

	// Обновляем коэффициенты
	double u = 2 * (lsparam/maxsize) * er;
	it = buf.begin();
	for( unsigned int i=0; i<maxsize; i++,it++ )
		w[i] = w[i] + *it * u;

	return lroundf(ls);
}
//--------------------------------------------------------------------------
int DigitalFilter::currentLS()
{
	return lroundf(ls);
}
//--------------------------------------------------------------------------
int DigitalFilter::filterIIR( int newval )
{
	if( newval > prev + thr || newval < prev - thr || maxsize < 1 )
	{
		if( maxsize > 0 )
			init(newval);
		prev = newval;
	}
	else
	{
		double aver;

		add(newval);
		for( FIFOBuffer::iterator i = buf.begin(); i != buf.end(); ++i )
			aver += *i;
		aver /= maxsize;
		prev = lroundf((coeff_prev * prev + coeff_new * aver)/(coeff_prev + coeff_new));
	}
	return prev;
}
//--------------------------------------------------------------------------
int DigitalFilter::currentIIR()
{
	return prev;
}
//--------------------------------------------------------------------------
<commit_msg>Исправлена ошибка в DigitalFilter<commit_after>// --------------------------------------------------------------------------
#include <cmath>
#include <iomanip>
#include <algorithm>
#include <iostream>
#include "UniSetTypes.h"
#include "DigitalFilter.h"
//--------------------------------------------------------------------------
using namespace UniSetTypes;
using namespace std;
//--------------------------------------------------------------------------
DigitalFilter::DigitalFilter( unsigned int bufsize, double T, double lsq,
	                          int iir_thr, double iir_coeff_prev,
	                          double iir_coeff_new ):
	Ti(T),
	val(0),
	M(0),
	S(0),
	tmr(UniSetTimer::WaitUpTime),
	maxsize(bufsize),
	mvec(bufsize),
	w(bufsize),
	lsparam(lsq),
	ls(0),
	thr(iir_thr),
	prev(0),
	coeff_prev(iir_coeff_prev),
	coeff_new(iir_coeff_new)
{
}
//--------------------------------------------------------------------------
DigitalFilter::~DigitalFilter()
{
}
//--------------------------------------------------------------------------
void DigitalFilter::setSettings( unsigned int bufsize, double T, double lsq,
	                             int iir_thr, double iir_coeff_prev,
	                             double iir_coeff_new )
{
	Ti = T;
	maxsize = bufsize;
	if( maxsize < 1 )
		maxsize = 1;

	coeff_prev = iir_coeff_prev;
	coeff_new = iir_coeff_new;
	if( iir_thr > 0 )
		thr = iir_thr;

	if( buf.size() > maxsize )
	{
		// удаляем лишние (первые) элементы
		int sub = buf.size() - maxsize;
		for( int i=0; i<sub; i++ )
			buf.erase( buf.begin() );
	}

	if( w.size() != maxsize || lsq != lsparam )
		w.assign(maxsize, 1.0/maxsize);
	lsparam = lsq;

	mvec.resize(maxsize);
}
//--------------------------------------------------------------------------
void DigitalFilter::init( int val )
{
	buf.clear();
	for( unsigned int i=0; i<maxsize; i++ )
		buf.push_back(val);

	w.assign(maxsize, 1.0/maxsize);

	tmr.reset();
	this->val = val;
}
//--------------------------------------------------------------------------
double DigitalFilter::firstLevel()
{
	// считаем среднее арифметическое
	M=0;
	for( FIFOBuffer::iterator i=buf.begin(); i!=buf.end(); ++i )
		M = M + (*i);

	M = M/buf.size();

	// считаем среднеквадратичное отклонение
	S=0;
	double r=0;
	for( FIFOBuffer::iterator i=buf.begin(); i!=buf.end(); ++i )
	{
		r = M-(*i);
		S = S + r*r;
	}

	S = S/buf.size();
	S = sqrt(S);

	if( S == 0 )
		return M;

	// Находим среднее арифметическое без учета элементов, отклонение которых вдвое превышает среднеквадратичное
	int n = 0;
	double val = 0; // Конечное среднее значение
	for( FIFOBuffer::iterator i=buf.begin(); i!=buf.end(); ++i )
	{
		if( fabs(M-(*i)) > S*2 )
		{
			val = val + (*i);
			n = n + 1;
		}
	}

	if( n==0 )
		return M;

	return ( val / n );
}
//--------------------------------------------------------------------------
int DigitalFilter::filterRC( int rawval )
{
	if( Ti <= 0 )
		return rawval;

	return lroundf(secondLevel(rawval));
}
//--------------------------------------------------------------------------

double DigitalFilter::secondLevel( double rawval )
{
	if( Ti <= 0 )
		return rawval;

	// Измеряем время с прошлого вызова функции
	int dt = tmr.getCurrent();
	if( dt == 0 )
		return val;

	tmr.reset();

	// Сама формула RC фильтра
	val = (rawval + Ti*val/dt) / (Ti/dt + 1);

	return val;
}
//--------------------------------------------------------------------------
int DigitalFilter::filter1( int newval )
{
	if( maxsize < 1 )
		return newval;

	add(newval);
	return lroundf(firstLevel());
}
//--------------------------------------------------------------------------
void DigitalFilter::add( int newval )
{
	// помещаем очередное значение в буфер
	// удаляя при этом старое (FIFO)
	buf.push_back(newval);
	if( buf.size() > maxsize )
		buf.erase( buf.begin() );
}
//--------------------------------------------------------------------------
int DigitalFilter::current1()
{
	return lroundf(firstLevel());
}
//--------------------------------------------------------------------------
int DigitalFilter::currentRC()
{
	return lroundf(secondLevel(current1()));
}
//--------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& os, const DigitalFilter& d )
{
	os << "(" << d.buf.size() << ")[";
	for( DigitalFilter::FIFOBuffer::const_iterator i=d.buf.begin(); i!=d.buf.end(); ++i )
	{
		os << " " << setw(5) << (*i);
	}
	os << " ]";
	return os;
}
//--------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& os, const DigitalFilter* d)
{
	return os << (*d);
}
//--------------------------------------------------------------------------
int DigitalFilter::median( int newval )
{
	if( maxsize < 1 )
		return newval;

	add(newval);

	FIFOBuffer::iterator it = buf.begin();
	for( unsigned int i=0; i<maxsize && it!=buf.end(); i++,it++ )
		mvec[i] = (*it);

	sort(mvec.begin(),mvec.end());

	return mvec[maxsize/2];
}
//--------------------------------------------------------------------------
int DigitalFilter::currentMedian()
{
	return mvec[maxsize/2];
}
//--------------------------------------------------------------------------
int DigitalFilter::leastsqr( int newval )
{
	ls = 0;

	add(newval);

	// Цифровая фильтрация
	FIFOBuffer::const_iterator it = buf.begin();
	for( unsigned int i=0; i<maxsize; i++,it++ )
		ls += *it * w[i];

	// Вычисляем ошибку выхода
	double er = newval - ls;

	// Обновляем коэффициенты
	double u = 2 * (lsparam/maxsize) * er;
	it = buf.begin();
	for( unsigned int i=0; i<maxsize; i++,it++ )
		w[i] = w[i] + *it * u;

	return lroundf(ls);
}
//--------------------------------------------------------------------------
int DigitalFilter::currentLS()
{
	return lroundf(ls);
}
//--------------------------------------------------------------------------
int DigitalFilter::filterIIR( int newval )
{
	if( newval > prev + thr || newval < prev - thr || maxsize < 1 )
	{
		if( maxsize > 0 )
			init(newval);
		prev = newval;
	}
	else
	{
		double aver;

		add(newval);
		for( FIFOBuffer::iterator i = buf.begin(); i != buf.end(); ++i )
			aver += *i;
		aver /= maxsize;
		prev = lroundf((coeff_prev * prev + coeff_new * aver)/(coeff_prev + coeff_new));
	}
	return prev;
}
//--------------------------------------------------------------------------
int DigitalFilter::currentIIR()
{
	return prev;
}
//--------------------------------------------------------------------------
<|endoftext|>