LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / forms / source / xforms / convert.cxx
blob948d526930f82897f11e87379c3ca548f0c887eb
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "convert.hxx"
23 #include <sstream>
24 #include <rtl/math.hxx>
25 #include <rtl/ustrbuf.hxx>
26 #include <osl/diagnose.h>
27 #include <tools/date.hxx>
28 #include <com/sun/star/uno/Type.hxx>
29 #include <com/sun/star/util/Date.hpp>
30 #include <com/sun/star/util/DateTime.hpp>
31 #include <com/sun/star/util/Time.hpp>
32 #include <comphelper/sequence.hxx>
33 #include <unotools/datetime.hxx>
35 using xforms::Convert;
36 using com::sun::star::uno::Any;
37 using com::sun::star::uno::makeAny;
38 using namespace utl;
40 Convert::Convert()
42 init();
45 namespace
48 OUString lcl_toXSD_OUString( const Any& rAny )
49 { OUString sStr; rAny >>= sStr; return sStr; }
52 Any lcl_toAny_OUString( const OUString& rStr )
53 { return Any(rStr); }
55 void lcl_appendInt32ToBuffer( const sal_Int32 _nValue, OUStringBuffer& _rBuffer, sal_Int16 _nMinDigits )
57 if ( ( _nMinDigits >= 4 ) && ( _nValue < 1000 ) )
58 _rBuffer.append( '0' );
59 if ( ( _nMinDigits >= 3 ) && ( _nValue < 100 ) )
60 _rBuffer.append( '0' );
61 if ( ( _nMinDigits >= 2 ) && ( _nValue < 10 ) )
62 _rBuffer.append( '0' );
63 _rBuffer.append( _nValue );
67 OUString lcl_toXSD_UNODate_typed( const css::util::Date& rDate )
70 OUStringBuffer sInfo;
71 lcl_appendInt32ToBuffer( rDate.Year, sInfo, 4 );
72 sInfo.append( "-" );
73 lcl_appendInt32ToBuffer( rDate.Month, sInfo, 2 );
74 sInfo.append( "-" );
75 lcl_appendInt32ToBuffer( rDate.Day, sInfo, 2 );
77 return sInfo.makeStringAndClear();
81 OUString lcl_toXSD_UNODate( const Any& rAny )
83 css::util::Date aDate;
84 OSL_VERIFY( rAny >>= aDate );
85 return lcl_toXSD_UNODate_typed( aDate );
89 css::util::Date lcl_toUNODate( const OUString& rString )
91 css::util::Date aDate( 1, 1, 1900 );
93 bool bWellformed = ISO8601parseDate(rString, aDate);
95 // sanity checks
96 if ( ( aDate.Year > 9999 ) || ( aDate.Month < 1 ) || ( aDate.Month > 12 ) || ( aDate.Day < 1 ) || ( aDate.Day > 31 ) )
97 bWellformed = false;
98 else
100 ::Date aDateCheck( 1, aDate.Month, aDate.Year );
101 if ( aDate.Day > aDateCheck.GetDaysInMonth() )
102 bWellformed = false;
105 // all okay?
106 if ( !bWellformed )
107 return css::util::Date( 1, 1, 1900 );
109 return aDate;
113 Any lcl_toAny_UNODate( const OUString& rString )
115 return makeAny( lcl_toUNODate( rString ) );
119 OUString lcl_toXSD_UNOTime_typed( const css::util::Time& rTime )
122 OUStringBuffer sInfo;
123 lcl_appendInt32ToBuffer( rTime.Hours, sInfo, 2 );
124 sInfo.append( ":" );
125 lcl_appendInt32ToBuffer( rTime.Minutes, sInfo, 2 );
126 sInfo.append( ":" );
127 lcl_appendInt32ToBuffer( rTime.Seconds, sInfo, 2 );
128 if ( rTime.NanoSeconds != 0 )
130 OSL_ENSURE(rTime.NanoSeconds < 1000000000,"NanoSeconds cannot be more than 999 999 999");
131 sInfo.append('.');
132 std::ostringstream ostr;
133 ostr.fill('0');
134 ostr.width(9);
135 ostr << rTime.NanoSeconds;
136 sInfo.append(OUString::createFromAscii(ostr.str().c_str()));
139 return sInfo.makeStringAndClear();
143 OUString lcl_toXSD_UNOTime( const Any& rAny )
145 css::util::Time aTime;
146 OSL_VERIFY( rAny >>= aTime );
147 return lcl_toXSD_UNOTime_typed( aTime );
151 css::util::Time lcl_toUNOTime( const OUString& rString )
153 css::util::Time aTime;
155 bool bWellformed = ISO8601parseTime(rString, aTime);
157 // sanity checks
158 // note that Seconds == 60 denotes leap seconds. Normally, they're not allowed everywhere,
159 // but we accept them all the time for simplicity reasons
160 if ( ( aTime.Hours > 24 )
161 || ( aTime.Minutes > 59 )
162 || ( aTime.Seconds > 60 )
164 bWellformed = false;
166 if ( bWellformed
167 && ( aTime.Hours == 24 )
168 && ( ( aTime.Minutes != 0 )
169 || ( aTime.Seconds != 0 )
170 || ( aTime.NanoSeconds != 0 )
173 bWellformed = false;
175 // all okay?
176 if ( !bWellformed )
177 return css::util::Time();
179 return aTime;
183 Any lcl_toAny_UNOTime( const OUString& rString )
185 return makeAny( lcl_toUNOTime( rString ) );
189 OUString lcl_toXSD_UNODateTime( const Any& rAny )
191 css::util::DateTime aDateTime;
192 OSL_VERIFY( rAny >>= aDateTime );
194 css::util::Date aDate( aDateTime.Day, aDateTime.Month, aDateTime.Year );
195 OUString sDate = lcl_toXSD_UNODate_typed( aDate );
197 css::util::Time const aTime( aDateTime.NanoSeconds, aDateTime.Seconds,
198 aDateTime.Minutes, aDateTime.Hours, aDateTime.IsUTC);
199 OUString sTime = lcl_toXSD_UNOTime_typed( aTime );
201 OUString sRet = sDate + "T" + sTime;
202 return sRet;
206 Any lcl_toAny_UNODateTime( const OUString& rString )
208 // separate the date from the time part
209 sal_Int32 nDateTimeSep = rString.indexOf( 'T' );
210 if ( nDateTimeSep == -1 )
211 nDateTimeSep = rString.indexOf( 't' );
213 css::util::Date aDate;
214 css::util::Time aTime;
215 if ( nDateTimeSep == -1 )
216 { // no time part
217 aDate = lcl_toUNODate( rString );
219 else
221 aDate = lcl_toUNODate( rString.copy( 0, nDateTimeSep ) );
222 aTime = lcl_toUNOTime( rString.copy( nDateTimeSep + 1 ) );
224 css::util::DateTime aDateTime(
225 aTime.NanoSeconds, aTime.Seconds, aTime.Minutes, aTime.Hours,
226 aDate.Day, aDate.Month, aDate.Year, aTime.IsUTC
228 return makeAny( aDateTime );
233 void Convert::init()
235 maMap[ cppu::UnoType<OUString>::get() ] = Convert_t(&lcl_toXSD_OUString, &lcl_toAny_OUString);
236 maMap[ cppu::UnoType<css::util::Date>::get() ] = Convert_t( &lcl_toXSD_UNODate, &lcl_toAny_UNODate );
237 maMap[ cppu::UnoType<css::util::Time>::get() ] = Convert_t( &lcl_toXSD_UNOTime, &lcl_toAny_UNOTime );
238 maMap[ cppu::UnoType<css::util::DateTime>::get() ] = Convert_t( &lcl_toXSD_UNODateTime, &lcl_toAny_UNODateTime );
242 Convert& Convert::get()
244 // create our Singleton instance on demand
245 static Convert aConvert;
246 return aConvert;
249 bool Convert::hasType( const css::uno::Type& rType )
251 return maMap.find( rType ) != maMap.end();
254 css::uno::Sequence<css::uno::Type> Convert::getTypes() const
256 return comphelper::mapKeysToSequence( maMap );
259 OUString Convert::toXSD( const css::uno::Any& rAny )
261 Map_t::iterator aIter = maMap.find( rAny.getValueType() );
262 return aIter != maMap.end() ? aIter->second.first( rAny ) : OUString();
265 css::uno::Any Convert::toAny( const OUString& rValue,
266 const css::uno::Type& rType )
268 Map_t::iterator aIter = maMap.find( rType );
269 return aIter != maMap.end() ? aIter->second.second( rValue ) : css::uno::Any();
273 OUString Convert::collapseWhitespace( const OUString& _rString )
275 sal_Int32 nLength = _rString.getLength();
276 OUStringBuffer aBuffer( nLength );
277 const sal_Unicode* pStr = _rString.getStr();
278 bool bStrip = true;
279 for( sal_Int32 i = 0; i < nLength; i++ )
281 sal_Unicode c = pStr[i];
282 if( c == u'\x0008' ||
283 c == u'\x000A' ||
284 c == u'\x000D' ||
285 c == u' ' )
287 if( ! bStrip )
289 aBuffer.append( u' ' );
290 bStrip = true;
293 else
295 bStrip = false;
296 aBuffer.append( c );
299 if( aBuffer[ aBuffer.getLength() - 1 ] == u' ' )
300 aBuffer.setLength( aBuffer.getLength() - 1 );
301 return aBuffer.makeStringAndClear();
304 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */