<commit_before>/*************************************************************************
 *
 *  $RCSfile: MConnection.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: hjs $ $Date: 2004-06-25 18:27:40 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the License); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef CONNECTIVITY_SCONNECTION_HXX
#define CONNECTIVITY_SCONNECTION_HXX

#ifndef _CONNECTIVITY_MAB_COLUMNALIAS_HXX_
#include "MColumnAlias.hxx"
#endif
#ifndef _CONNECTIVITY_MAB_CATALOG_HXX_
#include "MCatalog.hxx"
#endif

#ifndef _COM_SUN_STAR_SDBC_SQLWARNING_HPP_
#include <com/sun/star/sdbc/SQLWarning.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _CONNECTIVITY_OSUBCOMPONENT_HXX_
#include "OSubComponent.hxx"
#endif
//  #include <map>
#ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#endif
#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
#include "connectivity/CommonTools.hxx"
#endif
#ifndef CONNECTIVITY_CONNECTION_HXX
#include "TConnection.hxx"
#endif
#ifndef _CPPUHELPER_WEAKREF_HXX_
#include <cppuhelper/weakref.hxx>
#endif

namespace connectivity
{
    namespace mozab
    {

        class OStatement_Base;
        class MozabDriver;
        class ODatabaseMetaData;
        class MNameMapper;

        namespace SDBCAddress {
            typedef enum {
                Unknown     = 0,
                LDAP        = 1,
                Outlook     = 2,
                Mozilla     = 3,
                OutlookExp  = 4
            } sdbc_address_type;
        }

        // For the moment, we will connect the Mozilla address book to the Mozilla
        // top-level address book which will display whatever is in the preferences
        // file of Mozilla.
        // This one is a base uri which will be completed with the connection data.
        static sal_Char*    MOZ_SCHEME_MOZILLA          = "moz-abdirectory://";
        // This one is for mozilla native address book
        static sal_Char*    MOZ_SCHEME_MOZILLA_MDB      = "moz-abmdbdirectory://";
        // This one is for LDAP address book
        static sal_Char*    MOZ_SCHEME_LDAP             = "moz-abldapdirectory://";
        // These two uris will be used to obtain directory factories to access all
        // address books of the given type.
        static sal_Char*    MOZ_SCHEME_OUTLOOK_MAPI     = "moz-aboutlookdirectory://op/";
        static sal_Char*    MOZ_SCHEME_OUTLOOK_EXPRESS  = "moz-aboutlookdirectory://oe/";

        typedef connectivity::OMetaConnection               OConnection_BASE; // implements basics and text encoding

        class OConnection : public OConnection_BASE,
                            public connectivity::OSubComponent<OConnection, OConnection_BASE>
        {
            friend class connectivity::OSubComponent<OConnection, OConnection_BASE>;

        protected:
            //====================================================================
            // Data attributes
            //====================================================================
            ::com::sun::star::uno::WeakReference< ::com::sun::star::sdbc::XDatabaseMetaData > m_xMetaData;

            connectivity::OWeakRefArray             m_aStatements;  //  vector containing a list
                                                        //  of all the Statement objects
                                                        //  for this Connection

            ::com::sun::star::sdbc::SQLWarning      m_aLastWarning; //      Last SQLWarning generated by
                                                        //  an operation
            ::rtl::OUString                         m_sUser;        // the user name
            MozabDriver*                            m_pDriver;      //  Pointer to the owning
                                                                    //  driver object
            // Store Catalog
            ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier>         m_xCatalog;
            // Start of Additions from the land of mozilla
            OColumnAlias    m_aColumnAlias;
            rtl::OUString   m_sMozillaURI;
            sal_Int32       m_nAnonABCount;
            sal_Int32       m_nMaxResultRecords;
            sal_Bool        m_bUseSSL;
            rtl::OUString   m_sBindDN;
            rtl::OUString   m_sPassword;
            rtl::OUString   m_sHostName;
            MNameMapper*    m_aNameMapper;

            SDBCAddress::sdbc_address_type  m_eSDBCAddressType;

            sal_Bool        m_bForceLoadTable;

        public:
            virtual void construct( const ::rtl::OUString& url,const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info) throw(::com::sun::star::sdbc::SQLException);
            OConnection(MozabDriver*    _pDriver);
            virtual ~OConnection();

            void closeAllStatements () throw( ::com::sun::star::sdbc::SQLException);

            // OComponentHelper
            virtual void SAL_CALL disposing(void);
            // XInterface
            virtual void SAL_CALL release() throw();

            // XServiceInfo
            DECLARE_SERVICE_INFO();
            // XConnection
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XStatement > SAL_CALL createStatement(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XPreparedStatement > SAL_CALL prepareStatement( const ::rtl::OUString& sql ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XPreparedStatement > SAL_CALL prepareCall( const ::rtl::OUString& sql ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::rtl::OUString SAL_CALL nativeSQL( const ::rtl::OUString& sql ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL setAutoCommit( sal_Bool autoCommit ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Bool SAL_CALL getAutoCommit(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL commit(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL rollback(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Bool SAL_CALL isClosed(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData > SAL_CALL getMetaData(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL setReadOnly( sal_Bool readOnly ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Bool SAL_CALL isReadOnly(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL setCatalog( const ::rtl::OUString& catalog ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::rtl::OUString SAL_CALL getCatalog(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL setTransactionIsolation( sal_Int32 level ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Int32 SAL_CALL getTransactionIsolation(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getTypeMap(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL setTypeMap( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& typeMap ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            // XCloseable
            virtual void SAL_CALL close(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            // XWarningsSupplier
            virtual ::com::sun::star::uno::Any SAL_CALL getWarnings(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL clearWarnings(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            //
            MozabDriver*    getDriver() const { return m_pDriver;}

            // Added to enable me to use SQLInterpreter which requires an
            // XNameAccess i/f to access tables.
            ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier > SAL_CALL createCatalog();

            // Additions from the land of mozilla
            rtl::OUString getMozURI() const
                { return m_sMozillaURI; }
            // Get Ldap BindDN (user name)
            rtl::OUString getBindDN() const { return m_sBindDN; }
            // Get Ldap Password
            rtl::OUString getPassword() const { return m_sPassword; }
            // Get Ldap Host name
            rtl::OUString getHost() const { return m_sHostName; }
            // Get whether use ssl to connect to ldap
            sal_Bool getUseSSL() const {return m_bUseSSL;}

            sal_Bool usesFactory(void) const { return (m_eSDBCAddressType == SDBCAddress::Outlook) || (m_eSDBCAddressType == SDBCAddress::OutlookExp); }
            sal_Bool isLDAP(void) const { return m_eSDBCAddressType == SDBCAddress::LDAP; }

            sal_Bool    isOutlookExpress() const { return m_eSDBCAddressType == SDBCAddress::OutlookExp;}
            sal_Int32   getNextAnonymousAB()    { return (++m_nAnonABCount); }
            sal_Int32   getMaxResultRecords() const { return m_nMaxResultRecords; }

            SDBCAddress::sdbc_address_type getSDBCAddressType() const { return m_eSDBCAddressType;}

            const OColumnAlias & getColumnAlias() const
                              { return (m_aColumnAlias); }

            static const sal_Char*    getSDBC_SCHEME_MOZILLA();
            static const sal_Char*    getSDBC_SCHEME_LDAP();
            static const sal_Char*    getSDBC_SCHEME_OUTLOOK_MAPI();
            static const sal_Char*    getSDBC_SCHEME_OUTLOOK_EXPRESS();
            static ::rtl::OUString    getDriverImplementationName();

            MNameMapper* getNameMapper();
            void setForceLoadTables(sal_Bool aForce){ m_bForceLoadTable = aForce;}
            sal_Bool getForceLoadTables() { return m_bForceLoadTable;}

            // End of Additions from the land of mozilla
        };
    }
}
#endif // CONNECTIVITY_SCONNECTION_HXX

<commit_msg>INTEGRATION: CWS mozab05 (1.11.46); FILE MERGED 2005/01/28 07:21:41 windly 1.11.46.2: #i20088# thunderbird support 2005/01/17 05:30:43 windly 1.11.46.1: #i20088# Detect Mozilla Thunderbird Address Book: patchs for connectivity<commit_after>/*************************************************************************
 *
 *  $RCSfile: MConnection.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: vg $ $Date: 2005-02-21 12:21:42 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the License); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef CONNECTIVITY_SCONNECTION_HXX
#define CONNECTIVITY_SCONNECTION_HXX

#ifndef _CONNECTIVITY_MAB_COLUMNALIAS_HXX_
#include "MColumnAlias.hxx"
#endif
#ifndef _CONNECTIVITY_MAB_CATALOG_HXX_
#include "MCatalog.hxx"
#endif

#ifndef _COM_SUN_STAR_SDBC_SQLWARNING_HPP_
#include <com/sun/star/sdbc/SQLWarning.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _CONNECTIVITY_OSUBCOMPONENT_HXX_
#include "OSubComponent.hxx"
#endif
//  #include <map>
#ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#endif
#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
#include "connectivity/CommonTools.hxx"
#endif
#ifndef CONNECTIVITY_CONNECTION_HXX
#include "TConnection.hxx"
#endif
#ifndef _CPPUHELPER_WEAKREF_HXX_
#include <cppuhelper/weakref.hxx>
#endif
#ifndef _COM_SUN_STAR_MOZILLA_MOZILLPRODUCTTYPE_HPP_
#include <com/sun/star/mozilla/MozillaProductType.hpp>
#endif

namespace connectivity
{
    namespace mozab
    {

        class OStatement_Base;
        class MozabDriver;
        class ODatabaseMetaData;
        class MNameMapper;

        namespace SDBCAddress {
            typedef enum {
                Unknown     = 0,
                Mozilla     = 1,
                ThunderBird = 2,
                LDAP        = 3,
                Outlook     = 4,
                OutlookExp  = 5
            } sdbc_address_type;
        }

        // For the moment, we will connect the Mozilla address book to the Mozilla
        // top-level address book which will display whatever is in the preferences
        // file of Mozilla.
        // This one is a base uri which will be completed with the connection data.
        static sal_Char*    MOZ_SCHEME_MOZILLA          = "moz-abdirectory://";
        // This one is for mozilla native address book
        static sal_Char*    MOZ_SCHEME_MOZILLA_MDB      = "moz-abmdbdirectory://";
        // This one is for LDAP address book
        static sal_Char*    MOZ_SCHEME_LDAP             = "moz-abldapdirectory://";
        // These two uris will be used to obtain directory factories to access all
        // address books of the given type.
        static sal_Char*    MOZ_SCHEME_OUTLOOK_MAPI     = "moz-aboutlookdirectory://op/";
        static sal_Char*    MOZ_SCHEME_OUTLOOK_EXPRESS  = "moz-aboutlookdirectory://oe/";

        typedef connectivity::OMetaConnection               OConnection_BASE; // implements basics and text encoding

        class OConnection : public OConnection_BASE,
                            public connectivity::OSubComponent<OConnection, OConnection_BASE>
        {
            friend class connectivity::OSubComponent<OConnection, OConnection_BASE>;

        protected:
            //====================================================================
            // Data attributes
            //====================================================================
            ::com::sun::star::uno::WeakReference< ::com::sun::star::sdbc::XDatabaseMetaData > m_xMetaData;

            connectivity::OWeakRefArray             m_aStatements;  //  vector containing a list
                                                        //  of all the Statement objects
                                                        //  for this Connection

            ::com::sun::star::sdbc::SQLWarning      m_aLastWarning; //      Last SQLWarning generated by
                                                        //  an operation
            MozabDriver*                            m_pDriver;      //  Pointer to the owning
                                                                    //  driver object
            // Store Catalog
            ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier>         m_xCatalog;
            // Start of Additions from the land of mozilla
            OColumnAlias    m_aColumnAlias;
            rtl::OUString   m_sMozillaURI;
            rtl::OUString   m_sMozillaProfile;
            sal_Int32       m_nMaxResultRecords;
            MNameMapper*    m_aNameMapper;
            //LDAP only
            rtl::OUString   m_sHostName;
            sal_Bool        m_bUseSSL;
            rtl::OUString   m_sBindDN;
            rtl::OUString   m_sUser;        // the user name
            rtl::OUString   m_sPassword;

            SDBCAddress::sdbc_address_type  m_eSDBCAddressType;

            sal_Bool        m_bForceLoadTable;

        public:
            virtual void construct( const ::rtl::OUString& url,const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info) throw(::com::sun::star::sdbc::SQLException);
            OConnection(MozabDriver*    _pDriver);
            virtual ~OConnection();

            void closeAllStatements () throw( ::com::sun::star::sdbc::SQLException);

            // OComponentHelper
            virtual void SAL_CALL disposing(void);
            // XInterface
            virtual void SAL_CALL release() throw();

            // XServiceInfo
            DECLARE_SERVICE_INFO();
            // XConnection
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XStatement > SAL_CALL createStatement(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XPreparedStatement > SAL_CALL prepareStatement( const ::rtl::OUString& sql ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XPreparedStatement > SAL_CALL prepareCall( const ::rtl::OUString& sql ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::rtl::OUString SAL_CALL nativeSQL( const ::rtl::OUString& sql ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL setAutoCommit( sal_Bool autoCommit ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Bool SAL_CALL getAutoCommit(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL commit(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL rollback(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Bool SAL_CALL isClosed(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData > SAL_CALL getMetaData(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL setReadOnly( sal_Bool readOnly ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Bool SAL_CALL isReadOnly(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL setCatalog( const ::rtl::OUString& catalog ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::rtl::OUString SAL_CALL getCatalog(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL setTransactionIsolation( sal_Int32 level ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Int32 SAL_CALL getTransactionIsolation(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getTypeMap(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL setTypeMap( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& typeMap ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            // XCloseable
            virtual void SAL_CALL close(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            // XWarningsSupplier
            virtual ::com::sun::star::uno::Any SAL_CALL getWarnings(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL clearWarnings(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            //
            MozabDriver*    getDriver() const { return m_pDriver;}

            // Added to enable me to use SQLInterpreter which requires an
            // XNameAccess i/f to access tables.
            ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier > SAL_CALL createCatalog();

            // Additions from the land of mozilla
            rtl::OUString getMozURI() const     { return m_sMozillaURI; }
            rtl::OUString getMozProfile() const     { return m_sMozillaProfile; }
            void setMozProfile(rtl::OUString &aNewProfile)      { m_sMozillaProfile = aNewProfile; }

            ::com::sun::star::mozilla::MozillaProductType getProduct()
            {
                if (m_eSDBCAddressType == SDBCAddress::ThunderBird)
                    return ::com::sun::star::mozilla::MozillaProductType_Thunderbird;
                return ::com::sun::star::mozilla::MozillaProductType_Mozilla;
            }

            // Get Ldap BindDN (user name)
            rtl::OUString getBindDN() const { return m_sBindDN; }
            // Get Ldap Password
            rtl::OUString getPassword() const { return m_sPassword; }
            // Get Ldap Host name
            rtl::OUString getHost() const { return m_sHostName; }
            // Get whether use ssl to connect to ldap
            sal_Bool getUseSSL() const {return m_bUseSSL;}

            sal_Bool usesFactory(void) const { return (m_eSDBCAddressType == SDBCAddress::Outlook) || (m_eSDBCAddressType == SDBCAddress::OutlookExp); }
            sal_Bool isLDAP(void) const { return m_eSDBCAddressType == SDBCAddress::LDAP; }
            sal_Bool isThunderbird(void) const { return m_eSDBCAddressType == SDBCAddress::ThunderBird; }

            sal_Bool    isOutlookExpress() const { return m_eSDBCAddressType == SDBCAddress::OutlookExp;}
            sal_Int32   getMaxResultRecords() const { return m_nMaxResultRecords; }

            SDBCAddress::sdbc_address_type getSDBCAddressType() const { return m_eSDBCAddressType;}

            const OColumnAlias & getColumnAlias() const   { return (m_aColumnAlias); }

            static const sal_Char*    getSDBC_SCHEME_MOZILLA();
            static const sal_Char*    getSDBC_SCHEME_THUNDERBIRD();
            static const sal_Char*    getSDBC_SCHEME_LDAP();
            static const sal_Char*    getSDBC_SCHEME_OUTLOOK_MAPI();
            static const sal_Char*    getSDBC_SCHEME_OUTLOOK_EXPRESS();
            static ::rtl::OUString    getDriverImplementationName();

            MNameMapper* getNameMapper();
            void setForceLoadTables(sal_Bool aForce){ m_bForceLoadTable = aForce;}
            sal_Bool getForceLoadTables() { return m_bForceLoadTable;}

            // End of Additions from the land of mozilla
        };
    }
}
#endif // CONNECTIVITY_SCONNECTION_HXX

<|endoftext|>


<commit_before>#include "Base.h"
#include "Label.h"

namespace gameplay
{

Label::Label() : _text(L""), _font(NULL)
    , _textColor( 0.0f, 0.0f, 0.0f, 0.0f )
{
}

Label::~Label()
{
}

Label* Label::create(const char* id, Theme::Style* style)
{
    Label* label = new Label();
    label->_id = id ? id : "";
    label->initialize("Label", style, NULL);
    return label;
}

Control* Label::create(Theme::Style* style, Properties* properties)
{
    Label* label = new Label();
	label->initialize("Label", style, properties);
    return label;
}

void Label::initialize(const char* typeName, Theme::Style* style, Properties* properties)
{
    Control::initialize(typeName, style, properties);

	if (properties)
	{
		const char* text = properties->getString("text");
		if (text)
		{
			_text.assign( text, text + strlen( text ) );
		}
	}
}

const char* Label::getTypeName() const
{
    return "Label";
}

void Label::addListener(Control::Listener* listener, int eventFlags)
{
    if ((eventFlags & Control::Listener::TEXT_CHANGED) == Control::Listener::TEXT_CHANGED)
    {
        GP_ERROR("TEXT_CHANGED event is not applicable to this control.");
    }
    if ((eventFlags & Control::Listener::VALUE_CHANGED) == Control::Listener::VALUE_CHANGED)
    {
        GP_ERROR("VALUE_CHANGED event is not applicable to this control.");
    }

    Control::addListener(listener, eventFlags);
}

void Label::setText(const wchar_t* text)
{
    if ((text == NULL && _text.length() > 0) || wcscmp(text, _text.c_str()) != 0)
    {
        _text = text ? text : L"";
        if (_autoSize != AUTO_SIZE_NONE)
            setDirty(DIRTY_BOUNDS);
    }
}

const wchar_t* Label::getText()
{
    return _text.c_str();
}

void Label::update(float elapsedTime)
{
    Control::update(elapsedTime);

    // Update text opacity each frame since opacity is updated in Control::update.
    _textColor = getTextColor(getState());
    _textColor.w *= _opacity;
}

void Label::updateState(State state)
{
    Control::updateState(state);

    _font = getFont(state);
}

void Label::updateBounds()
{
    Control::updateBounds();

    if (_autoSize != AUTO_SIZE_NONE && _font)
    {
        // Measure bounds based only on normal state so that bounds updates are not always required on state changes.
        // This is a trade-off for functionality vs performance, but changing the size of UI controls on hover/focus/etc
        // is a pretty bad practice so we'll prioritize performance here.
        float w, h;
        _font->measureText(_text.c_str(), getFontSize(NORMAL), getTextDrawingFlags(NORMAL), &w, &h);
        if (_autoSize & AUTO_SIZE_WIDTH)
        {
            setWidthInternal(ceilf(w + getBorder(NORMAL).left + getBorder(NORMAL).right + getPadding().left + getPadding().right));
        }
        if (_autoSize & AUTO_SIZE_HEIGHT)
        {
            // recalculate height due to word wrapping
            if (_textBounds.width > 0.0f && (_autoSize & AUTO_SIZE_WIDTH) == 0)
            {
                gameplay::Rectangle clipBounds(_textBounds.width, FLT_MAX);
                gameplay::Rectangle out;
                _font->measureText(_text.c_str(), clipBounds, getFontSize(NORMAL), getTextDrawingFlags(NORMAL), &out);

                h = out.height;
            }

            setHeightInternal(ceilf(h + getBorder(NORMAL).top + getBorder(NORMAL).bottom + getPadding().top + getPadding().bottom));
        }
    }
}

void Label::updateAbsoluteBounds(const Vector2& offset)
{
    Control::updateAbsoluteBounds(offset);

    _textBounds.set(_viewportBounds.x, _viewportBounds.y, _viewportBounds.width, _viewportBounds.height);
}

unsigned int Label::drawText(Form* form) const
{
    if (_viewportClipBounds.width <= 0 || _viewportClipBounds.height <= 0)
        return 0;

    // Draw the text.
    if (_text.size() > 0 && _font)
    {
        Control::State state = getState();
        float fontSize = getFontSize(state);

        SpriteBatch* batch = _font->getSpriteBatch(fontSize);
        startBatch(form, batch);
        _font->drawText(_text.c_str(), _textBounds, _textColor, fontSize, getTextAlignment(state), true, getTextDrawingFlags(state), _viewportClipBounds);
        finishBatch(form, batch);

        return 1;
    }

    return 0;
}

}
<commit_msg>update control bounds after setting Label width/height<commit_after>#include "Base.h"
#include "Label.h"

namespace gameplay
{

Label::Label() : _text(L""), _font(NULL)
    , _textColor( 0.0f, 0.0f, 0.0f, 0.0f )
{
}

Label::~Label()
{
}

Label* Label::create(const char* id, Theme::Style* style)
{
    Label* label = new Label();
    label->_id = id ? id : "";
    label->initialize("Label", style, NULL);
    return label;
}

Control* Label::create(Theme::Style* style, Properties* properties)
{
    Label* label = new Label();
	label->initialize("Label", style, properties);
    return label;
}

void Label::initialize(const char* typeName, Theme::Style* style, Properties* properties)
{
    Control::initialize(typeName, style, properties);

	if (properties)
	{
		const char* text = properties->getString("text");
		if (text)
		{
			_text.assign( text, text + strlen( text ) );
		}
	}
}

const char* Label::getTypeName() const
{
    return "Label";
}

void Label::addListener(Control::Listener* listener, int eventFlags)
{
    if ((eventFlags & Control::Listener::TEXT_CHANGED) == Control::Listener::TEXT_CHANGED)
    {
        GP_ERROR("TEXT_CHANGED event is not applicable to this control.");
    }
    if ((eventFlags & Control::Listener::VALUE_CHANGED) == Control::Listener::VALUE_CHANGED)
    {
        GP_ERROR("VALUE_CHANGED event is not applicable to this control.");
    }

    Control::addListener(listener, eventFlags);
}

void Label::setText(const wchar_t* text)
{
    if ((text == NULL && _text.length() > 0) || wcscmp(text, _text.c_str()) != 0)
    {
        _text = text ? text : L"";
        if (_autoSize != AUTO_SIZE_NONE)
            setDirty(DIRTY_BOUNDS);
    }
}

const wchar_t* Label::getText()
{
    return _text.c_str();
}

void Label::update(float elapsedTime)
{
    Control::update(elapsedTime);

    // Update text opacity each frame since opacity is updated in Control::update.
    _textColor = getTextColor(getState());
    _textColor.w *= _opacity;
}

void Label::updateState(State state)
{
    Control::updateState(state);

    _font = getFont(state);
}

void Label::updateBounds()
{
    if (_autoSize != AUTO_SIZE_NONE && _font)
    {
        // Measure bounds based only on normal state so that bounds updates are not always required on state changes.
        // This is a trade-off for functionality vs performance, but changing the size of UI controls on hover/focus/etc
        // is a pretty bad practice so we'll prioritize performance here.
        float w, h;
        _font->measureText(_text.c_str(), getFontSize(NORMAL), getTextDrawingFlags(NORMAL), &w, &h);
        if (_autoSize & AUTO_SIZE_WIDTH)
        {
            setWidthInternal(ceilf(w + getBorder(NORMAL).left + getBorder(NORMAL).right + getPadding().left + getPadding().right));
        }
        if (_autoSize & AUTO_SIZE_HEIGHT)
        {
            // recalculate height due to word wrapping
            if (_textBounds.width > 0.0f && (_autoSize & AUTO_SIZE_WIDTH) == 0)
            {
                gameplay::Rectangle clipBounds(_textBounds.width, FLT_MAX);
                gameplay::Rectangle out;
                _font->measureText(_text.c_str(), clipBounds, getFontSize(NORMAL), getTextDrawingFlags(NORMAL), &out);

                h = out.height;
            }

            setHeightInternal(ceilf(h + getBorder(NORMAL).top + getBorder(NORMAL).bottom + getPadding().top + getPadding().bottom));
        }
    }

    Control::updateBounds();
}

void Label::updateAbsoluteBounds(const Vector2& offset)
{
    Control::updateAbsoluteBounds(offset);

    _textBounds.set(_viewportBounds.x, _viewportBounds.y, _viewportBounds.width, _viewportBounds.height);
}

unsigned int Label::drawText(Form* form) const
{
    if (_viewportClipBounds.width <= 0 || _viewportClipBounds.height <= 0)
        return 0;

    // Draw the text.
    if (_text.size() > 0 && _font)
    {
        Control::State state = getState();
        float fontSize = getFontSize(state);

        SpriteBatch* batch = _font->getSpriteBatch(fontSize);
        startBatch(form, batch);
        _font->drawText(_text.c_str(), _textBounds, _textColor, fontSize, getTextAlignment(state), true, getTextDrawingFlags(state), _viewportClipBounds);
        finishBatch(form, batch);

        return 1;
    }

    return 0;
}

}
<|endoftext|>


<commit_before>// this small program is used to generate string index files

#include <string>
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <dirent.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <algorithm>
#include <assert.h>
using namespace std;

unordered_map<string,int> subject_to_id;
unordered_map<string,int> predict_to_id;
vector<string> id_to_subject;
vector<string> id_to_predict;

void insert_subclass(ofstream& ontology_file,string child,string parent){
	int id[2];
	if(subject_to_id.find(child)==subject_to_id.end()){
		int size =subject_to_id.size();
		subject_to_id[child]=size;
		id_to_subject.push_back(child);
	}
	if(subject_to_id.find(parent)==subject_to_id.end()){
		int size =subject_to_id.size();
		subject_to_id[parent]=size;
		id_to_subject.push_back(parent);
	}
	id[0]=subject_to_id[child];
	id[1]=subject_to_id[parent];
	ontology_file<<id[0]<<"\t"<<id[1]<<endl;
}

int main(int argc,char** argv){

	struct dirent *ptr;
    DIR *dir;
    if(argc<=1){
    	printf("usage: ./index_server dir\n");
    	return 0;
    }
    dir=opendir(argv[1]);
    printf("files:\n");

    while((ptr=readdir(dir))!=NULL){
        if(ptr->d_name[0] == '.')
            continue;
        string filename=string(argv[1])+"/"+string(ptr->d_name);
        printf("loading %s ...\n",ptr->d_name);
        ifstream file(filename.c_str());
        ofstream output(("id_"+string(ptr->d_name)).c_str());
        // S P O .
		string subject;
		string predict;
		string object;
		string useless_dot;
        while(file>>subject>>predict>>object>>useless_dot){
			int id[3];
			//replace prefix
			string prefix="<http://swat.cse.lehigh.edu/onto/univ-bench.owl";
			if(equal(prefix.begin(), prefix.end(), subject.begin()))
				subject="<ub"+subject.substr(prefix.size());
			if(equal(prefix.begin(), prefix.end(), predict.begin()))
				predict="<ub"+predict.substr(prefix.size());
			if(equal(prefix.begin(), prefix.end(), object.begin()))
				object="<ub"+object.substr(prefix.size());

			if(subject_to_id.find(subject)==subject_to_id.end()){
				int size =subject_to_id.size();
				subject_to_id[subject]=size;
				id_to_subject.push_back(subject);
			}
			if(predict_to_id.find(predict)==predict_to_id.end()){
				int size =predict_to_id.size();
				predict_to_id[predict]=size;
				id_to_predict.push_back(predict);
			}
			if(subject_to_id.find(object)==subject_to_id.end() ){
				int size =subject_to_id.size();
				subject_to_id[object]=size;
				id_to_subject.push_back(object);
			}
			id[0]=subject_to_id[subject];
			id[1]=predict_to_id[predict];
			id[2]=subject_to_id[object];
			output<<id[0]<<"\t"<<id[1]<<"\t"<<id[2]<<endl;
		}
		file.close();
		output.close();
    }
    closedir(dir);

    cout<<id_to_subject.size()<<endl;
    ofstream f1("index_subject");
    for(int i=0;i<id_to_subject.size();i++){
    	f1<<id_to_subject[i]<<endl;
    }
    f1.close();

    ofstream f2("index_predict");
    cout<<id_to_predict.size()<<endl;
    for(int i=0;i<id_to_predict.size();i++){
    	f2<<id_to_predict[i]<<endl;
    }
    f2.close();

    ofstream ontology_file("index_ontology");
    //Current I cannot correct parse the ontology file.
	//and not all the subClass are list in the file.
	//So I manually insert it and make it reasonable

	//Course
	insert_subclass(ontology_file,"<ub#GraduateCourse>","<ub#Course>");
	//student
	insert_subclass(ontology_file,"<ub#GraduateStudent>","<ub#Student>");
	insert_subclass(ontology_file,"<ub#UndergraduateStudent>","<ub#Student>");
	//professor
	insert_subclass(ontology_file,"<ub#FullProfessor>","<ub#Professor>");
	insert_subclass(ontology_file,"<ub#AssistantProfessor>","<ub#Professor>");
	insert_subclass(ontology_file,"<ub#AssociateProfessor>","<ub#Professor>");
	//Faculty
	insert_subclass(ontology_file,"<ub#Professor>","<ub#Faculty>");
	insert_subclass(ontology_file,"<ub#Lecturer>","<ub#Faculty>");

	//Person
	insert_subclass(ontology_file,"<ub#Student>","<ub#Person>");
	insert_subclass(ontology_file,"<ub#Faculty>","<ub#Person>");

	insert_subclass(ontology_file,"<ub#TeachingAssistant>","<ub#Person>");
	insert_subclass(ontology_file,"<ub#ResearchAssistant>","<ub#Person>");

    ontology_file.close();
}

<commit_msg>bug about ontology<commit_after>// this small program is used to generate string index files

#include <string>
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <dirent.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <algorithm>
#include <assert.h>
using namespace std;

unordered_map<string,int> subject_to_id;
unordered_map<string,int> predict_to_id;
vector<string> id_to_subject;
vector<string> id_to_predict;

void insert_subclass(ofstream& ontology_file,string child,string parent){
	int id[2];
	if(subject_to_id.find(child)==subject_to_id.end()){
		int size =subject_to_id.size();
		subject_to_id[child]=size;
		id_to_subject.push_back(child);
	}
	if(subject_to_id.find(parent)==subject_to_id.end()){
		int size =subject_to_id.size();
		subject_to_id[parent]=size;
		id_to_subject.push_back(parent);
	}
	id[0]=subject_to_id[child];
	id[1]=subject_to_id[parent];
	ontology_file<<id[0]<<"\t"<<id[1]<<endl;
}

int main(int argc,char** argv){

	struct dirent *ptr;
    DIR *dir;
    if(argc<=1){
    	printf("usage: ./index_server dir\n");
    	return 0;
    }
    dir=opendir(argv[1]);
    printf("files:\n");

    ofstream ontology_file("index_ontology");

    while((ptr=readdir(dir))!=NULL){
        if(ptr->d_name[0] == '.')
            continue;
        string filename=string(argv[1])+"/"+string(ptr->d_name);
        printf("loading %s ...\n",ptr->d_name);
        ifstream file(filename.c_str());
        ofstream output(("id_"+string(ptr->d_name)).c_str());
        // S P O .
		string subject;
		string predict;
		string object;
		string useless_dot;
        while(file>>subject>>predict>>object>>useless_dot){
			int id[3];
			//replace prefix
			string prefix="<http://swat.cse.lehigh.edu/onto/univ-bench.owl";
			if(equal(prefix.begin(), prefix.end(), subject.begin()))
				subject="<ub"+subject.substr(prefix.size());
			if(equal(prefix.begin(), prefix.end(), predict.begin()))
				predict="<ub"+predict.substr(prefix.size());
			if(equal(prefix.begin(), prefix.end(), object.begin()))
				object="<ub"+object.substr(prefix.size());

			if(subject_to_id.find(subject)==subject_to_id.end()){
				int size =subject_to_id.size();
				subject_to_id[subject]=size;
				id_to_subject.push_back(subject);
			}
			if(predict_to_id.find(predict)==predict_to_id.end()){
				int size =predict_to_id.size();
				predict_to_id[predict]=size;
				id_to_predict.push_back(predict);
			}
			if(subject_to_id.find(object)==subject_to_id.end() ){
				int size =subject_to_id.size();
				subject_to_id[object]=size;
				id_to_subject.push_back(object);
				// it means this type appears first time
				if(predict=="<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>"){
					ontology_file<<size<<"\t"<<-1<<endl;
				}
			}
			id[0]=subject_to_id[subject];
			id[1]=predict_to_id[predict];
			id[2]=subject_to_id[object];
			output<<id[0]<<"\t"<<id[1]<<"\t"<<id[2]<<endl;
		}
		file.close();
		output.close();
    }
    closedir(dir);

    cout<<id_to_subject.size()<<endl;
    ofstream f1("index_subject");
    for(int i=0;i<id_to_subject.size();i++){
    	f1<<id_to_subject[i]<<endl;
    }
    f1.close();

    ofstream f2("index_predict");
    cout<<id_to_predict.size()<<endl;
    for(int i=0;i<id_to_predict.size();i++){
    	f2<<id_to_predict[i]<<endl;
    }
    f2.close();

    //Current I cannot correct parse the ontology file.
	//and not all the subClass are list in the file.
	//So I manually insert it and make it reasonable

	//Course
	insert_subclass(ontology_file,"<ub#GraduateCourse>","<ub#Course>");
	//student
	insert_subclass(ontology_file,"<ub#GraduateStudent>","<ub#Student>");
	insert_subclass(ontology_file,"<ub#UndergraduateStudent>","<ub#Student>");
	//professor
	insert_subclass(ontology_file,"<ub#FullProfessor>","<ub#Professor>");
	insert_subclass(ontology_file,"<ub#AssistantProfessor>","<ub#Professor>");
	insert_subclass(ontology_file,"<ub#AssociateProfessor>","<ub#Professor>");
	//Faculty
	insert_subclass(ontology_file,"<ub#Professor>","<ub#Faculty>");
	insert_subclass(ontology_file,"<ub#Lecturer>","<ub#Faculty>");

	//Person
	insert_subclass(ontology_file,"<ub#Student>","<ub#Person>");
	insert_subclass(ontology_file,"<ub#Faculty>","<ub#Person>");

	insert_subclass(ontology_file,"<ub#TeachingAssistant>","<ub#Person>");
	insert_subclass(ontology_file,"<ub#ResearchAssistant>","<ub#Person>");

    ontology_file.close();
}

<|endoftext|>


<commit_before>/*
 * Event.cpp
 *
 * Copyright (C) 2006 - 2007 by Universitaet Stuttgart (VIS).
 * Alle Rechte vorbehalten.
 */

