1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_basegfx.hxx"
24 
25 #include <stringconversiontools.hxx>
26 #include <rtl/math.hxx>
27 
28 namespace basegfx
29 {
30     namespace internal
31     {
lcl_skipSpaces(sal_Int32 & io_rPos,const::rtl::OUString & rStr,const sal_Int32 nLen)32         void lcl_skipSpaces(sal_Int32& 				io_rPos,
33                             const ::rtl::OUString& 	rStr,
34                             const sal_Int32 		nLen)
35         {
36             while( io_rPos < nLen &&
37                     sal_Unicode(' ') == rStr[io_rPos] )
38             {
39                 ++io_rPos;
40             }
41         }
42 
lcl_skipSpacesAndCommas(sal_Int32 & io_rPos,const::rtl::OUString & rStr,const sal_Int32 nLen)43         void lcl_skipSpacesAndCommas(sal_Int32& 			io_rPos,
44                                         const ::rtl::OUString& rStr,
45                                         const sal_Int32 		nLen)
46         {
47             while(io_rPos < nLen
48                     && (sal_Unicode(' ') == rStr[io_rPos] || sal_Unicode(',') == rStr[io_rPos]))
49             {
50                 ++io_rPos;
51             }
52         }
53 
lcl_getDoubleChar(double & o_fRetval,sal_Int32 & io_rPos,const::rtl::OUString & rStr)54         bool lcl_getDoubleChar(double& 					o_fRetval,
55                                 sal_Int32& 				io_rPos,
56                                 const ::rtl::OUString& 	rStr)
57         {
58             sal_Unicode aChar( rStr[io_rPos] );
59             ::rtl::OUStringBuffer sNumberString;
60 
61             if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
62             {
63                 sNumberString.append(rStr[io_rPos]);
64                 aChar = rStr[++io_rPos];
65             }
66 
67             while((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
68                     || sal_Unicode('.') == aChar)
69             {
70                 sNumberString.append(rStr[io_rPos]);
71                 aChar = rStr[++io_rPos];
72             }
73 
74             if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar)
75             {
76                 sNumberString.append(rStr[io_rPos]);
77                 aChar = rStr[++io_rPos];
78 
79                 if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
80                 {
81                     sNumberString.append(rStr[io_rPos]);
82                     aChar = rStr[++io_rPos];
83                 }
84 
85                 while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
86                 {
87                     sNumberString.append(rStr[io_rPos]);
88                     aChar = rStr[++io_rPos];
89                 }
90             }
91 
92             if(sNumberString.getLength())
93             {
94                 rtl_math_ConversionStatus eStatus;
95                 o_fRetval = ::rtl::math::stringToDouble( sNumberString.makeStringAndClear(),
96                                                             (sal_Unicode)('.'),
97                                                             (sal_Unicode)(','),
98                                                             &eStatus,
99                                                             NULL );
100                 return ( eStatus == rtl_math_ConversionStatus_Ok );
101             }
102 
103             return false;
104         }
105 
lcl_importDoubleAndSpaces(double & o_fRetval,sal_Int32 & io_rPos,const::rtl::OUString & rStr,const sal_Int32 nLen)106         bool lcl_importDoubleAndSpaces( double& 				o_fRetval,
107                                         sal_Int32& 				io_rPos,
108                                         const ::rtl::OUString& 	rStr,
109                                         const sal_Int32 		nLen )
110         {
111             if( !lcl_getDoubleChar(o_fRetval, io_rPos, rStr) )
112                 return false;
113 
114             lcl_skipSpacesAndCommas(io_rPos, rStr, nLen);
115 
116             return true;
117         }
118 
lcl_importNumberAndSpaces(sal_Int32 & o_nRetval,sal_Int32 & io_rPos,const::rtl::OUString & rStr,const sal_Int32 nLen)119         bool lcl_importNumberAndSpaces(sal_Int32&                o_nRetval,
120                                         sal_Int32& 				io_rPos,
121                                         const ::rtl::OUString& 	rStr,
122                                         const sal_Int32 		nLen)
123         {
124             sal_Unicode aChar( rStr[io_rPos] );
125             ::rtl::OUStringBuffer sNumberString;
126 
127             if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
128             {
129                 sNumberString.append(rStr[io_rPos]);
130                 aChar = rStr[++io_rPos];
131             }
132 
133             while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
134             {
135                 sNumberString.append(rStr[io_rPos]);
136                 aChar = rStr[++io_rPos];
137             }
138 
139             if(sNumberString.getLength())
140             {
141                 o_nRetval = sNumberString.makeStringAndClear().toInt32();
142                 lcl_skipSpacesAndCommas(io_rPos, rStr, nLen);
143 
144                 return true;
145             }
146 
147             return false;
148         }
149 
lcl_skipNumber(sal_Int32 & io_rPos,const::rtl::OUString & rStr,const sal_Int32 nLen)150         void lcl_skipNumber(sal_Int32& 				io_rPos,
151                             const ::rtl::OUString& 	rStr,
152                             const sal_Int32 		nLen)
153         {
154             bool bSignAllowed(true);
155 
156             while(io_rPos < nLen && lcl_isOnNumberChar(rStr, io_rPos, bSignAllowed))
157             {
158                 bSignAllowed = false;
159                 ++io_rPos;
160             }
161         }
162 
lcl_skipDouble(sal_Int32 & io_rPos,const::rtl::OUString & rStr)163         void lcl_skipDouble(sal_Int32& 				io_rPos,
164                             const ::rtl::OUString& 	rStr)
165         {
166             sal_Unicode aChar( rStr[io_rPos] );
167 
168             if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
169                 aChar = rStr[++io_rPos];
170 
171             while((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
172                     || sal_Unicode('.') == aChar)
173             {
174                 aChar = rStr[++io_rPos];
175             }
176 
177             if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar)
178             {
179                 aChar = rStr[++io_rPos];
180 
181                 if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
182                     aChar = rStr[++io_rPos];
183 
184                 while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
185                 {
186                     aChar = rStr[++io_rPos];
187                 }
188             }
189         }
190 
lcl_putNumberCharWithSpace(::rtl::OUStringBuffer & rStr,double fValue,double fOldValue,bool bUseRelativeCoordinates)191         void lcl_putNumberCharWithSpace( ::rtl::OUStringBuffer& rStr,
192                                             double 		        fValue,
193                                             double 		        fOldValue,
194                                             bool 			        bUseRelativeCoordinates )
195         {
196             if( bUseRelativeCoordinates )
197                 fValue -= fOldValue;
198 
199             const sal_Int32 aLen( rStr.getLength() );
200             if(aLen)
201             {
202                 if( lcl_isOnNumberChar(rStr.charAt(aLen - 1), false) &&
203                     fValue >= 0.0 )
204                 {
205                     rStr.append( sal_Unicode(' ') );
206                 }
207             }
208 
209             lcl_putNumberChar(rStr, fValue);
210         }
211     } // namespace internal
212 }
213 
214 // eof
215