<commit_before>/*************************************************************************
 *
 *  $RCSfile: AColumn.cxx,v $
 *
 *  $Revision: 1.21 $
 *
 *  last change: $Author: vg $ $Date: 2003-04-15 17:36:12 $
 *
 *  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_ADO_COLUMN_HXX_
#include "ado/AColumn.hxx"
#endif
#ifndef _CONNECTIVITY_ADO_ACONNECTION_HXX_
#include "ado/AConnection.hxx"
#endif
#ifndef _CONNECTIVITY_ADO_AWRAPADO_HXX_
#include "ado/Awrapado.hxx"
#endif
#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx>
#endif
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_
#include <com/sun/star/sdbc/ColumnValue.hpp>
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef _CONNECTIVITY_ADO_CATALOG_HXX_
#include "ado/ACatalog.hxx"
#endif

using namespace ::comphelper;

using namespace connectivity::ado;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::sdbc;

void WpADOColumn::Create()
{
    IClassFactory2* pIUnknown   = NULL;
    IUnknown        *pOuter     = NULL;
    HRESULT         hr = -1;

    _ADOColumn* pColumn = NULL;
    hr = CoCreateInstance(ADOS::CLSID_ADOCOLUMN_25,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          ADOS::IID_ADOCOLUMN_25,
                          (void**)&pColumn );

    if( !FAILED( hr ) )
    {
        operator=( pColumn );
        pColumn->Release( );
    }
}
// -------------------------------------------------------------------------
OAdoColumn::OAdoColumn(sal_Bool _bCase,OConnection* _pConnection,_ADOColumn* _pColumn)
    : connectivity::sdbcx::OColumn(::rtl::OUString(),::rtl::OUString(),::rtl::OUString(),0,0,0,0,sal_False,sal_False,sal_False,_bCase)
    ,m_pConnection(_pConnection)
{
    construct();
    OSL_ENSURE(_pColumn,"Column can not be null!");
    m_aColumn = WpADOColumn(_pColumn);
    //  m_aColumn.put_ParentCatalog(_pConnection->getAdoCatalog()->getCatalog());
    fillPropertyValues();
}
// -------------------------------------------------------------------------
OAdoColumn::OAdoColumn(sal_Bool _bCase,OConnection* _pConnection)
    : connectivity::sdbcx::OColumn(_bCase)
    ,m_pConnection(_pConnection)
{
    m_aColumn.Create();
    m_aColumn.put_ParentCatalog(_pConnection->getAdoCatalog()->getCatalog());
    construct();
    fillPropertyValues();
    m_Type = DataType::OTHER;
}

//--------------------------------------------------------------------------
Sequence< sal_Int8 > OAdoColumn::getUnoTunnelImplementationId()
{
    static ::cppu::OImplementationId * pId = 0;
    if (! pId)
    {
        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
        if (! pId)
        {
            static ::cppu::OImplementationId aId;
            pId = &aId;
        }
    }
    return pId->getImplementationId();
}

// com::sun::star::lang::XUnoTunnel
//------------------------------------------------------------------
sal_Int64 OAdoColumn::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException)
{
    return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(),  rId.getConstArray(), 16 ) )
                ?
            (sal_Int64)this
                :
            OColumn_ADO::getSomething(rId);
}
// -------------------------------------------------------------------------
void OAdoColumn::construct()
{
    sal_Int32 nAttrib = isNew() ? 0 : PropertyAttribute::READONLY;

    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISASCENDING),     PROPERTY_ID_ISASCENDING,    nAttrib,&m_IsAscending, ::getBooleanCppuType());
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RELATEDCOLUMN),   PROPERTY_ID_RELATEDCOLUMN,  nAttrib,&m_ReferencedColumn,    ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
}
// -----------------------------------------------------------------------------
void OAdoColumn::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue)throw (Exception)
{
    if(m_aColumn.IsValid())
    {
        const sal_Char* pAdoPropertyName = NULL;

        switch(nHandle)
        {
            case PROPERTY_ID_ISASCENDING:
                m_aColumn.put_SortOrder(::cppu::any2bool(rValue) ? adSortAscending : adSortDescending);
                break;
            case PROPERTY_ID_RELATEDCOLUMN:
                {
                    ::rtl::OUString aVal;
                    rValue >>= aVal;
                    m_aColumn.put_RelatedColumn(aVal);
                }
                break;
            case PROPERTY_ID_NAME:
                {
                    ::rtl::OUString aVal;
                    rValue >>= aVal;
                    m_aColumn.put_Name(aVal);
                }
                break;
            case PROPERTY_ID_TYPE:
                {
                    sal_Int32 nVal=0;
                    rValue >>= nVal;
                    sal_Bool bForceTo;
                    const OTypeInfoMap* pTypeInfoMap = m_pConnection->getTypeInfo();
                    const OExtendedTypeInfo* pTypeInfo = OConnection::getTypeInfoFromType(  *m_pConnection->getTypeInfo()
                                                                                ,nVal
                                                                                ,m_TypeName
                                                                                ,m_Precision
                                                                                ,m_Scale
                                                                                ,ADOS::MapJdbc2ADOType(nVal,m_pConnection->getEngineType())
                                                                                ,bForceTo);
                    if ( pTypeInfo )
                        m_aColumn.put_Type(static_cast<DataTypeEnum>(pTypeInfo->eType));
                    else
                        m_aColumn.put_Type(ADOS::MapJdbc2ADOType(nVal,m_pConnection->getEngineType()));
                }
                break;
            case PROPERTY_ID_TYPENAME:
                //  rValue <<= m_pTable->getCatalog()->getConnection()->getTypeInfo()->find();
                break;
            case PROPERTY_ID_PRECISION:
                {
                    sal_Int32 nVal=0;
                    rValue >>= nVal;
                    m_aColumn.put_Precision(nVal);
                }
                break;
            case PROPERTY_ID_SCALE:
                {
                    sal_Int32 nVal=0;
                    rValue >>= nVal;
                    m_aColumn.put_NumericScale((sal_Int8)nVal);
                }
                break;
            case PROPERTY_ID_ISNULLABLE:
                {
                    sal_Int32 nVal=0;
                    rValue >>= nVal;
                    if ( nVal == ColumnValue::NULLABLE )
                        m_aColumn.put_Attributes( adColNullable );
                }
                break;
            case PROPERTY_ID_ISROWVERSION:
                break;

            case PROPERTY_ID_ISAUTOINCREMENT:
                OTools::putValue( m_aColumn.get_Properties(), ::rtl::OUString::createFromAscii( "Autoincrement" ), getBOOL( rValue ) );
                break;

            case PROPERTY_ID_DESCRIPTION:
                pAdoPropertyName = "Default";
                break;

            case PROPERTY_ID_DEFAULTVALUE:
                pAdoPropertyName = "Description";
                break;
        }

        if ( pAdoPropertyName )
            OTools::putValue( m_aColumn.get_Properties(), ::rtl::OUString::createFromAscii( pAdoPropertyName ), getString( rValue ) );
    }
    OColumn_ADO::setFastPropertyValue_NoBroadcast(nHandle,rValue);
}
// -----------------------------------------------------------------------------
void OAdoColumn::fillPropertyValues()
{
    if(m_aColumn.IsValid())
    {
        m_IsAscending = m_aColumn.get_SortOrder() == adSortAscending;
        m_ReferencedColumn = m_aColumn.get_RelatedColumn();
        m_Name = m_aColumn.get_Name();
        m_Precision     = m_aColumn.get_Precision();
        m_Scale         = m_aColumn.get_NumericScale();
        m_IsNullable    = ((m_aColumn.get_Attributes() & adColNullable) == adColNullable) ? ColumnValue::NULLABLE : ColumnValue::NO_NULLS;
        m_IsCurrency    = (m_aColumn.get_Type() == adCurrency);
        m_Type = ADOS::MapADOType2Jdbc(m_aColumn.get_Type());

        sal_Bool bForceTo = sal_True;
        const OTypeInfoMap* pTypeInfoMap = m_pConnection->getTypeInfo();
        const OExtendedTypeInfo* pTypeInfo = OConnection::getTypeInfoFromType(*m_pConnection->getTypeInfo(),m_Type,::rtl::OUString(),m_Precision,m_Scale,m_aColumn.get_Type(),bForceTo);
        if ( pTypeInfo )
                m_TypeName = pTypeInfo->aSimpleType.aTypeName;

        // fill some specific props
        {
            WpADOProperties aProps( m_aColumn.get_Properties() );

            if ( aProps.IsValid() )
            {
                m_IsAutoIncrement = OTools::getValue( aProps, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Autoincrement")) );

                m_Description = OTools::getValue( aProps, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Description")) );

                m_DefaultValue = OTools::getValue( aProps, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Default")) );

#if OSL_DEBUG_LEVEL > 0
                sal_Int32 nCount = aProps.GetItemCount();
                for (sal_Int32 i = 0; i<nCount; ++i)
                {
                    WpADOProperty aProp = aProps.GetItem(i);
                    ::rtl::OUString sName = aProp.GetName();
                    ::rtl::OUString sVal = aProp.GetValue();
                }
#endif
            }
        }
    }
}
// -----------------------------------------------------------------------------
WpADOColumn OAdoColumn::getColumnImpl() const
{
    return m_aColumn;
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void SAL_CALL OAdoColumn::acquire() throw(::com::sun::star::uno::RuntimeException)
{
    OColumn_ADO::acquire();
}
// -----------------------------------------------------------------------------
void SAL_CALL OAdoColumn::release() throw(::com::sun::star::uno::RuntimeException)
{
    OColumn_ADO::release();
}
// -----------------------------------------------------------------------------

<commit_msg>INTEGRATION: CWS oj07 (1.21.52); FILE MERGED 2003/08/22 09:21:04 oj 1.21.52.1: #109720# typehandling for ado adjusted<commit_after>/*************************************************************************
 *
 *  $RCSfile: AColumn.cxx,v $
 *
 *  $Revision: 1.22 $
 *
 *  last change: $Author: rt $ $Date: 2004-03-02 12:32:28 $
 *
 *  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_ADO_COLUMN_HXX_
#include "ado/AColumn.hxx"
#endif
#ifndef _CONNECTIVITY_ADO_ACONNECTION_HXX_
#include "ado/AConnection.hxx"
#endif
#ifndef _CONNECTIVITY_ADO_AWRAPADO_HXX_
#include "ado/Awrapado.hxx"
#endif
#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx>
#endif
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_
#include <com/sun/star/sdbc/ColumnValue.hpp>
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef _CONNECTIVITY_ADO_CATALOG_HXX_
#include "ado/ACatalog.hxx"
#endif

using namespace ::comphelper;

using namespace connectivity::ado;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::sdbc;

void WpADOColumn::Create()
{
    IClassFactory2* pIUnknown   = NULL;
    IUnknown        *pOuter     = NULL;
    HRESULT         hr = -1;

    _ADOColumn* pColumn = NULL;
    hr = CoCreateInstance(ADOS::CLSID_ADOCOLUMN_25,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          ADOS::IID_ADOCOLUMN_25,
                          (void**)&pColumn );

    if( !FAILED( hr ) )
    {
        operator=( pColumn );
        pColumn->Release( );
    }
}
// -------------------------------------------------------------------------
OAdoColumn::OAdoColumn(sal_Bool _bCase,OConnection* _pConnection,_ADOColumn* _pColumn)
    : connectivity::sdbcx::OColumn(::rtl::OUString(),::rtl::OUString(),::rtl::OUString(),0,0,0,0,sal_False,sal_False,sal_False,_bCase)
    ,m_pConnection(_pConnection)
{
    construct();
    OSL_ENSURE(_pColumn,"Column can not be null!");
    m_aColumn = WpADOColumn(_pColumn);
    //  m_aColumn.put_ParentCatalog(_pConnection->getAdoCatalog()->getCatalog());
    fillPropertyValues();
}
// -------------------------------------------------------------------------
OAdoColumn::OAdoColumn(sal_Bool _bCase,OConnection* _pConnection)
    : connectivity::sdbcx::OColumn(_bCase)
    ,m_pConnection(_pConnection)
{
    m_aColumn.Create();
    m_aColumn.put_ParentCatalog(_pConnection->getAdoCatalog()->getCatalog());
    construct();
    fillPropertyValues();
    m_Type = DataType::OTHER;
}

//--------------------------------------------------------------------------
Sequence< sal_Int8 > OAdoColumn::getUnoTunnelImplementationId()
{
    static ::cppu::OImplementationId * pId = 0;
    if (! pId)
    {
        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
        if (! pId)
        {
            static ::cppu::OImplementationId aId;
            pId = &aId;
        }
    }
    return pId->getImplementationId();
}

// com::sun::star::lang::XUnoTunnel
//------------------------------------------------------------------
sal_Int64 OAdoColumn::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException)
{
    return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(),  rId.getConstArray(), 16 ) )
                ?
            (sal_Int64)this
                :
            OColumn_ADO::getSomething(rId);
}
// -------------------------------------------------------------------------
void OAdoColumn::construct()
{
    sal_Int32 nAttrib = isNew() ? 0 : PropertyAttribute::READONLY;

    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISASCENDING),     PROPERTY_ID_ISASCENDING,    nAttrib,&m_IsAscending, ::getBooleanCppuType());
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RELATEDCOLUMN),   PROPERTY_ID_RELATEDCOLUMN,  nAttrib,&m_ReferencedColumn,    ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
}
// -----------------------------------------------------------------------------
void OAdoColumn::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue)throw (Exception)
{
    if(m_aColumn.IsValid())
    {
        const sal_Char* pAdoPropertyName = NULL;

        switch(nHandle)
        {
            case PROPERTY_ID_ISASCENDING:
                m_aColumn.put_SortOrder(::cppu::any2bool(rValue) ? adSortAscending : adSortDescending);
                break;
            case PROPERTY_ID_RELATEDCOLUMN:
                {
                    ::rtl::OUString aVal;
                    rValue >>= aVal;
                    m_aColumn.put_RelatedColumn(aVal);
                }
                break;
            case PROPERTY_ID_NAME:
                {
                    ::rtl::OUString aVal;
                    rValue >>= aVal;
                    m_aColumn.put_Name(aVal);
                }
                break;
            case PROPERTY_ID_TYPE:
                {
                    sal_Int32 nVal=0;
                    rValue >>= nVal;
                    m_aColumn.put_Type(ADOS::MapJdbc2ADOType(nVal,m_pConnection->getEngineType()));
                }
                break;
            case PROPERTY_ID_TYPENAME:
                //  rValue <<= m_pTable->getCatalog()->getConnection()->getTypeInfo()->find();
                break;
            case PROPERTY_ID_PRECISION:
                {
                    sal_Int32 nVal=0;
                    rValue >>= nVal;
                    m_aColumn.put_Precision(nVal);
                }
                break;
            case PROPERTY_ID_SCALE:
                {
                    sal_Int32 nVal=0;
                    rValue >>= nVal;
                    m_aColumn.put_NumericScale((sal_Int8)nVal);
                }
                break;
            case PROPERTY_ID_ISNULLABLE:
                {
                    sal_Int32 nVal=0;
                    rValue >>= nVal;
                    if ( nVal == ColumnValue::NULLABLE )
                        m_aColumn.put_Attributes( adColNullable );
                }
                break;
            case PROPERTY_ID_ISROWVERSION:
                break;

            case PROPERTY_ID_ISAUTOINCREMENT:
                OTools::putValue( m_aColumn.get_Properties(), ::rtl::OUString::createFromAscii( "Autoincrement" ), getBOOL( rValue ) );
                break;

            case PROPERTY_ID_DESCRIPTION:
                pAdoPropertyName = "Default";
                break;

            case PROPERTY_ID_DEFAULTVALUE:
                pAdoPropertyName = "Description";
                break;
        }

        if ( pAdoPropertyName )
            OTools::putValue( m_aColumn.get_Properties(), ::rtl::OUString::createFromAscii( pAdoPropertyName ), getString( rValue ) );
    }
    OColumn_ADO::setFastPropertyValue_NoBroadcast(nHandle,rValue);
}
// -----------------------------------------------------------------------------
void OAdoColumn::fillPropertyValues()
{
    if(m_aColumn.IsValid())
    {
        m_IsAscending       = m_aColumn.get_SortOrder() == adSortAscending;
        m_ReferencedColumn  = m_aColumn.get_RelatedColumn();
        m_Name              = m_aColumn.get_Name();
        m_Precision         = m_aColumn.get_Precision();
        m_Scale             = m_aColumn.get_NumericScale();
        m_IsNullable        = ((m_aColumn.get_Attributes() & adColNullable) == adColNullable) ? ColumnValue::NULLABLE : ColumnValue::NO_NULLS;

        DataTypeEnum eType  = m_aColumn.get_Type();
        m_IsCurrency        = (eType == adCurrency);
        m_Type              = ADOS::MapADOType2Jdbc(eType);

        sal_Bool bForceTo = sal_True;
        const OTypeInfoMap* pTypeInfoMap = m_pConnection->getTypeInfo();
        const OExtendedTypeInfo* pTypeInfo = OConnection::getTypeInfoFromType(*m_pConnection->getTypeInfo(),eType,::rtl::OUString(),m_Precision,m_Scale,bForceTo);
        if ( pTypeInfo )
            m_TypeName = pTypeInfo->aSimpleType.aTypeName;
        else if ( eType == adVarBinary && ADOS::isJetEngine(m_pConnection->getEngineType()) )
        {
            ::comphelper::TStringMixEqualFunctor aCase(sal_False);
            OTypeInfoMap::const_iterator aFind = ::std::find_if(pTypeInfoMap->begin(),
                                                            pTypeInfoMap->end(),
                                                            ::std::compose1(
                                                            ::std::bind2nd(aCase, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VarBinary"))),
                                                                ::std::compose1(
                                                                    ::std::mem_fun(&OExtendedTypeInfo::getDBName),
                                                                    ::std::select2nd<OTypeInfoMap::value_type>())
                                                                )

                                                    );

            if ( aFind != pTypeInfoMap->end() ) // change column type if necessary
            {
                eType = aFind->first;
                pTypeInfo = aFind->second;
            }

            if ( !pTypeInfo )
            {
                pTypeInfo = OConnection::getTypeInfoFromType(*m_pConnection->getTypeInfo(),adBinary,::rtl::OUString(),m_Precision,m_Scale,bForceTo);
                eType = adBinary;
            }

            if ( pTypeInfo )
            {
                m_TypeName = pTypeInfo->aSimpleType.aTypeName;
                m_Type  = ADOS::MapADOType2Jdbc(eType);
            }
        }

        // fill some specific props
        {
            WpADOProperties aProps( m_aColumn.get_Properties() );

            if ( aProps.IsValid() )
            {
                m_IsAutoIncrement = OTools::getValue( aProps, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Autoincrement")) );

                m_Description = OTools::getValue( aProps, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Description")) );

                m_DefaultValue = OTools::getValue( aProps, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Default")) );

#if OSL_DEBUG_LEVEL > 0
                sal_Int32 nCount = aProps.GetItemCount();
                for (sal_Int32 i = 0; i<nCount; ++i)
                {
                    WpADOProperty aProp = aProps.GetItem(i);
                    ::rtl::OUString sName = aProp.GetName();
                    ::rtl::OUString sVal = aProp.GetValue();
                }
#endif
            }
        }
    }
}
// -----------------------------------------------------------------------------
WpADOColumn OAdoColumn::getColumnImpl() const
{
    return m_aColumn;
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void SAL_CALL OAdoColumn::acquire() throw(::com::sun::star::uno::RuntimeException)
{
    OColumn_ADO::acquire();
}
// -----------------------------------------------------------------------------
void SAL_CALL OAdoColumn::release() throw(::com::sun::star::uno::RuntimeException)
{
    OColumn_ADO::release();
}
// -----------------------------------------------------------------------------

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#include <rtl/ustring.hxx>
#include <osl/module.h>
#define  DECLARE_FN_POINTERS 1
#include "EApi.h"
static const char *eBookLibNames[] = {
    "libebook-1.2.so.15",
    "libebook-1.2.so.14", // bumped again (evolution-3.6)
    "libebook-1.2.so.13", // bumped again (evolution-3.4)
    "libebook-1.2.so.12", // bumped again
    "libebook-1.2.so.10", // bumped again
    "libebook-1.2.so.9",  // evolution-2.8
    "libebook-1.2.so.5",  // evolution-2.4 and 2.6+
    "libebook-1.2.so.3",  // evolution-2.2
    "libebook.so.8"       // evolution-2.0
};

typedef void (*SymbolFunc) (void);

#define SYM_MAP(a) { #a, reinterpret_cast<SymbolFunc *>(&a) }
struct ApiMap
{
    const char *sym_name;
    SymbolFunc *ref_value;
};

static const ApiMap aCommonApiMap[] =
{
    SYM_MAP( eds_check_version ),
    SYM_MAP( e_contact_field_name ),
    SYM_MAP( e_contact_get ),
    SYM_MAP( e_contact_get_type ),
    SYM_MAP( e_contact_field_id ),
    SYM_MAP( e_book_new ),
    SYM_MAP( e_book_open ),
    SYM_MAP( e_book_get_source ),
    SYM_MAP( e_book_get_contacts ),
    SYM_MAP( e_book_query_field_test ),
    SYM_MAP( e_book_query_and ),
    SYM_MAP( e_book_query_or ),
    SYM_MAP( e_book_query_not ),
    SYM_MAP( e_book_query_ref ),
    SYM_MAP( e_book_query_unref ),
    SYM_MAP( e_book_query_from_string ),
    SYM_MAP( e_book_query_to_string ),
    SYM_MAP( e_book_query_field_exists )
};

//< 3.6 api
static const ApiMap aOldApiMap[] =
{
    SYM_MAP( e_book_get_addressbooks ),
    SYM_MAP( e_book_get_uri ),
    SYM_MAP( e_book_authenticate_user ),
    SYM_MAP( e_source_group_peek_base_uri),
    SYM_MAP( e_source_peek_name ),
    SYM_MAP( e_source_get_property ),
    SYM_MAP( e_source_list_peek_groups ),
    SYM_MAP( e_source_group_peek_sources )
};

//>= 3.6 api
static const ApiMap aNewApiMap[] =
{
    SYM_MAP( e_source_registry_list_sources ),
    SYM_MAP( e_source_registry_new_sync ),
    SYM_MAP( e_source_has_extension ),
    SYM_MAP( e_source_get_extension ),
    SYM_MAP( e_source_backend_get_backend_name ),
    SYM_MAP( e_source_get_display_name ),
    SYM_MAP( e_source_get_uid ),
    SYM_MAP( e_source_registry_ref_source),
    SYM_MAP( e_client_open_sync ),
    SYM_MAP( e_client_get_source ),
    SYM_MAP( e_book_client_get_contacts_sync ),
    SYM_MAP( e_client_util_free_object_slist )
};

//== indirect read access (3.6 only)
static const ApiMap aClientApiMap36[] =
{
    SYM_MAP( e_book_client_new )
};

//>= direct read access API (>= 3.8)
static const ApiMap aClientApiMap38[] =
{
    SYM_MAP( e_book_client_connect_direct_sync )
};

#undef SYM_MAP

template<size_t N> static bool
tryLink( oslModule &aModule, const char *pName, const ApiMap (&pMap)[N])
{
    for (guint i = 0; i < N; ++i)
    {
        SymbolFunc aMethod = reinterpret_cast<SymbolFunc>(osl_getFunctionSymbol
            (aModule, OUString::createFromAscii ( pMap[ i ].sym_name ).pData));
        if( !aMethod )
        {
            fprintf( stderr, "Warning: missing symbol '%s' in '%s'\n",
                 pMap[ i ].sym_name, pName );
            return false;
        }
        *pMap[ i ].ref_value = aMethod;
    }
    return true;
}

bool EApiInit()
{
    oslModule aModule;

    for( guint j = 0; j < G_N_ELEMENTS( eBookLibNames ); j++ )
    {
        aModule = osl_loadModule( OUString::createFromAscii
                                  ( eBookLibNames[ j ] ).pData,
                                  SAL_LOADMODULE_DEFAULT );

        if( aModule == NULL)
            continue;

        if (tryLink( aModule, eBookLibNames[ j ], aCommonApiMap))
        {
            if (eds_check_version( 3, 6, 0 ) != NULL)
            {
                if (tryLink( aModule, eBookLibNames[ j ], aOldApiMap))
                    return true;
            }
            else if (tryLink( aModule, eBookLibNames[ j ], aNewApiMap))
            {
                if (eds_check_version( 3, 7, 6 ) != NULL)
                {
                    if (tryLink( aModule, eBookLibNames[ j ], aClientApiMap36))
                        return true;
                }
                else
                {
                    if (tryLink( aModule, eBookLibNames[ j ], aClientApiMap38))
                        return true;
                }
            }
        }

        osl_unloadModule( aModule );
    }
    fprintf( stderr, "Can find no compliant libebook client libraries\n" );
    return false;
}

ESourceRegistry *get_e_source_registry()
{
    static ESourceRegistry *theInstance;
    if (!theInstance)
        theInstance = e_source_registry_new_sync(NULL, NULL);
    return theInstance;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>add libebook-1.2.so.16 in EApi.cxx<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#include <rtl/ustring.hxx>
#include <osl/module.h>
#define  DECLARE_FN_POINTERS 1
#include "EApi.h"
static const char *eBookLibNames[] = {
    "libebook-1.2.so.16",
    "libebook-1.2.so.15",
    "libebook-1.2.so.14", // bumped again (evolution-3.6)
    "libebook-1.2.so.13", // bumped again (evolution-3.4)
    "libebook-1.2.so.12", // bumped again
    "libebook-1.2.so.10", // bumped again
    "libebook-1.2.so.9",  // evolution-2.8
    "libebook-1.2.so.5",  // evolution-2.4 and 2.6+
    "libebook-1.2.so.3",  // evolution-2.2
    "libebook.so.8"       // evolution-2.0
};

typedef void (*SymbolFunc) (void);

#define SYM_MAP(a) { #a, reinterpret_cast<SymbolFunc *>(&a) }
struct ApiMap
{
    const char *sym_name;
    SymbolFunc *ref_value;
};

static const ApiMap aCommonApiMap[] =
{
    SYM_MAP( eds_check_version ),
    SYM_MAP( e_contact_field_name ),
    SYM_MAP( e_contact_get ),
    SYM_MAP( e_contact_get_type ),
    SYM_MAP( e_contact_field_id ),
    SYM_MAP( e_book_new ),
    SYM_MAP( e_book_open ),
    SYM_MAP( e_book_get_source ),
    SYM_MAP( e_book_get_contacts ),
    SYM_MAP( e_book_query_field_test ),
    SYM_MAP( e_book_query_and ),
    SYM_MAP( e_book_query_or ),
    SYM_MAP( e_book_query_not ),
    SYM_MAP( e_book_query_ref ),
    SYM_MAP( e_book_query_unref ),
    SYM_MAP( e_book_query_from_string ),
    SYM_MAP( e_book_query_to_string ),
    SYM_MAP( e_book_query_field_exists )
};

//< 3.6 api
static const ApiMap aOldApiMap[] =
{
    SYM_MAP( e_book_get_addressbooks ),
    SYM_MAP( e_book_get_uri ),
    SYM_MAP( e_book_authenticate_user ),
    SYM_MAP( e_source_group_peek_base_uri),
    SYM_MAP( e_source_peek_name ),
    SYM_MAP( e_source_get_property ),
    SYM_MAP( e_source_list_peek_groups ),
    SYM_MAP( e_source_group_peek_sources )
};

//>= 3.6 api
static const ApiMap aNewApiMap[] =
{
    SYM_MAP( e_source_registry_list_sources ),
    SYM_MAP( e_source_registry_new_sync ),
    SYM_MAP( e_source_has_extension ),
    SYM_MAP( e_source_get_extension ),
    SYM_MAP( e_source_backend_get_backend_name ),
    SYM_MAP( e_source_get_display_name ),
    SYM_MAP( e_source_get_uid ),
    SYM_MAP( e_source_registry_ref_source),
    SYM_MAP( e_client_open_sync ),
    SYM_MAP( e_client_get_source ),
    SYM_MAP( e_book_client_get_contacts_sync ),
    SYM_MAP( e_client_util_free_object_slist )
};

//== indirect read access (3.6 only)
static const ApiMap aClientApiMap36[] =
{
    SYM_MAP( e_book_client_new )
};

//>= direct read access API (>= 3.8)
static const ApiMap aClientApiMap38[] =
{
    SYM_MAP( e_book_client_connect_direct_sync )
};

#undef SYM_MAP

template<size_t N> static bool
tryLink( oslModule &aModule, const char *pName, const ApiMap (&pMap)[N])
{
    for (guint i = 0; i < N; ++i)
    {
        SymbolFunc aMethod = reinterpret_cast<SymbolFunc>(osl_getFunctionSymbol
            (aModule, OUString::createFromAscii ( pMap[ i ].sym_name ).pData));
        if( !aMethod )
        {
            fprintf( stderr, "Warning: missing symbol '%s' in '%s'\n",
                 pMap[ i ].sym_name, pName );
            return false;
        }
        *pMap[ i ].ref_value = aMethod;
    }
    return true;
}

bool EApiInit()
{
    oslModule aModule;

    for( guint j = 0; j < G_N_ELEMENTS( eBookLibNames ); j++ )
    {
        aModule = osl_loadModule( OUString::createFromAscii
                                  ( eBookLibNames[ j ] ).pData,
                                  SAL_LOADMODULE_DEFAULT );

        if( aModule == NULL)
            continue;

        if (tryLink( aModule, eBookLibNames[ j ], aCommonApiMap))
        {
            if (eds_check_version( 3, 6, 0 ) != NULL)
            {
                if (tryLink( aModule, eBookLibNames[ j ], aOldApiMap))
                    return true;
            }
            else if (tryLink( aModule, eBookLibNames[ j ], aNewApiMap))
            {
                if (eds_check_version( 3, 7, 6 ) != NULL)
                {
                    if (tryLink( aModule, eBookLibNames[ j ], aClientApiMap36))
                        return true;
                }
                else
                {
                    if (tryLink( aModule, eBookLibNames[ j ], aClientApiMap38))
                        return true;
                }
            }
        }

        osl_unloadModule( aModule );
    }
    fprintf( stderr, "Can find no compliant libebook client libraries\n" );
    return false;
}

ESourceRegistry *get_e_source_registry()
{
    static ESourceRegistry *theInstance;
    if (!theInstance)
        theInstance = e_source_registry_new_sync(NULL, NULL);
    return theInstance;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>// Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "mfem.hpp"
#include "unit_tests.hpp"

using namespace mfem;

static bool testQuadratureInterpolator(const int dim,
                                       const int p,
                                       const int q,
                                       const QVectorLayout q_layout,
                                       const int nx, const int ny, const int nz)
{
   const int vdim = dim;
   const int seed = 0x100001b3;
   const int ordering = Ordering::byNODES;

   REQUIRE((dim == 2 || dim == 3));
   Mesh mesh = dim == 1 ? Mesh::MakeCartesian1D(nx, Element::SEGMENT) :
               dim == 2 ? Mesh::MakeCartesian2D(nx,ny, Element::QUADRILATERAL):
               Mesh::MakeCartesian3D(nx,nx,nz, Element::HEXAHEDRON);

   mesh.SetCurvature(p, false, dim, ordering);

   const H1_FECollection fec(p, dim);
   FiniteElementSpace sfes(&mesh, &fec, 1, ordering);
   FiniteElementSpace vfes(&mesh, &fec, vdim, ordering);

   GridFunction x(&sfes);
   x.Randomize(seed);

   GridFunction nodes(&vfes);
   mesh.SetNodalFESpace(&vfes);
   mesh.SetNodalGridFunction(&nodes);
   {
      Array<int> dofs, vdofs;
      GridFunction rdm(&vfes);
      Vector h0(vfes.GetNDofs());
      rdm.Randomize(seed);
      rdm -= 0.5;
      h0 = infinity();
      for (int i = 0; i < mesh.GetNE(); i++)
      {
         vfes.GetElementDofs(i, dofs);
         const double hi = mesh.GetElementSize(i);
         for (int j = 0; j < dofs.Size(); j++)
         {
            h0(dofs[j]) = std::min(h0(dofs[j]), hi);
         }
      }
      for (int i = 0; i < vfes.GetNDofs(); i++)
      {
         for (int d = 0; d < dim; d++)
         {
            rdm(vfes.DofToVDof(i,d)) *= h0(i);
         }
      }
      for (int i = 0; i < vfes.GetNBE(); i++)
      {
         vfes.GetBdrElementVDofs(i, vdofs);
         for (int j = 0; j < vdofs.Size(); j++) { rdm(vdofs[j]) = 0.0; }
      }
      nodes -= rdm;
   }

   const Geometry::Type GeomType = mesh.GetElementBaseGeometry(0);
   const IntegrationRule &ir = IntRules.Get(GeomType, q);
   const QuadratureInterpolator *sqi(sfes.GetQuadratureInterpolator(ir));
   const QuadratureInterpolator *vqi(vfes.GetQuadratureInterpolator(ir));

   const int NE(mesh.GetNE());
   const int NQ(ir.GetNPoints());
   const int ND(sfes.GetFE(0)->GetDof());
   REQUIRE(ND == vfes.GetFE(0)->GetDof());

   const ElementDofOrdering nat_ordering = ElementDofOrdering::NATIVE;
   const ElementDofOrdering lex_ordering = ElementDofOrdering::LEXICOGRAPHIC;
   const Operator *SRN(sfes.GetElementRestriction(nat_ordering));
   const Operator *SRL(sfes.GetElementRestriction(lex_ordering));
   const Operator *VRN(vfes.GetElementRestriction(nat_ordering));
   const Operator *VRL(vfes.GetElementRestriction(lex_ordering));
   MFEM_VERIFY(SRN, "No element sn-restriction operator found!");
   MFEM_VERIFY(SRL, "No element sl-restriction operator found!");
   MFEM_VERIFY(VRN, "No element vn-restriction operator found!");
   MFEM_VERIFY(VRL, "No element vl-restriction operator found!");

   double val[2], der[2], det[2], pdr[2];

   {
      // Scalar
      sqi->SetOutputLayout(q_layout);
      Vector xe(1*ND*NE);
      REQUIRE(xe.Size() == SRN->Height());
      REQUIRE(SRN->Height() == SRL->Height());
      {
         // Full
         SRN->Mult(x, xe);
         sqi->DisableTensorProducts();
         Vector sq_val_f(NQ*NE), sq_der_f(dim*NQ*NE), sq_pdr_f(dim*NQ*NE);

         sqi->Values(xe, sq_val_f);
         val[0] = sq_val_f*sq_val_f;

         sqi->Derivatives(xe, sq_der_f);
         der[0] = sq_der_f*sq_der_f;

         sqi->PhysDerivatives(xe, sq_pdr_f);
         pdr[0] = sq_pdr_f*sq_pdr_f;
      }
      {
         // Tensor
         SRL->Mult(x, xe);
         sqi->EnableTensorProducts();
         Vector sq_val_t(NQ*NE), sq_der_t(dim*NQ*NE), sq_pdr_t(dim*NQ*NE);

         sqi->Values(xe, sq_val_t);
         val[1] = sq_val_t*sq_val_t;

         sqi->Derivatives(xe, sq_der_t);
         der[1] = sq_der_t*sq_der_t;

         sqi->PhysDerivatives(xe, sq_pdr_t);
         pdr[1] = sq_pdr_t*sq_pdr_t;
      }
      REQUIRE(val[0] == MFEM_Approx(val[1]));
      REQUIRE(der[0] == MFEM_Approx(der[1]));
      REQUIRE(pdr[0] == MFEM_Approx(pdr[1]));
   }

   {
      // Vector
      vqi->SetOutputLayout(q_layout);
      Vector ne(vdim*ND*NE);
      REQUIRE(ne.Size() == VRN->Height());
      REQUIRE(VRN->Height() == VRL->Height());
      {
         // Full
         VRN->Mult(nodes, ne);
         vqi->DisableTensorProducts();
         Vector vq_val_f(dim*NQ*NE), vq_der_f(vdim*dim*NQ*NE),
                vq_det_f(NQ*NE),
                vq_pdr_f(vdim*dim*NQ*NE);

         vqi->Values(ne, vq_val_f);
         val[0] = vq_val_f*vq_val_f;

         vqi->Derivatives(ne, vq_der_f);
         der[0] = vq_der_f*vq_der_f;

         vqi->Determinants(ne, vq_det_f);
         det[0] = vq_det_f*vq_det_f;

         vqi->PhysDerivatives(ne, vq_pdr_f);
         pdr[0] = vq_pdr_f*vq_pdr_f;
      }
      {
         // Tensor
         VRL->Mult(nodes, ne);
         vqi->EnableTensorProducts();
         Vector vq_val_t(dim*NQ*NE), vq_der_t(vdim*dim*NQ*NE),
                vq_det_t(NQ*NE),
                vq_pdr_t(vdim*dim*NQ*NE);

         vqi->Values(ne, vq_val_t);
         val[1] = vq_val_t*vq_val_t;

         vqi->Derivatives(ne, vq_der_t);
         der[1] = vq_der_t*vq_der_t;

         vqi->Determinants(ne, vq_det_t);
         det[1] = vq_det_t*vq_det_t;

         vqi->PhysDerivatives(ne, vq_pdr_t);
         pdr[1] = vq_pdr_t*vq_pdr_t;
      }
      REQUIRE(val[0] == MFEM_Approx(val[1]));
      REQUIRE(der[0] == MFEM_Approx(der[1]));
      REQUIRE(det[0] == MFEM_Approx(det[1]));
      REQUIRE(pdr[0] == MFEM_Approx(pdr[1]));
   }

   return true;
}

TEST_CASE("QuadratureInterpolator", "[QuadratureInterpolator]")
{
   const auto d = GENERATE(2,3); // dimension
   const auto p = GENERATE(range(1,8)); // element order
   const auto q = GENERATE_COPY(range(p+1,10)); // quadrature order
   const auto l = GENERATE(QVectorLayout::byNODES, QVectorLayout::byVDIM);
   const auto nx = GENERATE(3,4); // number of element in x
   const auto ny = GENERATE(5,6); // number of element in y
   const auto nz = GENERATE(1,3); // number of element in z
   REQUIRE(testQuadratureInterpolator(d, p, q, l, nx, ny, nz));
} // TEST_CASE "QuadratureInterpolator"
<commit_msg>Fix test_quadinterpolator orders<commit_after>// Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "mfem.hpp"
#include "unit_tests.hpp"

using namespace mfem;

static bool testQuadratureInterpolator(const int dim,
                                       const int p,
                                       const int q,
                                       const QVectorLayout q_layout,
                                       const int nx, const int ny, const int nz)
{
   const int vdim = dim;
   const int seed = 0x100001b3;
   const int ordering = Ordering::byNODES;

   REQUIRE((dim == 2 || dim == 3));
   Mesh mesh = dim == 1 ? Mesh::MakeCartesian1D(nx, Element::SEGMENT) :
               dim == 2 ? Mesh::MakeCartesian2D(nx,ny, Element::QUADRILATERAL):
               Mesh::MakeCartesian3D(nx,nx,nz, Element::HEXAHEDRON);

   mesh.SetCurvature(p, false, dim, ordering);

   const H1_FECollection fec(p, dim);
   FiniteElementSpace sfes(&mesh, &fec, 1, ordering);
   FiniteElementSpace vfes(&mesh, &fec, vdim, ordering);

   GridFunction x(&sfes);
   x.Randomize(seed);

   GridFunction nodes(&vfes);
   mesh.SetNodalFESpace(&vfes);
   mesh.SetNodalGridFunction(&nodes);
   {
      Array<int> dofs, vdofs;
      GridFunction rdm(&vfes);
      Vector h0(vfes.GetNDofs());
      rdm.Randomize(seed);
      rdm -= 0.5;
      h0 = infinity();
      for (int i = 0; i < mesh.GetNE(); i++)
      {
         vfes.GetElementDofs(i, dofs);
         const double hi = mesh.GetElementSize(i);
         for (int j = 0; j < dofs.Size(); j++)
         {
            h0(dofs[j]) = std::min(h0(dofs[j]), hi);
         }
      }
      for (int i = 0; i < vfes.GetNDofs(); i++)
      {
         for (int d = 0; d < dim; d++)
         {
            rdm(vfes.DofToVDof(i,d)) *= h0(i);
         }
      }
      for (int i = 0; i < vfes.GetNBE(); i++)
      {
         vfes.GetBdrElementVDofs(i, vdofs);
         for (int j = 0; j < vdofs.Size(); j++) { rdm(vdofs[j]) = 0.0; }
      }
      nodes -= rdm;
   }

   const Geometry::Type GeomType = mesh.GetElementBaseGeometry(0);
   const IntegrationRule &ir = IntRules.Get(GeomType, q);
   const QuadratureInterpolator *sqi(sfes.GetQuadratureInterpolator(ir));
   const QuadratureInterpolator *vqi(vfes.GetQuadratureInterpolator(ir));

   const int NE(mesh.GetNE());
   const int NQ(ir.GetNPoints());
   const int ND(sfes.GetFE(0)->GetDof());
   REQUIRE(ND == vfes.GetFE(0)->GetDof());

   const ElementDofOrdering nat_ordering = ElementDofOrdering::NATIVE;
   const ElementDofOrdering lex_ordering = ElementDofOrdering::LEXICOGRAPHIC;
   const Operator *SRN(sfes.GetElementRestriction(nat_ordering));
   const Operator *SRL(sfes.GetElementRestriction(lex_ordering));
   const Operator *VRN(vfes.GetElementRestriction(nat_ordering));
   const Operator *VRL(vfes.GetElementRestriction(lex_ordering));
   MFEM_VERIFY(SRN, "No element sn-restriction operator found!");
   MFEM_VERIFY(SRL, "No element sl-restriction operator found!");
   MFEM_VERIFY(VRN, "No element vn-restriction operator found!");
   MFEM_VERIFY(VRL, "No element vl-restriction operator found!");

   double val[2], der[2], det[2], pdr[2];

   {
      // Scalar
      sqi->SetOutputLayout(q_layout);
      Vector xe(1*ND*NE);
      REQUIRE(xe.Size() == SRN->Height());
      REQUIRE(SRN->Height() == SRL->Height());
      {
         // Full
         SRN->Mult(x, xe);
         sqi->DisableTensorProducts();
         Vector sq_val_f(NQ*NE), sq_der_f(dim*NQ*NE), sq_pdr_f(dim*NQ*NE);

         sqi->Values(xe, sq_val_f);
         val[0] = sq_val_f*sq_val_f;

         sqi->Derivatives(xe, sq_der_f);
         der[0] = sq_der_f*sq_der_f;

         sqi->PhysDerivatives(xe, sq_pdr_f);
         pdr[0] = sq_pdr_f*sq_pdr_f;
      }
      {
         // Tensor
         SRL->Mult(x, xe);
         sqi->EnableTensorProducts();
         Vector sq_val_t(NQ*NE), sq_der_t(dim*NQ*NE), sq_pdr_t(dim*NQ*NE);

         sqi->Values(xe, sq_val_t);
         val[1] = sq_val_t*sq_val_t;

         sqi->Derivatives(xe, sq_der_t);
         der[1] = sq_der_t*sq_der_t;

         sqi->PhysDerivatives(xe, sq_pdr_t);
         pdr[1] = sq_pdr_t*sq_pdr_t;
      }
      REQUIRE(val[0] == MFEM_Approx(val[1]));
      REQUIRE(der[0] == MFEM_Approx(der[1]));
      REQUIRE(pdr[0] == MFEM_Approx(pdr[1]));
   }

   {
      // Vector
      vqi->SetOutputLayout(q_layout);
      Vector ne(vdim*ND*NE);
      REQUIRE(ne.Size() == VRN->Height());
      REQUIRE(VRN->Height() == VRL->Height());
      {
         // Full
         VRN->Mult(nodes, ne);
         vqi->DisableTensorProducts();
         Vector vq_val_f(dim*NQ*NE), vq_der_f(vdim*dim*NQ*NE),
                vq_det_f(NQ*NE),
                vq_pdr_f(vdim*dim*NQ*NE);

         vqi->Values(ne, vq_val_f);
         val[0] = vq_val_f*vq_val_f;

         vqi->Derivatives(ne, vq_der_f);
         der[0] = vq_der_f*vq_der_f;

         vqi->Determinants(ne, vq_det_f);
         det[0] = vq_det_f*vq_det_f;

         vqi->PhysDerivatives(ne, vq_pdr_f);
         pdr[0] = vq_pdr_f*vq_pdr_f;
      }
      {
         // Tensor
         VRL->Mult(nodes, ne);
         vqi->EnableTensorProducts();
         Vector vq_val_t(dim*NQ*NE), vq_der_t(vdim*dim*NQ*NE),
                vq_det_t(NQ*NE),
                vq_pdr_t(vdim*dim*NQ*NE);

         vqi->Values(ne, vq_val_t);
         val[1] = vq_val_t*vq_val_t;

         vqi->Derivatives(ne, vq_der_t);
         der[1] = vq_der_t*vq_der_t;

         vqi->Determinants(ne, vq_det_t);
         det[1] = vq_det_t*vq_det_t;

         vqi->PhysDerivatives(ne, vq_pdr_t);
         pdr[1] = vq_pdr_t*vq_pdr_t;
      }
      REQUIRE(val[0] == MFEM_Approx(val[1]));
      REQUIRE(der[0] == MFEM_Approx(der[1]));
      REQUIRE(det[0] == MFEM_Approx(det[1]));
      REQUIRE(pdr[0] == MFEM_Approx(pdr[1]));
   }

   return true;
}

TEST_CASE("QuadratureInterpolator", "[QuadratureInterpolator]")
{
   const auto d = GENERATE(2,3); // dimension
   const auto p = GENERATE(range(1,8)); // element order
   const auto q = GENERATE_COPY(range(p+1,9)); // quadrature order
   const auto l = GENERATE(QVectorLayout::byNODES, QVectorLayout::byVDIM);
   const auto nx = GENERATE(3,4); // number of element in x
   const auto ny = GENERATE(5,6); // number of element in y
   const auto nz = GENERATE(1,3); // number of element in z
   REQUIRE(testQuadratureInterpolator(d, p, q, l, nx, ny, nz));
} // TEST_CASE "QuadratureInterpolator"
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2003-2006 Tommi Maekitalo
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "tnt/scopemanager.h"
#include "tnt/sessionscope.h"
#include "tnt/httprequest.h"
#include "tnt/httpreply.h"
#include <cxxtools/log.h>
#include <cxxtools/md5stream.h>
#include <pthread.h>
#include <stdlib.h>

log_define("tntnet.scopemanager")

namespace tnt
{
  ScopeManager::ScopeManager()
  {
  }

  ScopeManager::~ScopeManager()
  {
    for (sessionscopes_type::iterator it = sessionScopes.begin(); it != sessionScopes.end(); ++it)
      delete it->second;
    for (scopes_type::iterator it = applicationScopes.begin(); it != applicationScopes.end(); ++it)
      delete it->second;
  }

  Scope* ScopeManager::getApplicationScope(const std::string& appname)
  {
    cxxtools::MutexLock lock(applicationScopesMutex);

    scopes_type::iterator it = applicationScopes.find(appname);
    if (it == applicationScopes.end())
    {
      log_debug("applicationscope not found - create new");
      Scope* s = new Scope();
      it = applicationScopes.insert(scopes_type::value_type(appname, s)).first;
      return s;
    }
    else
      log_debug("applicationscope found");

    return it->second;
  }

  Sessionscope* ScopeManager::getSessionScope(const std::string& sessioncookie)
  {
    log_debug("getSessionScope(\"" << sessioncookie << "\")");

    cxxtools::MutexLock lock(sessionScopesMutex);
    sessionscopes_type::iterator it = sessionScopes.find(sessioncookie);
    if (it == sessionScopes.end())
    {
      log_debug("session " << sessioncookie << " not found");
      return 0;
    }
    else
    {
      log_debug("session " << sessioncookie << " found");
      it->second->touch();
      return it->second;
    }
  }

  bool ScopeManager::hasSessionScope(const std::string& sessioncookie)
  {
    cxxtools::MutexLock lock(sessionScopesMutex);
    sessionscopes_type::iterator it = sessionScopes.find(sessioncookie);
    return it != sessionScopes.end();
  }

  void ScopeManager::putSessionScope(const std::string& sessioncookie, Sessionscope* s)
  {
    s->addRef();

    cxxtools::MutexLock lock(sessionScopesMutex);
    sessionscopes_type::iterator it = sessionScopes.find(sessioncookie);
    if (it != sessionScopes.end())
    {
      it->second->release();
      it->second = s;
    }
    else
      sessionScopes[sessioncookie] = s;
  }

  void ScopeManager::removeApplicationScope(const std::string& appname)
  {
    cxxtools::MutexLock lock(applicationScopesMutex);
    scopes_type::iterator it = applicationScopes.find(appname);
    if (it != applicationScopes.end())
    {
      it->second->release();
      applicationScopes.erase(it);
    }
  }

  void ScopeManager::removeSessionScope(const std::string& sessioncookie)
  {
    cxxtools::MutexLock lock(sessionScopesMutex);
    sessionscopes_type::iterator it = sessionScopes.find(sessioncookie);
    if (it != sessionScopes.end())
    {
      it->second->release();
      sessionScopes.erase(it);
    }
  }

  void ScopeManager::preCall(HttpRequest& request, const std::string& app)
  {
    // check session-cookie
    std::string currentSessionCookieName = app.empty() ? std::string("tntnet") : "tntnet." + app;
    std::string currentSecureSessionCookieName = app.empty() ? std::string("stntnet") : "stntnet." + app;

    Cookie c = request.getCookie(currentSessionCookieName);
    if (c.getValue().empty())
    {
      /*
      cxxtools::MutexLock lock(sessionScopesMutex);
      log_debug(sessionScopes.size() << " sessions available");
      for (sessionscopes_type::iterator it = sessionScopes.begin(); it != sessionScopes.end(); ++it)
        log_debug("available session " << it->first << " value " << it->second);
        */

      log_debug("session cookie " << currentSessionCookieName << " not found - keep session");
    }
    else
    {
      log_debug("session cookie " << currentSessionCookieName << " found: " << c.getValue());

      cxxtools::MutexLock lock(sessionScopesMutex);

      Sessionscope* sessionScope;

      sessionscopes_type::iterator it = sessionScopes.find(c.getValue());
      if (it == sessionScopes.end())
      {
        log_debug("session not found - create new");
        sessionScope = new Sessionscope();
        sessionScope->addRef();
        sessionScopes.insert(sessionscopes_type::value_type(c.getValue(), sessionScope));
      }
      else
      {
        log_debug("session found");
        sessionScope = it->second;
        sessionScope->touch();
      }

      request.setSessionScope(sessionScope);
    }

    if (request.isSsl())
    {
      c = request.getCookie(currentSecureSessionCookieName);
      if (c.getValue().empty())
      {
        log_debug("secure session cookie " << currentSessionCookieName
            << " not found - keep session");
      }
      else if (request.isSsl())
      {
        log_debug("secure session cookie " << currentSessionCookieName
            << " found: " << c.getValue());

        cxxtools::MutexLock lock(sessionScopesMutex);

        Sessionscope* sessionScope;

        sessionscopes_type::iterator it = sessionScopes.find(c.getValue());
        if (it == sessionScopes.end())
        {
          log_debug("session not found - create new");
          sessionScope = new Sessionscope();
          sessionScope->addRef();
          sessionScopes.insert(sessionscopes_type::value_type(c.getValue(), sessionScope));
        }
        else
        {
          log_debug("session found");
          sessionScope = it->second;
          sessionScope->touch();
        }

        request.setSecureSessionScope(sessionScope);
      }
    }
    else
    {
      log_debug("secure session cookie " << currentSessionCookieName
          << " not checked in non ssl request");
    }

    // set application-scope
    request.setApplicationScope(getApplicationScope(app));
  }

  void ScopeManager::setSessionId(HttpRequest& request, const std::string& sessionId)
  {
    if (sessionId.empty())
    {
      request.setSessionScope(0);
    }
    else
    {
      Sessionscope* sessionScope = getSessionScope(sessionId);
      if (sessionScope != 0)
      {
        log_debug("session found");
        request.setSessionScope(sessionScope);
      }
    }
  }

  std::string ScopeManager::postCall(HttpRequest& request, HttpReply& reply, const std::string& app)
  {
    std::string currentSessionCookieName = app.empty() ? std::string("tntnet") : "tntnet." + app;
    std::string currentSecureSessionCookieName = app.empty() ? std::string("stntnet") : "stntnet." + app;

    std::string sessionId;

    if (reply.isClearSession())
    {
      sessionId = request.getCookie(currentSessionCookieName);
      if (!sessionId.empty())
        removeSessionScope(sessionId);

      std::string secureSessionId = request.getCookie(currentSecureSessionCookieName);
      if (!secureSessionId.empty())
        removeSessionScope(secureSessionId);
    }
    else
    {
      if (request.hasSessionScope())
      {
        // request has session scope
        sessionId = request.getCookie(currentSessionCookieName);
        if (sessionId.empty())
        {
          // client has no sessionId

          cxxtools::Md5stream c;
          c << request.getSerial() << '-' << ::pthread_self() << '-' << rand();
          sessionId = c.getHexDigest();
          log_info("create new session " << sessionId);
          reply.setCookie(currentSessionCookieName, sessionId);
          putSessionScope(sessionId, &request.getSessionScope());
        }
        else if (!hasSessionScope(sessionId))
        {
          // client has a sessionId but no associated session
          // this may happen, when tntnet is restarted while the browser has a session

          putSessionScope(sessionId, &request.getSessionScope());
        }
      }

      if (request.isSsl() && request.hasSecureSessionScope())
      {
        // request has secure session scope
        std::string sessionId = request.getCookie(currentSecureSessionCookieName);
        if (sessionId.empty())
        {
          // client has no sessionId

          cxxtools::Md5stream c;
          c << request.getSerial() << '-' << ::pthread_self() << '-' << rand();
          sessionId = c.getHexDigest();
          log_info("create new secure session " << sessionId);
          tnt::Cookie cookie(sessionId);
          cookie.setSecure();
          reply.setCookie(currentSecureSessionCookieName, cookie);
          putSessionScope(sessionId, &request.getSecureSessionScope());
        }
        else if (!hasSessionScope(sessionId))
        {
          // client has a sessionId but no associated session
          // this may happen, when tntnet is restarted while the browser has a session

          putSessionScope(sessionId, &request.getSecureSessionScope());
        }
      }
    }

    return sessionId;
  }

  void ScopeManager::checkSessionTimeout()
  {
    time_t currentTime;
    time(&currentTime);
    cxxtools::MutexLock lock(sessionScopesMutex);
    sessionscopes_type::iterator it = sessionScopes.begin();
    unsigned count = 0;
    while (it != sessionScopes.end())
    {
      Sessionscope* s = it->second;
      if (static_cast <unsigned> (currentTime - s->getAtime()) > s->getTimeout())
      {
        log_info("sessiontimeout for session " << it->first << " reached");
        sessionscopes_type::iterator it2 = it;
        ++it;
        s->release();
        sessionScopes.erase(it2);
        ++count;
      }
      else
        ++it;
    }

  }
}
<commit_msg>fix another possible leak of scopes<commit_after>/*
 * Copyright (C) 2003-2006 Tommi Maekitalo
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "tnt/scopemanager.h"
#include "tnt/sessionscope.h"
#include "tnt/httprequest.h"
#include "tnt/httpreply.h"
#include <cxxtools/log.h>
#include <cxxtools/md5stream.h>
#include <pthread.h>
#include <stdlib.h>

log_define("tntnet.scopemanager")

namespace tnt
{
  ScopeManager::ScopeManager()
  {
  }

  ScopeManager::~ScopeManager()
  {
    for (sessionscopes_type::iterator it = sessionScopes.begin(); it != sessionScopes.end(); ++it)
      delete it->second;
    for (scopes_type::iterator it = applicationScopes.begin(); it != applicationScopes.end(); ++it)
      delete it->second;
  }

  Scope* ScopeManager::getApplicationScope(const std::string& appname)
  {
    cxxtools::MutexLock lock(applicationScopesMutex);

    scopes_type::iterator it = applicationScopes.find(appname);
    if (it == applicationScopes.end())
    {
      log_debug("applicationscope not found - create new");
      Scope* s = new Scope();
      it = applicationScopes.insert(scopes_type::value_type(appname, s)).first;
      return s;
    }
    else
      log_debug("applicationscope found");

    return it->second;
  }

  Sessionscope* ScopeManager::getSessionScope(const std::string& sessioncookie)
  {
    log_debug("getSessionScope(\"" << sessioncookie << "\")");

    cxxtools::MutexLock lock(sessionScopesMutex);
    sessionscopes_type::iterator it = sessionScopes.find(sessioncookie);
    if (it == sessionScopes.end())
    {
      log_debug("session " << sessioncookie << " not found");
      return 0;
    }
    else
    {
      log_debug("session " << sessioncookie << " found");
      it->second->touch();
      return it->second;
    }
  }

  bool ScopeManager::hasSessionScope(const std::string& sessioncookie)
  {
    cxxtools::MutexLock lock(sessionScopesMutex);
    sessionscopes_type::iterator it = sessionScopes.find(sessioncookie);
    return it != sessionScopes.end();
  }

  void ScopeManager::putSessionScope(const std::string& sessioncookie, Sessionscope* s)
  {
    s->addRef();

    cxxtools::MutexLock lock(sessionScopesMutex);
    sessionscopes_type::iterator it = sessionScopes.find(sessioncookie);
    if (it != sessionScopes.end())
    {
      if (it->second->release() == 0)
        delete it->second;
      it->second = s;
    }
    else
      sessionScopes[sessioncookie] = s;
  }

  void ScopeManager::removeApplicationScope(const std::string& appname)
  {
    cxxtools::MutexLock lock(applicationScopesMutex);
    scopes_type::iterator it = applicationScopes.find(appname);
    if (it != applicationScopes.end())
    {
      if (it->second->release() == 0)
        delete it->second;
      applicationScopes.erase(it);
    }
  }

  void ScopeManager::removeSessionScope(const std::string& sessioncookie)
  {
    cxxtools::MutexLock lock(sessionScopesMutex);
    sessionscopes_type::iterator it = sessionScopes.find(sessioncookie);
    if (it != sessionScopes.end())
    {
      if (it->second->release() == 0)
        delete it->second;
      sessionScopes.erase(it);
    }
  }

  void ScopeManager::preCall(HttpRequest& request, const std::string& app)
  {
    // check session-cookie
    std::string currentSessionCookieName = app.empty() ? std::string("tntnet") : "tntnet." + app;
    std::string currentSecureSessionCookieName = app.empty() ? std::string("stntnet") : "stntnet." + app;

    Cookie c = request.getCookie(currentSessionCookieName);
    if (c.getValue().empty())
    {
      /*
      cxxtools::MutexLock lock(sessionScopesMutex);
      log_debug(sessionScopes.size() << " sessions available");
      for (sessionscopes_type::iterator it = sessionScopes.begin(); it != sessionScopes.end(); ++it)
        log_debug("available session " << it->first << " value " << it->second);
        */

      log_debug("session cookie " << currentSessionCookieName << " not found - keep session");
    }
    else
    {
      log_debug("session cookie " << currentSessionCookieName << " found: " << c.getValue());

      cxxtools::MutexLock lock(sessionScopesMutex);

      Sessionscope* sessionScope;

      sessionscopes_type::iterator it = sessionScopes.find(c.getValue());
      if (it == sessionScopes.end())
      {
        log_debug("session not found - create new");
        sessionScope = new Sessionscope();
        sessionScope->addRef();
        sessionScopes.insert(sessionscopes_type::value_type(c.getValue(), sessionScope));
      }
      else
      {
        log_debug("session found");
        sessionScope = it->second;
        sessionScope->touch();
      }

      request.setSessionScope(sessionScope);
    }

    if (request.isSsl())
    {
      c = request.getCookie(currentSecureSessionCookieName);
      if (c.getValue().empty())
      {
        log_debug("secure session cookie " << currentSessionCookieName
            << " not found - keep session");
      }
      else if (request.isSsl())
      {
        log_debug("secure session cookie " << currentSessionCookieName
            << " found: " << c.getValue());

        cxxtools::MutexLock lock(sessionScopesMutex);

        Sessionscope* sessionScope;

        sessionscopes_type::iterator it = sessionScopes.find(c.getValue());
        if (it == sessionScopes.end())
        {
          log_debug("session not found - create new");
          sessionScope = new Sessionscope();
          sessionScope->addRef();
          sessionScopes.insert(sessionscopes_type::value_type(c.getValue(), sessionScope));
        }
        else
        {
          log_debug("session found");
          sessionScope = it->second;
          sessionScope->touch();
        }

        request.setSecureSessionScope(sessionScope);
      }
    }
    else
    {
      log_debug("secure session cookie " << currentSessionCookieName
          << " not checked in non ssl request");
    }

    // set application-scope
    request.setApplicationScope(getApplicationScope(app));
  }

  void ScopeManager::setSessionId(HttpRequest& request, const std::string& sessionId)
  {
    if (sessionId.empty())
    {
      request.setSessionScope(0);
    }
    else
    {
      Sessionscope* sessionScope = getSessionScope(sessionId);
      if (sessionScope != 0)
      {
        log_debug("session found");
        request.setSessionScope(sessionScope);
      }
    }
  }

  std::string ScopeManager::postCall(HttpRequest& request, HttpReply& reply, const std::string& app)
  {
    std::string currentSessionCookieName = app.empty() ? std::string("tntnet") : "tntnet." + app;
    std::string currentSecureSessionCookieName = app.empty() ? std::string("stntnet") : "stntnet." + app;

    std::string sessionId;

    if (reply.isClearSession())
    {
      sessionId = request.getCookie(currentSessionCookieName);
      if (!sessionId.empty())
        removeSessionScope(sessionId);

      std::string secureSessionId = request.getCookie(currentSecureSessionCookieName);
      if (!secureSessionId.empty())
        removeSessionScope(secureSessionId);
    }
    else
    {
      if (request.hasSessionScope())
      {
        // request has session scope
        sessionId = request.getCookie(currentSessionCookieName);
        if (sessionId.empty())
        {
          // client has no sessionId

          cxxtools::Md5stream c;
          c << request.getSerial() << '-' << ::pthread_self() << '-' << rand();
          sessionId = c.getHexDigest();
          log_info("create new session " << sessionId);
          reply.setCookie(currentSessionCookieName, sessionId);
          putSessionScope(sessionId, &request.getSessionScope());
        }
        else if (!hasSessionScope(sessionId))
        {
          // client has a sessionId but no associated session
          // this may happen, when tntnet is restarted while the browser has a session

          putSessionScope(sessionId, &request.getSessionScope());
        }
      }

      if (request.isSsl() && request.hasSecureSessionScope())
      {
        // request has secure session scope
        std::string sessionId = request.getCookie(currentSecureSessionCookieName);
        if (sessionId.empty())
        {
          // client has no sessionId

          cxxtools::Md5stream c;
          c << request.getSerial() << '-' << ::pthread_self() << '-' << rand();
          sessionId = c.getHexDigest();
          log_info("create new secure session " << sessionId);
          tnt::Cookie cookie(sessionId);
          cookie.setSecure();
          reply.setCookie(currentSecureSessionCookieName, cookie);
          putSessionScope(sessionId, &request.getSecureSessionScope());
        }
        else if (!hasSessionScope(sessionId))
        {
          // client has a sessionId but no associated session
          // this may happen, when tntnet is restarted while the browser has a session

          putSessionScope(sessionId, &request.getSecureSessionScope());
        }
      }
    }

    return sessionId;
  }

  void ScopeManager::checkSessionTimeout()
  {
    time_t currentTime;
    time(&currentTime);
    cxxtools::MutexLock lock(sessionScopesMutex);
    sessionscopes_type::iterator it = sessionScopes.begin();
    unsigned count = 0;
    while (it != sessionScopes.end())
    {
      Sessionscope* s = it->second;
      if (static_cast <unsigned> (currentTime - s->getAtime()) > s->getTimeout())
      {
        log_info("sessiontimeout for session " << it->first << " reached");
        sessionscopes_type::iterator it2 = it;
        ++it;
        if (s->release() == 0)
          delete s;
        sessionScopes.erase(it2);
        ++count;
      }
      else
        ++it;
    }

  }
}
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/mman.h>