#include "vislib/Event.h"

#ifndef _WIN32
#include <climits>
#endif /* !_WIN32 */

#include "vislib/assert.h"
#include "vislib/error.h"
#include "vislib/IllegalParamException.h"
#include "vislib/SystemException.h"
#include "vislib/Trace.h"
#include "vislib/UnsupportedOperationException.h"

/*
 * vislib::sys::Event::TIMEOUT_INFINITE
 */
#ifdef _WIN32
const DWORD vislib::sys::Event::TIMEOUT_INFINITE = INFINITE;
#else /* _WIN32 */
const DWORD vislib::sys::Event::TIMEOUT_INFINITE = UINT_MAX;
#endif /* _WIN32 */

/*
 * vislib::sys::Event::Event
 */
vislib::sys::Event::Event(const bool isManualReset,
                          const bool isInitiallySignaled) {
#ifdef _WIN32
    this->handle = ::CreateEvent(NULL, isManualReset ? TRUE : FALSE, FALSE,
        NULL);
    ASSERT(this->handle != NULL);

#else /* _WIN32 */
    this->isManualReset = isManualReset;

    if (!isInitiallySignaled) {
        this->semaphore.TryLock();
    }

#endif /* _WIN32 */
}

/*
 * vislib::sys::Event::~Event
 */
