(file) Return to CQLUtilities.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / CQL

  1 martin 1.22 //%LICENSE////////////////////////////////////////////////////////////////
  2 martin 1.23 //
  3 martin 1.22 // Licensed to The Open Group (TOG) under one or more contributor license
  4             // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
  5             // this work for additional information regarding copyright ownership.
  6             // Each contributor licenses this file to you under the OpenPegasus Open
  7             // Source License; you may not use this file except in compliance with the
  8             // License.
  9 martin 1.23 //
 10 martin 1.22 // Permission is hereby granted, free of charge, to any person obtaining a
 11             // copy of this software and associated documentation files (the "Software"),
 12             // to deal in the Software without restriction, including without limitation
 13             // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 14             // and/or sell copies of the Software, and to permit persons to whom the
 15             // Software is furnished to do so, subject to the following conditions:
 16 martin 1.23 //
 17 martin 1.22 // The above copyright notice and this permission notice shall be included
 18             // in all copies or substantial portions of the Software.
 19 martin 1.23 //
 20 martin 1.22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 21 martin 1.23 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 22 martin 1.22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 23             // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 24             // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 25             // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 26             // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27 martin 1.23 //
 28 martin 1.22 //////////////////////////////////////////////////////////////////////////
 29 chuck  1.2  //
 30             //%/////////////////////////////////////////////////////////////////////////////
 31 lucier 1.7  
 32 chuck  1.2  #include <Pegasus/CQL/CQLUtilities.h>
 33 lucier 1.7  
 34             // Query includes
 35             #include <Pegasus/Query/QueryCommon/QueryException.h>
 36             
 37             // Pegasus Common includes
 38             #include <Pegasus/Common/Tracer.h>
 39 ajay.rao 1.26 #include <Pegasus/Common/StringConversion.h>
 40 lucier   1.7  
 41               // standard includes
 42 chuck    1.3  #include <errno.h>
 43 chuck    1.2  
 44 lucier   1.7  // symbol defines
 45 chuck    1.2  
 46 lucier   1.7  // required for the windows compile
 47 lucier   1.5  #ifndef _MSC_VER
 48               #define _MSC_VER 0
 49               #endif
 50               
 51 chuck    1.2  PEGASUS_NAMESPACE_BEGIN
 52               
 53 ajay.rao 1.26 const char CQLUtilities::KEY[] = "CQL.CQLUtilities.INVALID_STRING";
 54               const char CQLUtilities::MSG[] = "Error converting string to $0. "
 55                   " String '$1' is invalid or causes an overflow ";
 56 chuck    1.2  
 57               Uint64 CQLUtilities::stringToUint64(const String &stringNum)
 58               {
 59 karl     1.19     PEG_METHOD_ENTER(TRC_CQL,"CQLUtilities::stringToUint64()");
 60                   Uint64 x = 0;
 61 ajay.rao 1.26     CString cstrNum = stringNum.getCString();
 62                   const char *p = (const char*)cstrNum;
 63                   const char *pstart = p;
 64                   Boolean isError = false;
 65                   Uint32 endStr = 0;
 66 kumpf    1.24 
 67 ajay.rao 1.26     if (*p)
 68 karl     1.19     {
 69 ajay.rao 1.26         endStr = stringNum.size() - 1;
 70 chuck    1.2      }
 71               
 72 kumpf    1.24     // If the string is a real number, use stringToReal, then convert to
 73 karl     1.19     // a Uint64
 74                   if (isReal(stringNum))
 75 lucier   1.7      {
 76 karl     1.19         // Note:  the cast will rip off any non-whole number precision.
 77 kumpf    1.24         // CQL spec is silent on whether to round up, round down, throw an
 78                       // error, or allow the platform to round as it sees fit.
 79 karl     1.19         // We chose the latter for now.
 80                       return (Uint64) stringToReal64(stringNum);
 81 lucier   1.7      }
 82 chuck    1.2  
 83 ajay.rao 1.26     if (*p == '+')
 84 chuck    1.2      {
 85 ajay.rao 1.26         ++p;
 86 chuck    1.2      }
 87               
 88 ajay.rao 1.26     // There cannot be a negative '-' sign or empty string
 89                   if (*p == '-' || !*p)
 90                   {
 91                        isError = true;
 92                   }
 93                   else if (!((*p >= '0') && (*p <= '9')))
 94 lucier   1.7      {
 95 ajay.rao 1.26          isError = true;
 96 karl     1.19     }
 97                   // if hexidecimal
 98 ajay.rao 1.26     else  if ( ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X'))))
 99 karl     1.19     {
100 ajay.rao 1.26          if (!StringConversion::hexStringToUint64(p,x,true))
101                        {
102                           isError = true;
103                        }
104                   }
105                   else if (pstart[endStr] == 'b' || pstart[endStr] == 'B')
106                   {
107                        if (!StringConversion::binaryStringToUint64(p,x,true))
108                        {
109                           isError = true;
110                        }
111                   }
112                   else if (!StringConversion::decimalStringToUint64(p,x,true))
113 karl     1.19     {
114 ajay.rao 1.26          isError = true;
115 lucier   1.7      }
116 ajay.rao 1.26     // return the value for the decimal string
117                   if(isError)
118 karl     1.19     {
119 ajay.rao 1.26        MessageLoaderParms mload(
120                          CQLUtilities::KEY,
121                          CQLUtilities::MSG,
122                          "Uint64",
123                          stringNum);
124                      throw CQLRuntimeException(mload);
125 lucier   1.7      }
126 ajay.rao 1.26     else
127 karl     1.19     {
128 ajay.rao 1.26       PEG_METHOD_EXIT();
129                     return x;
130 karl     1.19     }
131 chuck    1.2  }
132               
133               Sint64 CQLUtilities::stringToSint64(const String &stringNum)
134               {
135 karl     1.19     PEG_METHOD_ENTER(TRC_CQL,"CQLUtilities::stringToSint64()");
136                   Sint64 x = 0;
137 ajay.rao 1.26     CString cstrNum = stringNum.getCString();
138                   const char *p = (const char*)cstrNum;
139                   const char* pstart = p;
140                   Boolean isError = false;
141                   Uint32 endStr = 0;
142 kumpf    1.24 
143 ajay.rao 1.26     if (*p)
144 karl     1.19     {
145 ajay.rao 1.26         endStr = stringNum.size() - 1;
146 chuck    1.2      }
147               
148 kumpf    1.24     // If the string is a real number, use stringToReal, then convert to
149 karl     1.19     // a Sint64
150                   if (isReal(stringNum))
151 lucier   1.7      {
152 kumpf    1.24         // Note:  the cast will rip off any non-whole number precision.
153 karl     1.19         // CQL spec is silent on whether to round up, round down, throw
154 kumpf    1.24         // an error, or allow the platform to round as it sees fit.
155 karl     1.19         // We chose the latter for now.
156                       return (Sint64) stringToReal64(stringNum);
157 lucier   1.7      }
158 kumpf    1.24 
159 karl     1.19     // skip over the sign if there is one
160 ajay.rao 1.26     if ((*p == '-')||(*p == '+'))
161 chuck    1.2      {
162 karl     1.19         p++;
163 chuck    1.2      }
164 kumpf    1.24 
165 ajay.rao 1.26     if (!(*p >= '0') && (*p <= '9'))
166 karl     1.19     {
167 ajay.rao 1.26         isError = true;
168 karl     1.19     }
169               
170                   // ********************
171                   // Build the Sint64 as a negative number, regardless of the
172                   // eventual sign (negative numbers can be bigger than positive ones)
173                   // ********************
174 kumpf    1.24 
175 karl     1.19     // if hexidecimal
176 ajay.rao 1.26     else if ( (*p == '0') && (p[1] == 'x') || (p[1] == 'X'))
177 karl     1.19     {
178                       // Convert a hexadecimal string
179 ajay.rao 1.26         if (!StringConversion::stringToSint64(
180                           (const char *)(stringNum.getCString()),
181                           StringConversion::hexStringToUint64,
182                           x))
183 karl     1.19         {
184 ajay.rao 1.26            isError = true;
185 karl     1.19         }
186               
187 ajay.rao 1.26         // return value from the hex string
188 kumpf    1.24 
189                   }  // end if hexidecimal
190 karl     1.19 
191                   // if binary
192 ajay.rao 1.26 
193                   else if ( (pstart[endStr] == 'b') || (pstart[endStr] == 'B') )
194 karl     1.19     {
195 chuck    1.2      // Add on each digit, checking for overflow errors
196 ajay.rao 1.26       if (!StringConversion::stringToSint64(
197                         (const char *)(stringNum.getCString()),
198                         StringConversion::binaryStringToUint64,
199                         x))
200                      {
201                         isError = true;
202                      }
203 karl     1.19 
204 ajay.rao 1.26     // return value from the binary string
205 karl     1.19 
206 ajay.rao 1.26     }  // end if binary
207 kumpf    1.24 
208 ajay.rao 1.26     // Expect a positive decimal digit:
209 chuck    1.2  
210               
211 ajay.rao 1.26     else if (!StringConversion::stringToSint64(
212                        (const char *)(stringNum.getCString()),
213                        StringConversion::decimalStringToUint64,
214                        x))
215 chuck    1.2      {
216 ajay.rao 1.26        isError = true;
217 chuck    1.2      }
218 ajay.rao 1.26     if(isError)
219 lucier   1.7      {
220 ajay.rao 1.26       MessageLoaderParms mload(
221                         CQLUtilities::KEY,
222                         CQLUtilities::MSG,
223                         "Sint64",
224                         stringNum);
225                     throw CQLRuntimeException(mload);
226 karl     1.19 
227 lucier   1.7      }
228 ajay.rao 1.26     else
229 lucier   1.7      {
230 ajay.rao 1.26       PEG_METHOD_EXIT();
231                     return x;
232 lucier   1.7      }
233 chuck    1.2  
234               }
235               
236               Real64 CQLUtilities::stringToReal64(const String &stringNum)
237               {
238 karl     1.19     PEG_METHOD_ENTER(TRC_CQL,"CQLUtilities::stringToReal64()");
239 kumpf    1.24 
240 karl     1.19     Real64 x = 0;
241 ajay.rao 1.26     CString cstrNum = stringNum.getCString();
242                   const char *p = (const char*)cstrNum;
243 karl     1.19     Boolean neg = false;
244 kumpf    1.24 
245 karl     1.19     if (*p  == '-')
246                   {
247                       neg = true;
248 ajay.rao 1.26     }
249                   if(!isReal(stringNum))
250 karl     1.19     {
251 ajay.rao 1.26       // Check if it it is a binary or hex integer
252                     Uint32 endString = stringNum.size() - 1;
253 karl     1.19         if (neg)
254                           x = stringToSint64(stringNum);
255                       else
256 chuck    1.2  
257 karl     1.19 // Check if the complier is MSVC 6, which does not support the conversion
258 kumpf    1.24 //  operator from Uint64 to Real64
259 lucier   1.5  #if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC) && (_MSC_VER < 1300)
260 ajay.rao 1.26        {
261                        Uint64 num = stringToUint64(stringNum);
262                        Sint64 half = num / 2;
263                        x = half;
264                        x += half;
265                        if (num % 2)  // if odd, then add the lost remainder
266                            x += 1;
267                      }
268 lucier   1.5  #else
269 karl     1.19         x = stringToUint64(stringNum);
270 kumpf    1.24 #endif
271 karl     1.19         PEG_METHOD_EXIT();
272                       return x;
273 kumpf    1.24     }
274               
275 karl     1.19     //
276                   // Do the conversion
277                   //
278 ajay.rao 1.26     if (!StringConversion::stringToReal64(
279                       (const char *)(stringNum.getCString()),
280                       x))
281                   {
282                     MessageLoaderParms mload(
283                         CQLUtilities::KEY,
284                         CQLUtilities::MSG,
285                         "Real64",
286                         stringNum);
287                     throw CQLRuntimeException(mload);
288 chuck    1.2      }
289 karl     1.19     PEG_METHOD_EXIT();
290                   //  printf("String %s = %.16e\n", (const char *)stringNum.getCString(), x);
291                     return x;
292 chuck    1.2  }
293               
294 lucier   1.11 String CQLUtilities::formatRealStringExponent(const String &realString)
295               {
296 karl     1.19     String newString(realString);
297                   Uint32 expIndex = PEG_NOT_FOUND;
298                   Uint32 index = newString.size() - 1;
299 kumpf    1.24 
300 karl     1.19     expIndex = newString.find('E');
301                   if (expIndex == PEG_NOT_FOUND)
302                       expIndex = newString.find('e');
303 kumpf    1.24 
304 karl     1.19     if (expIndex == PEG_NOT_FOUND)
305                       return newString;  // no exponent symbol, so just return
306 kumpf    1.24 
307 karl     1.19     // format the exponent
308                   index = expIndex + 1;  // start index at next character
309                   if (newString[index] == '+')
310                       newString.remove(index, 1);  // remove the '+' symbol
311 kumpf    1.24 
312 karl     1.19     if (newString[index] == '-')
313                       index++;   // skip the '-' exponent sign
314 kumpf    1.24 
315 karl     1.19     while (newString[index] == '0' && index < newString.size())
316                   {
317                       newString.remove(index, 1);
318                   }
319 kumpf    1.24 
320 karl     1.19     // If only an 'e' is left (only 0's behind it) then strip the 'e'
321                   if (index >= newString.size())
322                       newString.remove(expIndex, 1);
323 kumpf    1.24 
324 karl     1.19     return newString;
325 lucier   1.11 }
326               
327 humberto 1.12 Boolean CQLUtilities::isReal(const String &numString)
328               {
329 karl     1.19     // If there is a decimal point, we consider it to be a real.
330                   if (numString.find('.') == PEG_NOT_FOUND)
331                       return false;
332                   return true;
333 humberto 1.12 }
334               
335 chuck    1.2  PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2