#include <iostream>
#include <string>

#include <mesos/executor.hpp>

#include <stout/duration.hpp>
#include <stout/numify.hpp>
#include <stout/os.hpp>

using namespace mesos;

// The amount of memory in MB each balloon step consumes.
const static size_t BALLOON_STEP_MB = 64;

// This function will increase the memory footprint gradually. The parameter
// limit specifies the upper limit (in MB) of the memory footprint. The
// parameter step specifies the step size (in MB).
static void balloon(size_t limit)
{
  size_t chunk = BALLOON_STEP_MB * 1024 * 1024;
  for (size_t i = 0; i < limit / BALLOON_STEP_MB; i++) {
    std::cout << "Increasing memory footprint by "
              << BALLOON_STEP_MB << " MB" << std::endl;

    // Allocate page-aligned virtual memory.
    void* buffer = NULL;
    if (posix_memalign(&buffer, getpagesize(), chunk) != 0) {
      perror("Failed to allocate page-aligned memory, posix_memalign");
      abort();
    }

    // We use mlock and memset here to make sure that the memory
    // actually gets paged in and thus accounted for.
    if (mlock(buffer, chunk) != 0) {
      perror("Failed to lock memory, mlock");
      abort();
    }

    if (memset(buffer, 1, chunk) != buffer) {
      perror("Failed to fill memory, memset");
      abort();
    }

    // Try not to increase the memory footprint too fast.
    os::sleep(Seconds(1));
  }
}