vislib::sys::Event::~Event(void) {
#ifdef _WIN32
    ::CloseHandle(this->handle);

#else /* _WIN32 */
    /* Nothing to do. */

#endif /* _WIN32 */
}

/*
 * vislib::sys::Event::Reset
 */
void vislib::sys::Event::Reset(void) {
#ifdef _WIN32
    if (!::ResetEvent(this->handle)) {
        throw SystemException(__FILE__, __LINE__);
    }

#else /* _WIN32 */
    TRACE(vislib::Trace::LEVEL_VL_INFO, "Event::Reset\n");

    this->semaphore.TryLock();
    ASSERT(!this->semaphore.TryLock());

#endif /* _WIN32 */
}

/*
 * vislib::sys::Event::Set
 */
void vislib::sys::Event::Set(void) {
#ifdef _WIN32
    if (!::SetEvent(this->handle)) {
        throw SystemException(__FILE__, __LINE__);
    }

#else /* _WIN32 */
    TRACE(vislib::Trace::LEVEL_VL_INFO, "Event::Set\n");

    if (!this->semaphore.TryLock()) {
        /* Count is 0, i. e. semaphore is in non-signaled state. */
        this->semaphore.Unlock();
    }

#endif /* _WIN32 */
}

/*
 * vislib::sys::Event::Wait
 */
