LCOV - code coverage report
Current view: top level - forms/source/xforms - convert.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 155 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 25 0.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             : 
      21             : #include "convert.hxx"
      22             : 
      23             : #include "unohelper.hxx"
      24             : #include <algorithm>
      25             : #include <functional>
      26             : #include <o3tl/compat_functional.hxx>
      27             : #include <rtl/math.hxx>
      28             : #include <rtl/ustrbuf.hxx>
      29             : #include <osl/diagnose.h>
      30             : #include <tools/date.hxx>
      31             : #include <com/sun/star/uno/Type.hxx>
      32             : #include <com/sun/star/xsd/WhiteSpaceTreatment.hpp>
      33             : #include <com/sun/star/util/Date.hpp>
      34             : #include <com/sun/star/util/DateTime.hpp>
      35             : #include <com/sun/star/util/Time.hpp>
      36             : #include <unotools/datetime.hxx>
      37             : 
      38             : using xforms::Convert;
      39             : using com::sun::star::uno::Any;
      40             : using com::sun::star::uno::makeAny;
      41             : using namespace std;
      42             : using namespace o3tl;
      43             : using namespace utl;
      44             : 
      45             : typedef com::sun::star::util::Date UNODate;
      46             : typedef com::sun::star::util::Time UNOTime;
      47             : typedef com::sun::star::util::DateTime UNODateTime;
      48             : 
      49           0 : Convert::Convert()
      50           0 :     : maMap()
      51             : {
      52           0 :     init();
      53           0 : }
      54             : 
      55             : #define ADD_ENTRY(XCONVERT,TYPE) XCONVERT->maMap[ cppu::UnoType<TYPE>::get() ] = Convert_t( &lcl_toXSD_##TYPE, &lcl_toAny_##TYPE )
      56             : 
      57             : namespace
      58             : {
      59             : 
      60           0 :     OUString lcl_toXSD_OUString( const Any& rAny )
      61           0 :     { OUString sStr; rAny >>= sStr; return sStr; }
      62             : 
      63             : 
      64           0 :     Any lcl_toAny_OUString( const OUString& rStr )
      65           0 :     { Any aAny; aAny <<= rStr; return aAny; }
      66             : 
      67             : 
      68           0 :     OUString lcl_toXSD_bool( const Any& rAny )
      69           0 :     { bool b = false; rAny >>= b; return b ? OUString("true") : OUString("false"); }
      70             : 
      71             : 
      72           0 :     Any lcl_toAny_bool( const OUString& rStr )
      73             :     {
      74           0 :         bool b = ( rStr == "true"  ||  rStr == "1" );
      75           0 :         return makeAny( b );
      76             :     }
      77             : 
      78             : 
      79           0 :     OUString lcl_toXSD_double( const Any& rAny )
      80             :     {
      81           0 :         double f = 0.0;
      82           0 :         rAny >>= f;
      83             : 
      84           0 :         return rtl::math::isFinite( f )
      85             :             ? rtl::math::doubleToUString( f, rtl_math_StringFormat_Automatic,
      86             :                                         rtl_math_DecimalPlaces_Max, '.',
      87             :                                         true )
      88           0 :             : OUString();
      89             :     }
      90             : 
      91             : 
      92           0 :     Any lcl_toAny_double( const OUString& rString )
      93             :     {
      94             :         rtl_math_ConversionStatus eStatus;
      95             :         double f = rtl::math::stringToDouble(
      96           0 :             rString, '.', ',', &eStatus, NULL );
      97           0 :         return ( eStatus == rtl_math_ConversionStatus_Ok ) ? makeAny( f ) : Any();
      98             :     }
      99             : 
     100             : 
     101           0 :     void lcl_appendInt32ToBuffer( const sal_Int32 _nValue, OUStringBuffer& _rBuffer, sal_Int16 _nMinDigits )
     102             :     {
     103           0 :         if ( ( _nMinDigits >= 4 ) && ( _nValue < 1000 ) )
     104           0 :             _rBuffer.append( '0' );
     105           0 :         if ( ( _nMinDigits >= 3 ) && ( _nValue < 100 ) )
     106           0 :             _rBuffer.append( '0' );
     107           0 :         if ( ( _nMinDigits >= 2 ) && ( _nValue < 10 ) )
     108           0 :             _rBuffer.append( '0' );
     109           0 :         _rBuffer.append( _nValue );
     110           0 :     }
     111             : 
     112             : 
     113           0 :     OUString lcl_toXSD_UNODate_typed( const UNODate& rDate )
     114             :     {
     115             : 
     116           0 :         OUStringBuffer sInfo;
     117           0 :         lcl_appendInt32ToBuffer( rDate.Year, sInfo, 4 );
     118           0 :         sInfo.appendAscii( "-" );
     119           0 :         lcl_appendInt32ToBuffer( rDate.Month, sInfo, 2 );
     120           0 :         sInfo.appendAscii( "-" );
     121           0 :         lcl_appendInt32ToBuffer( rDate.Day, sInfo, 2 );
     122             : 
     123           0 :         return sInfo.makeStringAndClear();
     124             :     }
     125             : 
     126             : 
     127           0 :     OUString lcl_toXSD_UNODate( const Any& rAny )
     128             :     {
     129           0 :         UNODate aDate;
     130           0 :         OSL_VERIFY( rAny >>= aDate );
     131           0 :         return lcl_toXSD_UNODate_typed( aDate );
     132             :     }
     133             : 
     134             : 
     135           0 :     UNODate lcl_toUNODate( const OUString& rString )
     136             :     {
     137           0 :         UNODate aDate( 1, 1, 1900 );
     138             : 
     139           0 :         bool bWellformed = ISO8601parseDate(rString, aDate);
     140             : 
     141             :         // sanity checks
     142           0 :         if ( ( aDate.Year > 9999 ) || ( aDate.Month < 1 ) || ( aDate.Month > 12 ) || ( aDate.Day < 1 ) || ( aDate.Day > 31 ) )
     143           0 :             bWellformed = false;
     144             :         else
     145             :         {
     146           0 :             ::Date aDateCheck( 1, aDate.Month, aDate.Year );
     147           0 :             if ( aDate.Day > aDateCheck.GetDaysInMonth() )
     148           0 :                 bWellformed = false;
     149             :         }
     150             : 
     151             :         // all okay?
     152           0 :         if ( !bWellformed )
     153           0 :             return UNODate( 1, 1, 1900 );
     154             : 
     155           0 :         return aDate;
     156             :     }
     157             : 
     158             : 
     159           0 :     Any lcl_toAny_UNODate( const OUString& rString )
     160             :     {
     161           0 :         return makeAny( lcl_toUNODate( rString ) );
     162             :     }
     163             : 
     164             : 
     165           0 :     OUString lcl_toXSD_UNOTime_typed( const UNOTime& rTime )
     166             :     {
     167             : 
     168           0 :         OUStringBuffer sInfo;
     169           0 :         lcl_appendInt32ToBuffer( rTime.Hours, sInfo, 2 );
     170           0 :         sInfo.appendAscii( ":" );
     171           0 :         lcl_appendInt32ToBuffer( rTime.Minutes, sInfo, 2 );
     172           0 :         sInfo.appendAscii( ":" );
     173           0 :         lcl_appendInt32ToBuffer( rTime.Seconds, sInfo, 2 );
     174           0 :         if ( rTime.NanoSeconds != 0 )
     175             :         {
     176             :             OSL_ENSURE(rTime.NanoSeconds < 1000000000,"NanoSeconds cannot be more than 999 999 999");
     177           0 :             sInfo.append('.');
     178           0 :             std::ostringstream ostr;
     179           0 :             ostr.fill('0');
     180           0 :             ostr.width(9);
     181           0 :             ostr << rTime.NanoSeconds;
     182           0 :             sInfo.append(OUString::createFromAscii(ostr.str().c_str()));
     183             :         }
     184             : 
     185           0 :         return sInfo.makeStringAndClear();
     186             :     }
     187             : 
     188             : 
     189           0 :     OUString lcl_toXSD_UNOTime( const Any& rAny )
     190             :     {
     191           0 :         UNOTime aTime;
     192           0 :         OSL_VERIFY( rAny >>= aTime );
     193           0 :         return lcl_toXSD_UNOTime_typed( aTime );
     194             :     }
     195             : 
     196             : 
     197           0 :     UNOTime lcl_toUNOTime( const OUString& rString )
     198             :     {
     199           0 :         UNOTime aTime;
     200             : 
     201           0 :         bool bWellformed = ISO8601parseTime(rString, aTime);
     202             : 
     203             :         // sanity checks
     204             :         // note that Seconds == 60 denotes leap seconds. Normally, they're not allowed everywhere,
     205             :         // but we accept them all the time for simplicity reasons
     206           0 :         if  (  ( aTime.Hours > 24 )
     207           0 :             || ( aTime.Minutes > 59 )
     208           0 :             || ( aTime.Seconds > 60 )
     209             :             )
     210           0 :             bWellformed = false;
     211             : 
     212           0 :         if  (   bWellformed
     213           0 :             &&  ( aTime.Hours == 24 )
     214           0 :             &&  (   ( aTime.Minutes != 0 )
     215           0 :                 ||  ( aTime.Seconds != 0 )
     216           0 :                 ||  ( aTime.NanoSeconds != 0 )
     217             :                 )
     218             :             )
     219           0 :             bWellformed = false;
     220             : 
     221             :         // all okay?
     222           0 :         if ( !bWellformed )
     223           0 :             return UNOTime();
     224             : 
     225           0 :         return aTime;
     226             :     }
     227             : 
     228             : 
     229           0 :     Any lcl_toAny_UNOTime( const OUString& rString )
     230             :     {
     231           0 :         return makeAny( lcl_toUNOTime( rString ) );
     232             :     }
     233             : 
     234             : 
     235           0 :     OUString lcl_toXSD_UNODateTime( const Any& rAny )
     236             :     {
     237           0 :         UNODateTime aDateTime;
     238           0 :         OSL_VERIFY( rAny >>= aDateTime );
     239             : 
     240           0 :         UNODate aDate( aDateTime.Day, aDateTime.Month, aDateTime.Year );
     241           0 :         OUString sDate = lcl_toXSD_UNODate_typed( aDate );
     242             : 
     243             :         UNOTime const aTime( aDateTime.NanoSeconds, aDateTime.Seconds,
     244           0 :                     aDateTime.Minutes, aDateTime.Hours, aDateTime.IsUTC);
     245           0 :         OUString sTime = lcl_toXSD_UNOTime_typed( aTime );
     246             : 
     247           0 :         OUString sRet = sDate + "T" + sTime;
     248           0 :         return sRet;
     249             :     }
     250             : 
     251             : 
     252           0 :     Any lcl_toAny_UNODateTime( const OUString& rString )
     253             :     {
     254             :         // separate the date from the time part
     255           0 :         sal_Int32 nDateTimeSep = rString.indexOf( 'T' );
     256           0 :         if ( nDateTimeSep == -1 )
     257           0 :             nDateTimeSep = rString.indexOf( 't' );
     258             : 
     259           0 :         UNODate aDate;
     260           0 :         UNOTime aTime;
     261           0 :         if ( nDateTimeSep == -1 )
     262             :         {   // no time part
     263           0 :             aDate = lcl_toUNODate( rString );
     264             :         }
     265             :         else
     266             :         {
     267           0 :             aDate = lcl_toUNODate( rString.copy( 0, nDateTimeSep ) );
     268           0 :             aTime = lcl_toUNOTime( rString.copy( nDateTimeSep + 1 ) );
     269             :         }
     270             :         UNODateTime aDateTime(
     271             :             aTime.NanoSeconds, aTime.Seconds, aTime.Minutes, aTime.Hours,
     272             :             aDate.Day, aDate.Month, aDate.Year, aTime.IsUTC
     273           0 :         );
     274           0 :         return makeAny( aDateTime );
     275             :     }
     276             : }
     277             : 
     278             : 
     279           0 : void Convert::init()
     280             : {
     281           0 :     ADD_ENTRY( this, OUString );
     282           0 :     ADD_ENTRY( this, bool );
     283           0 :     ADD_ENTRY( this, double );
     284           0 :     ADD_ENTRY( this, UNODate );
     285           0 :     ADD_ENTRY( this, UNOTime );
     286           0 :     ADD_ENTRY( this, UNODateTime );
     287           0 : }
     288             : 
     289             : 
     290           0 : Convert& Convert::get()
     291             : {
     292             :     // create our Singleton instance on demand
     293             :     static Convert* pConvert = NULL;
     294           0 :     if( pConvert == NULL )
     295           0 :         pConvert = new Convert();
     296             : 
     297             :     OSL_ENSURE( pConvert != NULL, "no converter?" );
     298           0 :     return *pConvert;
     299             : }
     300             : 
     301           0 : bool Convert::hasType( const Type_t& rType )
     302             : {
     303           0 :     return maMap.find( rType ) != maMap.end();
     304             : }
     305             : 
     306           0 : Convert::Types_t Convert::getTypes()
     307             : {
     308           0 :     Types_t aTypes( maMap.size() );
     309             :     transform( maMap.begin(), maMap.end(), aTypes.getArray(),
     310           0 :                o3tl::select1st<Map_t::value_type>() );
     311           0 :     return aTypes;
     312             : }
     313             : 
     314           0 : OUString Convert::toXSD( const Any_t& rAny )
     315             : {
     316           0 :     Map_t::iterator aIter = maMap.find( rAny.getValueType() );
     317           0 :     return aIter != maMap.end() ? aIter->second.first( rAny ) : OUString();
     318             : }
     319             : 
     320           0 : Convert::Any_t Convert::toAny( const OUString& rValue,
     321             :                                const Type_t& rType )
     322             : {
     323           0 :     Map_t::iterator aIter = maMap.find( rType );
     324           0 :     return aIter != maMap.end() ? aIter->second.second( rValue ) : Any_t();
     325             : }
     326             : 
     327             : 
     328           0 : OUString Convert::collapseWhitespace( const OUString& _rString )
     329             : {
     330           0 :     sal_Int32 nLength = _rString.getLength();
     331           0 :     OUStringBuffer aBuffer( nLength );
     332           0 :     const sal_Unicode* pStr = _rString.getStr();
     333           0 :     bool bStrip = true;
     334           0 :     for( sal_Int32 i = 0; i < nLength; i++ )
     335             :     {
     336           0 :         sal_Unicode c = pStr[i];
     337           0 :         if( c == sal_Unicode(0x08) ||
     338           0 :             c == sal_Unicode(0x0A) ||
     339           0 :             c == sal_Unicode(0x0D) ||
     340             :             c == sal_Unicode(0x20) )
     341             :         {
     342           0 :             if( ! bStrip )
     343             :             {
     344           0 :                 aBuffer.append( sal_Unicode(0x20) );
     345           0 :                 bStrip = true;
     346             :             }
     347             :         }
     348             :         else
     349             :         {
     350           0 :             bStrip = false;
     351           0 :             aBuffer.append( c );
     352             :         }
     353             :     }
     354           0 :     if( aBuffer[ aBuffer.getLength() - 1 ] == sal_Unicode( 0x20 ) )
     355           0 :         aBuffer.setLength( aBuffer.getLength() - 1 );
     356           0 :     return aBuffer.makeStringAndClear();
     357             : }
     358             : 
     359             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11