class BalloonExecutor : public Executor
{
public:
  virtual ~BalloonExecutor() {}

  virtual void registered(ExecutorDriver* driver,
                          const ExecutorInfo& executorInfo,
                          const FrameworkInfo& frameworkInfo,
                          const SlaveInfo& slaveInfo)
  {
    std::cout << "Registered" << std::endl;
  }

  virtual void reregistered(ExecutorDriver* driver,
                            const SlaveInfo& slaveInfo)
  {
    std::cout << "Reregistered" << std::endl;
  }

  virtual void disconnected(ExecutorDriver* driver)
  {
    std::cout << "Disconnected" << std::endl;
  }

  virtual void launchTask(ExecutorDriver* driver, const TaskInfo& task)
  {
    std::cout << "Starting task " << task.task_id().value() << std::endl;

    TaskStatus status;
    status.mutable_task_id()->MergeFrom(task.task_id());
    status.set_state(TASK_RUNNING);

    driver->sendStatusUpdate(status);

    // Get the balloon limit (in MB).
    Try<size_t> limit = numify<size_t>(task.data());
    assert(limit.isSome());
    size_t balloonLimit = limit.get();

    // Artificially increase the memory usage gradually. The
    // balloonLimit specifies the upper limit. The balloonLimit can be
    // larger than the amount of memory allocated to this executor. In
    // that case, the isolator (e.g. cgroups) should be able to detect
    // that and the task should not be able to reach TASK_FINISHED
    // state.
    balloon(balloonLimit);

    std::cout << "Finishing task " << task.task_id().value() << std::endl;

    status.mutable_task_id()->MergeFrom(task.task_id());
    status.set_state(TASK_FINISHED);

    driver->sendStatusUpdate(status);
  }