bool vislib::sys::Event::Wait(const DWORD timeout) {
#ifdef _WIN32
    switch (::WaitForSingleObject(this->handle, timeout)) {

        case WAIT_OBJECT_0:
            /* falls through. */
        case WAIT_ABANDONED:
            return true;
            /* Unreachable. */

        case WAIT_TIMEOUT:
            return false;
            /* Unreachable. */

        default:
            throw SystemException(__FILE__, __LINE__);
            /* Unreachable. */
    }

#else /* _WIN32 */
    TRACE(vislib::Trace::LEVEL_VL_INFO, "Event::Wait\n");
    bool retval = false;

    if (timeout == TIMEOUT_INFINITE) {
        this->semaphore.Lock();
        retval = true;

    } else {
        retval = this->semaphore.TryLock(timeout);
    }

    if (retval && this->isManualReset) {
        TRACE(vislib::Trace::LEVEL_VL_INFO, "Event::Wait signal again\n");
        this->semaphore.Unlock();
    }

    return retval;
#endif /* _WIN32 */
}

/*
 * vislib::sys::Event::Event
 */
vislib::sys::Event::Event(const Event& rhs) {
    throw UnsupportedOperationException("vislib::sys::Event::Event",
        __FILE__, __LINE__);
}

/*
 * vislib::sys::Event::operator =
 */
vislib::sys::Event& vislib::sys::Event::operator =(const Event& rhs) {
    if (this != &rhs) {
        throw IllegalParamException("rhs", __FILE__, __LINE__);
    }

    return *this;
}
<commit_msg>Fixed wrong initialisation of semaphore.<commit_after>/*
 * Event.cpp
 *
 * Copyright (C) 2006 - 2007 by Universitaet Stuttgart (VIS).
 * Alle Rechte vorbehalten.
 */

#include "vislib/Event.h"

#ifndef _WIN32
#include <climits>
#endif /* !_WIN32 */

#include "vislib/assert.h"
#include "vislib/error.h"
#include "vislib/IllegalParamException.h"
#include "vislib/SystemException.h"
#include "vislib/Trace.h"
#include "vislib/UnsupportedOperationException.h"

/*
 * vislib::sys::Event::TIMEOUT_INFINITE
 */
#ifdef _WIN32
const DWORD vislib::sys::Event::TIMEOUT_INFINITE = INFINITE;
#else /* _WIN32 */
const DWORD vislib::sys::Event::TIMEOUT_INFINITE = UINT_MAX;
#endif /* _WIN32 */

/*
 * vislib::sys::Event::Event
 */
vislib::sys::Event::Event(const bool isManualReset,
                          const bool isInitiallySignaled)
#ifndef _WIN32
        : isManualReset(isManualReset),
        semaphore(isInitiallySignaled ? 1 : 0, 1)
#endif /* _WIN32 */
{
#ifdef _WIN32
    this->handle = ::CreateEvent(NULL, isManualReset ? TRUE : FALSE, FALSE,
        NULL);
    ASSERT(this->handle != NULL);
#endif /* _WIN32 */
}

/*
 * vislib::sys::Event::~Event
 */
vislib::sys::Event::~Event(void) {
#ifdef _WIN32
    ::CloseHandle(this->handle);

#else /* _WIN32 */
    /* Nothing to do. */

#endif /* _WIN32 */
}

/*
 * vislib::sys::Event::Reset
 */
void vislib::sys::Event::Reset(void) {
#ifdef _WIN32
    if (!::ResetEvent(this->handle)) {
        throw SystemException(__FILE__, __LINE__);
    }

#else /* _WIN32 */
    TRACE(vislib::Trace::LEVEL_VL_INFO, "Event::Reset\n");

    this->semaphore.TryLock();
    ASSERT(!this->semaphore.TryLock());

#endif /* _WIN32 */
}

/*
 * vislib::sys::Event::Set
 */
void vislib::sys::Event::Set(void) {
#ifdef _WIN32
    if (!::SetEvent(this->handle)) {
        throw SystemException(__FILE__, __LINE__);
    }

#else /* _WIN32 */
    TRACE(vislib::Trace::LEVEL_VL_INFO, "Event::Set\n");

    if (!this->semaphore.TryLock()) {
        /* Count is 0, i. e. semaphore is in non-signaled state. */
        this->semaphore.Unlock();
    }

#endif /* _WIN32 */
}

/*
 * vislib::sys::Event::Wait
 */
bool vislib::sys::Event::Wait(const DWORD timeout) {
#ifdef _WIN32
    switch (::WaitForSingleObject(this->handle, timeout)) {

        case WAIT_OBJECT_0:
            /* falls through. */
        case WAIT_ABANDONED:
            return true;
            /* Unreachable. */

        case WAIT_TIMEOUT:
            return false;
            /* Unreachable. */

        default:
            throw SystemException(__FILE__, __LINE__);
            /* Unreachable. */
    }

#else /* _WIN32 */
    TRACE(vislib::Trace::LEVEL_VL_INFO, "Event::Wait\n");
    bool retval = false;

    if (timeout == TIMEOUT_INFINITE) {
        this->semaphore.Lock();
        retval = true;

    } else {
        retval = this->semaphore.TryLock(timeout);
    }

    if (retval && this->isManualReset) {
        TRACE(vislib::Trace::LEVEL_VL_INFO, "Event::Wait signal again\n");
        this->semaphore.Unlock();
    }

    return retval;
#endif /* _WIN32 */
}

/*
 * vislib::sys::Event::Event
 */
vislib::sys::Event::Event(const Event& rhs) {
    throw UnsupportedOperationException("vislib::sys::Event::Event",
        __FILE__, __LINE__);
}

/*
 * vislib::sys::Event::operator =
 */
vislib::sys::Event& vislib::sys::Event::operator =(const Event& rhs) {
    if (this != &rhs) {
        throw IllegalParamException("rhs", __FILE__, __LINE__);
    }

    return *this;
}
<|endoftext|>


<commit_before>/*MIT License

Copyright (c) 2018 MTA SZTAKI

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.*/

#include "apeSceneNetworkImpl.h"
#include "apeReplicaManager.h"
#include "apeNodeImpl.h"

ape::SceneNetworkImpl::SceneNetworkImpl()
	: mpRakReplicaPeer(nullptr)
	, mpRakStreamPeer(nullptr)
	, mpReplicaManager3(nullptr)
	, mpNatPunchthroughClient(nullptr)
	, mpLobbyManager(nullptr)
{
	mpCoreConfig = ape::ICoreConfig::getSingletonPtr();
	mpEventManager = ape::IEventManager::getSingletonPtr();
	mpSceneManager = ape::ISceneManager::getSingletonPtr();
	mpEventManager->connectEvent(ape::Event::Group::POINT_CLOUD, std::bind(&SceneNetworkImpl::eventCallBack, this, std::placeholders::_1));
	mStreamReplicas = std::vector<ape::Replica*>();
	mIsConnectedToNATServer = false;
	mNATServerAddress.FromString("");
	mParticipantType = mpCoreConfig->getNetworkConfig().participant;
	mReplicaHostGuid = RakNet::RakNetGUID();

	if (mParticipantType == ape::SceneNetwork::HOST)
	{
		mIsReplicaHost = true;
		init();
		if (mpCoreConfig->getNetworkConfig().selected == ape::NetworkConfig::INTERNET)
		{
			bool createSessionResult = mpLobbyManager->createSession(mpCoreConfig->getNetworkConfig().lobbyConfig.roomName, mGuid.ToString());
			APE_LOG_DEBUG("lobbyManager->createSession(): " << createSessionResult);
		}
		createReplicaHost();
	}
	else if (mParticipantType == ape::SceneNetwork::GUEST)
	{
		mIsReplicaHost = false;
		init();
		std::string uuid;
		if (mpCoreConfig->getNetworkConfig().selected == ape::NetworkConfig::INTERNET)
		{
			APE_LOG_DEBUG("use lobbyManager to get scene session guid");
			std::string name = mpCoreConfig->getNetworkConfig().lobbyConfig.roomName;
			bool getSessionRes = mpLobbyManager->getSessionHostGuid(name, uuid);
			APE_LOG_DEBUG("lobbyManager->getSessionHostGuid() res: " << getSessionRes << " uuid: " << uuid);
			//if (getSessionRes && !uuid.empty())
			//{
				//connect2ReplicaHost(uuid);
			//}
		}
		connect2ReplicaHost(uuid);
	}
}

ape::SceneNetworkImpl::~SceneNetworkImpl()
{
	if (mpRakReplicaPeer)
	{
		mpRakReplicaPeer->Shutdown(100);
		RakNet::RakPeerInterface::DestroyInstance(mpRakReplicaPeer);
	}

	if (mpNatPunchthroughClient)
		RakNet::NatPunchthroughClient::DestroyInstance(mpNatPunchthroughClient);

	if (mpLobbyManager)
	{
		if (mParticipantType == ape::SceneNetwork::ParticipantType::HOST)
			mpLobbyManager->removeSession(mpCoreConfig->getNetworkConfig().lobbyConfig.roomName);

		delete mpLobbyManager;
		mpLobbyManager = nullptr;
	}
}

void ape::SceneNetworkImpl::eventCallBack(const ape::Event & event)
{
	if (mpCoreConfig->getNetworkConfig().selected == ape::NetworkConfig::LAN && mpCoreConfig->getNetworkConfig().lanConfig.hostStreamPort.length())
	{
		if (auto entity = mpSceneManager->getEntity(event.subjectName).lock())
		{
			if (auto pointCloud = ((ape::PointCloudImpl*)entity.get()))
			{
				if (mIsStreamHost)
				{
					if (event.type == ape::Event::Type::POINT_CLOUD_PARAMETERS)
					{
						mStreamReplicas.push_back(pointCloud);
						APE_LOG_DEBUG("listenStreamPeerSenderThread for replica named: " << event.subjectName);
						std::thread runStreamPeerSenderListenThread((std::bind(&ape::Replica::listenStreamPeerSendThread, pointCloud, mpRakStreamPeer)));
						runStreamPeerSenderListenThread.detach();
					}
				}
				else if(event.type == ape::Event::Type::POINT_CLOUD_CREATE)
				{
					mStreamReplicas.push_back(pointCloud);
					APE_LOG_DEBUG("listenStreamPeerReceiverThread for replica named: " << event.subjectName);
					std::thread runStreamPeerReceiverListenThread((std::bind(&ape::Replica::listenStreamPeerReceiveThread, pointCloud, mpRakStreamPeer)));
					runStreamPeerReceiverListenThread.detach();
				}
			}
		}
	}
}

