xref: /trunk/main/basegfx/source/tools/stringconversiontools.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
11f882ec4SArmin Le Grand /**************************************************************
21f882ec4SArmin Le Grand  *
31f882ec4SArmin Le Grand  * Licensed to the Apache Software Foundation (ASF) under one
41f882ec4SArmin Le Grand  * or more contributor license agreements.  See the NOTICE file
51f882ec4SArmin Le Grand  * distributed with this work for additional information
61f882ec4SArmin Le Grand  * regarding copyright ownership.  The ASF licenses this file
71f882ec4SArmin Le Grand  * to you under the Apache License, Version 2.0 (the
81f882ec4SArmin Le Grand  * "License"); you may not use this file except in compliance
91f882ec4SArmin Le Grand  * with the License.  You may obtain a copy of the License at
101f882ec4SArmin Le Grand  *
111f882ec4SArmin Le Grand  *   http://www.apache.org/licenses/LICENSE-2.0
121f882ec4SArmin Le Grand  *
131f882ec4SArmin Le Grand  * Unless required by applicable law or agreed to in writing,
141f882ec4SArmin Le Grand  * software distributed under the License is distributed on an
151f882ec4SArmin Le Grand  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
161f882ec4SArmin Le Grand  * KIND, either express or implied.  See the License for the
171f882ec4SArmin Le Grand  * specific language governing permissions and limitations
181f882ec4SArmin Le Grand  * under the License.
191f882ec4SArmin Le Grand  *
201f882ec4SArmin Le Grand  *************************************************************/
211f882ec4SArmin Le Grand 
221f882ec4SArmin Le Grand // MARKER(update_precomp.py): autogen include statement, do not remove
231f882ec4SArmin Le Grand #include "precompiled_basegfx.hxx"
241f882ec4SArmin Le Grand 
251f882ec4SArmin Le Grand #include <stringconversiontools.hxx>
261f882ec4SArmin Le Grand #include <rtl/math.hxx>
271f882ec4SArmin Le Grand 
281f882ec4SArmin Le Grand namespace basegfx
291f882ec4SArmin Le Grand {
301f882ec4SArmin Le Grand     namespace internal
311f882ec4SArmin Le Grand     {
lcl_skipSpaces(sal_Int32 & io_rPos,const::rtl::OUString & rStr,const sal_Int32 nLen)321f882ec4SArmin Le Grand         void lcl_skipSpaces(sal_Int32&              io_rPos,
331f882ec4SArmin Le Grand                             const ::rtl::OUString&  rStr,
341f882ec4SArmin Le Grand                             const sal_Int32         nLen)
351f882ec4SArmin Le Grand         {
361f882ec4SArmin Le Grand             while( io_rPos < nLen &&
371f882ec4SArmin Le Grand                     sal_Unicode(' ') == rStr[io_rPos] )
381f882ec4SArmin Le Grand             {
391f882ec4SArmin Le Grand                 ++io_rPos;
401f882ec4SArmin Le Grand             }
411f882ec4SArmin Le Grand         }
421f882ec4SArmin Le Grand 
lcl_skipSpacesAndCommas(sal_Int32 & io_rPos,const::rtl::OUString & rStr,const sal_Int32 nLen)431f882ec4SArmin Le Grand         void lcl_skipSpacesAndCommas(sal_Int32&             io_rPos,
441f882ec4SArmin Le Grand                                         const ::rtl::OUString& rStr,
451f882ec4SArmin Le Grand                                         const sal_Int32         nLen)
461f882ec4SArmin Le Grand         {
471f882ec4SArmin Le Grand             while(io_rPos < nLen
481f882ec4SArmin Le Grand                     && (sal_Unicode(' ') == rStr[io_rPos] || sal_Unicode(',') == rStr[io_rPos]))
491f882ec4SArmin Le Grand             {
501f882ec4SArmin Le Grand                 ++io_rPos;
511f882ec4SArmin Le Grand             }
521f882ec4SArmin Le Grand         }
531f882ec4SArmin Le Grand 
lcl_getDoubleChar(double & o_fRetval,sal_Int32 & io_rPos,const::rtl::OUString & rStr)54*788dccbdSArmin Le Grand         bool lcl_getDoubleChar(double& o_fRetval, sal_Int32& io_rPos, const ::rtl::OUString& rStr)
551f882ec4SArmin Le Grand         {
561f882ec4SArmin Le Grand             sal_Unicode aChar( rStr[io_rPos] );
571f882ec4SArmin Le Grand             ::rtl::OUStringBuffer sNumberString;
581f882ec4SArmin Le Grand 
59*788dccbdSArmin Le Grand             // sign
601f882ec4SArmin Le Grand             if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
611f882ec4SArmin Le Grand             {
621f882ec4SArmin Le Grand                 sNumberString.append(rStr[io_rPos]);
631f882ec4SArmin Le Grand                 aChar = rStr[++io_rPos];
641f882ec4SArmin Le Grand             }
651f882ec4SArmin Le Grand 
66*788dccbdSArmin Le Grand             // numbers before point
67*788dccbdSArmin Le Grand             while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
681f882ec4SArmin Le Grand             {
691f882ec4SArmin Le Grand                 sNumberString.append(rStr[io_rPos]);
701f882ec4SArmin Le Grand                 aChar = rStr[++io_rPos];
711f882ec4SArmin Le Grand             }
721f882ec4SArmin Le Grand 
73*788dccbdSArmin Le Grand             // point
74*788dccbdSArmin Le Grand             if(sal_Unicode('.') == aChar)
75*788dccbdSArmin Le Grand             {
76*788dccbdSArmin Le Grand                 sNumberString.append(rStr[io_rPos]);
77*788dccbdSArmin Le Grand                 aChar = rStr[++io_rPos];
78*788dccbdSArmin Le Grand             }
79*788dccbdSArmin Le Grand 
80*788dccbdSArmin Le Grand             // numbers after point
81*788dccbdSArmin Le Grand             while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
82*788dccbdSArmin Le Grand             {
83*788dccbdSArmin Le Grand                 sNumberString.append(rStr[io_rPos]);
84*788dccbdSArmin Le Grand                 aChar = rStr[++io_rPos];
85*788dccbdSArmin Le Grand             }
86*788dccbdSArmin Le Grand 
87*788dccbdSArmin Le Grand             // 'e'
881f882ec4SArmin Le Grand             if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar)
891f882ec4SArmin Le Grand             {
901f882ec4SArmin Le Grand                 sNumberString.append(rStr[io_rPos]);
911f882ec4SArmin Le Grand                 aChar = rStr[++io_rPos];
921f882ec4SArmin Le Grand 
93*788dccbdSArmin Le Grand                 // sign for 'e'
941f882ec4SArmin Le Grand                 if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
951f882ec4SArmin Le Grand                 {
961f882ec4SArmin Le Grand                     sNumberString.append(rStr[io_rPos]);
971f882ec4SArmin Le Grand                     aChar = rStr[++io_rPos];
981f882ec4SArmin Le Grand                 }
991f882ec4SArmin Le Grand 
100*788dccbdSArmin Le Grand                 // number for 'e'
1011f882ec4SArmin Le Grand                 while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
1021f882ec4SArmin Le Grand                 {
1031f882ec4SArmin Le Grand                     sNumberString.append(rStr[io_rPos]);
1041f882ec4SArmin Le Grand                     aChar = rStr[++io_rPos];
1051f882ec4SArmin Le Grand                 }
1061f882ec4SArmin Le Grand             }
1071f882ec4SArmin Le Grand 
1081f882ec4SArmin Le Grand             if(sNumberString.getLength())
1091f882ec4SArmin Le Grand             {
1101f882ec4SArmin Le Grand                 rtl_math_ConversionStatus eStatus;
1111f882ec4SArmin Le Grand                 o_fRetval = ::rtl::math::stringToDouble( sNumberString.makeStringAndClear(),
1121f882ec4SArmin Le Grand                                                             (sal_Unicode)('.'),
1131f882ec4SArmin Le Grand                                                             (sal_Unicode)(','),
1141f882ec4SArmin Le Grand                                                             &eStatus,
1151f882ec4SArmin Le Grand                                                             NULL );
1161f882ec4SArmin Le Grand                 return ( eStatus == rtl_math_ConversionStatus_Ok );
1171f882ec4SArmin Le Grand             }
1181f882ec4SArmin Le Grand 
1191f882ec4SArmin Le Grand             return false;
1201f882ec4SArmin Le Grand         }
1211f882ec4SArmin Le Grand 
lcl_importDoubleAndSpaces(double & o_fRetval,sal_Int32 & io_rPos,const::rtl::OUString & rStr,const sal_Int32 nLen)1221f882ec4SArmin Le Grand         bool lcl_importDoubleAndSpaces( double&                 o_fRetval,
1231f882ec4SArmin Le Grand                                         sal_Int32&              io_rPos,
1241f882ec4SArmin Le Grand                                         const ::rtl::OUString&  rStr,
1251f882ec4SArmin Le Grand                                         const sal_Int32         nLen )
1261f882ec4SArmin Le Grand         {
1271f882ec4SArmin Le Grand             if( !lcl_getDoubleChar(o_fRetval, io_rPos, rStr) )
1281f882ec4SArmin Le Grand                 return false;
1291f882ec4SArmin Le Grand 
1301f882ec4SArmin Le Grand             lcl_skipSpacesAndCommas(io_rPos, rStr, nLen);
1311f882ec4SArmin Le Grand 
1321f882ec4SArmin Le Grand             return true;
1331f882ec4SArmin Le Grand         }
1341f882ec4SArmin Le Grand 
lcl_importNumberAndSpaces(sal_Int32 & o_nRetval,sal_Int32 & io_rPos,const::rtl::OUString & rStr,const sal_Int32 nLen)1351f882ec4SArmin Le Grand         bool lcl_importNumberAndSpaces(sal_Int32&                o_nRetval,
1361f882ec4SArmin Le Grand                                         sal_Int32&              io_rPos,
1371f882ec4SArmin Le Grand                                         const ::rtl::OUString&  rStr,
1381f882ec4SArmin Le Grand                                         const sal_Int32         nLen)
1391f882ec4SArmin Le Grand         {
1401f882ec4SArmin Le Grand             sal_Unicode aChar( rStr[io_rPos] );
1411f882ec4SArmin Le Grand             ::rtl::OUStringBuffer sNumberString;
1421f882ec4SArmin Le Grand 
1431f882ec4SArmin Le Grand             if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
1441f882ec4SArmin Le Grand             {
1451f882ec4SArmin Le Grand                 sNumberString.append(rStr[io_rPos]);
1461f882ec4SArmin Le Grand                 aChar = rStr[++io_rPos];
1471f882ec4SArmin Le Grand             }
1481f882ec4SArmin Le Grand 
1491f882ec4SArmin Le Grand             while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
1501f882ec4SArmin Le Grand             {
1511f882ec4SArmin Le Grand                 sNumberString.append(rStr[io_rPos]);
1521f882ec4SArmin Le Grand                 aChar = rStr[++io_rPos];
1531f882ec4SArmin Le Grand             }
1541f882ec4SArmin Le Grand 
1551f882ec4SArmin Le Grand             if(sNumberString.getLength())
1561f882ec4SArmin Le Grand             {
1571f882ec4SArmin Le Grand                 o_nRetval = sNumberString.makeStringAndClear().toInt32();
1581f882ec4SArmin Le Grand                 lcl_skipSpacesAndCommas(io_rPos, rStr, nLen);
1591f882ec4SArmin Le Grand 
1601f882ec4SArmin Le Grand                 return true;
1611f882ec4SArmin Le Grand             }
1621f882ec4SArmin Le Grand 
1631f882ec4SArmin Le Grand             return false;
1641f882ec4SArmin Le Grand         }
1651f882ec4SArmin Le Grand 
lcl_skipNumber(sal_Int32 & io_rPos,const::rtl::OUString & rStr,const sal_Int32 nLen)1661f882ec4SArmin Le Grand         void lcl_skipNumber(sal_Int32&              io_rPos,
1671f882ec4SArmin Le Grand                             const ::rtl::OUString&  rStr,
1681f882ec4SArmin Le Grand                             const sal_Int32         nLen)
1691f882ec4SArmin Le Grand         {
1701f882ec4SArmin Le Grand             bool bSignAllowed(true);
1711f882ec4SArmin Le Grand 
172*788dccbdSArmin Le Grand             while(io_rPos < nLen && lcl_isOnNumberChar(rStr, io_rPos, bSignAllowed, true))
1731f882ec4SArmin Le Grand             {
1741f882ec4SArmin Le Grand                 bSignAllowed = false;
1751f882ec4SArmin Le Grand                 ++io_rPos;
1761f882ec4SArmin Le Grand             }
1771f882ec4SArmin Le Grand         }
1781f882ec4SArmin Le Grand 
lcl_skipDouble(sal_Int32 & io_rPos,const::rtl::OUString & rStr)179*788dccbdSArmin Le Grand         void lcl_skipDouble(sal_Int32& io_rPos, const ::rtl::OUString& rStr)
1801f882ec4SArmin Le Grand         {
1811f882ec4SArmin Le Grand             sal_Unicode aChar( rStr[io_rPos] );
1821f882ec4SArmin Le Grand 
183*788dccbdSArmin Le Grand             // sign
1841f882ec4SArmin Le Grand             if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
1851f882ec4SArmin Le Grand             {
1861f882ec4SArmin Le Grand                 aChar = rStr[++io_rPos];
1871f882ec4SArmin Le Grand             }
1881f882ec4SArmin Le Grand 
189*788dccbdSArmin Le Grand             // numbers before point
190*788dccbdSArmin Le Grand             while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
191*788dccbdSArmin Le Grand             {
192*788dccbdSArmin Le Grand                 aChar = rStr[++io_rPos];
193*788dccbdSArmin Le Grand             }
194*788dccbdSArmin Le Grand 
195*788dccbdSArmin Le Grand             // point
196*788dccbdSArmin Le Grand             if(sal_Unicode('.') == aChar)
197*788dccbdSArmin Le Grand             {
198*788dccbdSArmin Le Grand                 aChar = rStr[++io_rPos];
199*788dccbdSArmin Le Grand             }
200*788dccbdSArmin Le Grand 
201*788dccbdSArmin Le Grand             // numbers after point
202*788dccbdSArmin Le Grand             while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
203*788dccbdSArmin Le Grand             {
204*788dccbdSArmin Le Grand                 aChar = rStr[++io_rPos];
205*788dccbdSArmin Le Grand             }
206*788dccbdSArmin Le Grand 
207*788dccbdSArmin Le Grand             // 'e'
2081f882ec4SArmin Le Grand             if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar)
2091f882ec4SArmin Le Grand             {
2101f882ec4SArmin Le Grand                 aChar = rStr[++io_rPos];
2111f882ec4SArmin Le Grand 
212*788dccbdSArmin Le Grand                 // sign of 'e'
2131f882ec4SArmin Le Grand                 if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
214*788dccbdSArmin Le Grand                 {
2151f882ec4SArmin Le Grand                     aChar = rStr[++io_rPos];
216*788dccbdSArmin Le Grand                 }
2171f882ec4SArmin Le Grand 
218*788dccbdSArmin Le Grand                 // numbers for 'e'
2191f882ec4SArmin Le Grand                 while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
2201f882ec4SArmin Le Grand                 {
2211f882ec4SArmin Le Grand                     aChar = rStr[++io_rPos];
2221f882ec4SArmin Le Grand                 }
2231f882ec4SArmin Le Grand             }
2241f882ec4SArmin Le Grand         }
2251f882ec4SArmin Le Grand 
lcl_putNumberCharWithSpace(::rtl::OUStringBuffer & rStr,double fValue,double fOldValue,bool bUseRelativeCoordinates)2261f882ec4SArmin Le Grand         void lcl_putNumberCharWithSpace( ::rtl::OUStringBuffer& rStr,
2271f882ec4SArmin Le Grand                                             double              fValue,
2281f882ec4SArmin Le Grand                                             double              fOldValue,
2291f882ec4SArmin Le Grand                                             bool                    bUseRelativeCoordinates )
2301f882ec4SArmin Le Grand         {
2311f882ec4SArmin Le Grand             if( bUseRelativeCoordinates )
2321f882ec4SArmin Le Grand                 fValue -= fOldValue;
2331f882ec4SArmin Le Grand 
2341f882ec4SArmin Le Grand             const sal_Int32 aLen( rStr.getLength() );
2351f882ec4SArmin Le Grand             if(aLen)
2361f882ec4SArmin Le Grand             {
237*788dccbdSArmin Le Grand                 if( lcl_isOnNumberChar(rStr.charAt(aLen - 1), false, true) &&
2381f882ec4SArmin Le Grand                     fValue >= 0.0 )
2391f882ec4SArmin Le Grand                 {
2401f882ec4SArmin Le Grand                     rStr.append( sal_Unicode(' ') );
2411f882ec4SArmin Le Grand                 }
2421f882ec4SArmin Le Grand             }
2431f882ec4SArmin Le Grand 
2441f882ec4SArmin Le Grand             lcl_putNumberChar(rStr, fValue);
2451f882ec4SArmin Le Grand         }
2461f882ec4SArmin Le Grand     } // namespace internal
2471f882ec4SArmin Le Grand }
2481f882ec4SArmin Le Grand 
2491f882ec4SArmin Le Grand // eof
250