  virtual void killTask(ExecutorDriver* driver, const TaskID& taskId)
  {
    std::cout << "Kill task " << taskId.value() << std::endl;
  }

  virtual void frameworkMessage(ExecutorDriver* driver, const std::string& data)
  {
    std::cout << "Framework message: " << data << std::endl;
  }

  virtual void shutdown(ExecutorDriver* driver)
  {
    std::cout << "Shutdown" << std::endl;
  }

  virtual void error(ExecutorDriver* driver, const std::string& message)
  {
    std::cout << "Error message: " << message << std::endl;
  }
};

int main(int argc, char** argv)
{
  BalloonExecutor executor;
  MesosExecutorDriver driver(&executor);
  return driver.run() == DRIVER_STOPPED ? 0 : 1;
}
<commit_msg>Changed BalloonExecutor to do memset before mlock.<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/mman.h>

#include <iostream>
#include <string>

#include <mesos/executor.hpp>

#include <stout/duration.hpp>
#include <stout/numify.hpp>
#include <stout/os.hpp>

using namespace mesos;

// The amount of memory in MB each balloon step consumes.
const static size_t BALLOON_STEP_MB = 64;

// This function will increase the memory footprint gradually. The parameter
// limit specifies the upper limit (in MB) of the memory footprint. The
// parameter step specifies the step size (in MB).
static void balloon(size_t limit)
{
  size_t chunk = BALLOON_STEP_MB * 1024 * 1024;
  for (size_t i = 0; i < limit / BALLOON_STEP_MB; i++) {
    std::cout << "Increasing memory footprint by "
              << BALLOON_STEP_MB << " MB" << std::endl;

    // Allocate page-aligned virtual memory.
    void* buffer = NULL;
    if (posix_memalign(&buffer, getpagesize(), chunk) != 0) {
      perror("Failed to allocate page-aligned memory, posix_memalign");
      abort();
    }

    // We use memset and mlock here to make sure that the memory
    // actually gets paged in and thus accounted for.
    if (memset(buffer, 1, chunk) != buffer) {
      perror("Failed to fill memory, memset");
      abort();
    }

    if (mlock(buffer, chunk) != 0) {
      perror("Failed to lock memory, mlock");
      abort();
    }

    // Try not to increase the memory footprint too fast.
    os::sleep(Seconds(1));
  }
}