void ape::SceneNetworkImpl::init()
{
	ape::NetworkConfig::NatPunchThroughConfig natPunchThroughServerConfig = mpCoreConfig->getNetworkConfig().natPunchThroughConfig;
	mNATServerIP = natPunchThroughServerConfig.ip;
	mNATServerPort = natPunchThroughServerConfig.port;
	ape::NetworkConfig::LobbyConfig lobbyServerConfig = mpCoreConfig->getNetworkConfig().lobbyConfig;
	ape::NetworkConfig::LanConfig localNetworkConfig = mpCoreConfig->getNetworkConfig().lanConfig;
	mLobbyServerIP = lobbyServerConfig.ip;
	APE_LOG_DEBUG("mLobbyServerIP: " << mLobbyServerIP);
	mLobbyServerPort = lobbyServerConfig.port;
	APE_LOG_DEBUG("mLobbyServerPort: " << mLobbyServerPort);
	mLobbyServerSessionName = lobbyServerConfig.roomName;
	APE_LOG_DEBUG("mLobbyServerSessionName: " << mLobbyServerSessionName);
	mpLobbyManager = new LobbyManager(mLobbyServerIP, mLobbyServerPort, mLobbyServerSessionName);
	mpRakReplicaPeer = RakNet::RakPeerInterface::GetInstance();
	mpNetworkIDManager = RakNet::NetworkIDManager::GetInstance();
	if (mpCoreConfig->getNetworkConfig().selected == ape::NetworkConfig::INTERNET)
	{
		mpNatPunchthroughClient = RakNet::NatPunchthroughClient::GetInstance();
		mpRakReplicaPeer->AttachPlugin(mpNatPunchthroughClient);
	}
	mpReplicaManager3 = std::make_shared<ape::ReplicaManager>();
	mpRakReplicaPeer->AttachPlugin(mpReplicaManager3.get());
	mpReplicaManager3->SetNetworkIDManager(mpNetworkIDManager);
	mpReplicaManager3->SetAutoManageConnections(false,true);
	RakNet::SocketDescriptor sd;
	sd.socketFamily = AF_INET;
	if (mpCoreConfig->getNetworkConfig().selected == ape::NetworkConfig::LAN)
	{
		if (mParticipantType == ape::SceneNetwork::HOST)
		{
			sd.port = atoi(localNetworkConfig.hostReplicaPort.c_str());
		}
	}
	RakNet::StartupResult sr = mpRakReplicaPeer->Startup(8, &sd, 1);
	APE_LOG_DEBUG("Raknet StartupResult: " << (int)sr);
	RakAssert(sr == RakNet::RAKNET_STARTED);
	mpRakReplicaPeer->SetMaximumIncomingConnections(8);
	mpRakReplicaPeer->SetTimeoutTime(30000,RakNet::UNASSIGNED_SYSTEM_ADDRESS);
	mGuid = mpRakReplicaPeer->GetGuidFromSystemAddress(RakNet::UNASSIGNED_SYSTEM_ADDRESS);
	mAddress = mpRakReplicaPeer->GetSystemAddressFromGuid(mGuid);
	APE_LOG_DEBUG("Our guid is: " << mGuid.ToString());
	APE_LOG_DEBUG("Started on: " << mAddress.ToString(true));
	if (mpCoreConfig->getNetworkConfig().selected == ape::NetworkConfig::INTERNET)
	{
		RakNet::ConnectionAttemptResult car = mpRakReplicaPeer->Connect(mNATServerIP.c_str(), atoi(mNATServerPort.c_str()), 0, 0);
		if (car != RakNet::CONNECTION_ATTEMPT_STARTED)
		{
			APE_LOG_DEBUG("Failed connect call to " << mNATServerIP.c_str() << ". Code=" << car);
		}
		else
		{
			APE_LOG_DEBUG("Try to connect to NAT punchthrough server: " << mNATServerIP << "|" << mNATServerPort);
			while (!mIsConnectedToNATServer)
			{
				listenReplicaPeer();
				std::this_thread::sleep_for(std::chrono::milliseconds(100));
			}
		}
	}
	APE_LOG_DEBUG("runReplicaPeerListenThread");
	std::thread runReplicaPeerListenThread((std::bind(&SceneNetworkImpl::runReplicaPeerListen, this)));
	runReplicaPeerListenThread.detach();
	if (mpCoreConfig->getNetworkConfig().selected == ape::NetworkConfig::LAN && mpCoreConfig->getNetworkConfig().lanConfig.hostStreamPort.length())
	{
		mpRakStreamPeer = RakNet::RakPeerInterface::GetInstance();
		int socketFamily;
		socketFamily = AF_INET;
		auto myIPAddress = std::string(mAddress.ToString(false));
		if (mpCoreConfig->getNetworkConfig().lanConfig.hostStreamIP == myIPAddress)
		{
			mIsStreamHost = true;
			mpRakStreamPeer->SetTimeoutTime(5000, RakNet::UNASSIGNED_SYSTEM_ADDRESS);
			RakNet::SocketDescriptor socketDescriptor(atoi(mpCoreConfig->getNetworkConfig().lanConfig.hostStreamPort.c_str()), 0);
			socketDescriptor.socketFamily = socketFamily;
			mpRakStreamPeer->SetMaximumIncomingConnections(4);
			RakNet::StartupResult sr;
			sr = mpRakStreamPeer->Startup(4, &socketDescriptor, 1);
			if (sr != RakNet::RAKNET_STARTED)
			{
				APE_LOG_DEBUG("Stream server failed to start. Error=" << sr);
			}
			APE_LOG_DEBUG("Started stream server on " << mpRakStreamPeer->GetMyBoundAddress().ToString(true));
		}
		else
		{
			mIsStreamHost = false;
			mpRakStreamPeer->SetTimeoutTime(5000, RakNet::UNASSIGNED_SYSTEM_ADDRESS);
			RakNet::SocketDescriptor socketDescriptor(0, 0);
			socketDescriptor.socketFamily = socketFamily;
			RakNet::StartupResult sr;
			sr = mpRakStreamPeer->Startup(4, &socketDescriptor, 1);
			if (sr != RakNet::RAKNET_STARTED)
			{
				APE_LOG_DEBUG("Stream client failed to start. Error=" << sr);
			}
			APE_LOG_DEBUG("Started stream client on " << mpRakStreamPeer->GetMyBoundAddress().ToString(true));
		}
	}
}

void ape::SceneNetworkImpl::connect2ReplicaHost(std::string guid)
{
	mReplicaHostGuid.FromString(guid.c_str());
	if (mpCoreConfig->getNetworkConfig().selected == ape::NetworkConfig::INTERNET)
	{
		APE_LOG_DEBUG("Try to NAT punch to: " << mReplicaHostGuid.ToString());
		if (mpNatPunchthroughClient->OpenNAT(mReplicaHostGuid, mNATServerAddress))
		{
			APE_LOG_DEBUG("Wait for server response....");
		}
		else
		{
			APE_LOG_DEBUG("Failed to connect.......");
		}
	}
	else if ((mpCoreConfig->getNetworkConfig().selected == ape::NetworkConfig::LAN))
	{
		APE_LOG_DEBUG("Try to connect to host IP: " << mpCoreConfig->getNetworkConfig().lanConfig.hostReplicaIP << " port: " << mpCoreConfig->getNetworkConfig().lanConfig.hostReplicaPort);
		RakNet::ConnectionAttemptResult car = mpRakReplicaPeer->Connect(mpCoreConfig->getNetworkConfig().lanConfig.hostReplicaIP.c_str(), atoi(mpCoreConfig->getNetworkConfig().lanConfig.hostReplicaPort.c_str()), 0, 0);
		if (car != RakNet::CONNECTION_ATTEMPT_STARTED)
		{
			APE_LOG_DEBUG("Failed connect call to " << mpCoreConfig->getNetworkConfig().lanConfig.hostReplicaPort << ". Code=" << car);
		}
		else
		{
			APE_LOG_DEBUG("Connection attempt was successful to remote system " << mpCoreConfig->getNetworkConfig().lanConfig.hostReplicaPort);
		}
	}
}

void ape::SceneNetworkImpl::leave()
{

}

void ape::SceneNetworkImpl::destroy()
{
}

void ape::SceneNetworkImpl::createReplicaHost()
{
	APE_LOG_DEBUG("Listening....");
	if (mpCoreConfig->getNetworkConfig().selected == ape::NetworkConfig::INTERNET)
		mpNatPunchthroughClient->FindRouterPortStride(mNATServerAddress);
}

bool ape::SceneNetworkImpl::isReplicaHost()
{
	return mIsReplicaHost;
}

std::string ape::SceneNetworkImpl::getGUID()
{
	return mGuid.ToString();
}

std::weak_ptr<RakNet::ReplicaManager3> ape::SceneNetworkImpl::getReplicaManager()
{
	return mpReplicaManager3;
}

ape::SceneNetwork::ParticipantType ape::SceneNetworkImpl::getParticipantType()
{
	return mParticipantType;
}

void ape::SceneNetworkImpl::runReplicaPeerListen()
{
	while (true)
	{
		listenReplicaPeer();
		std::this_thread::sleep_for (std::chrono::milliseconds(10));
	}
}

