LCOV - code coverage report
Current view: top level - comphelper/source/misc - namedvaluecollection.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 132 143 92.3 %
Date: 2015-06-13 12:38:46 Functions: 28 28 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <comphelper/namedvaluecollection.hxx>
      21             : 
      22             : #include <com/sun/star/beans/NamedValue.hpp>
      23             : #include <com/sun/star/lang/IllegalArgumentException.hpp>
      24             : #include <com/sun/star/beans/PropertyState.hpp>
      25             : 
      26             : #include <rtl/ustrbuf.hxx>
      27             : #include <rtl/instance.hxx>
      28             : #include <sal/log.hxx>
      29             : 
      30             : #include <algorithm>
      31             : #include <functional>
      32             : #include <unordered_map>
      33             : 
      34             : namespace comphelper
      35             : {
      36             : 
      37             : 
      38             :     using ::com::sun::star::uno::Any;
      39             :     using ::com::sun::star::uno::Sequence;
      40             :     using ::com::sun::star::beans::PropertyValue;
      41             :     using ::com::sun::star::beans::NamedValue;
      42             :     using ::com::sun::star::uno::Type;
      43             :     using ::com::sun::star::uno::cpp_acquire;
      44             :     using ::com::sun::star::uno::cpp_release;
      45             :     using ::com::sun::star::uno::cpp_queryInterface;
      46             :     using ::com::sun::star::lang::IllegalArgumentException;
      47             :     using ::com::sun::star::beans::PropertyState_DIRECT_VALUE;
      48             : 
      49             :     typedef std::unordered_map< OUString, Any, OUStringHash >    NamedValueRepository;
      50             : 
      51      131785 :     struct NamedValueCollection_Impl
      52             :     {
      53             :         NamedValueRepository    aValues;
      54             :     };
      55             : 
      56       17331 :     NamedValueCollection::NamedValueCollection()
      57       17331 :         :m_pImpl( new NamedValueCollection_Impl )
      58             :     {
      59       17331 :     }
      60             : 
      61             : 
      62        5485 :     NamedValueCollection::NamedValueCollection( const NamedValueCollection& _rCopySource )
      63        5485 :         :m_pImpl( new NamedValueCollection_Impl )
      64             :     {
      65        5485 :         *this = _rCopySource;
      66        5485 :     }
      67             : 
      68             : 
      69        5598 :     NamedValueCollection& NamedValueCollection::operator=( const NamedValueCollection& i_rCopySource )
      70             :     {
      71        5598 :         m_pImpl->aValues = i_rCopySource.m_pImpl->aValues;
      72        5598 :         return *this;
      73             :     }
      74             : 
      75             : 
      76        4280 :     NamedValueCollection::NamedValueCollection( const Any& _rElements )
      77        4280 :         :m_pImpl( new NamedValueCollection_Impl )
      78             :     {
      79        4280 :         impl_assign( _rElements );
      80        4280 :     }
      81             : 
      82             : 
      83        4060 :     NamedValueCollection::NamedValueCollection( const Sequence< Any >& _rArguments )
      84        4060 :         :m_pImpl( new NamedValueCollection_Impl )
      85             :     {
      86        4060 :         impl_assign( _rArguments );
      87        4060 :     }
      88             : 
      89             : 
      90       34953 :     NamedValueCollection::NamedValueCollection( const Sequence< PropertyValue >& _rArguments )
      91       34953 :         :m_pImpl( new NamedValueCollection_Impl )
      92             :     {
      93       34953 :         impl_assign( _rArguments );
      94       34953 :     }
      95             : 
      96             : 
      97          49 :     NamedValueCollection::NamedValueCollection( const Sequence< NamedValue >& _rArguments )
      98          49 :         :m_pImpl( new NamedValueCollection_Impl )
      99             :     {
     100          49 :         impl_assign( _rArguments );
     101          49 :     }
     102             : 
     103             : 
     104       65627 :     NamedValueCollection::~NamedValueCollection()
     105             :     {
     106       65627 :     }
     107             : 
     108             : 
     109          24 :     bool NamedValueCollection::canExtractFrom( ::com::sun::star::uno::Any const & i_value )
     110             :     {
     111          24 :         Type const & aValueType = i_value.getValueType();
     112          48 :         if  (   aValueType.equals( ::cppu::UnoType< PropertyValue >::get() )
     113          24 :             ||  aValueType.equals( ::cppu::UnoType< NamedValue >::get() )
     114          24 :             ||  aValueType.equals( ::cppu::UnoType< Sequence< PropertyValue > >::get() )
     115          25 :             ||  aValueType.equals( ::cppu::UnoType< Sequence< NamedValue > >::get() )
     116             :             )
     117          24 :             return true;
     118           0 :         return false;
     119             :     }
     120             : 
     121             : 
     122         100 :     NamedValueCollection& NamedValueCollection::merge( const NamedValueCollection& _rAdditionalValues, bool _bOverwriteExisting )
     123             :     {
     124         738 :         for (   NamedValueRepository::const_iterator namedValue = _rAdditionalValues.m_pImpl->aValues.begin();
     125         492 :                 namedValue != _rAdditionalValues.m_pImpl->aValues.end();
     126             :                 ++namedValue
     127             :             )
     128             :         {
     129         146 :             if ( _bOverwriteExisting || !impl_has( namedValue->first ) )
     130         146 :                 impl_put( namedValue->first, namedValue->second );
     131             :         }
     132             : 
     133         100 :         return *this;
     134             :     }
     135             : 
     136             : 
     137          24 :     size_t NamedValueCollection::size() const
     138             :     {
     139          24 :         return m_pImpl->aValues.size();
     140             :     }
     141             : 
     142             : 
     143          24 :     bool NamedValueCollection::empty() const
     144             :     {
     145          24 :         return m_pImpl->aValues.empty();
     146             :     }
     147             : 
     148             : 
     149           1 :     ::std::vector< OUString > NamedValueCollection::getNames() const
     150             :     {
     151           1 :         ::std::vector< OUString > aNames;
     152           4 :         for ( NamedValueRepository::const_iterator it = m_pImpl->aValues.begin(), end = m_pImpl->aValues.end(); it != end; ++it )
     153             :         {
     154           3 :             aNames.push_back( it->first );
     155             :         }
     156           1 :         return aNames;
     157             :     }
     158             : 
     159             : 
     160        4280 :     void NamedValueCollection::impl_assign( const Any& i_rWrappedElements )
     161             :     {
     162        4280 :         Sequence< NamedValue > aNamedValues;
     163        8560 :         Sequence< PropertyValue > aPropertyValues;
     164        8560 :         NamedValue aNamedValue;
     165        8560 :         PropertyValue aPropertyValue;
     166             : 
     167        4280 :         if ( i_rWrappedElements >>= aNamedValues )
     168          29 :             impl_assign( aNamedValues );
     169        4251 :         else if ( i_rWrappedElements >>= aPropertyValues )
     170        3653 :             impl_assign( aPropertyValues );
     171         598 :         else if ( i_rWrappedElements >>= aNamedValue )
     172           0 :             impl_assign( Sequence< NamedValue >( &aNamedValue, 1 ) );
     173         598 :         else if ( i_rWrappedElements >>= aPropertyValue )
     174           0 :             impl_assign( Sequence< PropertyValue >( &aPropertyValue, 1 ) );
     175             :         else
     176        4280 :             SAL_WARN_IF( i_rWrappedElements.hasValue(), "comphelper", "NamedValueCollection::impl_assign(Any): unsupported type!" );
     177        4280 :     }
     178             : 
     179             : 
     180        4068 :     void NamedValueCollection::impl_assign( const Sequence< Any >& _rArguments )
     181             :     {
     182             :         {
     183        4068 :             NamedValueRepository aEmpty;
     184        4068 :             m_pImpl->aValues.swap( aEmpty );
     185             :         }
     186             : 
     187        4068 :         PropertyValue aPropertyValue;
     188        8136 :         NamedValue aNamedValue;
     189             : 
     190        4068 :         const Any* pArgument = _rArguments.getConstArray();
     191        4068 :         const Any* pArgumentEnd = _rArguments.getConstArray() + _rArguments.getLength();
     192        4994 :         for ( ; pArgument != pArgumentEnd; ++pArgument )
     193             :         {
     194         926 :             if ( *pArgument >>= aPropertyValue )
     195         915 :                 m_pImpl->aValues[ aPropertyValue.Name ] = aPropertyValue.Value;
     196          11 :             else if ( *pArgument >>= aNamedValue )
     197          11 :                 m_pImpl->aValues[ aNamedValue.Name ] = aNamedValue.Value;
     198             :             else
     199             :             {
     200             :                 SAL_WARN_IF(
     201             :                     pArgument->hasValue(), "comphelper",
     202             :                     ("NamedValueCollection::impl_assign: encountered a value"
     203             :                      " type which I cannot handle: "
     204             :                      + pArgument->getValueTypeName()));
     205             :             }
     206        4068 :         }
     207        4068 :     }
     208             : 
     209             : 
     210       38606 :     void NamedValueCollection::impl_assign( const Sequence< PropertyValue >& _rArguments )
     211             :     {
     212             :         {
     213       38606 :             NamedValueRepository aEmpty;
     214       38606 :             m_pImpl->aValues.swap( aEmpty );
     215             :         }
     216             : 
     217       38606 :         const PropertyValue* pArgument = _rArguments.getConstArray();
     218       38606 :         const PropertyValue* pArgumentEnd = _rArguments.getConstArray() + _rArguments.getLength();
     219      319872 :         for ( ; pArgument != pArgumentEnd; ++pArgument )
     220      281266 :             m_pImpl->aValues[ pArgument->Name ] = pArgument->Value;
     221       38606 :     }
     222             : 
     223             : 
     224          90 :     void NamedValueCollection::impl_assign( const Sequence< NamedValue >& _rArguments )
     225             :     {
     226             :         {
     227          90 :             NamedValueRepository aEmpty;
     228          90 :             m_pImpl->aValues.swap( aEmpty );
     229             :         }
     230             : 
     231          90 :         const NamedValue* pArgument = _rArguments.getConstArray();
     232          90 :         const NamedValue* pArgumentEnd = _rArguments.getConstArray() + _rArguments.getLength();
     233         355 :         for ( ; pArgument != pArgumentEnd; ++pArgument )
     234         265 :             m_pImpl->aValues[ pArgument->Name ] = pArgument->Value;
     235          90 :     }
     236             : 
     237             : 
     238      100336 :     bool NamedValueCollection::get_ensureType( const OUString& _rValueName, void* _pValueLocation, const Type& _rExpectedValueType ) const
     239             :     {
     240      100336 :         NamedValueRepository::const_iterator pos = m_pImpl->aValues.find( _rValueName );
     241      100336 :         if ( pos != m_pImpl->aValues.end() )
     242             :         {
     243       47109 :             if ( uno_type_assignData(
     244             :                     _pValueLocation, _rExpectedValueType.getTypeLibType(),
     245       94218 :                     const_cast< void* >( pos->second.getValue() ), pos->second.getValueType().getTypeLibType(),
     246             :                     reinterpret_cast< uno_QueryInterfaceFunc >( cpp_queryInterface ),
     247             :                     reinterpret_cast< uno_AcquireFunc >( cpp_acquire ),
     248             :                     reinterpret_cast< uno_ReleaseFunc >( cpp_release )
     249       94218 :                 ) )
     250             :                 // argument exists, and could be extracted
     251       47109 :                 return true;
     252             : 
     253             :             // argument exists, but is of wrong type
     254           0 :             OUStringBuffer aBuffer;
     255           0 :             aBuffer.appendAscii( "Invalid value type for '" );
     256           0 :             aBuffer.append     ( _rValueName );
     257           0 :             aBuffer.appendAscii( "'.\nExpected: " );
     258           0 :             aBuffer.append     ( _rExpectedValueType.getTypeName() );
     259           0 :             aBuffer.appendAscii( "\nFound: " );
     260           0 :             aBuffer.append     ( pos->second.getValueType().getTypeName() );
     261           0 :             throw IllegalArgumentException( aBuffer.makeStringAndClear(), NULL, 0 );
     262             :         }
     263             : 
     264             :         // argument does not exist
     265       53227 :         return false;
     266             :     }
     267             : 
     268             :     namespace
     269             :     {
     270             :         class theEmptyDefault : public rtl::Static<Any, theEmptyDefault> {};
     271             :     }
     272             : 
     273             : 
     274       14453 :     const Any& NamedValueCollection::impl_get( const OUString& _rValueName ) const
     275             :     {
     276       14453 :         NamedValueRepository::const_iterator pos = m_pImpl->aValues.find( _rValueName );
     277       14453 :         if ( pos != m_pImpl->aValues.end() )
     278        2707 :             return pos->second;
     279             : 
     280       11746 :         return theEmptyDefault::get();
     281             :     }
     282             : 
     283             : 
     284       78038 :     bool NamedValueCollection::impl_has( const OUString& _rValueName ) const
     285             :     {
     286       78038 :         NamedValueRepository::const_iterator pos = m_pImpl->aValues.find( _rValueName );
     287       78038 :         return ( pos != m_pImpl->aValues.end() );
     288             :     }
     289             : 
     290             : 
     291       70590 :     bool NamedValueCollection::impl_put( const OUString& _rValueName, const Any& _rValue )
     292             :     {
     293       70590 :         bool bHas = impl_has( _rValueName );
     294       70590 :         m_pImpl->aValues[ _rValueName ] = _rValue;
     295       70590 :         return bHas;
     296             :     }
     297             : 
     298             : 
     299       48858 :     bool NamedValueCollection::impl_remove( const OUString& _rValueName )
     300             :     {
     301       48858 :         NamedValueRepository::iterator pos = m_pImpl->aValues.find( _rValueName );
     302       48858 :         if ( pos == m_pImpl->aValues.end() )
     303       43849 :             return false;
     304        5009 :         m_pImpl->aValues.erase( pos );
     305        5009 :         return true;
     306             :     }
     307             : 
     308             : 
     309             :     namespace
     310             :     {
     311             :         struct Value2PropertyValue : public ::std::unary_function< NamedValueRepository::value_type, PropertyValue >
     312             :         {
     313      111824 :             PropertyValue operator()( const NamedValueRepository::value_type& _rValue )
     314             :             {
     315             :                 return PropertyValue(
     316      111824 :                     _rValue.first, 0, _rValue.second, PropertyState_DIRECT_VALUE );
     317             :             }
     318             :         };
     319             : 
     320             :         struct Value2NamedValue : public ::std::unary_function< NamedValueRepository::value_type, NamedValue >
     321             :         {
     322         253 :             NamedValue operator()( const NamedValueRepository::value_type& _rValue )
     323             :             {
     324         253 :                 return NamedValue( _rValue.first, _rValue.second );
     325             :             }
     326             :         };
     327             :     }
     328             : 
     329             : 
     330       24112 :     sal_Int32 NamedValueCollection::operator >>= ( Sequence< PropertyValue >& _out_rValues ) const
     331             :     {
     332       24112 :         _out_rValues.realloc( m_pImpl->aValues.size() );
     333       24112 :         ::std::transform( m_pImpl->aValues.begin(), m_pImpl->aValues.end(), _out_rValues.getArray(), Value2PropertyValue() );
     334       24112 :         return _out_rValues.getLength();
     335             :     }
     336             : 
     337             : 
     338          40 :     sal_Int32 NamedValueCollection::operator >>= ( Sequence< NamedValue >& _out_rValues ) const
     339             :     {
     340          40 :         _out_rValues.realloc( m_pImpl->aValues.size() );
     341          40 :         ::std::transform( m_pImpl->aValues.begin(), m_pImpl->aValues.end(), _out_rValues.getArray(), Value2NamedValue() );
     342          40 :         return _out_rValues.getLength();
     343             :     }
     344             : 
     345             : 
     346             : } // namespace comphelper
     347             : 
     348             : 
     349             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11