class BalloonExecutor : public Executor
{
public:
  virtual ~BalloonExecutor() {}

  virtual void registered(ExecutorDriver* driver,
                          const ExecutorInfo& executorInfo,
                          const FrameworkInfo& frameworkInfo,
                          const SlaveInfo& slaveInfo)
  {
    std::cout << "Registered" << std::endl;
  }

  virtual void reregistered(ExecutorDriver* driver,
                            const SlaveInfo& slaveInfo)
  {
    std::cout << "Reregistered" << std::endl;
  }

  virtual void disconnected(ExecutorDriver* driver)
  {
    std::cout << "Disconnected" << std::endl;
  }

  virtual void launchTask(ExecutorDriver* driver, const TaskInfo& task)
  {
    std::cout << "Starting task " << task.task_id().value() << std::endl;

    TaskStatus status;
    status.mutable_task_id()->MergeFrom(task.task_id());
    status.set_state(TASK_RUNNING);

    driver->sendStatusUpdate(status);

    // Get the balloon limit (in MB).
    Try<size_t> limit = numify<size_t>(task.data());
    assert(limit.isSome());
    size_t balloonLimit = limit.get();

    // Artificially increase the memory usage gradually. The
    // balloonLimit specifies the upper limit. The balloonLimit can be
    // larger than the amount of memory allocated to this executor. In
    // that case, the isolator (e.g. cgroups) should be able to detect
    // that and the task should not be able to reach TASK_FINISHED
    // state.
    balloon(balloonLimit);

    std::cout << "Finishing task " << task.task_id().value() << std::endl;

    status.mutable_task_id()->MergeFrom(task.task_id());
    status.set_state(TASK_FINISHED);

    driver->sendStatusUpdate(status);
  }

  virtual void killTask(ExecutorDriver* driver, const TaskID& taskId)
  {
    std::cout << "Kill task " << taskId.value() << std::endl;
  }

  virtual void frameworkMessage(ExecutorDriver* driver, const std::string& data)
  {
    std::cout << "Framework message: " << data << std::endl;
  }

  virtual void shutdown(ExecutorDriver* driver)
  {
    std::cout << "Shutdown" << std::endl;
  }

  virtual void error(ExecutorDriver* driver, const std::string& message)
  {
    std::cout << "Error message: " << message << std::endl;
  }
};

int main(int argc, char** argv)
{
  BalloonExecutor executor;
  MesosExecutorDriver driver(&executor);
  return driver.run() == DRIVER_STOPPED ? 0 : 1;
}
<|endoftext|>