void ape::SceneNetworkImpl::listenReplicaPeer()
{
	RakNet::Packet *packet;
	for (packet = mpRakReplicaPeer->Receive(); packet; mpRakReplicaPeer->DeallocatePacket(packet), packet = mpRakReplicaPeer->Receive())
	{
		switch (packet->data[0])
		{
			case ID_NEW_INCOMING_CONNECTION:
			{
				if (mpCoreConfig->getNetworkConfig().selected == ape::NetworkConfig::INTERNET)
				{
					APE_LOG_DEBUG("ID_NEW_INCOMING_CONNECTION from " << packet->systemAddress.ToString() << " guid: " << packet->guid.ToString());
				}
				else if (mpCoreConfig->getNetworkConfig().selected == ape::NetworkConfig::LAN)
				{
					if (mParticipantType == ape::SceneNetwork::HOST)
					{
						RakNet::Connection_RM3 *connection = mpReplicaManager3->AllocConnection(packet->systemAddress, packet->guid);
						if (mpReplicaManager3->PushConnection(connection))
						{
							APE_LOG_DEBUG("Alloc connection to: " << packet->systemAddress.ToString() << " guid: " << packet->guid.ToString() << " was successful");
						}
						else
						{
							mpReplicaManager3->DeallocConnection(connection);
							APE_LOG_DEBUG("Alloc connection to: " << packet->systemAddress.ToString() << " guid: " << packet->guid.ToString() << " was not successful thus this was deallocated");
						}
					}
				}
			}
				break;
			case ID_DISCONNECTION_NOTIFICATION:
				APE_LOG_DEBUG("ID_DISCONNECTION_NOTIFICATION");
				break;
			case ID_CONNECTION_REQUEST_ACCEPTED:
				{
					APE_LOG_DEBUG("ID_CONNECTION_REQUEST_ACCEPTED from " << packet->systemAddress.ToString(true) << ", guid=" << packet->guid.ToString() << ", participantType=" << mParticipantType);
					if (mpCoreConfig->getNetworkConfig().selected == ape::NetworkConfig::INTERNET)
					{
						if (mNATServerIP == packet->systemAddress.ToString(false))
						{
							mNATServerAddress = packet->systemAddress;
							RakNet::ConnectionState cs = mpRakReplicaPeer->GetConnectionState(mNATServerAddress);
							if (cs == RakNet::IS_CONNECTED)
								mIsConnectedToNATServer = true;
							else
								mIsConnectedToNATServer = false;
						}
						else if (mParticipantType == ape::SceneNetwork::ParticipantType::HOST)
						{
							RakNet::Connection_RM3 *connection = mpReplicaManager3->AllocConnection(packet->systemAddress, packet->guid);
							if (mpReplicaManager3->PushConnection(connection))
							{
								APE_LOG_DEBUG("Alloc connection to: " << packet->systemAddress.ToString() << " guid: " << packet->guid.ToString() << " was successful");
							}
							else
							{
								mpReplicaManager3->DeallocConnection(connection);
								APE_LOG_DEBUG("Alloc connection to: " << packet->systemAddress.ToString() << " guid: " << packet->guid.ToString() << " was not successful thus this was deallocated");
							}
						}
					}
					else if (mpCoreConfig->getNetworkConfig().selected == ape::NetworkConfig::LAN)
					{
						if (mParticipantType == ape::SceneNetwork::ParticipantType::HOST)
						{
							mpRakReplicaPeer->GetConnectionState(packet->systemAddress);
							RakNet::ConnectionAttemptResult car = mpRakReplicaPeer->Connect(packet->systemAddress.ToString(false), packet->systemAddress.GetPort(), 0, 0);
							if (car != RakNet::CONNECTION_ATTEMPT_STARTED)
							{
								APE_LOG_DEBUG("Failed connect call to " << packet->systemAddress.ToString(true) << ". Code=" << car);
							}
							else
							{
								APE_LOG_DEBUG("Connection success from remote system " << packet->systemAddress.ToString(true));
							}
						}
						else if (mParticipantType == ape::SceneNetwork::ParticipantType::GUEST)
						{
							RakNet::Connection_RM3 *connection = mpReplicaManager3->AllocConnection(packet->systemAddress, packet->guid);
							if (mpReplicaManager3->PushConnection(connection))
							{
								APE_LOG_DEBUG("Alloc connection to: " << packet->systemAddress.ToString() << " guid: " << packet->guid.ToString() << " was successful");
							}
							else
							{
								mpReplicaManager3->DeallocConnection(connection);
								APE_LOG_DEBUG("Alloc connection to: " << packet->systemAddress.ToString() << " guid: " << packet->guid.ToString() << " was not successful thus this was deallocated");
							}
						}
					}
				}
				break;
			case ID_ALREADY_CONNECTED:
				{
					APE_LOG_DEBUG("ID_ALREADY_CONNECTED with: " << packet->systemAddress.ToString() << " guid: " << packet->guid.ToString());
					break;
				}
			case ID_INCOMPATIBLE_PROTOCOL_VERSION:
				{
					APE_LOG_DEBUG("Failed to connect to: " << packet->systemAddress.ToString() << ". Reason:" << RakNet::PacketLogger::BaseIDTOString(packet->data[0]));
					break;
				}
			case ID_NAT_TARGET_NOT_CONNECTED:
			case ID_NAT_TARGET_UNRESPONSIVE:
			case ID_NAT_CONNECTION_TO_TARGET_LOST:
			case ID_NAT_ALREADY_IN_PROGRESS:
			case ID_NAT_PUNCHTHROUGH_FAILED:
				{
					APE_LOG_DEBUG("NAT punch to: " << packet->guid.ToString() << " failed. Reason: " << RakNet::PacketLogger::BaseIDTOString(packet->data[0]));
					break;
				}
			case ID_NAT_PUNCHTHROUGH_SUCCEEDED:
				{
					if (mpCoreConfig->getNetworkConfig().selected == ape::NetworkConfig::INTERNET)
					{
						unsigned char weAreTheSender = packet->data[1];
						if (mParticipantType == ape::SceneNetwork::ParticipantType::HOST)
						{
							mpRakReplicaPeer->GetConnectionState(packet->systemAddress);
							RakNet::ConnectionAttemptResult car = mpRakReplicaPeer->Connect(packet->systemAddress.ToString(false), packet->systemAddress.GetPort(), 0, 0);
							if (car != RakNet::CONNECTION_ATTEMPT_STARTED)
							{
								APE_LOG_DEBUG("Failed connect call to " << packet->systemAddress.ToString(true) << ". Code=" << car);
							}
							else
							{
								APE_LOG_DEBUG("NAT punch success from remote system " << packet->systemAddress.ToString(true));
							}
						}
						else if (mParticipantType == ape::SceneNetwork::ParticipantType::GUEST)
						{
							if (!weAreTheSender)
							{
								mpRakReplicaPeer->GetConnectionState(packet->systemAddress);
								RakNet::ConnectionAttemptResult car = mpRakReplicaPeer->Connect(packet->systemAddress.ToString(false), packet->systemAddress.GetPort(), 0, 0);
								if (car != RakNet::CONNECTION_ATTEMPT_STARTED)
								{
									APE_LOG_DEBUG("Failed connect call to " << packet->systemAddress.ToString(true) << ". Code=" << car);
								}
								else
								{
									APE_LOG_DEBUG("NAT punch success from remote system " << packet->systemAddress.ToString(true));
								}
							}
							else
							{
								RakNet::Connection_RM3 *connection = mpReplicaManager3->AllocConnection(packet->systemAddress, packet->guid);
								if (mpReplicaManager3->PushConnection(connection))
								{
									APE_LOG_DEBUG("Alloc connection to: " << packet->systemAddress.ToString() << " guid: " << packet->guid.ToString() << " was successful");
								}
								else
								{
									mpReplicaManager3->DeallocConnection(connection);
									APE_LOG_DEBUG("Alloc connection to: " << packet->systemAddress.ToString() << " guid: " << packet->guid.ToString() << " was not successful thus this was deallocated");
								}
							}
						}
					}
				}
				break;
			case ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE:
				{
					if (mpReplicaManager3->GetAllConnectionDownloadsCompleted() == true)
					{
						APE_LOG_DEBUG("Completed all remote downloads");
						if (!mIsStreamHost)
						{
							APE_LOG_DEBUG("Try to connect to stream host: " << mpCoreConfig->getNetworkConfig().lanConfig.hostStreamIP << "|" << mpCoreConfig->getNetworkConfig().lanConfig.hostStreamPort);
							RakNet::ConnectionAttemptResult car = mpRakStreamPeer->Connect(mpCoreConfig->getNetworkConfig().lanConfig.hostStreamIP.c_str(), atoi(mpCoreConfig->getNetworkConfig().lanConfig.hostStreamPort.c_str()), 0, 0);
							APE_LOG_DEBUG("Raknet Stream Connection to Host Result: " << (int)car);
							RakAssert(car == RakNet::RAKNET_STARTED);
						}
					}
					break;
				}
			default:
			{
				//APE_LOG_DEBUG("Unknown message type" << packet->data[0]);
			}
		}
	}
}

<commit_msg>Delete ApeSceneNetworkImpl.cpp<commit_after><|endoftext|>


<commit_before>//===--- TerminalReaderUnix.cpp - Input From UNIX Terminal ------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the interface reading from a UNIX terminal. It tries to
//  support all common terminal types.
//
//  Axel Naumann <axel@cern.ch>, 2011-05-12
//===----------------------------------------------------------------------===//

#ifndef WIN32

#include "textinput/StreamReaderUnix.h"

#include "textinput/TerminalConfigUnix.h"

#include <sys/uio.h>
#include <sys/select.h>
#include <unistd.h>
#include <termios.h>
#include <stdio.h>

#include <cctype>
#include <map>
#include <list>

namespace {
  using namespace textinput;

  class Rewind {
  public:
    Rewind(std::queue<char>& rab, InputData::EExtendedInput& ret):
    RAB(rab), Ret(ret) {}

    ~Rewind() {
      if (Ret != InputData::kEIUninitialized) return;
      // RAB.push(0x1b); already handled by ProcessCSI returning false.
      while (!Q.empty()) {
        RAB.push(Q.front());
        Q.pop();
      }
    }

    void push(char C) { Q.push(C); }

  private:
    std::queue<char> Q;
    std::queue<char>& RAB;
    InputData::EExtendedInput& Ret;
  };

  class ExtKeyMap {
  public:
    ExtKeyMap& operator[](char k) {
      std::map<char, ExtKeyMap*>::iterator I = Map.find(k);
      ExtKeyMap* N = 0;
      if (I == Map.end()) {
        N = &BumpAlloc();
        Map.insert(std::make_pair(k, N));
      } else {
        N = I->second;
      }
      return *N;
    }
    ExtKeyMap& operator=(InputData::EExtendedInput ei) {
      T.EI = ei; return *this; }
    void Set(InputData::EExtendedInput ei, char m = 0) {
      T.EI = ei; T.Mod = m; }

    bool empty() const { return Map.empty(); }
    bool haveSubTree() const { return !empty(); }
    bool haveExtInp() const { return empty(); }
    InputData::EExtendedInput getExtInp() const { return T.EI; }
    char getMod() const { return T.Mod; }

    ExtKeyMap* find(char c) const {
      std::map<char, ExtKeyMap*>::const_iterator I = Map.find(c);
      if (I == Map.end()) return 0;
      return I->second;
    }

    class EKMHolder {
    public:
      EKMHolder(): Watermark(kChunkSize) {}
      ~EKMHolder() {
        for (std::list<ExtKeyMap*>::iterator i = Heap.begin(), e = Heap.end();
             i != e; ++i) {
          delete [] *i;
        }
      }
      ExtKeyMap& next() {
        if (Watermark == kChunkSize) {
          ExtKeyMap* N = new ExtKeyMap[kChunkSize]();
          Heap.push_back(N);
          Watermark = 0;
        }
        return Heap.back()[Watermark++];
      }
    private:
      static const size_t kChunkSize = 100;
      std::list<ExtKeyMap*> Heap;
      size_t Watermark;
    };

    static ExtKeyMap& BumpAlloc() {
      static EKMHolder S;
      return S.next();
    }

  private:
    std::map<char, ExtKeyMap*> Map;
    struct T_ {
      T_(): EI(InputData::kEIUninitialized), Mod(0) {}
      InputData::EExtendedInput EI;
      char Mod;
    } T;
  };
} // unnamed namespace

namespace textinput {
  StreamReaderUnix::StreamReaderUnix():
    fHaveInputFocus(false), fIsTTY(isatty(fileno(stdin))) {
#ifdef TCSANOW
    TerminalConfigUnix::Get().TIOS()->c_iflag &= ~(ISTRIP|IXOFF);
    TerminalConfigUnix::Get().TIOS()->c_iflag |= BRKINT | INLCR;
    TerminalConfigUnix::Get().TIOS()->c_lflag &= ~(ICANON|ISIG|TOSTOP|IEXTEN);
    TerminalConfigUnix::Get().TIOS()->c_cc[VMIN] = 1;
    TerminalConfigUnix::Get().TIOS()->c_cc[VTIME] = 0;
#endif
  }

  StreamReaderUnix::~StreamReaderUnix() {
    ReleaseInputFocus();
  }

  void
  StreamReaderUnix::GrabInputFocus() {
    // set to raw i.e. unbuffered
    if (fHaveInputFocus) return;
    TerminalConfigUnix::Get().Attach();
    fHaveInputFocus = true;
  }

  void
  StreamReaderUnix::ReleaseInputFocus() {
    // set to buffered
    if (!fHaveInputFocus) return;
    TerminalConfigUnix::Get().Detach();
    fHaveInputFocus = false;
  }

  bool
  StreamReaderUnix::HavePendingInput() {
    if (!fReadAheadBuffer.empty())
      return true;
    fd_set PollSet;
    FD_ZERO(&PollSet);
    FD_SET(fileno(stdin), &PollSet);
    timeval timeout = {0,0}; // sec, musec
    int avail = select(fileno(stdin) /*fd*/ + 1, &PollSet, 0, 0, &timeout);
    return (avail == 1);
  }

  bool
  StreamReaderUnix::ProcessCSI(InputData& in) {
    static ExtKeyMap gExtKeyMap;
    if (gExtKeyMap.empty()) {
      // Gnome xterm
      gExtKeyMap['[']['A'] = InputData::kEIUp;
      gExtKeyMap['[']['B'] = InputData::kEIDown;
      gExtKeyMap['[']['C'] = InputData::kEIRight;
      gExtKeyMap['[']['D'] = InputData::kEILeft;
      gExtKeyMap['[']['O']['F'] = InputData::kEIEnd;
      gExtKeyMap['[']['O']['H'] = InputData::kEIHome;
      gExtKeyMap['[']['1']['~'] = InputData::kEIHome;
      gExtKeyMap['[']['2']['~'] = InputData::kEIIns;
      gExtKeyMap['[']['3']['~'] = InputData::kEIDel;
      gExtKeyMap['[']['4']['~'] = InputData::kEIEnd;
      gExtKeyMap['[']['5']['~'] = InputData::kEIPgUp;
      gExtKeyMap['[']['6']['~'] = InputData::kEIPgDown;
      gExtKeyMap['[']['1'][';']['5']['A'].Set(InputData::kEIUp,
                                         InputData::kModCtrl);
      gExtKeyMap['[']['1'][';']['5']['B'].Set(InputData::kEIDown,
                                         InputData::kModCtrl);
      gExtKeyMap['[']['1'][';']['5']['C'].Set(InputData::kEIRight,
                                         InputData::kModCtrl);
      gExtKeyMap['[']['1'][';']['5']['D'].Set(InputData::kEILeft,
                                         InputData::kModCtrl);

      // MacOS
      gExtKeyMap['O']['A'] = InputData::kEIUp;
      gExtKeyMap['O']['B'] = InputData::kEIDown;
      gExtKeyMap['O']['C'] = InputData::kEIRight;
      gExtKeyMap['O']['D'] = InputData::kEILeft;
      gExtKeyMap['O']['F'] = InputData::kEIEnd;
      gExtKeyMap['O']['H'] = InputData::kEIHome;
      gExtKeyMap['[']['5']['C'].Set(InputData::kEIRight, InputData::kModCtrl);
      gExtKeyMap['[']['5']['D'].Set(InputData::kEILeft, InputData::kModCtrl);
    }

    InputData::EExtendedInput ret = InputData::kEIUninitialized;
    char mod = 0;
    Rewind rwd(fReadAheadBuffer, ret);
    ExtKeyMap* EKM = &gExtKeyMap;
    while (EKM) {
      if (EKM->haveExtInp()) {
        ret = EKM->getExtInp();
        mod = EKM->getMod();
        EKM = 0;
      } else {
        char c1 = ReadRawCharacter();
        rwd.push(c1);
        EKM = EKM->find(c1);
      }
    }
    in.SetExtended(ret);
    in.SetModifier(mod);
    return ret != InputData::kEIUninitialized;
  }

  bool
  StreamReaderUnix::ReadInput(size_t& nRead, InputData& in) {
    int c = ReadRawCharacter();
    if (c == -1) {
      in.SetExtended(InputData::kEIEOF);
    } else if (c == 0x1b) {
      if (!ProcessCSI(in)) {
        in.SetExtended(InputData::kEIEsc);
      }
    } else if (isprint(c)) {
      in.SetRaw(c);
    } else if (c < 32 || c == (char)127 /* ^?, DEL on MacOS */) {
      if (c == 13) {
        in.SetExtended(InputData::kEIEnter);
      } else {
        in.SetRaw(c);
        in.SetModifier(InputData::kModCtrl);
      }
    } else {
      // woohoo, what's that?!
      in.SetRaw(c);
    }
    ++nRead;
    return true;
  }
  int
  StreamReaderUnix::ReadRawCharacter() {
    char buf;
    if (!fReadAheadBuffer.empty()) {
      buf = fReadAheadBuffer.front();
      fReadAheadBuffer.pop();
    } else {
       size_t ret = read(fileno(stdin), &buf, 1);
      if (ret != 1) return -1;
    }
    return buf;
  }
}

#endif // ifndef WIN32
<commit_msg>Solaris: FD_ZERO uses memset().<commit_after>//===--- TerminalReaderUnix.cpp - Input From UNIX Terminal ------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the interface reading from a UNIX terminal. It tries to
//  support all common terminal types.
//
//  Axel Naumann <axel@cern.ch>, 2011-05-12
//===----------------------------------------------------------------------===//

#ifndef WIN32

#include "textinput/StreamReaderUnix.h"

#include "textinput/TerminalConfigUnix.h"

#include <sys/uio.h>
#include <sys/select.h>
#include <unistd.h>
#include <termios.h>
#include <stdio.h>

#include <cctype>
#include <cstring>
#include <map>
#include <list>

namespace {
  using namespace textinput;
  using std::memset; // FD_ZERO

  class Rewind {
  public:
    Rewind(std::queue<char>& rab, InputData::EExtendedInput& ret):
    RAB(rab), Ret(ret) {}

    ~Rewind() {
      if (Ret != InputData::kEIUninitialized) return;
      // RAB.push(0x1b); already handled by ProcessCSI returning false.
      while (!Q.empty()) {
        RAB.push(Q.front());
        Q.pop();
      }
    }

    void push(char C) { Q.push(C); }

  private:
    std::queue<char> Q;
    std::queue<char>& RAB;
    InputData::EExtendedInput& Ret;
  };

  class ExtKeyMap {
  public:
    ExtKeyMap& operator[](char k) {
      std::map<char, ExtKeyMap*>::iterator I = Map.find(k);
      ExtKeyMap* N = 0;
      if (I == Map.end()) {
        N = &BumpAlloc();
        Map.insert(std::make_pair(k, N));
      } else {
        N = I->second;
      }
      return *N;
    }
    ExtKeyMap& operator=(InputData::EExtendedInput ei) {
      T.EI = ei; return *this; }
    void Set(InputData::EExtendedInput ei, char m = 0) {
      T.EI = ei; T.Mod = m; }

    bool empty() const { return Map.empty(); }
    bool haveSubTree() const { return !empty(); }
    bool haveExtInp() const { return empty(); }
    InputData::EExtendedInput getExtInp() const { return T.EI; }
    char getMod() const { return T.Mod; }

    ExtKeyMap* find(char c) const {
      std::map<char, ExtKeyMap*>::const_iterator I = Map.find(c);
      if (I == Map.end()) return 0;
      return I->second;
    }

    class EKMHolder {
    public:
      EKMHolder(): Watermark(kChunkSize) {}
      ~EKMHolder() {
        for (std::list<ExtKeyMap*>::iterator i = Heap.begin(), e = Heap.end();
             i != e; ++i) {
          delete [] *i;
        }
      }
      ExtKeyMap& next() {
        if (Watermark == kChunkSize) {
          ExtKeyMap* N = new ExtKeyMap[kChunkSize]();
          Heap.push_back(N);
          Watermark = 0;
        }
        return Heap.back()[Watermark++];
      }
    private:
      static const size_t kChunkSize = 100;
      std::list<ExtKeyMap*> Heap;
      size_t Watermark;
    };

    static ExtKeyMap& BumpAlloc() {
      static EKMHolder S;
      return S.next();
    }

  private:
    std::map<char, ExtKeyMap*> Map;
    struct T_ {
      T_(): EI(InputData::kEIUninitialized), Mod(0) {}
      InputData::EExtendedInput EI;
      char Mod;
    } T;
  };
} // unnamed namespace

namespace textinput {
  StreamReaderUnix::StreamReaderUnix():
    fHaveInputFocus(false), fIsTTY(isatty(fileno(stdin))) {
#ifdef TCSANOW
    TerminalConfigUnix::Get().TIOS()->c_iflag &= ~(ISTRIP|IXOFF);
    TerminalConfigUnix::Get().TIOS()->c_iflag |= BRKINT | INLCR;
    TerminalConfigUnix::Get().TIOS()->c_lflag &= ~(ICANON|ISIG|TOSTOP|IEXTEN);
    TerminalConfigUnix::Get().TIOS()->c_cc[VMIN] = 1;
    TerminalConfigUnix::Get().TIOS()->c_cc[VTIME] = 0;
#endif
  }

  StreamReaderUnix::~StreamReaderUnix() {
    ReleaseInputFocus();
  }

  void
  StreamReaderUnix::GrabInputFocus() {
    // set to raw i.e. unbuffered
    if (fHaveInputFocus) return;
    TerminalConfigUnix::Get().Attach();
    fHaveInputFocus = true;
  }

  void
  StreamReaderUnix::ReleaseInputFocus() {
    // set to buffered
    if (!fHaveInputFocus) return;
    TerminalConfigUnix::Get().Detach();
    fHaveInputFocus = false;
  }

  bool
  StreamReaderUnix::HavePendingInput() {
    if (!fReadAheadBuffer.empty())
      return true;
    fd_set PollSet;
    FD_ZERO(&PollSet);
    FD_SET(fileno(stdin), &PollSet);
    timeval timeout = {0,0}; // sec, musec
    int avail = select(fileno(stdin) /*fd*/ + 1, &PollSet, 0, 0, &timeout);
    return (avail == 1);
  }

  bool
  StreamReaderUnix::ProcessCSI(InputData& in) {
    static ExtKeyMap gExtKeyMap;
    if (gExtKeyMap.empty()) {
      // Gnome xterm
      gExtKeyMap['[']['A'] = InputData::kEIUp;
      gExtKeyMap['[']['B'] = InputData::kEIDown;
      gExtKeyMap['[']['C'] = InputData::kEIRight;
      gExtKeyMap['[']['D'] = InputData::kEILeft;
      gExtKeyMap['[']['O']['F'] = InputData::kEIEnd;
      gExtKeyMap['[']['O']['H'] = InputData::kEIHome;
      gExtKeyMap['[']['1']['~'] = InputData::kEIHome;
      gExtKeyMap['[']['2']['~'] = InputData::kEIIns;
      gExtKeyMap['[']['3']['~'] = InputData::kEIDel;
      gExtKeyMap['[']['4']['~'] = InputData::kEIEnd;
      gExtKeyMap['[']['5']['~'] = InputData::kEIPgUp;
      gExtKeyMap['[']['6']['~'] = InputData::kEIPgDown;
      gExtKeyMap['[']['1'][';']['5']['A'].Set(InputData::kEIUp,
                                         InputData::kModCtrl);
      gExtKeyMap['[']['1'][';']['5']['B'].Set(InputData::kEIDown,
                                         InputData::kModCtrl);
      gExtKeyMap['[']['1'][';']['5']['C'].Set(InputData::kEIRight,
                                         InputData::kModCtrl);
      gExtKeyMap['[']['1'][';']['5']['D'].Set(InputData::kEILeft,
                                         InputData::kModCtrl);

      // MacOS
      gExtKeyMap['O']['A'] = InputData::kEIUp;
      gExtKeyMap['O']['B'] = InputData::kEIDown;
      gExtKeyMap['O']['C'] = InputData::kEIRight;
      gExtKeyMap['O']['D'] = InputData::kEILeft;
      gExtKeyMap['O']['F'] = InputData::kEIEnd;
      gExtKeyMap['O']['H'] = InputData::kEIHome;
      gExtKeyMap['[']['5']['C'].Set(InputData::kEIRight, InputData::kModCtrl);
      gExtKeyMap['[']['5']['D'].Set(InputData::kEILeft, InputData::kModCtrl);
    }

    InputData::EExtendedInput ret = InputData::kEIUninitialized;
    char mod = 0;
    Rewind rwd(fReadAheadBuffer, ret);
    ExtKeyMap* EKM = &gExtKeyMap;
    while (EKM) {
      if (EKM->haveExtInp()) {
        ret = EKM->getExtInp();
        mod = EKM->getMod();
        EKM = 0;
      } else {
        char c1 = ReadRawCharacter();
        rwd.push(c1);
        EKM = EKM->find(c1);
      }
    }
    in.SetExtended(ret);
    in.SetModifier(mod);
    return ret != InputData::kEIUninitialized;
  }

  bool
  StreamReaderUnix::ReadInput(size_t& nRead, InputData& in) {
    int c = ReadRawCharacter();
    if (c == -1) {
      in.SetExtended(InputData::kEIEOF);
    } else if (c == 0x1b) {
      if (!ProcessCSI(in)) {
        in.SetExtended(InputData::kEIEsc);
      }
    } else if (isprint(c)) {
      in.SetRaw(c);
    } else if (c < 32 || c == (char)127 /* ^?, DEL on MacOS */) {
      if (c == 13) {
        in.SetExtended(InputData::kEIEnter);
      } else {
        in.SetRaw(c);
        in.SetModifier(InputData::kModCtrl);
      }
    } else {
      // woohoo, what's that?!
      in.SetRaw(c);
    }
    ++nRead;
    return true;
  }
  int
  StreamReaderUnix::ReadRawCharacter() {
    char buf;
    if (!fReadAheadBuffer.empty()) {
      buf = fReadAheadBuffer.front();
      fReadAheadBuffer.pop();
    } else {
       size_t ret = read(fileno(stdin), &buf, 1);
      if (ret != 1) return -1;
    }
    return buf;
  }
}

#endif // ifndef WIN32
<|endoftext|>


<commit_before>#include <cstdlib>
#include <HsFFI.h>
#include <QtCore/QAtomicInt>
#include <QtCore/QMetaObject>
#include <QtCore/QString>
#include <QtCore/QDebug>

#include "hsqml.h"
#include "HsQMLClass.h"
#include "HsQMLManager.h"

enum MDFields {
    MD_METHOD_COUNT   = 4,
    MD_PROPERTY_COUNT = 6,
};

QAtomicInt gClassId;

namespace QDeclarativePrivate
{
    enum RegistrationType {
        TypeRegistration = 0
    };

    int Q_DECLARATIVE_EXPORT qmlregister(RegistrationType, void*);
};

struct RegisterType {
    int version;

    int typeId;
    int listId;

    int objectSize;
    void (*create)(void*);

    QString noCreationReason;

    const char* uri;
    int versionMajor;
    int versionMinor;
    const char* elementName;
    const QMetaObject* metaObject;

    void* attachedPropertiesFunction;
    const QMetaObject* attachedPropertiesMetaObject;

    int parserStatusCast;
    int valueSourceCast;
    int valueInterceptorCast;

    QObject* (*extensionObjectCreate)(QObject *);
    const QMetaObject* extensionMetaObject;

    void* customParser;
    int revision;
};

static void* newObjectPtr(const void* pp)
{
    if (pp) {
        return new void*(*static_cast<void* const*>(pp));
    }
    else {
        return new void*();
    }
}

static void deleteObjectPtr(void* p)
{
    delete reinterpret_cast<void**>(p);
}

HsQMLClass::HsQMLClass(
    unsigned int*  metaData,
    char*          metaStrData,
    HsQMLUniformFunc* methods,
    HsQMLUniformFunc* properties)
    : mRefCount(0)
    , mMetaData(metaData)
    , mMetaStrData(metaStrData)
    , mMethods(methods)
    , mProperties(properties)
    , mMethodCount(metaData[MD_METHOD_COUNT])
    , mPropertyCount(metaData[MD_PROPERTY_COUNT])
{
    ref(Handle);

    // Create meta-object
    QMetaObject tmp = {
          &QObject::staticMetaObject,
          mMetaStrData,
          mMetaData,
          0};
    mMetaObject = new QMetaObject(tmp);

    // Register with Qt meta-type system
    QByteArray rawName(name());
    QByteArray pointerName(rawName + '*');
    int pointerType = QMetaType::registerType(
        pointerName, deleteObjectPtr, newObjectPtr);

    // Register with QML meta-type system
    RegisterType regInfo = {
        0,
        pointerType, 0,
        0, 0,
        QString(),
        0, 0, 0, 0, mMetaObject,
        0, 0,
        -1, -1, -1,
        0, 0,
        0,
        0
    };
    QDeclarativePrivate::qmlregister(
        QDeclarativePrivate::TypeRegistration, &regInfo);
}

HsQMLClass::~HsQMLClass()
{
    for (int i=0; i<mMethodCount; i++) {
        gManager->freeFun((HsFunPtr)mMethods[i]);
    }
    for (unsigned int i=0; i<2*mPropertyCount; i++) {
        if (mProperties[i]) {
            gManager->freeFun((HsFunPtr)mProperties[i]);
        }
    }
    std::free(mMetaData);
    std::free(mMetaStrData);
    std::free(mMethods);
    std::free(mProperties);

    // Leak QMetaObject because there is no way to unregister it
    //delete mMetaObject;
}

const char* HsQMLClass::name()
{
    return mMetaObject->className();
}

int HsQMLClass::methodCount()
{
    return mMethodCount;
}

int HsQMLClass::propertyCount()
{
    return mPropertyCount;
}

const HsQMLUniformFunc* HsQMLClass::methods()
{
    return mMethods;
}

const HsQMLUniformFunc* HsQMLClass::properties()
{
    return mProperties;
}

const QMetaObject* HsQMLClass::metaObj()
{
    return mMetaObject;
}

void HsQMLClass::ref(RefSrc src)
{
    int count = mRefCount.fetchAndAddOrdered(1);

    if (gLogLevel >= (count == 0 ? 1 : 2)) {
        qDebug() << QString().sprintf(
            "HsQML: %s Class, name=%s, src=%d, count=%d.",
            count ? "Ref" : "New", name(), src, count+1);
    }
}

void HsQMLClass::deref(RefSrc src)
{
    int count = mRefCount.fetchAndAddOrdered(-1);

    if (gLogLevel >= (count == 1 ? 1 : 2)) {
        qDebug() << QString().sprintf(
            "HsQML: %s Class, name=%s, src=%d, count=%d.",
            count > 1 ? "Deref" : "Delete", name(), src, count);
    }

    if (count == 1) {
        delete this;
    }
}

extern "C" int hsqml_get_next_class_id()
{
    return gClassId.fetchAndAddRelaxed(1);
}

extern "C" HsQMLClassHandle* hsqml_create_class(
    unsigned int*  metaData,
    char*          metaStrData,
    HsQMLUniformFunc* methods,
    HsQMLUniformFunc* properties)
{
    HsQMLClass* klass = new HsQMLClass(
            metaData, metaStrData, methods, properties);
    return (HsQMLClassHandle*)klass;
}

extern "C" void hsqml_finalise_class_handle(
    HsQMLClassHandle* hndl)
{
    HsQMLClass* klass = (HsQMLClass*)hndl;
    klass->deref(HsQMLClass::Handle);
}
<commit_msg>Fix crash when logging class creation.<commit_after>#include <cstdlib>
#include <HsFFI.h>
#include <QtCore/QAtomicInt>
#include <QtCore/QMetaObject>
#include <QtCore/QString>
#include <QtCore/QDebug>

#include "hsqml.h"
#include "HsQMLClass.h"
#include "HsQMLManager.h"

enum MDFields {
    MD_METHOD_COUNT   = 4,
    MD_PROPERTY_COUNT = 6,
};

QAtomicInt gClassId;

namespace QDeclarativePrivate
{
    enum RegistrationType {
        TypeRegistration = 0
    };

    int Q_DECLARATIVE_EXPORT qmlregister(RegistrationType, void*);
};

struct RegisterType {
    int version;

    int typeId;
    int listId;

    int objectSize;
    void (*create)(void*);

    QString noCreationReason;

    const char* uri;
    int versionMajor;
    int versionMinor;
    const char* elementName;
    const QMetaObject* metaObject;

    void* attachedPropertiesFunction;
    const QMetaObject* attachedPropertiesMetaObject;

    int parserStatusCast;
    int valueSourceCast;
    int valueInterceptorCast;

    QObject* (*extensionObjectCreate)(QObject *);
    const QMetaObject* extensionMetaObject;

    void* customParser;
    int revision;
};

static void* newObjectPtr(const void* pp)
{
    if (pp) {
        return new void*(*static_cast<void* const*>(pp));
    }
    else {
        return new void*();
    }
}

static void deleteObjectPtr(void* p)
{
    delete reinterpret_cast<void**>(p);
}

HsQMLClass::HsQMLClass(
    unsigned int*  metaData,
    char*          metaStrData,
    HsQMLUniformFunc* methods,
    HsQMLUniformFunc* properties)
    : mRefCount(0)
    , mMetaData(metaData)
    , mMetaStrData(metaStrData)
    , mMethods(methods)
    , mProperties(properties)
    , mMethodCount(metaData[MD_METHOD_COUNT])
    , mPropertyCount(metaData[MD_PROPERTY_COUNT])
{
    // Create meta-object
    QMetaObject tmp = {
          &QObject::staticMetaObject,
          mMetaStrData,
          mMetaData,
          0};
    mMetaObject = new QMetaObject(tmp);

    // Register with Qt meta-type system
    QByteArray rawName(name());
    QByteArray pointerName(rawName + '*');
    int pointerType = QMetaType::registerType(
        pointerName, deleteObjectPtr, newObjectPtr);

    // Register with QML meta-type system
    RegisterType regInfo = {
        0,
        pointerType, 0,
        0, 0,
        QString(),
        0, 0, 0, 0, mMetaObject,
        0, 0,
        -1, -1, -1,
        0, 0,
        0,
        0
    };
    QDeclarativePrivate::qmlregister(
        QDeclarativePrivate::TypeRegistration, &regInfo);

    // Add reference
    ref(Handle);
}

HsQMLClass::~HsQMLClass()
{
    for (int i=0; i<mMethodCount; i++) {
        gManager->freeFun((HsFunPtr)mMethods[i]);
    }
    for (unsigned int i=0; i<2*mPropertyCount; i++) {
        if (mProperties[i]) {
            gManager->freeFun((HsFunPtr)mProperties[i]);
        }
    }
    std::free(mMetaData);
    std::free(mMetaStrData);
    std::free(mMethods);
    std::free(mProperties);

    // Leak QMetaObject because there is no way to unregister it
    //delete mMetaObject;
}

const char* HsQMLClass::name()
{
    return mMetaObject->className();
}

int HsQMLClass::methodCount()
{
    return mMethodCount;
}

int HsQMLClass::propertyCount()
{
    return mPropertyCount;
}

const HsQMLUniformFunc* HsQMLClass::methods()
{
    return mMethods;
}

const HsQMLUniformFunc* HsQMLClass::properties()
{
    return mProperties;
}

const QMetaObject* HsQMLClass::metaObj()
{
    return mMetaObject;
}

void HsQMLClass::ref(RefSrc src)
{
    int count = mRefCount.fetchAndAddOrdered(1);

    if (gLogLevel >= (count == 0 ? 1 : 2)) {
        qDebug() << QString().sprintf(
            "HsQML: %s Class, name=%s, src=%d, count=%d.",
            count ? "Ref" : "New", name(), src, count+1);
    }
}

void HsQMLClass::deref(RefSrc src)
{
    int count = mRefCount.fetchAndAddOrdered(-1);

    if (gLogLevel >= (count == 1 ? 1 : 2)) {
        qDebug() << QString().sprintf(
            "HsQML: %s Class, name=%s, src=%d, count=%d.",
            count > 1 ? "Deref" : "Delete", name(), src, count);
    }

    if (count == 1) {
        delete this;
    }
}

extern "C" int hsqml_get_next_class_id()
{
    return gClassId.fetchAndAddRelaxed(1);
}

extern "C" HsQMLClassHandle* hsqml_create_class(
    unsigned int*  metaData,
    char*          metaStrData,
    HsQMLUniformFunc* methods,
    HsQMLUniformFunc* properties)
{
    HsQMLClass* klass = new HsQMLClass(
            metaData, metaStrData, methods, properties);
    return (HsQMLClassHandle*)klass;
}

extern "C" void hsqml_finalise_class_handle(
    HsQMLClassHandle* hndl)
{
    HsQMLClass* klass = (HsQMLClass*)hndl;
    klass->deref(HsQMLClass::Handle);
}
<|endoftext|>